Some clean up (#8673)

This commit is contained in:
tool4ever
2025-09-08 22:40:03 +02:00
committed by GitHub
parent ca61627f5b
commit c0b667c373
7 changed files with 45 additions and 80 deletions

View File

@@ -442,14 +442,12 @@ public class CountersPutAi extends CountersAi {
} }
sa.addDividedAllocation(c, amount); sa.addDividedAllocation(c, amount);
return decision; return decision;
} else { } else if (!hasSacCost) {
if (!hasSacCost) {
// for Sacrifice costs, evaluate further to see if it's worth using the ability before the card dies // for Sacrifice costs, evaluate further to see if it's worth using the ability before the card dies
return decision; return decision;
} }
} }
} }
}
sa.resetTargets(); sa.resetTargets();
@@ -684,14 +682,12 @@ public class CountersPutAi extends CountersAi {
|| (sa.getRootAbility().isTrigger() && !sa.getRootAbility().isOptionalTrigger()); || (sa.getRootAbility().isTrigger() && !sa.getRootAbility().isOptionalTrigger());
if (sa.usesTargeting()) { if (sa.usesTargeting()) {
CardCollection list = null; CardCollection list;
if (sa.isCurse()) { if (sa.isCurse()) {
list = ai.getOpponents().getCardsIn(ZoneType.Battlefield); list = ai.getOpponents().getCardsIn(ZoneType.Battlefield);
} else { } else {
list = new CardCollection(ai.getCardsIn(ZoneType.Battlefield)); list = new CardCollection(ai.getCardsIn(ZoneType.Battlefield));
} }
list = CardLists.getTargetableCards(list, sa); list = CardLists.getTargetableCards(list, sa);
if (list.isEmpty() && isMandatoryTrigger) { if (list.isEmpty() && isMandatoryTrigger) {
@@ -707,9 +703,8 @@ public class CountersPutAi extends CountersAi {
|| sa.getTargets().isEmpty()) { || sa.getTargets().isEmpty()) {
sa.resetTargets(); sa.resetTargets();
return new AiAbilityDecision(0, AiPlayDecision.TargetingFailed); return new AiAbilityDecision(0, AiPlayDecision.TargetingFailed);
} else {
break;
} }
break;
} }
if (sa.isCurse()) { if (sa.isCurse()) {
@@ -752,8 +747,6 @@ public class CountersPutAi extends CountersAi {
final SpellAbility root = sa.getRootAbility(); final SpellAbility root = sa.getRootAbility();
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
final String aiLogic = sa.getParamOrDefault("AILogic", ""); final String aiLogic = sa.getParamOrDefault("AILogic", "");
boolean preferred = true;
CardCollection list;
final String amountStr = sa.getParamOrDefault("CounterNum", "1"); final String amountStr = sa.getParamOrDefault("CounterNum", "1");
final boolean divided = sa.isDividedAsYouChoose(); final boolean divided = sa.isDividedAsYouChoose();
final int amount = AbilityUtils.calculateAmount(source, amountStr, sa); final int amount = AbilityUtils.calculateAmount(source, amountStr, sa);
@@ -775,11 +768,11 @@ public class CountersPutAi extends CountersAi {
AiAbilityDecision decision = doChargeToCMCLogic(ai, sa); AiAbilityDecision decision = doChargeToCMCLogic(ai, sa);
if (decision.willingToPlay()) { if (decision.willingToPlay()) {
return decision; 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()) { 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(); sa.resetTargets();
Iterable<Card> 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()) { while (sa.canAddMoreTarget()) {
if (mandatory) { if (mandatory) {
// When things are mandatory, gotta handle a little differently // When things are mandatory, gotta handle a little differently
@@ -879,28 +872,22 @@ public class CountersPutAi extends CountersAi {
if (choice == null && mandatory) { if (choice == null && mandatory) {
choice = Aggregates.random(list); choice = Aggregates.random(list);
} }
} else { } else if (type.equals("M1M1")) {
if (type.equals("M1M1")) {
choice = ComputerUtilCard.getWorstCreatureAI(list); choice = ComputerUtilCard.getWorstCreatureAI(list);
} else { } else {
choice = Aggregates.random(list); choice = Aggregates.random(list);
} }
} } else if (preferred) {
} else {
if (preferred) {
list = ComputerUtil.getSafeTargets(ai, sa, list); list = ComputerUtil.getSafeTargets(ai, sa, list);
choice = chooseBoonTarget(list, type); choice = chooseBoonTarget(list, type);
if (choice == null && mandatory) { if (choice == null && mandatory) {
choice = Aggregates.random(list); choice = Aggregates.random(list);
} }
} else { } else if (type.equals("P1P1")) {
if (type.equals("P1P1")) {
choice = ComputerUtilCard.getWorstCreatureAI(list); choice = ComputerUtilCard.getWorstCreatureAI(list);
} else { } else {
choice = Aggregates.random(list); choice = Aggregates.random(list);
} }
}
}
if (choice != null && divided) { if (choice != null && divided) {
int alloc = Math.max(amount / totalTargets, 1); int alloc = Math.max(amount / totalTargets, 1);
if (sa.getTargets().size() == Math.min(totalTargets, sa.getMaxTargets()) - 1) { if (sa.getTargets().size() == Math.min(totalTargets, sa.getMaxTargets()) - 1) {
@@ -1094,8 +1081,7 @@ public class CountersPutAi extends CountersAi {
Player ai = sa.getActivatingPlayer(); Player ai = sa.getActivatingPlayer();
GameEntity e = (GameEntity) params.get("Target"); GameEntity e = (GameEntity) params.get("Target");
// for Card try to select not useless counter // for Card try to select not useless counter
if (e instanceof Card) { if (e instanceof Card c) {
Card c = (Card) e;
if (c.getController().isOpponentOf(ai)) { if (c.getController().isOpponentOf(ai)) {
if (options.contains(CounterEnumType.M1M1) && !c.hasKeyword(Keyword.UNDYING)) { if (options.contains(CounterEnumType.M1M1) && !c.hasKeyword(Keyword.UNDYING)) {
return CounterEnumType.M1M1; return CounterEnumType.M1M1;
@@ -1112,8 +1098,7 @@ public class CountersPutAi extends CountersAi {
} }
} }
} }
} else if (e instanceof Player) { } else if (e instanceof Player p) {
Player p = (Player) e;
if (p.isOpponentOf(ai)) { if (p.isOpponentOf(ai)) {
if (options.contains(CounterEnumType.POISON)) { if (options.contains(CounterEnumType.POISON)) {
return CounterEnumType.POISON; return CounterEnumType.POISON;
@@ -1247,9 +1232,8 @@ public class CountersPutAi extends CountersAi {
if (numCtrs < optimalCMC) { if (numCtrs < optimalCMC) {
// If the AI has less counters than the optimal CMC, it should play the ability. // If the AI has less counters than the optimal CMC, it should play the ability.
return new AiAbilityDecision(100, AiPlayDecision.WillPlay); 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. // If the AI has enough counters or more than the optimal CMC, it should not play the ability.
return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi); return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi);
} }
} }
}

View File

@@ -577,9 +577,6 @@ public class Player extends GameEntity implements Comparable<Player> {
} }
public final boolean payLife(final int lifePayment, final SpellAbility cause, final boolean effect) { 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<AbilityKey, Object> params) {
// fast check for pay zero life // fast check for pay zero life
if (lifePayment <= 0) { if (lifePayment <= 0) {
cause.setPaidLife(0); cause.setPaidLife(0);
@@ -599,9 +596,6 @@ public class Player extends GameEntity implements Comparable<Player> {
if (cause.isReplacementAbility() && effect) { if (cause.isReplacementAbility() && effect) {
replaceParams.putAll(cause.getReplacingObjects()); replaceParams.putAll(cause.getReplacingObjects());
} }
if (params != null) {
replaceParams.putAll(params);
}
switch (getGame().getReplacementHandler().run(ReplacementType.PayLife, replaceParams)) { switch (getGame().getReplacementHandler().run(ReplacementType.PayLife, replaceParams)) {
case Replaced: case Replaced:
return true; return true;

View File

@@ -22,7 +22,6 @@ import java.util.Map;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import forge.game.ability.AbilityKey; import forge.game.ability.AbilityKey;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.card.CardLists;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.util.Localizer; import forge.util.Localizer;
@@ -60,18 +59,9 @@ public class TriggerAttackerBlocked extends Trigger {
return false; return false;
} }
if (hasParam("ValidBlocker")) { if (!matchesValidParam("ValidBlocker", runParams.get(AbilityKey.Blockers))) {
@SuppressWarnings("unchecked")
int count = CardLists.getValidCardCount(
(Iterable<Card>) runParams.get(AbilityKey.Blockers),
getParam("ValidBlocker"),
getHostCard().getController(), getHostCard(), this
);
if (count == 0) {
return false; return false;
} }
}
return true; return true;
} }

View File

@@ -2,6 +2,6 @@ Name:Phyrexian Reaper
ManaCost:4 B ManaCost:4 B
Types:Creature Phyrexian Zombie Types:Creature Phyrexian Zombie
PT:3/3 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 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. Oracle:Whenever Phyrexian Reaper becomes blocked by a green creature, destroy that creature. It can't be regenerated.

View File

@@ -3,7 +3,7 @@ ManaCost:3 B
Types:Creature Phyrexian Minion Types:Creature Phyrexian Minion
PT:2/2 PT:2/2
K:Flying 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 SVar:TrigDestroyBlocker:DB$ Destroy | Defined$ TriggeredBlockerLKICopy | NoRegen$ True
AI:RemoveDeck:Random AI:RemoveDeck:Random
Oracle:Flying\nWhenever Phyrexian Slayer becomes blocked by a white creature, destroy that creature. It can't be regenerated. Oracle:Flying\nWhenever Phyrexian Slayer becomes blocked by a white creature, destroy that creature. It can't be regenerated.

View File

@@ -3,7 +3,7 @@ ManaCost:2 U
Types:Creature Human Wizard Types:Creature Human Wizard
PT:3/2 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. 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 DeckHas:Ability$Graveyard
DeckHints: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. 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.

View File

@@ -246,11 +246,9 @@ public abstract class InputPayMana extends InputSyncronizedBase {
int maAmount = ma.totalAmountOfManaGenerated(saPaidFor, true); int maAmount = ma.totalAmountOfManaGenerated(saPaidFor, true);
if (amountOfMana == -1) { if (amountOfMana == -1) {
amountOfMana = maAmount; amountOfMana = maAmount;
} else { } else if (amountOfMana != maAmount) {
if (amountOfMana != maAmount) {
guessAbilityWithRequiredColors = false; guessAbilityWithRequiredColors = false;
} }
}
abilitiesMap.put(ma.getView(), ma); abilitiesMap.put(ma.getView(), ma);
@@ -290,8 +288,7 @@ public abstract class InputPayMana extends InputSyncronizedBase {
//avoid unnecessary prompt by pretending we need White //avoid unnecessary prompt by pretending we need White
//for the sake of "Add one mana of any color" effects //for the sake of "Add one mana of any color" effects
colorNeeded = MagicColor.WHITE; colorNeeded = MagicColor.WHITE;
} } else {
else {
final HashMap<SpellAbilityView, SpellAbility> colorMatches = new HashMap<>(); final HashMap<SpellAbilityView, SpellAbility> colorMatches = new HashMap<>();
for (SpellAbility sa : abilitiesMap.values()) { for (SpellAbility sa : abilitiesMap.values()) {
if (sa.isManaAbilityFor(saPaidFor, colorNeeded)) { if (sa.isManaAbilityFor(saPaidFor, colorNeeded)) {