mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 18:28:00 +00:00
Merge branch 'fix' into 'master'
Simulation: fix for Pack Rat tokens (bad diff because of missing CMC) See merge request core-developers/forge!5980
This commit is contained in:
@@ -514,9 +514,8 @@ public class AiAttackController {
|
||||
if (Iterables.any(oppBattlefield, Predicates.and(CardPredicates.Presets.UNTAPPED, CardPredicates.Presets.LANDS))) {
|
||||
maxBlockersAfterCrew = Integer.MAX_VALUE;
|
||||
break;
|
||||
} else {
|
||||
maxBlockersAfterCrew--;
|
||||
}
|
||||
maxBlockersAfterCrew--;
|
||||
} else if (cardType.hasSubtype("Vehicle") && !cardType.isCreature()) {
|
||||
maxBlockersAfterCrew--;
|
||||
}
|
||||
|
||||
@@ -2436,7 +2436,7 @@ public class ComputerUtil {
|
||||
CardCollection cardsInPlay = CardLists.getNotType(game.getCardsIn(ZoneType.Battlefield), "Land");
|
||||
CardCollection humanlist = CardLists.filterControlledBy(cardsInPlay, ai.getOpponents());
|
||||
CardCollection computerlist = ai.getCreaturesInPlay();
|
||||
return (ComputerUtilCard.evaluatePermanentList(computerlist) + 3) < ComputerUtilCard.evaluatePermanentList(humanlist) ? "Carnage" : "Homage";
|
||||
return ComputerUtilCard.evaluatePermanentList(computerlist) + 3 < ComputerUtilCard.evaluatePermanentList(humanlist) ? "Carnage" : "Homage";
|
||||
case "Judgment":
|
||||
if (votes.isEmpty()) {
|
||||
CardCollection list = new CardCollection();
|
||||
@@ -2446,9 +2446,8 @@ public class ComputerUtil {
|
||||
}
|
||||
}
|
||||
return ComputerUtilCard.getBestAI(list);
|
||||
} else {
|
||||
return Iterables.getFirst(votes.keySet(), null);
|
||||
}
|
||||
return Iterables.getFirst(votes.keySet(), null);
|
||||
case "Protection":
|
||||
if (votes.isEmpty()) {
|
||||
List<String> restrictedToColors = Lists.newArrayList();
|
||||
@@ -2459,9 +2458,8 @@ public class ComputerUtil {
|
||||
}
|
||||
CardCollection lists = CardLists.filterControlledBy(game.getCardsInGame(), ai.getOpponents());
|
||||
return StringUtils.capitalize(ComputerUtilCard.getMostProminentColor(lists, restrictedToColors));
|
||||
} else {
|
||||
return Iterables.getFirst(votes.keySet(), null);
|
||||
}
|
||||
return Iterables.getFirst(votes.keySet(), null);
|
||||
case "FeatherOrQuill":
|
||||
// try to mill opponent with Quill vote
|
||||
if (opponent && !controller.cantLose()) {
|
||||
|
||||
@@ -2292,9 +2292,8 @@ public class ComputerUtilCombat {
|
||||
}
|
||||
if (!withoutAbilities) {
|
||||
return canGainKeyword(combatant, Lists.newArrayList(keyword), combat);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public final static boolean canGainKeyword(final Card combatant, final List<String> keywords, final Combat combat) {
|
||||
|
||||
@@ -306,52 +306,50 @@ public class ComputerUtilMana {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (saHost != null) {
|
||||
if (ma.getPayCosts().hasTapCost() && AiCardMemory.isRememberedCard(ai, ma.getHostCard(), MemorySet.PAYS_TAP_COST)) {
|
||||
if (ma.getPayCosts().hasTapCost() && AiCardMemory.isRememberedCard(ai, ma.getHostCard(), MemorySet.PAYS_TAP_COST)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkTapTypeCost(ai, ma.getPayCosts(), ma.getHostCard(), sa)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkForManaSacrificeCost(ai, ma.getPayCosts(), ma.getHostCard(), ma, ma.isTrigger())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sa.getApi() == ApiType.Animate) {
|
||||
// For abilities like Genju of the Cedars, make sure that we're not activating the aura ability by tapping the enchanted card for mana
|
||||
if (saHost.isAura() && "Enchanted".equals(sa.getParam("Defined"))
|
||||
&& ma.getHostCard() == saHost.getEnchantingCard()
|
||||
&& ma.getPayCosts().hasTapCost()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkTapTypeCost(ai, ma.getPayCosts(), ma.getHostCard(), sa)) {
|
||||
// If a manland was previously animated this turn, do not tap it to animate another manland
|
||||
if (saHost.isLand() && ma.getHostCard().isLand()
|
||||
&& ai.getController().isAI()
|
||||
&& AnimateAi.isAnimatedThisTurn(ai, ma.getHostCard())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkForManaSacrificeCost(ai, ma.getPayCosts(), ma.getHostCard(), ma, ma.isTrigger())) {
|
||||
} else if (sa.getApi() == ApiType.Pump) {
|
||||
if ((saHost.isInstant() || saHost.isSorcery())
|
||||
&& ma.getHostCard().isCreature()
|
||||
&& ai.getController().isAI()
|
||||
&& ma.getPayCosts().hasTapCost()
|
||||
&& sa.getTargets().getTargetCards().contains(ma.getHostCard())) {
|
||||
// do not activate pump instants/sorceries targeting creatures by tapping targeted
|
||||
// creatures for mana (for example, Servant of the Conduit)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sa.getApi() == ApiType.Animate) {
|
||||
// For abilities like Genju of the Cedars, make sure that we're not activating the aura ability by tapping the enchanted card for mana
|
||||
if (saHost.isAura() && "Enchanted".equals(sa.getParam("Defined"))
|
||||
&& ma.getHostCard() == saHost.getEnchantingCard()
|
||||
&& ma.getPayCosts().hasTapCost()) {
|
||||
} else if (sa.getApi() == ApiType.Attach
|
||||
&& "AvoidPayingWithAttachTarget".equals(saHost.getSVar("AIPaymentPreference"))) {
|
||||
// For cards like Genju of the Cedars, make sure we're not attaching to the same land that will
|
||||
// be tapped to pay its own cost if there's another untapped land like that available
|
||||
if (ma.getHostCard().equals(sa.getTargetCard())) {
|
||||
if (CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), Predicates.and(CardPredicates.nameEquals(ma.getHostCard().getName()), CardPredicates.Presets.UNTAPPED)).size() > 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If a manland was previously animated this turn, do not tap it to animate another manland
|
||||
if (saHost.isLand() && ma.getHostCard().isLand()
|
||||
&& ai.getController().isAI()
|
||||
&& AnimateAi.isAnimatedThisTurn(ai, ma.getHostCard())) {
|
||||
continue;
|
||||
}
|
||||
} else if (sa.getApi() == ApiType.Pump) {
|
||||
if ((saHost.isInstant() || saHost.isSorcery())
|
||||
&& ma.getHostCard().isCreature()
|
||||
&& ai.getController().isAI()
|
||||
&& ma.getPayCosts().hasTapCost()
|
||||
&& sa.getTargets().getTargetCards().contains(ma.getHostCard())) {
|
||||
// do not activate pump instants/sorceries targeting creatures by tapping targeted
|
||||
// creatures for mana (for example, Servant of the Conduit)
|
||||
continue;
|
||||
}
|
||||
} else if (sa.getApi() == ApiType.Attach
|
||||
&& "AvoidPayingWithAttachTarget".equals(saHost.getSVar("AIPaymentPreference"))) {
|
||||
// For cards like Genju of the Cedars, make sure we're not attaching to the same land that will
|
||||
// be tapped to pay its own cost if there's another untapped land like that available
|
||||
if (ma.getHostCard().equals(sa.getTargetCard())) {
|
||||
if (CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), Predicates.and(CardPredicates.nameEquals(ma.getHostCard().getName()), CardPredicates.Presets.UNTAPPED)).size() > 1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1023,9 +1023,8 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
}
|
||||
if (blink) {
|
||||
return c.isToken();
|
||||
} else {
|
||||
return c.isToken() || c.getCMC() > 0;
|
||||
}
|
||||
return c.isToken() || c.getCMC() > 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -315,7 +315,6 @@ public class ControlGainAi extends SpellAbilityAi {
|
||||
} else {
|
||||
return this.canPlayAI(ai, sa);
|
||||
}
|
||||
|
||||
} // pumpDrawbackAI()
|
||||
|
||||
@Override
|
||||
|
||||
@@ -153,10 +153,9 @@ public abstract class DamageAiBase extends SpellAbilityAi {
|
||||
}
|
||||
if (value < 0.2f) { //hard floor to reduce ridiculous odds for instants over time
|
||||
return false;
|
||||
} else {
|
||||
final float chance = MyRandom.getRandom().nextFloat();
|
||||
return chance < value;
|
||||
}
|
||||
final float chance = MyRandom.getRandom().nextFloat();
|
||||
return chance < value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -811,9 +811,8 @@ public class DamageDealAi extends DamageAiBase {
|
||||
if (!c.hasKeyword(Keyword.INDESTRUCTIBLE) && ComputerUtilCombat.getDamageToKill(c, false) <= restDamage) {
|
||||
if (c.getController().equals(ai)) {
|
||||
return false;
|
||||
} else {
|
||||
urgent = true;
|
||||
}
|
||||
urgent = true;
|
||||
}
|
||||
if (c.getController().isOpponentOf(ai) ^ c.getName().equals("Stuffy Doll")) {
|
||||
positive = true;
|
||||
|
||||
@@ -198,7 +198,7 @@ public class EffectAi extends SpellAbilityAi {
|
||||
final Card host = saTop.getHostCard();
|
||||
if (saTop.getActivatingPlayer() != ai // from opponent
|
||||
&& host.canDamagePrevented(false) // no prevent damage
|
||||
&& host != null && (host.isInstant() || host.isSorcery())
|
||||
&& (host.isInstant() || host.isSorcery())
|
||||
&& !host.hasKeyword("Prevent all damage that would be dealt by CARDNAME.")) { // valid target
|
||||
final ApiType type = saTop.getApi();
|
||||
if (type == ApiType.DealDamage || type == ApiType.DamageAll) { // burn spell
|
||||
|
||||
@@ -286,12 +286,11 @@ public class FightAi extends SpellAbilityAi {
|
||||
private static boolean shouldFight(Card fighter, Card opponent, int pumpAttack, int pumpDefense) {
|
||||
if (canKill(fighter, opponent, pumpAttack)) {
|
||||
if (!canKill(opponent, fighter, -pumpDefense)) { // can survive
|
||||
return true;
|
||||
} else {
|
||||
if (MyRandom.getRandom().nextInt(20) < (opponent.getCMC() - fighter.getCMC())) { // trade
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (MyRandom.getRandom().nextInt(20) < (opponent.getCMC() - fighter.getCMC())) { // trade
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -233,10 +233,14 @@ public class GameCopier {
|
||||
if (card.isPaired()) {
|
||||
otherCard.setPairedWith(cardMap.get(card.getPairedWith()));
|
||||
}
|
||||
if (card.getCopiedPermanent() != null) {
|
||||
// TODO would it be safe to simply reuse the prototype?
|
||||
otherCard.setCopiedPermanent(CardFactory.copyCard(card.getCopiedPermanent(), false));
|
||||
}
|
||||
// TODO: Verify that the above relationships are preserved bi-directionally or not.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final boolean USE_FROM_PAPER_CARD = true;
|
||||
private Card createCardCopy(Game newGame, Player newOwner, Card c) {
|
||||
if (c.isToken() && !c.isImmutable()) {
|
||||
|
||||
@@ -547,9 +547,8 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView,
|
||||
public String getSVar(final String name) {
|
||||
if (sVars.containsKey(name)) {
|
||||
return sVars.get(name);
|
||||
} else {
|
||||
return getSVarFallback().getSVar(name);
|
||||
}
|
||||
return getSVarFallback().getSVar(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1422,7 +1422,7 @@ public class AbilityUtils {
|
||||
|
||||
// do blessing there before condition checks
|
||||
if (sa.isSpell() && sa.isBlessing() && !sa.getHostCard().isPermanent()) {
|
||||
if (pl != null && pl.getZone(ZoneType.Battlefield).size() >= 10) {
|
||||
if (pl.getZone(ZoneType.Battlefield).size() >= 10) {
|
||||
pl.setBlessing(true);
|
||||
}
|
||||
}
|
||||
@@ -1871,9 +1871,8 @@ public class AbilityUtils {
|
||||
list = CardLists.getValidCards(list, k[1].split(","), sa.getActivatingPlayer(), c, sa);
|
||||
if (k[0].contains("TotalToughness")) {
|
||||
return doXMath(Aggregates.sum(list, CardPredicates.Accessors.fnGetNetToughness), expr, c, ctb);
|
||||
} else {
|
||||
return doXMath(list.size(), expr, c, ctb);
|
||||
}
|
||||
return doXMath(list.size(), expr, c, ctb);
|
||||
}
|
||||
|
||||
if (sq[0].startsWith("LastStateGraveyard")) {
|
||||
@@ -3208,9 +3207,8 @@ public class AbilityUtils {
|
||||
} else if (s[0].contains("DivideEvenlyDown")) {
|
||||
if (secondaryNum == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return num / secondaryNum;
|
||||
}
|
||||
return num / secondaryNum;
|
||||
} else if (s[0].contains("Mod")) {
|
||||
return num % secondaryNum;
|
||||
} else if (s[0].contains("Abs")) {
|
||||
@@ -3218,15 +3216,13 @@ public class AbilityUtils {
|
||||
} else if (s[0].contains("LimitMax")) {
|
||||
if (num < secondaryNum) {
|
||||
return num;
|
||||
} else {
|
||||
return secondaryNum;
|
||||
}
|
||||
return secondaryNum;
|
||||
} else if (s[0].contains("LimitMin")) {
|
||||
if (num > secondaryNum) {
|
||||
return num;
|
||||
} else {
|
||||
return secondaryNum;
|
||||
}
|
||||
return secondaryNum;
|
||||
|
||||
} else {
|
||||
return num;
|
||||
|
||||
@@ -371,8 +371,8 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
return false;
|
||||
}
|
||||
|
||||
public long getTransformedTimestamp() { return transformedTimestamp; }
|
||||
public void incrementTransformedTimestamp() { this.transformedTimestamp++; }
|
||||
public long getTransformedTimestamp() { return transformedTimestamp; }
|
||||
public void incrementTransformedTimestamp() { this.transformedTimestamp++; }
|
||||
|
||||
public CardState getCurrentState() {
|
||||
return currentState;
|
||||
@@ -3037,7 +3037,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
return tokenCard;
|
||||
}
|
||||
public final void setTokenCard(boolean tokenC) {
|
||||
if (tokenCard = tokenC) { return; }
|
||||
if (tokenCard == tokenC) { return; }
|
||||
tokenCard = tokenC;
|
||||
view.updateTokenCard(this);
|
||||
}
|
||||
@@ -5232,9 +5232,9 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
// this is the amount of damage a creature needs to receive before it dies
|
||||
public final int getLethal() {
|
||||
if (hasKeyword("Lethal damage dealt to CARDNAME is determined by its power rather than its toughness.")) {
|
||||
return getNetPower(); }
|
||||
else {
|
||||
return getNetToughness(); }
|
||||
return getNetPower();
|
||||
}
|
||||
return getNetToughness();
|
||||
}
|
||||
|
||||
// this is the minimal damage a trampling creature has to assign to a blocker
|
||||
|
||||
@@ -185,7 +185,6 @@ public class TokenInfo {
|
||||
}
|
||||
}
|
||||
if (!typeMap.isEmpty()) {
|
||||
|
||||
CardType type = new CardType(result.getType());
|
||||
final boolean nameGenerated = result.getName().endsWith(" Token");
|
||||
boolean typeChanged = false;
|
||||
|
||||
@@ -135,56 +135,54 @@ public class CostDiscard extends CostPartWithList {
|
||||
if (this.payCostFromSource()) {
|
||||
return source.canBeDiscardedBy(ability, effect);
|
||||
}
|
||||
else if (type.equals("Hand")) {
|
||||
// trying to discard an empty hand always work even with Tamiyo
|
||||
if (payer.getZone(ZoneType.Hand).isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
return payer.canDiscardBy(ability, effect);
|
||||
// this will always work
|
||||
}
|
||||
else if (type.equals("LastDrawn")) {
|
||||
final Card c = payer.getLastDrawnCard();
|
||||
return handList.contains(c);
|
||||
}
|
||||
else if (type.equals("DifferentNames")) {
|
||||
Set<String> cardNames = Sets.newHashSet();
|
||||
for (Card c : handList) {
|
||||
cardNames.add(c.getName());
|
||||
}
|
||||
return cardNames.size() >= amount;
|
||||
}
|
||||
else {
|
||||
if (type.equals("Hand")) {
|
||||
// trying to discard an empty hand always work even with Tamiyo
|
||||
if (payer.getZone(ZoneType.Hand).isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
return payer.canDiscardBy(ability, effect);
|
||||
// this will always work
|
||||
boolean sameName = false;
|
||||
if (type.contains("+WithSameName")) {
|
||||
sameName = true;
|
||||
type = TextUtil.fastReplace(type, "+WithSameName", "");
|
||||
}
|
||||
else if (type.equals("LastDrawn")) {
|
||||
final Card c = payer.getLastDrawnCard();
|
||||
return handList.contains(c);
|
||||
if (!type.equals("Random") && !type.contains("X")) {
|
||||
// Knollspine Invocation fails to activate without the above conditional
|
||||
handList = CardLists.getValidCards(handList, type.split(";"), payer, source, ability);
|
||||
}
|
||||
else if (type.equals("DifferentNames")) {
|
||||
Set<String> cardNames = Sets.newHashSet();
|
||||
for (Card c : handList) {
|
||||
cardNames.add(c.getName());
|
||||
}
|
||||
return cardNames.size() >= amount;
|
||||
}
|
||||
else {
|
||||
boolean sameName = false;
|
||||
if (type.contains("+WithSameName")) {
|
||||
sameName = true;
|
||||
type = TextUtil.fastReplace(type, "+WithSameName", "");
|
||||
}
|
||||
if (!type.equals("Random") && !type.contains("X")) {
|
||||
// Knollspine Invocation fails to activate without the above conditional
|
||||
handList = CardLists.getValidCards(handList, type.split(";"), payer, source, ability);
|
||||
}
|
||||
if (sameName) {
|
||||
for (Card c : handList) {
|
||||
if (CardLists.filter(handList, CardPredicates.nameEquals(c.getName())).size() > 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
int adjustment = 0;
|
||||
if (source.isInZone(ZoneType.Hand) && payer.equals(source.getOwner())) {
|
||||
// If this card is in my hand, I can't use it to pay for it's own cost
|
||||
if (handList.contains(source)) {
|
||||
adjustment = 1;
|
||||
if (sameName) {
|
||||
for (Card c : handList) {
|
||||
if (CardLists.filter(handList, CardPredicates.nameEquals(c.getName())).size() > 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
int adjustment = 0;
|
||||
if (source.isInZone(ZoneType.Hand) && payer.equals(source.getOwner())) {
|
||||
// If this card is in my hand, I can't use it to pay for it's own cost
|
||||
if (handList.contains(source)) {
|
||||
adjustment = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (amount > handList.size() - adjustment) {
|
||||
// not enough cards in hand to pay
|
||||
return false;
|
||||
}
|
||||
if (amount > handList.size() - adjustment) {
|
||||
// not enough cards in hand to pay
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -148,13 +148,12 @@ public class CostPartMana extends CostPart {
|
||||
int timesToPay = AbilityUtils.calculateAmount(sa.getHostCard(), sa.getSVar("NumTimes"), sa);
|
||||
if (timesToPay == 0) {
|
||||
return null;
|
||||
} else {
|
||||
ManaCostBeingPaid totalMana = new ManaCostBeingPaid(getManaToPay());
|
||||
for (int i = 1; i < timesToPay; i++) {
|
||||
totalMana.addManaCost(getManaToPay());
|
||||
}
|
||||
return totalMana.toManaCost();
|
||||
}
|
||||
ManaCostBeingPaid totalMana = new ManaCostBeingPaid(getManaToPay());
|
||||
for (int i = 1; i < timesToPay; i++) {
|
||||
totalMana.addManaCost(getManaToPay());
|
||||
}
|
||||
return totalMana.toManaCost();
|
||||
}
|
||||
return getManaToPay();
|
||||
}
|
||||
|
||||
@@ -434,8 +434,8 @@ public class ReplacementHandler {
|
||||
private void getPossibleReplaceDamageList(PlayerCollection players, final boolean isCombat, final CardDamageMap damageMap, final SpellAbility cause) {
|
||||
for (Map.Entry<GameEntity, Map<Card, Integer>> et : damageMap.columnMap().entrySet()) {
|
||||
final GameEntity target = et.getKey();
|
||||
int playerIndex = (target instanceof Player ? players.indexOf(((Player) target)) :
|
||||
players.indexOf(((Card) target).getController()));
|
||||
int playerIndex = target instanceof Player ? players.indexOf(((Player) target)) :
|
||||
players.indexOf(((Card) target).getController());
|
||||
if (playerIndex == -1) continue;
|
||||
Map<ReplacementEffect, List<Map<AbilityKey, Object>>> replaceCandidateMap = replaceDamageList.get(playerIndex);
|
||||
for (Map.Entry<Card, Integer> e : et.getValue().entrySet()) {
|
||||
@@ -501,8 +501,8 @@ public class ReplacementHandler {
|
||||
Map<ReplacementEffect, List<Map<AbilityKey, Object>>> newReplaceCandidateMap = replaceCandidateMap;
|
||||
if (!target.equals(newTarget)) {
|
||||
PlayerCollection players = game.getPlayersInTurnOrder();
|
||||
int playerIndex = (newTarget instanceof Player ? players.indexOf(((Player) newTarget)) :
|
||||
players.indexOf(((Card) newTarget).getController()));
|
||||
int playerIndex = newTarget instanceof Player ? players.indexOf(((Player) newTarget)) :
|
||||
players.indexOf(((Card) newTarget).getController());
|
||||
newReplaceCandidateMap = replaceDamageList.get(playerIndex);
|
||||
}
|
||||
|
||||
|
||||
@@ -386,9 +386,8 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")) {
|
||||
return InputConfirm.confirm(this, CardView.get(attacker),
|
||||
localizer.getMessage("lblAssignCombatDamageWerentBlocked"));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user