Merge branch 'charming' into 'master'

CharmEffect - fix choosing illegal mode

See merge request core-developers/forge!5885
This commit is contained in:
Michael Kamensky
2021-11-26 19:40:40 +00:00
5 changed files with 36 additions and 13 deletions

View File

@@ -69,6 +69,9 @@ public class CharmAi extends SpellAbilityAi {
if (timingRight) { if (timingRight) {
// Set minimum choices for triggers where chooseMultipleOptionsAi() returns null // Set minimum choices for triggers where chooseMultipleOptionsAi() returns null
chosenList = chooseOptionsAi(choices, ai, true, num, min, sa.hasParam("CanRepeatModes")); chosenList = chooseOptionsAi(choices, ai, true, num, min, sa.hasParam("CanRepeatModes"));
if (chosenList.isEmpty() && min != 0) {
return false;
}
} else { } else {
return false; return false;
} }
@@ -251,4 +254,23 @@ public class CharmAi extends SpellAbilityAi {
public Player chooseSinglePlayer(Player ai, SpellAbility sa, Iterable<Player> opponents, Map<String, Object> params) { public Player chooseSinglePlayer(Player ai, SpellAbility sa, Iterable<Player> opponents, Map<String, Object> params) {
return Aggregates.random(opponents); return Aggregates.random(opponents);
} }
@Override
protected boolean doTriggerAINoCost(final Player aiPlayer, final SpellAbility sa, final boolean mandatory) {
// already done by chooseOrderOfSimultaneousStackEntry
if (sa.getChosenList() != null) {
return true;
}
return super.doTriggerAINoCost(aiPlayer, sa, mandatory);
}
@Override
public boolean chkDrawbackWithSubs(Player aiPlayer, AbilitySub ab) {
// choices were already targeted
if (ab.getRootAbility().getChosenList() != null) {
return true;
}
return super.chkDrawbackWithSubs(aiPlayer, ab);
}
} }

View File

@@ -17,11 +17,10 @@ public class GameLossAi extends SpellAbilityAi {
if (sa.usesTargeting()) { if (sa.usesTargeting()) {
sa.resetTargets(); sa.resetTargets();
sa.getTargets().add(opp); sa.getTargets().add(opp);
return true;
} }
// In general, don't return true. return false;
// But this card wins the game, I can make an exception for that
return true;
} }
@Override @Override
@@ -35,7 +34,7 @@ public class GameLossAi extends SpellAbilityAi {
loser = ai.getGame().getCombat().getDefenderPlayerByAttacker(sa.getHostCard()); loser = ai.getGame().getCombat().getDefenderPlayerByAttacker(sa.getHostCard());
} }
if (!mandatory && loser.cantLose()) { if (!mandatory && (loser == ai || loser.cantLose())) {
return false; return false;
} }

View File

@@ -38,7 +38,7 @@ public class LifeLoseAi extends SpellAbilityAi {
SpellAbility root = sa.getRootAbility(); SpellAbility root = sa.getRootAbility();
if (root.getXManaCostPaid() != null) { if (root.getXManaCostPaid() != null) {
amount = root.getXManaCostPaid(); amount = root.getXManaCostPaid();
} else { } else if (root.getPayCosts() != null && root.getPayCosts().hasXInAnyCostPart()) {
// Set PayX here to maximum value. // Set PayX here to maximum value.
final int xPay = ComputerUtilCost.getMaxXValue(sa, ai); final int xPay = ComputerUtilCost.getMaxXValue(sa, ai);
root.setXManaCostPaid(xPay); root.setXManaCostPaid(xPay);

View File

@@ -33,17 +33,18 @@ public class CharmEffect extends SpellAbilityEffect {
} }
} }
int indx = 0;
List<AbilitySub> choices = Lists.newArrayList(sa.getAdditionalAbilityList("Choices")); List<AbilitySub> choices = Lists.newArrayList(sa.getAdditionalAbilityList("Choices"));
if (restriction != null) { List<AbilitySub> toRemove = Lists.newArrayList();
List<AbilitySub> toRemove = Lists.newArrayList(); for (AbilitySub ch : choices) {
for (AbilitySub ch : choices) { // 603.3c If one of the modes would be illegal, that mode can't be chosen.
if (restriction.contains(ch.getDescription())) { if ((ch.usesTargeting() && ch.isTrigger() && ch.getTargetRestrictions().getNumCandidates(ch, true) == 0) ||
toRemove.add(ch); (restriction != null && restriction.contains(ch.getDescription()))) {
} toRemove.add(ch);
} }
choices.removeAll(toRemove);
} }
choices.removeAll(toRemove);
int indx = 0;
// set CharmOrder // set CharmOrder
for (AbilitySub sub : choices) { for (AbilitySub sub : choices) {
sub.setSVar("CharmOrder", Integer.toString(indx)); sub.setSVar("CharmOrder", Integer.toString(indx));

View File

@@ -20,6 +20,7 @@ import forge.game.zone.ZoneType;
import forge.util.TextUtil; import forge.util.TextUtil;
public class PumpAllEffect extends SpellAbilityEffect { public class PumpAllEffect extends SpellAbilityEffect {
private static void applyPumpAll(final SpellAbility sa, private static void applyPumpAll(final SpellAbility sa,
final Iterable<Card> list, final int a, final int d, final Iterable<Card> list, final int a, final int d,
final List<String> keywords, final List<ZoneType> affectedZones) { final List<String> keywords, final List<ZoneType> affectedZones) {