mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 20:58:03 +00:00
StrictAmount fix (#1993)
This commit is contained in:
@@ -786,7 +786,7 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean chooseBinary(SpellAbility sa, String question, BinaryChoiceType kindOfChoice, Boolean defaultVal) {
|
public boolean chooseBinary(SpellAbility sa, String question, BinaryChoiceType kindOfChoice, Boolean defaultVal) {
|
||||||
switch(kindOfChoice) {
|
switch (kindOfChoice) {
|
||||||
case TapOrUntap: return true;
|
case TapOrUntap: return true;
|
||||||
case UntapOrLeaveTapped:
|
case UntapOrLeaveTapped:
|
||||||
Card source = sa.getHostCard();
|
Card source = sa.getHostCard();
|
||||||
|
|||||||
@@ -1766,13 +1766,13 @@ public class GameAction {
|
|||||||
boolean recheck = false;
|
boolean recheck = false;
|
||||||
|
|
||||||
// Corner Case 1: Legendary with non legendary creature names
|
// Corner Case 1: Legendary with non legendary creature names
|
||||||
CardCollection nonLegendaryNames = new CardCollection(Iterables.filter(a, new Predicate<Card>() {
|
CardCollection nonLegendaryNames = CardLists.filter(a, new Predicate<Card>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Card input) {
|
public boolean apply(Card input) {
|
||||||
return input.hasNonLegendaryCreatureNames();
|
return input.hasNonLegendaryCreatureNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
}));
|
});
|
||||||
|
|
||||||
Multimap<String, Card> uniqueLegends = Multimaps.index(a, CardPredicates.Accessors.fnGetNetName);
|
Multimap<String, Card> uniqueLegends = Multimaps.index(a, CardPredicates.Accessors.fnGetNetName);
|
||||||
CardCollection removed = new CardCollection();
|
CardCollection removed = new CardCollection();
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final boolean hasCardAttachment(final String cardName) {
|
public final boolean hasCardAttachment(final String cardName) {
|
||||||
return CardLists.count(getAttachedCards(), CardPredicates.nameEquals(cardName)) > 0;
|
return Iterables.any(getAttachedCards(), CardPredicates.nameEquals(cardName));
|
||||||
}
|
}
|
||||||
public final boolean isEnchantedBy(final String cardName) {
|
public final boolean isEnchantedBy(final String cardName) {
|
||||||
// Rule 303.4k Even if c is no Aura it still counts
|
// Rule 303.4k Even if c is no Aura it still counts
|
||||||
|
|||||||
@@ -151,22 +151,18 @@ public class SacrificeEffect extends SpellAbilityEffect {
|
|||||||
validTargets = CardLists.filter(validTargets, CardPredicates.canBeSacrificedBy(sa, true));
|
validTargets = CardLists.filter(validTargets, CardPredicates.canBeSacrificedBy(sa, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isStrict = sa.hasParam("StrictAmount");
|
||||||
|
int minTargets = optional && !isStrict ? 0 : amount;
|
||||||
|
boolean notEnoughTargets = validTargets.size() < minTargets;
|
||||||
|
|
||||||
if (sa.hasParam("Random")) {
|
if (sa.hasParam("Random")) {
|
||||||
choosenToSacrifice = new CardCollection(Aggregates.random(validTargets, Math.min(amount, validTargets.size())));
|
choosenToSacrifice = new CardCollection(Aggregates.random(validTargets, Math.min(amount, validTargets.size())));
|
||||||
} else if (optional && !p.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantSacrifice"), null)) {
|
} else if (notEnoughTargets || (optional && !p.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantSacrifice"), null))) {
|
||||||
choosenToSacrifice = CardCollection.EMPTY;
|
choosenToSacrifice = CardCollection.EMPTY;
|
||||||
} else {
|
} else {
|
||||||
boolean isStrict = sa.hasParam("StrictAmount");
|
choosenToSacrifice = destroy ?
|
||||||
int minTargets = optional ? 0 : amount;
|
|
||||||
boolean notEnoughTargets = isStrict && validTargets.size() < minTargets;
|
|
||||||
|
|
||||||
if (!notEnoughTargets) {
|
|
||||||
choosenToSacrifice = destroy ?
|
|
||||||
p.getController().choosePermanentsToDestroy(sa, minTargets, amount, validTargets, msg) :
|
p.getController().choosePermanentsToDestroy(sa, minTargets, amount, validTargets, msg) :
|
||||||
p.getController().choosePermanentsToSacrifice(sa, minTargets, amount, validTargets, msg);
|
p.getController().choosePermanentsToSacrifice(sa, minTargets, amount, validTargets, msg);
|
||||||
} else {
|
|
||||||
choosenToSacrifice = CardCollection.EMPTY;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,7 +214,7 @@ public class SacrificeEffect extends SpellAbilityEffect {
|
|||||||
final int amount = AbilityUtils.calculateAmount(sa.getHostCard(), num, sa);
|
final int amount = AbilityUtils.calculateAmount(sa.getHostCard(), num, sa);
|
||||||
|
|
||||||
if (valid.equals("Self")) {
|
if (valid.equals("Self")) {
|
||||||
sb.append("Sacrifices ").append(sa.getHostCard().toString());
|
sb.append("Sacrifices ").append(sa.getHostCard());
|
||||||
} else if (valid.equals("Card.AttachedBy")) {
|
} else if (valid.equals("Card.AttachedBy")) {
|
||||||
final Card toSac = sa.getHostCard().getEnchantingCard();
|
final Card toSac = sa.getHostCard().getEnchantingCard();
|
||||||
sb.append(toSac.getController()).append(" sacrifices ").append(toSac).append(".");
|
sb.append(toSac.getController()).append(" sacrifices ").append(toSac).append(".");
|
||||||
|
|||||||
@@ -3549,6 +3549,10 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
return hasCardAttachment(c);
|
return hasCardAttachment(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final boolean isFortifying() {
|
||||||
|
return this.isAttachedToEntity();
|
||||||
|
}
|
||||||
|
|
||||||
public final Card getEquipping() {
|
public final Card getEquipping() {
|
||||||
return this.getAttachedTo();
|
return this.getAttachedTo();
|
||||||
}
|
}
|
||||||
@@ -3556,10 +3560,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
return this.isAttachedToEntity();
|
return this.isAttachedToEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isFortifying() {
|
|
||||||
return this.isAttachedToEntity();
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void unEquipCard(final Card c) { // equipment.unEquipCard(equippedCard);
|
public final void unEquipCard(final Card c) { // equipment.unEquipCard(equippedCard);
|
||||||
this.unattachFromEntity(c);
|
this.unattachFromEntity(c);
|
||||||
}
|
}
|
||||||
@@ -5063,7 +5063,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
if (!isPhasedOut()) {
|
if (!isPhasedOut()) {
|
||||||
// If this is currently PhasedIn, it's about to phase out.
|
// If this is currently PhasedIn, it's about to phase out.
|
||||||
// Run trigger before it does because triggers don't work with phased out objects
|
// Run trigger before it does because triggers don't work with phased out objects
|
||||||
getGame().getTriggerHandler().runTrigger(TriggerType.PhaseOut, runParams, false);
|
getGame().getTriggerHandler().runTrigger(TriggerType.PhaseOut, runParams, true);
|
||||||
// when it doesn't exist the game will no longer see it as tapped
|
// when it doesn't exist the game will no longer see it as tapped
|
||||||
runUntapCommands();
|
runUntapCommands();
|
||||||
// TODO CR 702.26f need to run LeavesPlay + changeController commands but only when worded "for as long as"
|
// TODO CR 702.26f need to run LeavesPlay + changeController commands but only when worded "for as long as"
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ public class Untap extends Phase {
|
|||||||
if (c.hasKeyword("You may choose not to untap CARDNAME during your untap step.") && c.isTapped()) {
|
if (c.hasKeyword("You may choose not to untap CARDNAME during your untap step.") && c.isTapped()) {
|
||||||
StringBuilder prompt = new StringBuilder("Untap " + c.toString() + "?");
|
StringBuilder prompt = new StringBuilder("Untap " + c.toString() + "?");
|
||||||
boolean defaultChoice = true;
|
boolean defaultChoice = true;
|
||||||
if (c.getGainControlTargets().size() > 0) {
|
if (c.hasGainControlTarget()) {
|
||||||
final Iterable<Card> targets = c.getGainControlTargets();
|
final Iterable<Card> targets = c.getGainControlTargets();
|
||||||
prompt.append("\r\n").append(c).append(" is controlling: ");
|
prompt.append("\r\n").append(c).append(" is controlling: ");
|
||||||
for (final Card target : targets) {
|
for (final Card target : targets) {
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ ManaCost:5
|
|||||||
Types:Artifact Creature Juggernaut
|
Types:Artifact Creature Juggernaut
|
||||||
PT:5/3
|
PT:5/3
|
||||||
K:Trample
|
K:Trample
|
||||||
K:CARDNAME attacks each combat if able.
|
|
||||||
K:Unearth:5 R
|
K:Unearth:5 R
|
||||||
|
S:Mode$ MustAttack | ValidCreature$ Card.Self | Description$ CARDNAME attacks each combat if able.
|
||||||
DeckHas:Ability$Graveyard
|
DeckHas:Ability$Graveyard
|
||||||
DeckHints:Color$Red
|
DeckHints:Color$Red
|
||||||
Oracle:Trample\nMishra's Juggernaut attacks each turn if able.\nUnearth {5}{R} ({5}{R}: Return this card from your graveyard to the battlefield. It gains haste. Exile it at the beginning of the next end step or if it would leave the battlefield. Unearth only as a sorcery.)
|
Oracle:Trample\nMishra's Juggernaut attacks each combat if able.\nUnearth {5}{R} ({5}{R}: Return this card from your graveyard to the battlefield. It gains haste. Exile it at the beginning of the next end step or if it would leave the battlefield. Unearth only as a sorcery.)
|
||||||
|
|||||||
Reference in New Issue
Block a user