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) {
// Set minimum choices for triggers where chooseMultipleOptionsAi() returns null
chosenList = chooseOptionsAi(choices, ai, true, num, min, sa.hasParam("CanRepeatModes"));
if (chosenList.isEmpty() && min != 0) {
return false;
}
} else {
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) {
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()) {
sa.resetTargets();
sa.getTargets().add(opp);
return true;
}
// In general, don't return true.
// But this card wins the game, I can make an exception for that
return true;
return false;
}
@Override
@@ -35,7 +34,7 @@ public class GameLossAi extends SpellAbilityAi {
loser = ai.getGame().getCombat().getDefenderPlayerByAttacker(sa.getHostCard());
}
if (!mandatory && loser.cantLose()) {
if (!mandatory && (loser == ai || loser.cantLose())) {
return false;
}

View File

@@ -38,7 +38,7 @@ public class LifeLoseAi extends SpellAbilityAi {
SpellAbility root = sa.getRootAbility();
if (root.getXManaCostPaid() != null) {
amount = root.getXManaCostPaid();
} else {
} else if (root.getPayCosts() != null && root.getPayCosts().hasXInAnyCostPart()) {
// Set PayX here to maximum value.
final int xPay = ComputerUtilCost.getMaxXValue(sa, ai);
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"));
if (restriction != null) {
List<AbilitySub> toRemove = Lists.newArrayList();
for (AbilitySub ch : choices) {
if (restriction.contains(ch.getDescription())) {
toRemove.add(ch);
}
List<AbilitySub> toRemove = Lists.newArrayList();
for (AbilitySub ch : choices) {
// 603.3c If one of the modes would be illegal, that mode can't be chosen.
if ((ch.usesTargeting() && ch.isTrigger() && ch.getTargetRestrictions().getNumCandidates(ch, true) == 0) ||
(restriction != null && restriction.contains(ch.getDescription()))) {
toRemove.add(ch);
}
choices.removeAll(toRemove);
}
choices.removeAll(toRemove);
int indx = 0;
// set CharmOrder
for (AbilitySub sub : choices) {
sub.setSVar("CharmOrder", Integer.toString(indx));

View File

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