diff --git a/forge-ai/src/main/java/forge/ai/CreatureEvaluator.java b/forge-ai/src/main/java/forge/ai/CreatureEvaluator.java index a9a58304bd4..75a02f932ef 100644 --- a/forge-ai/src/main/java/forge/ai/CreatureEvaluator.java +++ b/forge-ai/src/main/java/forge/ai/CreatureEvaluator.java @@ -45,7 +45,7 @@ public class CreatureEvaluator implements Function { value += addValue(toughness * 10, "toughness: " + toughness); // because backside is always stronger the potential makes it better than a single faced card - if (c.hasKeyword(Keyword.DAYBOUND)) { + if (c.hasKeyword(Keyword.DAYBOUND) && c.hasBackSide()) { value += addValue(power * 10, "transforming"); } } diff --git a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java index b9816b409de..a8ff585f6ca 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -3486,7 +3486,8 @@ public class AbilityUtils { } if (value.equals("OpponentsAttackedThisCombat")) { - return doXMath(game.getCombat().getAttackedOpponents(player).size(), m, source, ctb); + int amount = game.getCombat() == null ? 0 : game.getCombat().getAttackedOpponents(player).size(); + return doXMath(amount, m, source, ctb); } if (value.equals("DungeonsCompleted")) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/ControlGainEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ControlGainEffect.java index a7133e10f6a..5a9da7560c9 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ControlGainEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ControlGainEffect.java @@ -124,11 +124,12 @@ public class ControlGainEffect extends SpellAbilityEffect { sa.getParam("Chooser"), sa).get(0) : activator; CardCollectionView choices = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), sa.getParam("Choices"), activator, source, sa); - if (!choices.isEmpty()) { - String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : - Localizer.getInstance().getMessage("lblChooseaCard") +" "; - tgtCards = chooser.getController().chooseCardsForEffect(choices, sa, title, 1, 1, false, null); + if (choices.isEmpty()) { + return; } + String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : + Localizer.getInstance().getMessage("lblChooseaCard") +" "; + tgtCards = chooser.getController().chooseCardsForEffect(choices, sa, title, 1, 1, false, null); } else { tgtCards = getDefinedCards(sa); } diff --git a/forge-game/src/main/java/forge/game/card/CardProperty.java b/forge-game/src/main/java/forge/game/card/CardProperty.java index 05740a79848..0af9888951c 100644 --- a/forge-game/src/main/java/forge/game/card/CardProperty.java +++ b/forge-game/src/main/java/forge/game/card/CardProperty.java @@ -1703,7 +1703,7 @@ public class CardProperty { return false; } } else if (property.equals("hadToAttackThisCombat")) { - AttackRequirement e = game.getCombat().getAttackConstraints().getRequirements().get(card); + AttackRequirement e = combat.getAttackConstraints().getRequirements().get(card); if (e == null || !e.hasCreatureRequirement() || !e.getAttacker().equalsWithTimestamp(card)) { return false; } diff --git a/forge-game/src/main/java/forge/game/trigger/Trigger.java b/forge-game/src/main/java/forge/game/trigger/Trigger.java index d736589e14d..ad862b5c5bf 100644 --- a/forge-game/src/main/java/forge/game/trigger/Trigger.java +++ b/forge-game/src/main/java/forge/game/trigger/Trigger.java @@ -384,7 +384,8 @@ public abstract class Trigger extends TriggerReplacementBase { for (Player opp : this.getHostCard().getController().getOpponents()) { if (opp.equals(attackedP)) { continue; - } else if (opp.getLife() > life) { + } + if (opp.getLife() > life) { found = true; break; } diff --git a/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java b/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java index 277fd56868c..012c3712426 100644 --- a/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java +++ b/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java @@ -175,21 +175,6 @@ public class WrappedAbility extends Ability { return sa.copy(); } - @Override - public Player getActivatingPlayer() { - return sa.getActivatingPlayer(); - } - - @Override - public String getDescription() { - return sa.getDescription(); - } - - @Override - public ManaCost getMultiKickerManaCost() { - return sa.getMultiKickerManaCost(); - } - @Override public SpellAbilityRestriction getRestrictions() { return sa.getRestrictions(); @@ -249,14 +234,18 @@ public class WrappedAbility extends Ability { } @Override - public AbilitySub getSubAbility() { - return sa.getSubAbility(); + public void setStackDescription(final String s) { + sa.setStackDescription(s); } @Override public TargetRestrictions getTargetRestrictions() { return sa.getTargetRestrictions(); } + @Override + public void setTargetRestrictions(final TargetRestrictions tgt) { + sa.setTargetRestrictions(tgt); + } @Override public Card getTargetCard() { @@ -267,6 +256,10 @@ public class WrappedAbility extends Ability { public TargetChoices getTargets() { return sa.getTargets(); } + @Override + public void setTargets(TargetChoices targets) { + sa.setTargets(targets); + } @Override public boolean isAbility() { @@ -327,16 +320,28 @@ public class WrappedAbility extends Ability { // sa.resetOnceResolved(); } + @Override + public Player getActivatingPlayer() { + return sa.getActivatingPlayer(); + } @Override public void setActivatingPlayer(final Player player) { sa.setActivatingPlayer(player); } + @Override + public String getDescription() { + return sa.getDescription(); + } @Override public void setDescription(final String s) { sa.setDescription(s); } + @Override + public ManaCost getMultiKickerManaCost() { + return sa.getMultiKickerManaCost(); + } @Override public void setMultiKickerManaCost(final ManaCost cost) { sa.setMultiKickerManaCost(cost); @@ -358,25 +363,14 @@ public class WrappedAbility extends Ability { } @Override - public void setStackDescription(final String s) { - sa.setStackDescription(s); + public AbilitySub getSubAbility() { + return sa.getSubAbility(); } - @Override public void setSubAbility(final AbilitySub subAbility) { sa.setSubAbility(subAbility); } - @Override - public void setTargetRestrictions(final TargetRestrictions tgt) { - sa.setTargetRestrictions(tgt); - } - - @Override - public void setTargets(TargetChoices targets) { - sa.setTargets(targets); - } - @Override public void setTargetCard(final Card card) { sa.setTargetCard(card); diff --git a/forge-gui/res/cardsfolder/upcoming/astral_confrontation.txt b/forge-gui/res/cardsfolder/upcoming/astral_confrontation.txt new file mode 100644 index 00000000000..b5325fe01ae --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/astral_confrontation.txt @@ -0,0 +1,7 @@ +Name:Astral Confrontation +ManaCost:4 W +Types:Instant +S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ X | EffectZone$ All | Description$ This spell costs {1} less to cast for each opponent you're attacking. +SVar:X:PlayerCountPropertyYou$OpponentsAttackedThisCombat +A:SP$ ChangeZone | Cost$ 4 W | ValidTgts$ Creature | TgtPrompt$ Select target creature | Origin$ Battlefield | Destination$ Exile | SpellDescription$ Exile target creature. +Oracle:This spell costs 1 less to cast for each opponent you're attacking.\nExile target creature. diff --git a/forge-gui/res/cardsfolder/upcoming/bronze_walrus.txt b/forge-gui/res/cardsfolder/upcoming/bronze_walrus.txt new file mode 100644 index 00000000000..8cd0fe6cb95 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/bronze_walrus.txt @@ -0,0 +1,8 @@ +Name:Bronze Walrus +ManaCost:3 +Types:Artifact Creature Walrus +PT:2/2 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigScry | TriggerDescription$ When CARDNAME enters the battlefield, scry 2. (Look at the top two cards of your library, then put any number of them on the bottom of your library and the rest on top in any order.) +SVar:TrigScry:DB$ Scry | ScryNum$ 2 +A:AB$ Mana | Cost$ T | Produced$ Any | SpellDescription$ Add one mana of any color. +Oracle:When Bronze Walrus enters the battlefield, scry 2. (Look at the top two cards of your library, then put any number of them on the bottom of your library and the rest on top in any order.)\n{T}: Add one mana of any color. diff --git a/forge-gui/res/cardsfolder/upcoming/circle_of_the_land_druid.txt b/forge-gui/res/cardsfolder/upcoming/circle_of_the_land_druid.txt new file mode 100644 index 00000000000..7eab57122a1 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/circle_of_the_land_druid.txt @@ -0,0 +1,10 @@ +Name:Circle of the Land Druid +ManaCost:1 G +Types:Creature Gnome Druid +PT:1/1 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigMill | TriggerDescription$ When CARDNAME enters the battlefield, you may mill four cards. (You may put the top four cards of your library into your graveyard.) +SVar:TrigMill:DB$ Mill | NumCards$ 4 | Defined$ You | Optional$ True +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigChangeZone | TriggerDescription$ Natural Recovery — When CARDNAME dies, return target land card from your graveyard to your hand. +SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | ValidTgts$ Land.YouCtrl +DeckHas:Ability$Mill|Graveyard +Oracle:When Circle of the Land Druid enters the battlefield, you may mill four cards. (You may put the top four cards of your library into your graveyard.)\nNatural Recovery — When Circle of the Land Druid dies, return target land card from your graveyard to your hand. diff --git a/forge-gui/res/cardsfolder/upcoming/clockwork_fox.txt b/forge-gui/res/cardsfolder/upcoming/clockwork_fox.txt new file mode 100644 index 00000000000..c60ee91e115 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/clockwork_fox.txt @@ -0,0 +1,8 @@ +Name:Clockwork Fox +ManaCost:3 +Types:Artifact Creature Fox +PT:3/2 +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME leaves the battlefield, you draw two cards and each opponent draws a card. +SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 2 | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | Defined$ Player.Opponent | NumCards$ 1 +Oracle:When Clockwork Fox leaves the battlefield, you draw two cards and each opponent draws a card. diff --git a/forge-gui/res/editions/Alchemy Horizons Baldur's Gate.txt b/forge-gui/res/editions/Alchemy Horizons Baldur's Gate.txt index 4e9b48dd31a..e89f6086041 100644 --- a/forge-gui/res/editions/Alchemy Horizons Baldur's Gate.txt +++ b/forge-gui/res/editions/Alchemy Horizons Baldur's Gate.txt @@ -376,6 +376,26 @@ ScryfallCode=HBG 264 C Prophetic Prism @Diego Gisbert 265 C Spiked Pit Trap @Deruchenko Alexander 266 R Baldur's Gate @Titus Lunter +289 L Plains @Bruce Brenneise +290 L Plains @Leanna Crossan +291 L Plains @Titus Lunter +292 L Plains @Emmanuel Shiu +293 L Island @Bruce Brenneise +294 L Island @Piotr Dura +295 L Island @James Paick +296 L Island @Sam White +297 L Swamp @Piotr Dura +298 L Swamp @Logan Feliciano +299 L Swamp @Grady Frederick +300 L Swamp @Sam White +301 L Mountain @Matt Gaser +302 L Mountain @Lucas Graciano +303 L Mountain @Muhammad Firdaus +304 L Mountain @Sam White +305 L Forest @Bruce Brenneise +306 L Forest @Muhammad Firdaus +307 L Forest @Lucas Graciano +308 L Forest @Julian Kok Joon Wen [rebalanced] A166 C A-Sepulcher Ghoul @Jason A. Engle diff --git a/forge-gui/res/editions/Judge Gift Cards 2022.txt b/forge-gui/res/editions/Judge Gift Cards 2022.txt index 94879906576..f0b922dde4c 100644 --- a/forge-gui/res/editions/Judge Gift Cards 2022.txt +++ b/forge-gui/res/editions/Judge Gift Cards 2022.txt @@ -10,4 +10,7 @@ ScryfallCode=P22 2 R Omniscience @Alayna Danner 3 R Parallel Lives @Greg Staples 4 R Stranglehold @Ralph Horsley +5 R Smothering Tithe @Aurore Folny +6 R Training Grounds @Caroline Gariba 9 R No Mercy @John Stanko +10 R R Growing Rites of Itlimoc @Dmitry Burmak