diff --git a/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java b/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java index 9eb1f695c08..e8c18354697 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java @@ -442,11 +442,9 @@ public class CountersPutAi extends CountersAi { } sa.addDividedAllocation(c, amount); return decision; - } else { - if (!hasSacCost) { - // for Sacrifice costs, evaluate further to see if it's worth using the ability before the card dies - return decision; - } + } else if (!hasSacCost) { + // for Sacrifice costs, evaluate further to see if it's worth using the ability before the card dies + return decision; } } } @@ -684,14 +682,12 @@ public class CountersPutAi extends CountersAi { || (sa.getRootAbility().isTrigger() && !sa.getRootAbility().isOptionalTrigger()); if (sa.usesTargeting()) { - CardCollection list = null; - + CardCollection list; if (sa.isCurse()) { list = ai.getOpponents().getCardsIn(ZoneType.Battlefield); } else { list = new CardCollection(ai.getCardsIn(ZoneType.Battlefield)); } - list = CardLists.getTargetableCards(list, sa); if (list.isEmpty() && isMandatoryTrigger) { @@ -707,9 +703,8 @@ public class CountersPutAi extends CountersAi { || sa.getTargets().isEmpty()) { sa.resetTargets(); return new AiAbilityDecision(0, AiPlayDecision.TargetingFailed); - } else { - break; } + break; } if (sa.isCurse()) { @@ -752,8 +747,6 @@ public class CountersPutAi extends CountersAi { final SpellAbility root = sa.getRootAbility(); final Card source = sa.getHostCard(); final String aiLogic = sa.getParamOrDefault("AILogic", ""); - boolean preferred = true; - CardCollection list; final String amountStr = sa.getParamOrDefault("CounterNum", "1"); final boolean divided = sa.isDividedAsYouChoose(); final int amount = AbilityUtils.calculateAmount(source, amountStr, sa); @@ -775,11 +768,11 @@ public class CountersPutAi extends CountersAi { AiAbilityDecision decision = doChargeToCMCLogic(ai, sa); if (decision.willingToPlay()) { return decision; - } else if (mandatory) { - return new AiAbilityDecision(50, AiPlayDecision.MandatoryPlay); - } else { - return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi); } + if (mandatory) { + return new AiAbilityDecision(50, AiPlayDecision.MandatoryPlay); + } + return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi); } if (!sa.usesTargeting()) { @@ -830,19 +823,19 @@ public class CountersPutAi extends CountersAi { } } - if (sa.isCurse()) { - list = ai.getOpponents().getCardsIn(ZoneType.Battlefield); - } else { - list = new CardCollection(ai.getCardsIn(ZoneType.Battlefield)); - } - list = CardLists.getTargetableCards(list, sa); - - // Filter AI-specific targets if provided - list = ComputerUtil.filterAITgts(sa, ai, list, false); - - int totalTargets = list.size(); - sa.resetTargets(); + + Iterable filteredField; + if (sa.isCurse()) { + filteredField = ai.getOpponents().getCardsIn(ZoneType.Battlefield); + } else { + filteredField = ai.getCardsIn(ZoneType.Battlefield); + } + CardCollection list = CardLists.getTargetableCards(filteredField, sa); + list = ComputerUtil.filterAITgts(sa, ai, list, false); + int totalTargets = list.size(); + boolean preferred = true; + while (sa.canAddMoreTarget()) { if (mandatory) { // When things are mandatory, gotta handle a little differently @@ -879,27 +872,21 @@ public class CountersPutAi extends CountersAi { if (choice == null && mandatory) { choice = Aggregates.random(list); } + } else if (type.equals("M1M1")) { + choice = ComputerUtilCard.getWorstCreatureAI(list); } else { - if (type.equals("M1M1")) { - choice = ComputerUtilCard.getWorstCreatureAI(list); - } else { - choice = Aggregates.random(list); - } + choice = Aggregates.random(list); } + } else if (preferred) { + list = ComputerUtil.getSafeTargets(ai, sa, list); + choice = chooseBoonTarget(list, type); + if (choice == null && mandatory) { + choice = Aggregates.random(list); + } + } else if (type.equals("P1P1")) { + choice = ComputerUtilCard.getWorstCreatureAI(list); } else { - if (preferred) { - list = ComputerUtil.getSafeTargets(ai, sa, list); - choice = chooseBoonTarget(list, type); - if (choice == null && mandatory) { - choice = Aggregates.random(list); - } - } else { - if (type.equals("P1P1")) { - choice = ComputerUtilCard.getWorstCreatureAI(list); - } else { - choice = Aggregates.random(list); - } - } + choice = Aggregates.random(list); } if (choice != null && divided) { int alloc = Math.max(amount / totalTargets, 1); @@ -1094,8 +1081,7 @@ public class CountersPutAi extends CountersAi { Player ai = sa.getActivatingPlayer(); GameEntity e = (GameEntity) params.get("Target"); // for Card try to select not useless counter - if (e instanceof Card) { - Card c = (Card) e; + if (e instanceof Card c) { if (c.getController().isOpponentOf(ai)) { if (options.contains(CounterEnumType.M1M1) && !c.hasKeyword(Keyword.UNDYING)) { return CounterEnumType.M1M1; @@ -1112,8 +1098,7 @@ public class CountersPutAi extends CountersAi { } } } - } else if (e instanceof Player) { - Player p = (Player) e; + } else if (e instanceof Player p) { if (p.isOpponentOf(ai)) { if (options.contains(CounterEnumType.POISON)) { return CounterEnumType.POISON; @@ -1247,9 +1232,8 @@ public class CountersPutAi extends CountersAi { if (numCtrs < optimalCMC) { // If the AI has less counters than the optimal CMC, it should play the ability. return new AiAbilityDecision(100, AiPlayDecision.WillPlay); - } else { - // If the AI has enough counters or more than the optimal CMC, it should not play the ability. - return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi); } + // If the AI has enough counters or more than the optimal CMC, it should not play the ability. + return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi); } } diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index b4f52c9b163..aba9ecbfc94 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -577,9 +577,6 @@ public class Player extends GameEntity implements Comparable { } public final boolean payLife(final int lifePayment, final SpellAbility cause, final boolean effect) { - return payLife(lifePayment, cause, effect, null); - } - public final boolean payLife(final int lifePayment, final SpellAbility cause, final boolean effect, Map params) { // fast check for pay zero life if (lifePayment <= 0) { cause.setPaidLife(0); @@ -599,9 +596,6 @@ public class Player extends GameEntity implements Comparable { if (cause.isReplacementAbility() && effect) { replaceParams.putAll(cause.getReplacingObjects()); } - if (params != null) { - replaceParams.putAll(params); - } switch (getGame().getReplacementHandler().run(ReplacementType.PayLife, replaceParams)) { case Replaced: return true; diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerAttackerBlocked.java b/forge-game/src/main/java/forge/game/trigger/TriggerAttackerBlocked.java index 3f6ada026e7..23fa0b0b5b3 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerAttackerBlocked.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerAttackerBlocked.java @@ -22,7 +22,6 @@ import java.util.Map; import com.google.common.collect.Iterables; import forge.game.ability.AbilityKey; import forge.game.card.Card; -import forge.game.card.CardLists; import forge.game.spellability.SpellAbility; import forge.util.Localizer; @@ -60,17 +59,8 @@ public class TriggerAttackerBlocked extends Trigger { return false; } - if (hasParam("ValidBlocker")) { - @SuppressWarnings("unchecked") - int count = CardLists.getValidCardCount( - (Iterable) runParams.get(AbilityKey.Blockers), - getParam("ValidBlocker"), - getHostCard().getController(), getHostCard(), this - ); - - if (count == 0) { - return false; - } + if (!matchesValidParam("ValidBlocker", runParams.get(AbilityKey.Blockers))) { + return false; } return true; diff --git a/forge-gui/res/cardsfolder/p/phyrexian_reaper.txt b/forge-gui/res/cardsfolder/p/phyrexian_reaper.txt index 89f93143f86..a04f8e79922 100644 --- a/forge-gui/res/cardsfolder/p/phyrexian_reaper.txt +++ b/forge-gui/res/cardsfolder/p/phyrexian_reaper.txt @@ -2,6 +2,6 @@ Name:Phyrexian Reaper ManaCost:4 B Types:Creature Phyrexian Zombie PT:3/3 -T:Mode$ AttackerBlocked | ValidCard$ Card.Self | ValidBlocker$ Creature.Green | Execute$ TrigDestroyBlocker | TriggerDescription$ Whenever CARDNAME becomes blocked by a green creature, destroy that creature. It can't be regenerated. +T:Mode$ AttackerBlockedByCreature | ValidCard$ Card.Self | ValidBlocker$ Creature.Green | Execute$ TrigDestroyBlocker | TriggerDescription$ Whenever CARDNAME becomes blocked by a green creature, destroy that creature. It can't be regenerated. SVar:TrigDestroyBlocker:DB$ Destroy | Defined$ TriggeredBlockerLKICopy | NoRegen$ True Oracle:Whenever Phyrexian Reaper becomes blocked by a green creature, destroy that creature. It can't be regenerated. diff --git a/forge-gui/res/cardsfolder/p/phyrexian_slayer.txt b/forge-gui/res/cardsfolder/p/phyrexian_slayer.txt index a1329a6535b..44d48e2792a 100644 --- a/forge-gui/res/cardsfolder/p/phyrexian_slayer.txt +++ b/forge-gui/res/cardsfolder/p/phyrexian_slayer.txt @@ -3,7 +3,7 @@ ManaCost:3 B Types:Creature Phyrexian Minion PT:2/2 K:Flying -T:Mode$ AttackerBlocked | ValidCard$ Card.Self | ValidBlocker$ Creature.White | Execute$ TrigDestroyBlocker | TriggerDescription$ Whenever CARDNAME becomes blocked by a white creature, destroy that creature. It can't be regenerated. +T:Mode$ AttackerBlockedByCreature | ValidCard$ Card.Self | ValidBlocker$ Creature.White | Execute$ TrigDestroyBlocker | TriggerDescription$ Whenever CARDNAME becomes blocked by a white creature, destroy that creature. It can't be regenerated. SVar:TrigDestroyBlocker:DB$ Destroy | Defined$ TriggeredBlockerLKICopy | NoRegen$ True AI:RemoveDeck:Random Oracle:Flying\nWhenever Phyrexian Slayer becomes blocked by a white creature, destroy that creature. It can't be regenerated. diff --git a/forge-gui/res/cardsfolder/s/sage_of_days.txt b/forge-gui/res/cardsfolder/s/sage_of_days.txt index f4c5a17637c..2a9bf74a532 100644 --- a/forge-gui/res/cardsfolder/s/sage_of_days.txt +++ b/forge-gui/res/cardsfolder/s/sage_of_days.txt @@ -3,7 +3,7 @@ ManaCost:2 U Types:Creature Human Wizard PT:3/2 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDig | TriggerDescription$ When CARDNAME enters, look at the top three cards of your library. You may put one of those cards back on top of your library. Put the rest into your graveyard. -SVar:TrigDig:DB$ Dig | DigNum$ 3 | ChangeNum$ 1 | ChangeValid$ Card | DestinationZone2$ Graveyard | DestinationZone$ Library | LibraryPosition$ 0 | Optional$ True +SVar:TrigDig:DB$ Dig | DigNum$ 3 | ChangeNum$ 1 | ChangeValid$ Card | DestinationZone2$ Graveyard | DestinationZone$ Library | LibraryPosition$ 0 | Optional$ True | NoReveal$ True DeckHas:Ability$Graveyard DeckHints:Ability$Graveyard Oracle:When Sage of Days enters, look at the top three cards of your library. You may put one of those cards back on top of your library. Put the rest into your graveyard. diff --git a/forge-gui/src/main/java/forge/gamemodes/match/input/InputPayMana.java b/forge-gui/src/main/java/forge/gamemodes/match/input/InputPayMana.java index b7e6bb21952..6cb1739caa7 100644 --- a/forge-gui/src/main/java/forge/gamemodes/match/input/InputPayMana.java +++ b/forge-gui/src/main/java/forge/gamemodes/match/input/InputPayMana.java @@ -246,10 +246,8 @@ public abstract class InputPayMana extends InputSyncronizedBase { int maAmount = ma.totalAmountOfManaGenerated(saPaidFor, true); if (amountOfMana == -1) { amountOfMana = maAmount; - } else { - if (amountOfMana != maAmount) { - guessAbilityWithRequiredColors = false; - } + } else if (amountOfMana != maAmount) { + guessAbilityWithRequiredColors = false; } abilitiesMap.put(ma.getView(), ma); @@ -290,8 +288,7 @@ public abstract class InputPayMana extends InputSyncronizedBase { //avoid unnecessary prompt by pretending we need White //for the sake of "Add one mana of any color" effects colorNeeded = MagicColor.WHITE; - } - else { + } else { final HashMap colorMatches = new HashMap<>(); for (SpellAbility sa : abilitiesMap.values()) { if (sa.isManaAbilityFor(saPaidFor, colorNeeded)) {