From 404fd94a2fcb275b78b85404fc55930450c16c94 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 16 Nov 2022 22:49:56 -0500 Subject: [PATCH 01/14] comet_stellar_pup.txt --- .../upcoming/comet_stellar_pup.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/comet_stellar_pup.txt diff --git a/forge-gui/res/cardsfolder/upcoming/comet_stellar_pup.txt b/forge-gui/res/cardsfolder/upcoming/comet_stellar_pup.txt new file mode 100644 index 00000000000..532e612f816 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/comet_stellar_pup.txt @@ -0,0 +1,19 @@ +Name:Comet, Stellar Pup +ManaCost:2 R W +Types:Legendary Planeswalker Comet +Loyalty:5 +A:AB$ RollDice | Cost$ AddCounter<0/LOYALTY> | Planeswalker$ True | ResultSubAbilities$ 1-2:Token,3:Unearth,4-5:Damage,6:CometGo | SpellDescription$ Roll a six-sided die. +SVar:Token:DB$ PutCounter | CounterType$ LOYALTY | CounterNum$ 2 | SubAbility$ DBToken | SpellDescription$ 1 or 2 – [+2], then create two 1/1 green Squirrel creature tokens. They gain haste until end of turn. +SVar:DBToken:DB$ Token | TokenAmount$ 2 | TokenScript$ g_1_1_squirrel | PumpKeywords$ Haste | PumpDuration$ EOT +SVar:Unearth:DB$ RemoveCounter | CounterType$ LOYALTY | CounterNum$ 1 | SubAbility$ DBChangeZone | SpellDescription$ 3 – [-1], then return a card with mana value 2 or less from your graveyard to your hand. +SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | Mandatory$ True | ChangeType$ Card.YouOwn+cmcLE2 | ChangeDescription$ Choose a card with mana value 2 or less | Hidden$ True +SVar:Damage:DB$ ChooseEntity | CardChoices$ Creature | PlayerChoices$ Player | RememberChosen$ True | SubAbility$ DBDamage | SpellDescription$ 4 or 5 – CARDNAME deals damage equal to the number of loyalty counters on him to a creature or player, then [-2]. +SVar:DBDamage:DB$ DealDamage | NumDmg$ X | Defined$ Remembered | SubAbility$ DBRemoveCounters +SVar:X:Count$CardCounters.LOYALTY +SVar:DBRemoveCounters:DB$ RemoveCounter | CounterType$ LOYALTY | CounterNum$ 2 | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:CometGo:DB$ PutCounter | CounterType$ LOYALTY | SubAbility$ DBEffect | SpellDescription$ 6 – [+1], and you may activate CARDNAME's loyalty ability two more times this turn. +SVar:DBEffect:DB$ Effect | StaticAbilities$ LoyaltyAbs +SVar:LoyaltyAbs:Mode$ NumLoyaltyAct | ValidCard$ Card.EffectSource | Additional$ 2 | Description$ You may activate EFFECTSOURCE's loyalty ability two more times this turn. +DeckHas:Ability$Token|Graveyard & Type$Squirrel +Oracle:[0]: Roll a six-sided die.\n1 or 2 — [+2], then create two 1/1 green Squirrel creature tokens. They gain haste until end of turn.\n3 — [-1], then return a card with mana value 2 or less from your graveyard to your hand.\n4 or 5 — Comet, Stellar Pup deals damage equal to the number of loyalty counters on him to a creature or player, then [-2].\n6 — [+1], and you may activate Comet, Stellar Pup's loyalty ability two more times this turn. From 09109b7b8ed0d52ae4106cca716dff4b12e4a4f2 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 16 Nov 2022 22:55:26 -0500 Subject: [PATCH 02/14] ChooseEntityEffect allow for player choices --- .../ability/effects/ChooseEntityEffect.java | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChooseEntityEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChooseEntityEffect.java index b702c7ed633..b626627eb02 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChooseEntityEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChooseEntityEffect.java @@ -1,20 +1,17 @@ package forge.game.ability.effects; -import com.google.common.collect.Lists; import forge.game.Game; import forge.game.GameEntity; import forge.game.ability.AbilityUtils; import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; -import forge.game.card.CardCollection; import forge.game.card.CardLists; import forge.game.player.Player; -import forge.game.player.PlayerCollection; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; import forge.util.Aggregates; - -import java.util.List; +import forge.util.Localizer; +import forge.util.collect.FCollection; public class ChooseEntityEffect extends SpellAbilityEffect { @Override @@ -29,18 +26,26 @@ public class ChooseEntityEffect extends SpellAbilityEffect { final Player activator = sa.getActivatingPlayer(); final Game game = activator.getGame(); - List choices = Lists.newArrayList(); - String cardsDef = sa.getParam("CardChoices"); - String playersDef = sa.getParam("PlayerChoices"); - CardCollection cards = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), cardsDef, activator, - host, sa); - choices.addAll(cards); - PlayerCollection players = AbilityUtils.getDefinedPlayers(host, playersDef, sa); - choices.addAll(players); + FCollection choices = new FCollection<>(); + if (sa.hasParam("CardChoices")) { + choices.addAll(CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), sa.getParam("CardChoices"), + activator, host, sa)); + } + if (sa.hasParam("PlayerChoices")) { + choices.addAll(AbilityUtils.getDefinedPlayers(host, sa.getParam("PlayerChoices"), sa)); + } - Object chosen = null; - if (sa.hasParam("Random")) { // currently we only choose at random for this - chosen = Aggregates.random(choices); + FCollection chosen = new FCollection<>(); + int n = sa.hasParam("ChoiceAmount") ? AbilityUtils.calculateAmount(host, sa.getParam("ChoiceAmount"), sa) : 1; + if (sa.hasParam("Random")) { + for (int i = 0; i < n; i++) { + chosen.add(Aggregates.random(choices)); + choices.remove(chosen); + } else { + final String prompt = sa.hasParam("ChoicePrompt") ? sa.getParam("ChoicePrompt") : + Localizer.getInstance().getMessage("lblChooseEntity"); + chosen.addAll(activator.getController().chooseEntitiesForEffect(choices, n, n, null, sa, prompt, + null, null)); } if (chosen == null) { System.err.println("Error: ChooseEntityEffect.java unable to choose an entity"); @@ -48,7 +53,9 @@ public class ChooseEntityEffect extends SpellAbilityEffect { } if (sa.hasParam("RememberChosen")) { - host.addRemembered(chosen); + for (GameEntity ge : chosen) { + host.addRemembered(ge); + } } } } From ec35b9f05cec1c0deaa9582dffc5d86cd79f1dfd Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 16 Nov 2022 22:56:03 -0500 Subject: [PATCH 03/14] refactor other loyalty ability amount modifying cards --- forge-gui/res/cardsfolder/o/oath_of_teferi.txt | 2 +- forge-gui/res/cardsfolder/t/the_chain_veil.txt | 4 ++-- forge-gui/res/cardsfolder/u/urza_assembles_the_titans.txt | 6 +++--- .../upcoming/urza_lord_protector_urza_planeswalker.txt | 4 +++- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/forge-gui/res/cardsfolder/o/oath_of_teferi.txt b/forge-gui/res/cardsfolder/o/oath_of_teferi.txt index e3dbe0456a0..733d18d9f9d 100644 --- a/forge-gui/res/cardsfolder/o/oath_of_teferi.txt +++ b/forge-gui/res/cardsfolder/o/oath_of_teferi.txt @@ -6,6 +6,6 @@ SVar:TrigExile:DB$ ChangeZone | ValidTgts$ Permanent.Other+YouCtrl | Mandatory$ SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ TrigBounce | TriggerDescription$ Return exiled permanent to the battlefield. | RememberObjects$ RememberedLKI | SubAbility$ DBCleanup SVar:TrigBounce:DB$ ChangeZone | Origin$ Exile | Destination$ Battlefield | Defined$ DelayTriggerRememberedLKI SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True -S:Mode$ Continuous | AffectedZone$ Battlefield | Affected$ Planeswalker.YouCtrl | AddHiddenKeyword$ CARDNAME's loyalty abilities can be activated twice each turn rather than only once | Description$ You may activate the loyalty abilities of planeswalkers you control twice each turn rather than only once. +S:Mode$ NumLoyaltyAct | ValidCard$ Planeswalker.YouCtrl | Twice$ True | Description$ You may activate the loyalty abilities of planeswalkers you control twice each turn rather than only once. SVar:NeedsToPlay:Planeswalker.YouCtrl Oracle:When Oath of Teferi enters the battlefield, exile another target permanent you control. Return it to the battlefield under its owner's control at the beginning of the next end step.\nYou may activate the loyalty abilities of planeswalkers you control twice each turn rather than only once. diff --git a/forge-gui/res/cardsfolder/t/the_chain_veil.txt b/forge-gui/res/cardsfolder/t/the_chain_veil.txt index 887b7d12330..8a0d5967e50 100644 --- a/forge-gui/res/cardsfolder/t/the_chain_veil.txt +++ b/forge-gui/res/cardsfolder/t/the_chain_veil.txt @@ -3,8 +3,8 @@ ManaCost:4 Types:Legendary Artifact T:Mode$ Phase | Phase$ End of Turn | ActivateNoLoyaltyAbilitiesCondition$ True | ValidPlayer$ You | Execute$ TrigLoseLife | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your end step, if you didn't activate a loyalty ability of a planeswalker this turn, you lose 2 life. SVar:TrigLoseLife:DB$ LoseLife | Defined$ You | LifeAmount$ 2 -A:AB$ Effect | Cost$ 4 T | StaticAbilities$ STPump | AILogic$ ChainVeil | SpellDescription$ For each planeswalker you control, you may activate one of its loyalty abilities once this turn as though none of its loyalty abilities had been activated this turn. -SVar:STPump:Mode$ Continuous | EffectZone$ Command | AffectedZone$ Battlefield | Affected$ Planeswalker.YouCtrl | AddHiddenKeyword$ May activate CARDNAME's loyalty abilities once | Description$ For each planeswalker you control, you may activate one of its loyalty abilities once this turn as though none of its loyalty abilities had been activated this turn. +A:AB$ Effect | Cost$ 4 T | StaticAbilities$ LoyaltyAbs | AILogic$ ChainVeil | SpellDescription$ For each planeswalker you control, you may activate one of its loyalty abilities once this turn as though none of its loyalty abilities had been activated this turn. +SVar:LoyaltyAbs:Mode$ NumLoyaltyAct | ValidCard$ Planeswalker.YouCtrl | Additional$ 1 | Description$ For each planeswalker you control, you may activate one of its loyalty abilities once this turn as though none of its loyalty abilities had been activated this turn. SVar:NeedsToPlay:Planeswalker.YouCtrl AI:RemoveDeck:All AI:RemoveDeck:Random diff --git a/forge-gui/res/cardsfolder/u/urza_assembles_the_titans.txt b/forge-gui/res/cardsfolder/u/urza_assembles_the_titans.txt index c9733d36e40..1826ac67eda 100644 --- a/forge-gui/res/cardsfolder/u/urza_assembles_the_titans.txt +++ b/forge-gui/res/cardsfolder/u/urza_assembles_the_titans.txt @@ -5,8 +5,8 @@ K:Read ahead:3:DBScry,DBChangeZone,DBLoyalty SVar:DBScry:DB$ Scry | ScryNum$ 4 | SubAbility$ DBDig | SpellAbility$ Scry 4, then you may reveal the top card of your library. If a planeswalker card is revealed this way, put it into your hand. SVar:DBDig:DB$ Dig | DigNum$ 1 | Reveal$ True | ChangeNum$ All | ChangeValid$ Planeswalker | LibraryPosition2$ 0 SVar:DBChangeZone:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | ChangeType$ Planeswalker.cmcLE6 | ChangeNum$ 1 | SpellDescription$ You may put a planeswalker card with mana value 6 or less from your hand onto the battlefield. -SVar:DBLoyalty:DB$ Effect | StaticAbilities$ STPump | SpellDescription$ You may activate the loyalty abilities of planeswalkers you control twice this turn rather than only once. -SVar:STPump:Mode$ Continuous | EffectZone$ Command | AffectedZone$ Battlefield | Affected$ Planeswalker.YouCtrl | AddHiddenKeyword$ CARDNAME's loyalty abilities can be activated twice each turn rather than only once | Description$ You may activate the loyalty abilities of planeswalkers you control twice this turn rather than only once. +SVar:DBLoyalty:DB$ Effect | StaticAbilities$ PWTwice | SpellDescription$ You may activate the loyalty abilities of planeswalkers you control twice this turn rather than only once. +SVar:PWTwice:Mode$ NumLoyaltyAct | ValidCard$ Planeswalker.YouCtrl | Twice$ True | Description$ You may activate the loyalty abilities of planeswalkers you control twice this turn rather than only once. DeckNeeds:Type$Planeswalker AI:RemoveDeck:Random -Oracle:Read ahead (Choose a chapter and start with that many lore counters. Add one after your draw step. Skipped chapters don't trigger. Sacrifice after III.)\nI — Scry 4, then you may reveal the top card of your library. If a planeswalker card is revealed this way, put it into your hand.\nII — You may put a planeswalker card with mana value 6 or less from your hand onto the battlefield.\nIII — You may activate the loyalty abilities of planeswalkers you control twice this turn rather than only once. \ No newline at end of file +Oracle:Read ahead (Choose a chapter and start with that many lore counters. Add one after your draw step. Skipped chapters don't trigger. Sacrifice after III.)\nI — Scry 4, then you may reveal the top card of your library. If a planeswalker card is revealed this way, put it into your hand.\nII — You may put a planeswalker card with mana value 6 or less from your hand onto the battlefield.\nIII — You may activate the loyalty abilities of planeswalkers you control twice this turn rather than only once. diff --git a/forge-gui/res/cardsfolder/upcoming/urza_lord_protector_urza_planeswalker.txt b/forge-gui/res/cardsfolder/upcoming/urza_lord_protector_urza_planeswalker.txt index b2f358db037..559334d01a3 100644 --- a/forge-gui/res/cardsfolder/upcoming/urza_lord_protector_urza_planeswalker.txt +++ b/forge-gui/res/cardsfolder/upcoming/urza_lord_protector_urza_planeswalker.txt @@ -17,7 +17,7 @@ ManaCost:no cost Colors:white,blue Types:Legendary Planeswalker Urza Loyalty:7 -S:Mode$ Continuous | EffectZone$ Battlefield | Affected$ Card.Self | AddHiddenKeyword$ CARDNAME's loyalty abilities can be activated twice each turn rather than only once | Description$ You may activate the loyalty abilities of CARDNAME twice each turn rather than only once. +S:Mode$ NumLoyaltyAct | ValidCard$ Card.Self | Twice$ True | Description$ You may activate the loyalty abilities of CARDNAME twice each turn rather than only once. A:AB$ Effect | Cost$ AddCounter<2/LOYALTY> | Planeswalker$ True | StaticAbilities$ ReduceCost | SubAbility$ DBGainLife | SpellDescription$ Artifact, instant, and sorcery spells you cast this turn cost {2} less to cast. SVar:ReduceCost:Mode$ ReduceCost | EffectZone$ Command | ValidCard$ Artifact,Instant,Sorcery | Type$ Spell | Activator$ You | Amount$ 2 | Description$ Artifact, instant, and sorcery spells you cast this turn cost {2} less to cast. SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 2 | SpellDescription$ You gain 2 life. @@ -27,4 +27,6 @@ A:AB$ Token | Cost$ AddCounter<0/LOYALTY> | Planeswalker$ True | TokenScript$ c_ A:AB$ ChangeZone | Cost$ SubCounter<3/LOYALTY> | Planeswalker$ True | ValidTgts$ Permanent.nonLand | TgtPrompt$ Select target nonland permanent | Origin$ Battlefield | Destination$ Exile | SpellDescription$ Exile target nonland permanent. A:AB$ PumpAll | Cost$ SubCounter<10/LOYALTY> | Planeswalker$ True | Ultimate$ True | ValidCards$ Artifact.YouCtrl,Planeswalker.YouCtrl | KW$ Indestructible | SubAbility$ DBDestroyAll | SpellDescription$ Artifacts and planeswalkers you control gain indestructible until end of turn. SVar:DBDestroyAll:DB$ DestroyAll | ValidCards$ Permanent.nonLand | SpellDescription$ Destroy all nonland permanents. +DeckHas:Ability$LifeGain|Discard|Token & Type$Soldier +DeckHints:Type$Planeswalker Oracle:You may activate the loyalty abilities of Urza, Planeswalker twice each turn rather than only once.\n[+2]: Artifact, instant, and sorcery spells you cast this turn cost {2} less to cast. You gain 2 life.\n[+1]: Draw two cards, then discard a card.\n[-3]: Exile target nonland permanent.\n[-10]: Artifacts and planeswalkers you control gain indestructible until end of turn. Destroy all nonland permanents. From 9ac1754db7c8665d29b86c5fabbf4ad404eb1cfe Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 16 Nov 2022 22:56:51 -0500 Subject: [PATCH 04/14] refactor PW loyalty ability checks from KW to StaticAbilityNumLoyaltyAct --- .../spellability/SpellAbilityRestriction.java | 7 ++- .../StaticAbilityNumLoyaltyAct.java | 61 +++++++++++++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 forge-game/src/main/java/forge/game/staticability/StaticAbilityNumLoyaltyAct.java diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java b/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java index 0ed423661a0..ad7f323c46d 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java @@ -38,6 +38,7 @@ import forge.game.cost.IndividualCostPaymentInstance; import forge.game.phase.PhaseType; import forge.game.player.Player; import forge.game.staticability.StaticAbilityCastWithFlash; +import forge.game.staticability.StaticAbilityNumLoyaltyAct; import forge.game.zone.Zone; import forge.game.zone.ZoneType; import forge.util.Expressions; @@ -474,11 +475,11 @@ public class SpellAbilityRestriction extends SpellAbilityVariables { } if (sa.isPwAbility()) { - final int initialLimit = c.hasKeyword("CARDNAME's loyalty abilities can be activated twice each turn rather than only once") ? 1 : 0; - final int limits = c.getAmountOfKeyword("May activate CARDNAME's loyalty abilities once") + initialLimit; + final int initialLimit = StaticAbilityNumLoyaltyAct.limitIncrease(c) ? 1 : 0; + final int limit = StaticAbilityNumLoyaltyAct.additionalActivations(c) + initialLimit; int numActivates = c.getPlaneswalkerAbilityActivated(); - if (numActivates > limits) { + if (numActivates > limit) { return false; } } diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityNumLoyaltyAct.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityNumLoyaltyAct.java new file mode 100644 index 00000000000..ee4a98a6b6e --- /dev/null +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityNumLoyaltyAct.java @@ -0,0 +1,61 @@ +package forge.game.staticability; + +import forge.game.ability.AbilityUtils; +import forge.game.card.Card; +import forge.game.zone.ZoneType; + +/** + * The Class StaticAbility_NumLoyaltyAct. + * - used to modify how many times a planeswalker may activate loyalty abilities per turn + */ +public class StaticAbilityNumLoyaltyAct { + + static String MODE = "NumLoyaltyAct"; + + public static boolean limitIncrease(final Card card) { + for (final Card ca : card.getGame().getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) { + for (final StaticAbility stAb : ca.getStaticAbilities()) { + if (!stAb.getParam("Mode").equals(MODE) || stAb.isSuppressed() || !stAb.checkConditions()) { + continue; + } + + if (applyLimitIncrease(stAb, card)) { + return true; + } + } + } + return false; + } + + public static boolean applyLimitIncrease(final StaticAbility stAb, final Card card) { + + if (!stAb.matchesValidParam("ValidCard", card)) { + return false; + } + + if (!stAb.hasParam("Twice")) { + return false; + } + + return true; + } + + public static int additionalActivations(final Card card) { + int addl = 0; + for (final Card ca : card.getGame().getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) { + for (final StaticAbility stAb : ca.getStaticAbilities()) { + if (!stAb.getParam("Mode").equals(MODE) || stAb.isSuppressed() || !stAb.checkConditions()) { + continue; + } + if (!stAb.matchesValidParam("ValidCard", card)) { + continue; + } + if (stAb.hasParam("Additional")) { + int more = AbilityUtils.calculateAmount(card, stAb.getParam("Additional"), stAb); + addl = addl + more; + } + } + } + return addl; + } +} From 2134f92dc6df7af76fbfd21e26e116d1ec1c93b6 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 16 Nov 2022 22:57:07 -0500 Subject: [PATCH 05/14] add Comet to TypeLists.txt --- forge-gui/res/lists/TypeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/forge-gui/res/lists/TypeLists.txt b/forge-gui/res/lists/TypeLists.txt index 8e643be2944..2fc9ca37443 100644 --- a/forge-gui/res/lists/TypeLists.txt +++ b/forge-gui/res/lists/TypeLists.txt @@ -334,6 +334,7 @@ Basri Bolas Calix Chandra +Comet Dack Dakkon Daretti From 8cef5814b1502b935ba10d3a81569e448fd8cdd2 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 16 Nov 2022 22:57:25 -0500 Subject: [PATCH 06/14] typo --- forge-gui/src/main/java/forge/player/PlayerControllerHuman.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index 07a17901f8c..24cedc83146 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -631,7 +631,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont } @Override - public List chooseEntitiesForEffect(final FCollectionView optionList, final int min, final int max, + public List chooseEntitiesForEffect(final FCollectionView optionList, final int min, final int max, final DelayedReveal delayedReveal, final SpellAbility sa, final String title, final Player targetedPlayer, Map params) { // useful details for debugging problems with the mass select logic Sentry.setExtra("Card", sa.getCardView().toString()); From e32cfb65d2a1cdf0e509645cb9bf7874fc2ee201 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 16 Nov 2022 22:57:46 -0500 Subject: [PATCH 07/14] default prompt for ChooseEntityEffect --- forge-gui/res/languages/de-DE.properties | 2 ++ forge-gui/res/languages/en-US.properties | 2 ++ forge-gui/res/languages/es-ES.properties | 2 ++ forge-gui/res/languages/fr-FR.properties | 2 ++ forge-gui/res/languages/it-IT.properties | 2 ++ forge-gui/res/languages/ja-JP.properties | 2 ++ forge-gui/res/languages/pt-BR.properties | 2 ++ forge-gui/res/languages/zh-CN.properties | 2 ++ 8 files changed, 16 insertions(+) diff --git a/forge-gui/res/languages/de-DE.properties b/forge-gui/res/languages/de-DE.properties index fc27f0766f0..ae692e0253f 100644 --- a/forge-gui/res/languages/de-DE.properties +++ b/forge-gui/res/languages/de-DE.properties @@ -1876,6 +1876,8 @@ lblChooseSpecifiedRangeColors=Wähle {0} bis {1} Farbe(n) lblLeftClockwise=Links (Uhrzeigersinn) lblRightAntiClockwise=Rechts (gegen die Uhr) lblChooseDirection=Wähle eine Richtung +#ChooseEntityEffect.java +lblChooseEntity=Choose entity #ChooseGenericEffect.java lblChooseOne=Wähle eines #ChooseNumberEffect.java diff --git a/forge-gui/res/languages/en-US.properties b/forge-gui/res/languages/en-US.properties index 4b2dc10895b..3dd8c2fd28b 100644 --- a/forge-gui/res/languages/en-US.properties +++ b/forge-gui/res/languages/en-US.properties @@ -1877,6 +1877,8 @@ lblChooseSpecifiedRangeColors=Choose {0} to {1} color lblLeftClockwise=Left (clockwise) lblRightAntiClockwise=Right (anticlockwise) lblChooseDirection=Choose a direction +#ChooseEntityEffect.java +lblChooseEntity=Choose entity #ChooseGenericEffect.java lblChooseOne=Choose one #ChooseNumberEffect.java diff --git a/forge-gui/res/languages/es-ES.properties b/forge-gui/res/languages/es-ES.properties index f9f5d7a844b..f5c5c31f374 100644 --- a/forge-gui/res/languages/es-ES.properties +++ b/forge-gui/res/languages/es-ES.properties @@ -1875,6 +1875,8 @@ lblChooseSpecifiedRangeColors=Elige entre {0} y {1} colores lblLeftClockwise=Izquierda (sentido horario) lblRightAntiClockwise=Derecha (sentido antihorario) lblChooseDirection=Elige una dirección +#ChooseEntityEffect.java +lblChooseEntity=Choose entity #ChooseGenericEffect.java lblChooseOne=Elige uno #ChooseNumberEffect.java diff --git a/forge-gui/res/languages/fr-FR.properties b/forge-gui/res/languages/fr-FR.properties index 909101ea843..3b53a9ee4fb 100644 --- a/forge-gui/res/languages/fr-FR.properties +++ b/forge-gui/res/languages/fr-FR.properties @@ -1878,6 +1878,8 @@ lblChooseSpecifiedRangeColors=Choisir {0} à {1} couleur lblLeftClockwise=Gauche (dans le sens des aiguilles d''une montre) lblRightAntiClockwise=Droite (sens inverse des aiguilles d''une montre) lblChooseDirection=Choisir une direction +#ChooseEntityEffect.java +lblChooseEntity=Choose entity #ChooseGenericEffect.java lblChooseOne=Choisissez-en un #ChooseNumberEffect.java diff --git a/forge-gui/res/languages/it-IT.properties b/forge-gui/res/languages/it-IT.properties index 0529e866d8c..914faae0fea 100644 --- a/forge-gui/res/languages/it-IT.properties +++ b/forge-gui/res/languages/it-IT.properties @@ -1874,6 +1874,8 @@ lblChooseSpecifiedRangeColors=Scegli da {0} a {1} colori lblLeftClockwise=Sinistra (senso orario) lblRightAntiClockwise=Destra (senso antiorario) lblChooseDirection=Scegli una direzione +#ChooseEntityEffect.java +lblChooseEntity=Choose entity #ChooseGenericEffect.java lblChooseOne=Scegli uno #ChooseNumberEffect.java diff --git a/forge-gui/res/languages/ja-JP.properties b/forge-gui/res/languages/ja-JP.properties index fecd6c619c6..1bf2231b768 100644 --- a/forge-gui/res/languages/ja-JP.properties +++ b/forge-gui/res/languages/ja-JP.properties @@ -1874,6 +1874,8 @@ lblChooseSpecifiedRangeColors=色 {0}~{1}色を選ぶ lblLeftClockwise=左(時計回り) lblRightAntiClockwise=右(反時計回り) lblChooseDirection=方向を選ぶ +#ChooseEntityEffect.java +lblChooseEntity=Choose entity #ChooseGenericEffect.java lblChooseOne=以下から 1つを選ぶ #ChooseNumberEffect.java diff --git a/forge-gui/res/languages/pt-BR.properties b/forge-gui/res/languages/pt-BR.properties index 15be37a0af0..1eb32aacc79 100644 --- a/forge-gui/res/languages/pt-BR.properties +++ b/forge-gui/res/languages/pt-BR.properties @@ -1936,6 +1936,8 @@ lblChooseSpecifiedRangeColors=Escolha {0} a {1} cor lblLeftClockwise=Esquerda (horário) lblRightAntiClockwise=Direita (anti-horário) lblChooseDirection=Escolha a direção +#ChooseEntityEffect.java +lblChooseEntity=Choose entity #ChooseGenericEffect.java lblChooseOne=Escolha um #ChooseNumberEffect.java diff --git a/forge-gui/res/languages/zh-CN.properties b/forge-gui/res/languages/zh-CN.properties index be0a39cba5c..0f0e2cfbab1 100644 --- a/forge-gui/res/languages/zh-CN.properties +++ b/forge-gui/res/languages/zh-CN.properties @@ -1878,6 +1878,8 @@ lblChooseSpecifiedRangeColors=选择{0}到{1}种颜色 lblLeftClockwise=左(顺时针) lblRightAntiClockwise=右(逆时针) lblChooseDirection=选择一个方向 +#ChooseEntityEffect.java +lblChooseEntity=Choose entity #ChooseGenericEffect.java lblChooseOne=选择一个 #ChooseNumberEffect.java From b5e278e8ed4c2da6f41d2d69e2e7b392516ae9d4 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 17 Nov 2022 10:37:02 -0500 Subject: [PATCH 08/14] remove ChooseEntityEffect.java --- .../main/java/forge/game/ability/ApiType.java | 1 - .../ability/effects/ChooseEntityEffect.java | 61 ------------------- .../ability/effects/DamageDealEffect.java | 32 ++++++++++ .../ability/effects/DamagePreventEffect.java | 23 +++++++ forge-gui/res/cardsfolder/f/faerie_dragon.txt | 6 +- .../upcoming/comet_stellar_pup.txt | 3 +- forge-gui/res/cardsfolder/w/whimsy.txt | 6 +- forge-gui/res/languages/de-DE.properties | 3 +- forge-gui/res/languages/en-US.properties | 3 +- forge-gui/res/languages/es-ES.properties | 3 +- forge-gui/res/languages/fr-FR.properties | 3 +- forge-gui/res/languages/it-IT.properties | 3 +- forge-gui/res/languages/ja-JP.properties | 3 +- forge-gui/res/languages/pt-BR.properties | 3 +- forge-gui/res/languages/zh-CN.properties | 3 +- 15 files changed, 68 insertions(+), 88 deletions(-) delete mode 100644 forge-game/src/main/java/forge/game/ability/effects/ChooseEntityEffect.java diff --git a/forge-game/src/main/java/forge/game/ability/ApiType.java b/forge-game/src/main/java/forge/game/ability/ApiType.java index 1d1e13a525b..e19938646fb 100644 --- a/forge-game/src/main/java/forge/game/ability/ApiType.java +++ b/forge-game/src/main/java/forge/game/ability/ApiType.java @@ -41,7 +41,6 @@ public enum ApiType { ChooseCard (ChooseCardEffect.class), ChooseColor (ChooseColorEffect.class), ChooseDirection (ChooseDirectionEffect.class), - ChooseEntity (ChooseEntityEffect.class), ChooseEvenOdd (ChooseEvenOddEffect.class), ChooseNumber (ChooseNumberEffect.class), ChoosePlayer (ChoosePlayerEffect.class), diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChooseEntityEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChooseEntityEffect.java deleted file mode 100644 index b626627eb02..00000000000 --- a/forge-game/src/main/java/forge/game/ability/effects/ChooseEntityEffect.java +++ /dev/null @@ -1,61 +0,0 @@ -package forge.game.ability.effects; - -import forge.game.Game; -import forge.game.GameEntity; -import forge.game.ability.AbilityUtils; -import forge.game.ability.SpellAbilityEffect; -import forge.game.card.Card; -import forge.game.card.CardLists; -import forge.game.player.Player; -import forge.game.spellability.SpellAbility; -import forge.game.zone.ZoneType; -import forge.util.Aggregates; -import forge.util.Localizer; -import forge.util.collect.FCollection; - -public class ChooseEntityEffect extends SpellAbilityEffect { - @Override - protected String getStackDescription(SpellAbility sa) { - return sa.hasParam("StackDescription") ? sa.getParam("StackDescription") : - sa.getParamOrDefault("SpellDescription", "Write a Stack/SpellDescription!"); - } - - @Override - public void resolve(SpellAbility sa) { - final Card host = sa.getHostCard(); - final Player activator = sa.getActivatingPlayer(); - final Game game = activator.getGame(); - - FCollection choices = new FCollection<>(); - if (sa.hasParam("CardChoices")) { - choices.addAll(CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), sa.getParam("CardChoices"), - activator, host, sa)); - } - if (sa.hasParam("PlayerChoices")) { - choices.addAll(AbilityUtils.getDefinedPlayers(host, sa.getParam("PlayerChoices"), sa)); - } - - FCollection chosen = new FCollection<>(); - int n = sa.hasParam("ChoiceAmount") ? AbilityUtils.calculateAmount(host, sa.getParam("ChoiceAmount"), sa) : 1; - if (sa.hasParam("Random")) { - for (int i = 0; i < n; i++) { - chosen.add(Aggregates.random(choices)); - choices.remove(chosen); - } else { - final String prompt = sa.hasParam("ChoicePrompt") ? sa.getParam("ChoicePrompt") : - Localizer.getInstance().getMessage("lblChooseEntity"); - chosen.addAll(activator.getController().chooseEntitiesForEffect(choices, n, n, null, sa, prompt, - null, null)); - } - if (chosen == null) { - System.err.println("Error: ChooseEntityEffect.java unable to choose an entity"); - return; - } - - if (sa.hasParam("RememberChosen")) { - for (GameEntity ge : chosen) { - host.addRemembered(ge); - } - } - } -} diff --git a/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java index 5f303703298..8fcab5a2d64 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java @@ -17,13 +17,17 @@ import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; import forge.game.card.CardCollection; import forge.game.card.CardDamageMap; +import forge.game.card.CardLists; import forge.game.card.CardUtil; import forge.game.keyword.Keyword; import forge.game.player.Player; import forge.game.replacement.ReplacementType; import forge.game.spellability.SpellAbility; +import forge.game.zone.ZoneType; +import forge.util.Aggregates; import forge.util.Lang; import forge.util.Localizer; +import forge.util.collect.FCollection; public class DamageDealEffect extends DamageBaseEffect { @@ -154,6 +158,34 @@ public class DamageDealEffect extends DamageBaseEffect { final boolean divideOnResolution = sa.hasParam("DividerOnResolution"); List tgts = getTargets(sa); + if (sa.hasParam("CardChoices") || sa.hasParam("PlayerChoices")) { // choosing outside Defined/Targeted + final Player activator = sa.getActivatingPlayer(); + FCollection choices = new FCollection<>(); + if (sa.hasParam("CardChoices")) { + choices.addAll(CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), + sa.getParam("CardChoices"), activator, hostCard, sa)); + } + if (sa.hasParam("PlayerChoices")) { + choices.addAll(AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("PlayerChoices"), sa)); + } + + int n = sa.hasParam("ChoiceAmount") ? + AbilityUtils.calculateAmount(hostCard, sa.getParam("ChoiceAmount"), sa) : 1; + if (sa.hasParam("Random")) { // only for Whimsy and Faerie Dragon + for (int i = 0; i < n; i++) { + GameObject random = Aggregates.random(choices); + tgts.add(random); + choices.remove(random); + hostCard.addRemembered(random); // remember random choices for log + } + } else { // only for Comet, Stellar Pup + final String prompt = sa.hasParam("ChoicePrompt") ? sa.getParam("ChoicePrompt") : + Localizer.getInstance().getMessage("lblChooseEntityDmg"); + tgts.addAll(sa.getActivatingPlayer().getController().chooseEntitiesForEffect(choices, n, n, null, sa, + prompt, null, null)); + } + } + if (sa.hasParam("OptionalDecider")) { Player decider = Iterables.getFirst(AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("OptionalDecider"), sa), null); if (decider != null && !decider.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoyouWantDealTargetDamageToTarget", String.valueOf(dmg), tgts.toString()), null)) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/DamagePreventEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DamagePreventEffect.java index 4970b73264f..b84d1e582af 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DamagePreventEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DamagePreventEffect.java @@ -2,13 +2,19 @@ package forge.game.ability.effects; import java.util.List; +import forge.game.GameEntity; import forge.game.GameObject; import forge.game.ability.AbilityUtils; import forge.game.card.Card; import forge.game.card.CardCollection; +import forge.game.card.CardLists; import forge.game.card.CardUtil; import forge.game.player.Player; import forge.game.spellability.SpellAbility; +import forge.game.zone.ZoneType; +import forge.util.Aggregates; +import forge.util.Localizer; +import forge.util.collect.FCollection; public class DamagePreventEffect extends DamagePreventEffectBase { @@ -66,6 +72,23 @@ public class DamagePreventEffect extends DamagePreventEffectBase { int numDam = AbilityUtils.calculateAmount(host, sa.getParam("Amount"), sa); final List tgts = getTargets(sa); + if (sa.hasParam("CardChoices") || sa.hasParam("PlayerChoices")) { // choosing outside Defined/Targeted + // only for Whimsy, for more robust version see DamageDealEffect + FCollection choices = new FCollection<>(); + if (sa.hasParam("CardChoices")) { + choices.addAll(CardLists.getValidCards(host.getGame().getCardsIn(ZoneType.Battlefield), + sa.getParam("CardChoices"), sa.getActivatingPlayer(), host, sa)); + } + if (sa.hasParam("PlayerChoices")) { + choices.addAll(AbilityUtils.getDefinedPlayers(host, sa.getParam("PlayerChoices"), sa)); + } + if (sa.hasParam("Random")) { + GameObject random = Aggregates.random(choices); + tgts.add(random); + host.addRemembered(random); // remember random choices for log + } + } + final CardCollection untargetedCards = CardUtil.getRadiance(sa); final boolean targeted = sa.usesTargeting(); diff --git a/forge-gui/res/cardsfolder/f/faerie_dragon.txt b/forge-gui/res/cardsfolder/f/faerie_dragon.txt index bc6a8366519..bd249607b8a 100644 --- a/forge-gui/res/cardsfolder/f/faerie_dragon.txt +++ b/forge-gui/res/cardsfolder/f/faerie_dragon.txt @@ -22,8 +22,7 @@ SVar:White:DB$ ChooseCard | Choices$ Permanent | IncludeSpellsOnStack$ True | At SVar:DBAnimateW:DB$ Animate | Defined$ ChosenCard | Colors$ White | OverwriteColors$ True | Duration$ Permanent | LockInText$ True | SubAbility$ DBCleanup SVar:Red:DB$ ChooseCard | Choices$ Permanent | IncludeSpellsOnStack$ True | AtRandom$ True | LockInText$ True | SubAbility$ DBAnimateR | SpellDescription$ A spell or permanent chosen at random becomes red. (Mana symbols on that permanent remain unchanged.) SVar:DBAnimateR:DB$ Animate | Defined$ ChosenCard | Colors$ Red | OverwriteColors$ True | Duration$ Permanent | LockInText$ True | SubAbility$ DBCleanup -SVar:Damage3:DB$ ChooseEntity | Random$ True | CardChoices$ Creature | PlayerChoices$ Player | RememberChosen$ True | SubAbility$ DBDamage3 | SpellDescription$ CARDNAME deals 3 damage to a creature or player chosen at random. -SVar:DBDamage3:DB$ DealDamage | Defined$ Remembered | NumDmg$ 3 | SubAbility$ DBCleanup +SVar:Damage3:DB$ DealDamage | NumDmg$ 3 | Random$ True | CardChoices$ Creature | PlayerChoices$ Player | RememberRandomChoice$ True | SubAbility$ DBCleanup | SpellDescription$ CARDNAME deals 3 damage to a creature or player chosen at random. SVar:Flying:DB$ ChooseCard | Choices$ Creature | AtRandom$ True | SubAbility$ DBPump8 | SpellDescription$ A creature chosen at random gains flying until end of turn. SVar:DBPump8:DB$ Pump | Defined$ ChosenCard | KW$ Flying | SubAbility$ DBCleanup SVar:P3P3:DB$ ChooseCard | Choices$ Creature | AtRandom$ True | SubAbility$ DBPump9 | SpellDescription$ A creature chosen at random gets +3/+3 until end of turn. @@ -43,8 +42,7 @@ SVar:M2M0:DB$ ChooseCard | Choices$ Creature | AtRandom$ True | SubAbility$ DBPu SVar:DBPump15:DB$ Pump | Defined$ ChosenCard | NumAtt$ -2 | SubAbility$ DBCleanup SVar:ToHand:DB$ ChooseCard | Choices$ Creature | AtRandom$ True | SubAbility$ DBChangeZone16 | SpellDescription$ Return a creature chosen at random to its owner's hand. SVar:DBChangeZone16:DB$ ChangeZone | Defined$ ChosenCard | Origin$ Battlefield | Destination$ Hand | SubAbility$ DBCleanup -SVar:Damage1:DB$ ChooseEntity | Random$ True | CardChoices$ Creature | PlayerChoices$ Player | RememberChosen$ True | SubAbility$ DBDamage1 | SpellDescription$ CARDNAME deals 1 damage to a creature or player chosen at random. -SVar:DBDamage1:DB$ DealDamage | Defined$ Remembered | NumDmg$ 1 | SubAbility$ DBCleanup +SVar:Damage1:DB$ DealDamage | NumDmg$ 1 | Random$ True | CardChoices$ Creature | PlayerChoices$ Player | RememberRandomChoice$ True | SubAbility$ DBCleanup | SpellDescription$ CARDNAME deals 1 damage to a creature or player chosen at random. SVar:Nerf:DB$ ChooseCard | Choices$ Creature.Other | AtRandom$ True | SubAbility$ DBAnimate18 | SpellDescription$ A creature other than CARDNAME chosen at random becomes 0/2 until end of turn. SVar:DBAnimate18:DB$ Animate | Defined$ ChosenCard | Power$ 0 | Toughness$ 2 | SubAbility$ DBCleanup SVar:Exile:DB$ ChooseCard | Choices$ Creature | AtRandom$ True | SubAbility$ DBChangeZone19 | SpellDescription$ Exile a creature chosen at random. Its controller gains life equal to its power. diff --git a/forge-gui/res/cardsfolder/upcoming/comet_stellar_pup.txt b/forge-gui/res/cardsfolder/upcoming/comet_stellar_pup.txt index 532e612f816..244f604b678 100644 --- a/forge-gui/res/cardsfolder/upcoming/comet_stellar_pup.txt +++ b/forge-gui/res/cardsfolder/upcoming/comet_stellar_pup.txt @@ -7,8 +7,7 @@ SVar:Token:DB$ PutCounter | CounterType$ LOYALTY | CounterNum$ 2 | SubAbility$ D SVar:DBToken:DB$ Token | TokenAmount$ 2 | TokenScript$ g_1_1_squirrel | PumpKeywords$ Haste | PumpDuration$ EOT SVar:Unearth:DB$ RemoveCounter | CounterType$ LOYALTY | CounterNum$ 1 | SubAbility$ DBChangeZone | SpellDescription$ 3 – [-1], then return a card with mana value 2 or less from your graveyard to your hand. SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | Mandatory$ True | ChangeType$ Card.YouOwn+cmcLE2 | ChangeDescription$ Choose a card with mana value 2 or less | Hidden$ True -SVar:Damage:DB$ ChooseEntity | CardChoices$ Creature | PlayerChoices$ Player | RememberChosen$ True | SubAbility$ DBDamage | SpellDescription$ 4 or 5 – CARDNAME deals damage equal to the number of loyalty counters on him to a creature or player, then [-2]. -SVar:DBDamage:DB$ DealDamage | NumDmg$ X | Defined$ Remembered | SubAbility$ DBRemoveCounters +SVar:Damage:DB$ DealDamage | NumDmg$ X | CardChoices$ Creature | PlayerChoices$ Player | SubAbility$ DBRemoveCounters | SpellDescription$ 4 or 5 – CARDNAME deals damage equal to the number of loyalty counters on him to a creature or player, then [-2]. SVar:X:Count$CardCounters.LOYALTY SVar:DBRemoveCounters:DB$ RemoveCounter | CounterType$ LOYALTY | CounterNum$ 2 | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True diff --git a/forge-gui/res/cardsfolder/w/whimsy.txt b/forge-gui/res/cardsfolder/w/whimsy.txt index 175a4822260..4e5a0d51294 100644 --- a/forge-gui/res/cardsfolder/w/whimsy.txt +++ b/forge-gui/res/cardsfolder/w/whimsy.txt @@ -9,8 +9,7 @@ SVar:Untap:DB$ ChooseCard | Choices$ Artifact.tapped,Creature.tapped,Land.tapped SVar:DBUntap4:DB$ Untap | Defined$ ChosenCard | SubAbility$ DBCleanup SVar:Tap:DB$ ChooseCard | Choices$ Artifact.untapped,Creature.untapped,Land.untapped | AtRandom$ True | SubAbility$ DBTap5 | SpellDescription$ Tap an artifact, creature or land chosen at random. SVar:DBTap5:DB$ Tap | Defined$ ChosenCard | SubAbility$ DBCleanup -SVar:Damage:DB$ ChooseEntity | Random$ True | CardChoices$ Creature | PlayerChoices$ Player | RememberChosen$ True | SubAbility$ DBDamage6 | SpellDescription$ CARDNAME deals 4 damage to a creature or player chosen at random. -SVar:DBDamage6:DB$ DealDamage | Defined$ Remembered | NumDmg$ 4 | SubAbility$ DBCleanup +SVar:Damage:DB$ DealDamage | NumDmg$ 4 | Random$ True | CardChoices$ Creature | PlayerChoices$ Player | SubAbility$ DBCleanup | SpellDescription$ CARDNAME deals 4 damage to a creature or player chosen at random. SVar:Draw3:DB$ ChoosePlayer | Choices$ Player | Random$ True | SubAbility$ DBDraw7 | SpellDescription$ A player chosen at random draws three cards. SVar:DBDraw7:DB$ Draw | NumCards$ 3 | Defined$ ChosenPlayer | SubAbility$ DBCleanup SVar:DestroyGain:DB$ ChooseCard | Choices$ Artifact | AtRandom$ True | SubAbility$ DBDestroy8 | SpellDescription$ Destroy an artifact chosen at random. It can't be regenerated. That artifact's controller gains life equal to its converted mana cost. @@ -21,8 +20,7 @@ SVar:DestroyAE:DB$ ChooseCard | Choices$ Artifact,Enchantment | AtRandom$ True | SVar:DBDestroy9:DB$ Destroy | Defined$ ChosenCard | SubAbility$ DBCleanup SVar:Gain3:DB$ ChoosePlayer | Choices$ Player | Random$ True | SubAbility$ DBGainLife10 | SpellDescription$ A player chosen at random gains 3 life. SVar:DBGainLife10:DB$ GainLife | Defined$ ChosenPlayer | LifeAmount$ 3 | SubAbility$ DBCleanup -SVar:Anoint:DB$ ChooseEntity | Random$ True | CardChoices$ Creature | PlayerChoices$ Player | RememberChosen$ True | SubAbility$ DBPreventDamage11 | SpellDescription$ Prevent the next 3 damage that would be dealt to a creature or player chosen at random this turn. -SVar:DBPreventDamage11:DB$ PreventDamage | Defined$ Remembered | Amount$ 3 | SubAbility$ DBCleanup +SVar:Anoint:DB$ PreventDamage | Random$ True | CardChoices$ Creature | PlayerChoices$ Player | Amount$ 3 | SubAbility$ DBCleanup | SpellDescription$ Prevent the next 3 damage that would be dealt to a creature or player chosen at random this turn. SVar:DestroyCL:DB$ ChooseCard | Choices$ Creature,Land | AtRandom$ True | SubAbility$ DBDestroy12 | SpellDescription$ Destroy a creature or land chosen at random. It can't be regenerated. SVar:DBDestroy12:DB$ Destroy | Defined$ ChosenCard | NoRegen$ True | SubAbility$ DBCleanup SVar:Mill2:DB$ ChoosePlayer | Choices$ Player | Random$ True | SubAbility$ DBMill13 | SpellDescription$ A player chosen at random mills two cards. diff --git a/forge-gui/res/languages/de-DE.properties b/forge-gui/res/languages/de-DE.properties index ae692e0253f..8eaf0cdf173 100644 --- a/forge-gui/res/languages/de-DE.properties +++ b/forge-gui/res/languages/de-DE.properties @@ -1876,8 +1876,6 @@ lblChooseSpecifiedRangeColors=Wähle {0} bis {1} Farbe(n) lblLeftClockwise=Links (Uhrzeigersinn) lblRightAntiClockwise=Rechts (gegen die Uhr) lblChooseDirection=Wähle eine Richtung -#ChooseEntityEffect.java -lblChooseEntity=Choose entity #ChooseGenericEffect.java lblChooseOne=Wähle eines #ChooseNumberEffect.java @@ -1946,6 +1944,7 @@ lblChooseCardsToTakeTargetCounters=Nimm {0}-Marken von welcher Karte lblSelectRemoveCountersNumberOfTarget=Wähle die zu entfernende Anzahl %s-Marken lblSelectCountersTypeToRemove=Wähle Marken-Typ fürs Entfernen #DamageDealEffect.java +lblChooseEntityDmg=Choose entity for damage lblDoyouWantDealTargetDamageToTarget=Soll {1} {0} Schaden erleiden? #DigEffect.java lblChooser=Auswählender diff --git a/forge-gui/res/languages/en-US.properties b/forge-gui/res/languages/en-US.properties index 3dd8c2fd28b..66fcc0e914c 100644 --- a/forge-gui/res/languages/en-US.properties +++ b/forge-gui/res/languages/en-US.properties @@ -1877,8 +1877,6 @@ lblChooseSpecifiedRangeColors=Choose {0} to {1} color lblLeftClockwise=Left (clockwise) lblRightAntiClockwise=Right (anticlockwise) lblChooseDirection=Choose a direction -#ChooseEntityEffect.java -lblChooseEntity=Choose entity #ChooseGenericEffect.java lblChooseOne=Choose one #ChooseNumberEffect.java @@ -1947,6 +1945,7 @@ lblChooseCardsToTakeTargetCounters=Choose cards to take {0} counters from lblSelectRemoveCountersNumberOfTarget=Select the number of {0} counters to remove lblSelectCountersTypeToRemove=Select type of counters to remove #DamageDealEffect.java +lblChooseEntityDmg=Choose entity for damage lblDoyouWantDealTargetDamageToTarget=Do you want to deal {0} damage to {1}? #DigEffect.java lblChooser=Chooser diff --git a/forge-gui/res/languages/es-ES.properties b/forge-gui/res/languages/es-ES.properties index f5c5c31f374..a1a5df2fb83 100644 --- a/forge-gui/res/languages/es-ES.properties +++ b/forge-gui/res/languages/es-ES.properties @@ -1875,8 +1875,6 @@ lblChooseSpecifiedRangeColors=Elige entre {0} y {1} colores lblLeftClockwise=Izquierda (sentido horario) lblRightAntiClockwise=Derecha (sentido antihorario) lblChooseDirection=Elige una dirección -#ChooseEntityEffect.java -lblChooseEntity=Choose entity #ChooseGenericEffect.java lblChooseOne=Elige uno #ChooseNumberEffect.java @@ -1945,6 +1943,7 @@ lblChooseCardsToTakeTargetCounters=Elige las cartas de las que coger {0} contado lblSelectRemoveCountersNumberOfTarget=Selecciona el número de {0} contadores a eliminar lblSelectCountersTypeToRemove=Selecciona el tipo de contadores a eliminar #DamageDealEffect.java +lblChooseEntityDmg=Choose entity for damage lblDoyouWantDealTargetDamageToTarget=¿Quieres hacer {0} de daño a {1}? #DigEffect.java lblChooser=Elector diff --git a/forge-gui/res/languages/fr-FR.properties b/forge-gui/res/languages/fr-FR.properties index 3b53a9ee4fb..fdd8dbc3bd6 100644 --- a/forge-gui/res/languages/fr-FR.properties +++ b/forge-gui/res/languages/fr-FR.properties @@ -1878,8 +1878,6 @@ lblChooseSpecifiedRangeColors=Choisir {0} à {1} couleur lblLeftClockwise=Gauche (dans le sens des aiguilles d''une montre) lblRightAntiClockwise=Droite (sens inverse des aiguilles d''une montre) lblChooseDirection=Choisir une direction -#ChooseEntityEffect.java -lblChooseEntity=Choose entity #ChooseGenericEffect.java lblChooseOne=Choisissez-en un #ChooseNumberEffect.java @@ -1948,6 +1946,7 @@ lblChooseCardsToTakeTargetCounters=Choisissez des cartes pour prendre {0} marque lblSelectRemoveCountersNumberOfTarget=Sélectionnez le nombre de {0} marqueurs à supprimer lblSelectCountersTypeToRemove=Sélectionner le type de marqueurs à supprimer #DamageDealEffect.java +lblChooseEntityDmg=Choose entity for damage lblDoyouWantDealTargetDamageToTarget=Voulez-vous infliger {0} dégâts à {1} ? #DigEffect.java lblChooser=Sélecteur diff --git a/forge-gui/res/languages/it-IT.properties b/forge-gui/res/languages/it-IT.properties index 914faae0fea..5230f87f331 100644 --- a/forge-gui/res/languages/it-IT.properties +++ b/forge-gui/res/languages/it-IT.properties @@ -1874,8 +1874,6 @@ lblChooseSpecifiedRangeColors=Scegli da {0} a {1} colori lblLeftClockwise=Sinistra (senso orario) lblRightAntiClockwise=Destra (senso antiorario) lblChooseDirection=Scegli una direzione -#ChooseEntityEffect.java -lblChooseEntity=Choose entity #ChooseGenericEffect.java lblChooseOne=Scegli uno #ChooseNumberEffect.java @@ -1944,6 +1942,7 @@ lblChooseCardsToTakeTargetCounters=Scegli le carte da cui prendere i segnalini { lblSelectRemoveCountersNumberOfTarget=Scegli il numero di segnalini {0} da rimuovere lblSelectCountersTypeToRemove=Scegli il tipo di segnalini da rimuovere #DamageDealEffect.java +lblChooseEntityDmg=Choose entity for damage lblDoyouWantDealTargetDamageToTarget=Vuoi infliggere {0} danno/i a {1}? #DigEffect.java lblChooser=Fai la tua scelta diff --git a/forge-gui/res/languages/ja-JP.properties b/forge-gui/res/languages/ja-JP.properties index 1bf2231b768..cf8a1c42230 100644 --- a/forge-gui/res/languages/ja-JP.properties +++ b/forge-gui/res/languages/ja-JP.properties @@ -1874,8 +1874,6 @@ lblChooseSpecifiedRangeColors=色 {0}~{1}色を選ぶ lblLeftClockwise=左(時計回り) lblRightAntiClockwise=右(反時計回り) lblChooseDirection=方向を選ぶ -#ChooseEntityEffect.java -lblChooseEntity=Choose entity #ChooseGenericEffect.java lblChooseOne=以下から 1つを選ぶ #ChooseNumberEffect.java @@ -1944,6 +1942,7 @@ lblChooseCardsToTakeTargetCounters={0}カウンターを取り除くカードを lblSelectRemoveCountersNumberOfTarget=取り除く {0}カウンターの数を選ぶ lblSelectCountersTypeToRemove=取り除くカウンターの種類を選ぶ #DamageDealEffect.java +lblChooseEntityDmg=Choose entity for damage lblDoyouWantDealTargetDamageToTarget={1}に {0}点のダメージを与えますか? #DigEffect.java lblChooser=選択者 diff --git a/forge-gui/res/languages/pt-BR.properties b/forge-gui/res/languages/pt-BR.properties index 1eb32aacc79..7bfa690f3df 100644 --- a/forge-gui/res/languages/pt-BR.properties +++ b/forge-gui/res/languages/pt-BR.properties @@ -1936,8 +1936,6 @@ lblChooseSpecifiedRangeColors=Escolha {0} a {1} cor lblLeftClockwise=Esquerda (horário) lblRightAntiClockwise=Direita (anti-horário) lblChooseDirection=Escolha a direção -#ChooseEntityEffect.java -lblChooseEntity=Choose entity #ChooseGenericEffect.java lblChooseOne=Escolha um #ChooseNumberEffect.java @@ -2006,6 +2004,7 @@ lblChooseCardsToTakeTargetCounters=Escolha as cartas para pegar {0} marcadores lblSelectRemoveCountersNumberOfTarget=Selecione o número de {0} marcadores para remover lblSelectCountersTypeToRemove=Selecione o tipo de marcadores para remover #DamageDealEffect.java +lblChooseEntityDmg=Choose entity for damage lblDoyouWantDealTargetDamageToTarget=Você quer dar {0} de dano em {1}? #DigEffect.java lblChooser=Seletor diff --git a/forge-gui/res/languages/zh-CN.properties b/forge-gui/res/languages/zh-CN.properties index 0f0e2cfbab1..b701c5bdf86 100644 --- a/forge-gui/res/languages/zh-CN.properties +++ b/forge-gui/res/languages/zh-CN.properties @@ -1878,8 +1878,6 @@ lblChooseSpecifiedRangeColors=选择{0}到{1}种颜色 lblLeftClockwise=左(顺时针) lblRightAntiClockwise=右(逆时针) lblChooseDirection=选择一个方向 -#ChooseEntityEffect.java -lblChooseEntity=Choose entity #ChooseGenericEffect.java lblChooseOne=选择一个 #ChooseNumberEffect.java @@ -1948,6 +1946,7 @@ lblChooseCardsToTakeTargetCounters=选择牌要获得{0}指示物自 lblSelectRemoveCountersNumberOfTarget=选择要删除的{0}指示物的数量 lblSelectCountersTypeToRemove=选择要删除的指示物类型 #DamageDealEffect.java +lblChooseEntityDmg=Choose entity for damage lblDoyouWantDealTargetDamageToTarget=你想对{1}造成{0}伤害吗? #DigEffect.java lblChooser=选择者 From d0249a96072c0a918f9c9f72a1164974ddc27a71 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 17 Nov 2022 10:38:51 -0500 Subject: [PATCH 09/14] remove unneeded import --- .../java/forge/game/ability/effects/DamagePreventEffect.java | 1 - 1 file changed, 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/ability/effects/DamagePreventEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DamagePreventEffect.java index b84d1e582af..a6d5774925e 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DamagePreventEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DamagePreventEffect.java @@ -13,7 +13,6 @@ import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; import forge.util.Aggregates; -import forge.util.Localizer; import forge.util.collect.FCollection; public class DamagePreventEffect extends DamagePreventEffectBase { From ac046b98d1a1c25fcdb932ae0bd6f1aee1978541 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 17 Nov 2022 15:44:55 -0500 Subject: [PATCH 10/14] tighten up Comet's outcome for roll of 6 --- .../forge/game/spellability/SpellAbilityRestriction.java | 2 +- .../game/staticability/StaticAbilityNumLoyaltyAct.java | 8 +++++++- forge-gui/res/cardsfolder/upcoming/comet_stellar_pup.txt | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java b/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java index ad7f323c46d..b22803c1936 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java @@ -476,7 +476,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables { if (sa.isPwAbility()) { final int initialLimit = StaticAbilityNumLoyaltyAct.limitIncrease(c) ? 1 : 0; - final int limit = StaticAbilityNumLoyaltyAct.additionalActivations(c) + initialLimit; + final int limit = StaticAbilityNumLoyaltyAct.additionalActivations(c, sa) + initialLimit; int numActivates = c.getPlaneswalkerAbilityActivated(); if (numActivates > limit) { diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityNumLoyaltyAct.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityNumLoyaltyAct.java index ee4a98a6b6e..43bd2d29646 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityNumLoyaltyAct.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityNumLoyaltyAct.java @@ -2,6 +2,7 @@ package forge.game.staticability; import forge.game.ability.AbilityUtils; import forge.game.card.Card; +import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; /** @@ -40,7 +41,7 @@ public class StaticAbilityNumLoyaltyAct { return true; } - public static int additionalActivations(final Card card) { + public static int additionalActivations(final Card card, final SpellAbility sa) { int addl = 0; for (final Card ca : card.getGame().getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) { for (final StaticAbility stAb : ca.getStaticAbilities()) { @@ -51,6 +52,11 @@ public class StaticAbilityNumLoyaltyAct { continue; } if (stAb.hasParam("Additional")) { + if (stAb.hasParam("OnlySourceAbs")) { + if (!stAb.getHostCard().getEffectSourceAbility().getRootAbility().equals(sa)) { + continue; + } + } int more = AbilityUtils.calculateAmount(card, stAb.getParam("Additional"), stAb); addl = addl + more; } diff --git a/forge-gui/res/cardsfolder/upcoming/comet_stellar_pup.txt b/forge-gui/res/cardsfolder/upcoming/comet_stellar_pup.txt index 244f604b678..b1b7e642804 100644 --- a/forge-gui/res/cardsfolder/upcoming/comet_stellar_pup.txt +++ b/forge-gui/res/cardsfolder/upcoming/comet_stellar_pup.txt @@ -12,7 +12,7 @@ SVar:X:Count$CardCounters.LOYALTY SVar:DBRemoveCounters:DB$ RemoveCounter | CounterType$ LOYALTY | CounterNum$ 2 | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:CometGo:DB$ PutCounter | CounterType$ LOYALTY | SubAbility$ DBEffect | SpellDescription$ 6 – [+1], and you may activate CARDNAME's loyalty ability two more times this turn. -SVar:DBEffect:DB$ Effect | StaticAbilities$ LoyaltyAbs -SVar:LoyaltyAbs:Mode$ NumLoyaltyAct | ValidCard$ Card.EffectSource | Additional$ 2 | Description$ You may activate EFFECTSOURCE's loyalty ability two more times this turn. +SVar:DBEffect:DB$ Effect | StaticAbilities$ LoyaltyAbs | RememberObjects$ Self | ExileOnMoved$ Battlefield +SVar:LoyaltyAbs:Mode$ NumLoyaltyAct | ValidCard$ Card.EffectSource | Additional$ 2 | OnlySourceAbs$ True | Description$ You may activate EFFECTSOURCE's loyalty ability two more times this turn. DeckHas:Ability$Token|Graveyard & Type$Squirrel Oracle:[0]: Roll a six-sided die.\n1 or 2 — [+2], then create two 1/1 green Squirrel creature tokens. They gain haste until end of turn.\n3 — [-1], then return a card with mana value 2 or less from your graveyard to your hand.\n4 or 5 — Comet, Stellar Pup deals damage equal to the number of loyalty counters on him to a creature or player, then [-2].\n6 — [+1], and you may activate Comet, Stellar Pup's loyalty ability two more times this turn. From 49b2b337d6bc0d5b8b0478f78e39aa6ef9dc3c1b Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 17 Nov 2022 15:47:07 -0500 Subject: [PATCH 11/14] spark_fiend.txt improve Descs --- forge-gui/res/cardsfolder/s/spark_fiend.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-gui/res/cardsfolder/s/spark_fiend.txt b/forge-gui/res/cardsfolder/s/spark_fiend.txt index 35c897e9439..70187978c77 100644 --- a/forge-gui/res/cardsfolder/s/spark_fiend.txt +++ b/forge-gui/res/cardsfolder/s/spark_fiend.txt @@ -2,14 +2,14 @@ Name:Spark Fiend ManaCost:4 R Types:Creature Beast PT:5/6 -T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigRollETB | TriggerDescription$ When Spark Fiend enters the battlefield, roll two six-sided dice. If you rolled 2, 3, or 12, sacrifice Spark Fiend. If you rolled 7 or 11, don't roll dice for Spark Fiend during any of your following upkeeps. If you rolled any other total, note that total. +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigRollETB | TriggerDescription$ When Spark Fiend enters the battlefield, roll two six-sided dice. If you rolled 2, 3, or 12, sacrifice CARDNAME. If you rolled 7 or 11, don't roll dice for CARDNAME during any of your following upkeeps. If you rolled any other total, note that total. SVar:TrigRollETB:DB$ RollDice | Amount$ 2 | ResultSubAbilities$ 2-3:DBSac,12:DBSac,7:DBSafe,Else:DBNote | ResultSVar$ Result SVar:DBSac:DB$ Sacrifice | Defined$ Self SVar:Safe:Number$1 SVar:Noted:Number$0 SVar:DBSafe:DB$ StoreSVar | SVar$ Safe | Type$ Number | Expression$ 0 SVar:DBNote:DB$ StoreSVar | SVar$ Noted | Type$ CountSVar | Expression$ Result -T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | CheckSVar$ Safe | SVarCompare$ NE0 | TriggerZones$ Battlefield | Execute$ TrigRoll | TriggerDescription$ At the beginning of your upkeep, roll two six-sided dice. If you rolled 7, sacrifice Spark Fiend. If you roll the noted total, don't roll dice for Spark Fiend during any of your following upkeeps. Otherwise, do nothing. +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | CheckSVar$ Safe | SVarCompare$ NE0 | TriggerZones$ Battlefield | Execute$ TrigRoll | TriggerDescription$ At the beginning of your upkeep, roll two six-sided dice. If you rolled 7, sacrifice CARDNAME. If you roll the noted total, don't roll dice for CARDNAME during any of your following upkeeps. Otherwise, do nothing. SVar:TrigRoll:DB$ RollDice | Amount$ 2 | ResultSubAbilities$ 7:DBSac | ResultSVar$ Result | SubAbility$ DBCheck SVar:DBCheck:DB$ StoreSVar | SVar$ Safe | Type$ CountSVar | Expression$ Result/Minus.Noted Oracle:When Spark Fiend enters the battlefield, roll two six-sided dice. If you rolled 2, 3, or 12, sacrifice Spark Fiend. If you rolled 7 or 11, don't roll dice for Spark Fiend during any of your following upkeeps. If you rolled any other total, note that total.\nAt the beginning of your upkeep, roll two six-sided dice. If you rolled 7, sacrifice Spark Fiend. If you roll the noted total, don't roll dice for Spark Fiend during any of your following upkeeps. Otherwise, do nothing. From d886a7b58c8a47b9691bd4fb853be9feea0294cd Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 17 Nov 2022 16:20:52 -0500 Subject: [PATCH 12/14] urza_lord_protector_urza_planeswalker.txt fix Oracle --- .../upcoming/urza_lord_protector_urza_planeswalker.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-gui/res/cardsfolder/upcoming/urza_lord_protector_urza_planeswalker.txt b/forge-gui/res/cardsfolder/upcoming/urza_lord_protector_urza_planeswalker.txt index 559334d01a3..ea89383e69c 100644 --- a/forge-gui/res/cardsfolder/upcoming/urza_lord_protector_urza_planeswalker.txt +++ b/forge-gui/res/cardsfolder/upcoming/urza_lord_protector_urza_planeswalker.txt @@ -17,7 +17,7 @@ ManaCost:no cost Colors:white,blue Types:Legendary Planeswalker Urza Loyalty:7 -S:Mode$ NumLoyaltyAct | ValidCard$ Card.Self | Twice$ True | Description$ You may activate the loyalty abilities of CARDNAME twice each turn rather than only once. +S:Mode$ NumLoyaltyAct | ValidCard$ Card.Self | Twice$ True | Description$ You may activate the loyalty abilities of CARDNAME twice each turn rather than only once. (You may activate the same ability twice.) A:AB$ Effect | Cost$ AddCounter<2/LOYALTY> | Planeswalker$ True | StaticAbilities$ ReduceCost | SubAbility$ DBGainLife | SpellDescription$ Artifact, instant, and sorcery spells you cast this turn cost {2} less to cast. SVar:ReduceCost:Mode$ ReduceCost | EffectZone$ Command | ValidCard$ Artifact,Instant,Sorcery | Type$ Spell | Activator$ You | Amount$ 2 | Description$ Artifact, instant, and sorcery spells you cast this turn cost {2} less to cast. SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 2 | SpellDescription$ You gain 2 life. @@ -29,4 +29,4 @@ A:AB$ PumpAll | Cost$ SubCounter<10/LOYALTY> | Planeswalker$ True | Ultimate$ Tr SVar:DBDestroyAll:DB$ DestroyAll | ValidCards$ Permanent.nonLand | SpellDescription$ Destroy all nonland permanents. DeckHas:Ability$LifeGain|Discard|Token & Type$Soldier DeckHints:Type$Planeswalker -Oracle:You may activate the loyalty abilities of Urza, Planeswalker twice each turn rather than only once.\n[+2]: Artifact, instant, and sorcery spells you cast this turn cost {2} less to cast. You gain 2 life.\n[+1]: Draw two cards, then discard a card.\n[-3]: Exile target nonland permanent.\n[-10]: Artifacts and planeswalkers you control gain indestructible until end of turn. Destroy all nonland permanents. +Oracle:You may activate the loyalty abilities of Urza, Planeswalker twice each turn rather than only once. (You may activate the same ability twice.)\n[+2]: Artifact, instant, and sorcery spells you cast this turn cost {2} less to cast. You gain 2 life.\n[+1]: Draw two cards, then discard a card.\n[0]: Create two 1/1 colorless Soldier artifact creature tokens.\n[−3]: Exile target nonland permanent.\n[−10]: Artifacts and planeswalkers you control gain indestructible until end of turn. Destroy all nonland permanents. From 36d2c8212e39fbf9a719d350beddf0ecdafdd547 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 17 Nov 2022 16:25:21 -0500 Subject: [PATCH 13/14] CMatchUI.getAbilityToPlay trim multi-line ability descs for menu --- .../src/main/java/forge/screens/match/CMatchUI.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java b/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java index 01ebb5a7c96..0b34f0a2995 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java @@ -927,7 +927,11 @@ public final class CMatchUI if (enabled && firstEnabled < 0) { firstEnabled = index; } - GuiUtils.addMenuItem(menu, FSkin.encodeSymbols(ab.toString(), true), + String s = ab.toString(); + if (s.contains("\n")) { + s = s.substring(0, s.indexOf("\n")); + } + GuiUtils.addMenuItem(menu, FSkin.encodeSymbols(s, true), shortcut > 0 ? KeyStroke.getKeyStroke(shortcut, 0) : null, new Runnable() { @Override From b651d6d14dadc59a3dc78cf441c10088c334a45a Mon Sep 17 00:00:00 2001 From: Northmoc Date: Fri, 18 Nov 2022 13:01:54 -0500 Subject: [PATCH 14/14] DamageDeal/Prevent use Targets/Defined OR Choices --- .../java/forge/game/ability/effects/DamageDealEffect.java | 4 +++- .../forge/game/ability/effects/DamagePreventEffect.java | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java index 8fcab5a2d64..0ea92400ad2 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java @@ -157,7 +157,7 @@ public class DamageDealEffect extends DamageBaseEffect { final boolean removeDamage = sa.hasParam("Remove"); final boolean divideOnResolution = sa.hasParam("DividerOnResolution"); - List tgts = getTargets(sa); + List tgts = Lists.newArrayList(); if (sa.hasParam("CardChoices") || sa.hasParam("PlayerChoices")) { // choosing outside Defined/Targeted final Player activator = sa.getActivatingPlayer(); FCollection choices = new FCollection<>(); @@ -184,6 +184,8 @@ public class DamageDealEffect extends DamageBaseEffect { tgts.addAll(sa.getActivatingPlayer().getController().chooseEntitiesForEffect(choices, n, n, null, sa, prompt, null, null)); } + } else { + tgts = getTargets(sa); } if (sa.hasParam("OptionalDecider")) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/DamagePreventEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DamagePreventEffect.java index a6d5774925e..d06dab25e17 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DamagePreventEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DamagePreventEffect.java @@ -2,6 +2,7 @@ package forge.game.ability.effects; import java.util.List; +import com.google.common.collect.Lists; import forge.game.GameEntity; import forge.game.GameObject; import forge.game.ability.AbilityUtils; @@ -70,7 +71,7 @@ public class DamagePreventEffect extends DamagePreventEffectBase { Card host = sa.getHostCard(); int numDam = AbilityUtils.calculateAmount(host, sa.getParam("Amount"), sa); - final List tgts = getTargets(sa); + List tgts = Lists.newArrayList(); if (sa.hasParam("CardChoices") || sa.hasParam("PlayerChoices")) { // choosing outside Defined/Targeted // only for Whimsy, for more robust version see DamageDealEffect FCollection choices = new FCollection<>(); @@ -81,11 +82,13 @@ public class DamagePreventEffect extends DamagePreventEffectBase { if (sa.hasParam("PlayerChoices")) { choices.addAll(AbilityUtils.getDefinedPlayers(host, sa.getParam("PlayerChoices"), sa)); } - if (sa.hasParam("Random")) { + if (sa.hasParam("Random")) { // currently everything using Choices is random GameObject random = Aggregates.random(choices); tgts.add(random); host.addRemembered(random); // remember random choices for log } + } else { + tgts = getTargets(sa); } final CardCollection untargetedCards = CardUtil.getRadiance(sa);