diff --git a/.gitattributes b/.gitattributes index 189af4f03fc..3f4e3a8d978 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1237,6 +1237,7 @@ res/cardsfolder/b/boros_signet.txt svneol=native#text/plain res/cardsfolder/b/boros_swiftblade.txt svneol=native#text/plain res/cardsfolder/b/borrowing_100000_arrows.txt svneol=native#text/plain res/cardsfolder/b/borrowing_the_east_wind.txt svneol=native#text/plain +res/cardsfolder/b/boseiju_who_shelters_all.txt -text res/cardsfolder/b/bosh_iron_golem.txt svneol=native#text/plain res/cardsfolder/b/bosh_iron_golem_avatar.txt -text res/cardsfolder/b/bosk_banneret.txt svneol=native#text/plain diff --git a/res/cardsfolder/b/boseiju_who_shelters_all.txt b/res/cardsfolder/b/boseiju_who_shelters_all.txt new file mode 100644 index 00000000000..e8714f1384c --- /dev/null +++ b/res/cardsfolder/b/boseiju_who_shelters_all.txt @@ -0,0 +1,8 @@ +Name:Boseiju, Who Shelters All +ManaCost:no cost +Types:Legandary Land +K:CARDNAME enters the battlefield tapped. +A:AB$ Mana | Cost$ T PayLife<2> | Produced$ 1 | AddsNoCounter$ !Permanent | SpellDescription$ Add {1} to your mana pool. If that mana is spent on an instant or sorcery spell, that spell can't be countered by spells or abilities. +SVar:Picture:http://www.wizards.com/global/images/magic/general/boseju_who_shelters_all.jpg +Oracle:Boseiju, Who Shelters All enters the battlefield tapped.\n{T}, Pay 2 life: Add {1} to your mana pool. If that mana is spent on an instant or sorcery spell, that spell can't be countered by spells or abilities.{T}, Pay 1 life: Add {G} or {W} to your mana pool.\n{1}, {T}, Sacrifice Horizon Canopy: Draw a card. +SetInfo:CHK Rare \ No newline at end of file diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index 64d96812bae..b93ec413623 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -5101,15 +5101,21 @@ public class Card extends GameEntity implements Comparable { // Inclusive restrictions are Card types final String[] incR = restriction.split("\\.", 2); + boolean testFailed = false; + if(incR[0].startsWith("!")) { + testFailed = true; // a bit counter logical )) + incR[0] = incR[0].substring(1); // consume negation sign + } + if (incR[0].equals("Spell") && !this.isSpell()) { - return false; + return testFailed; } if (incR[0].equals("Permanent") && (this.isInstant() || this.isSorcery())) { - return false; + return testFailed; } if (!incR[0].equals("card") && !incR[0].equals("Card") && !incR[0].equals("Spell") && !incR[0].equals("Permanent") && !(this.isType(incR[0]))) { - return false; // Check for wrong type + return testFailed; // Check for wrong type } if (incR.length > 1) { @@ -5117,11 +5123,11 @@ public class Card extends GameEntity implements Comparable { final String[] exR = excR.split("\\+"); // Exclusive Restrictions are ... for (int j = 0; j < exR.length; j++) { if (!this.hasProperty(exR[j], sourceController, source)) { - return false; + return testFailed; } } } - return true; + return !testFailed; } // isValid(String Restriction) // Takes arguments like Blue or withFlying diff --git a/src/main/java/forge/card/mana/Mana.java b/src/main/java/forge/card/mana/Mana.java index 55742456e70..3b5f496aca8 100644 --- a/src/main/java/forge/card/mana/Mana.java +++ b/src/main/java/forge/card/mana/Mana.java @@ -20,6 +20,7 @@ package forge.card.mana; import forge.Card; import forge.card.MagicColor; import forge.card.spellability.AbilityManaPart; +import forge.card.spellability.SpellAbility; /** *

@@ -38,7 +39,6 @@ public class Mana { result = prime * result + color; result = prime * result + (hasRestrictions ? 1231 : 1237); result = prime * result + ((manaAbility == null) ? 0 : manaAbility.hashCode()); - result = prime * result + (pumpCounterMagic ? 1231 : 1237); result = prime * result + ((sourceCard == null) ? 0 : sourceCard.hashCode()); return result; } @@ -69,7 +69,6 @@ public class Mana { private Card sourceCard = null; private AbilityManaPart manaAbility = null; private boolean hasRestrictions = false; - private boolean pumpCounterMagic = false; /** *

@@ -90,9 +89,6 @@ public class Mana { if (!manaAbility.getManaRestrictions().isEmpty()) { this.hasRestrictions = true; } - if (manaAbility.cannotCounterPaidWith()) { - this.pumpCounterMagic = true; - } } if (source == null) { return; @@ -144,8 +140,8 @@ public class Mana { * * @return a boolean. */ - public final boolean addsNoCounterMagic() { - return this.pumpCounterMagic; + public final boolean addsNoCounterMagic(SpellAbility saBeingPaid) { + return this.manaAbility != null && manaAbility.cannotCounterPaidWith(saBeingPaid); } /** diff --git a/src/main/java/forge/card/mana/ManaPool.java b/src/main/java/forge/card/mana/ManaPool.java index 7ea029ef55c..e99fd97805c 100644 --- a/src/main/java/forge/card/mana/ManaPool.java +++ b/src/main/java/forge/card/mana/ManaPool.java @@ -240,15 +240,8 @@ public class ManaPool { final Mana mana = this.getMana(manaShard, saBeingPaidFor, manaCost.getSourceRestriction()); if (mana == null) { return; // no matching mana in the pool - } - else if (manaCost.isNeeded(mana)) { - manaCost.payMana(mana); - saBeingPaidFor.getPayingMana().add(mana); - this.removeMana( mana); - if (mana.addsNoCounterMagic() && saBeingPaidFor.getSourceCard() != null) { - saBeingPaidFor.getSourceCard().setCanCounter(false); - } - } + } else + tryPayCostWithMana(saBeingPaidFor, manaCost, mana); } /** @@ -268,25 +261,26 @@ public class ManaPool { // Mana restriction must be checked before this method is called final List paidAbs = sa.getPayingManaAbilities(); - final List manaPaid = sa.getPayingMana(); - SpellAbility tail = ma; AbilityManaPart abManaPart = null; - while(abManaPart == null && tail != null) - { + while(abManaPart == null && tail != null) { abManaPart = tail.getManaPart(); tail = tail.getSubAbility(); } paidAbs.add(ma); // assumes some part on the mana produced by the ability will get used for (final Mana mana : abManaPart.getLastManaProduced()) { - if (manaCost.isNeeded(mana)) { - manaCost.payMana(mana); - manaPaid.add(mana); - this.removeMana(mana); - if (mana.addsNoCounterMagic() && sa.getSourceCard() != null) { - sa.getSourceCard().setCanCounter(false); - } + tryPayCostWithMana(sa, manaCost, mana); + } + } + + private void tryPayCostWithMana(final SpellAbility sa, ManaCostBeingPaid manaCost, final Mana mana) { + if (manaCost.isNeeded(mana)) { + manaCost.payMana(mana); + sa.getPayingMana().add(mana); + this.removeMana(mana); + if (mana.addsNoCounterMagic(sa) && sa.getSourceCard() != null) { + sa.getSourceCard().setCanCounter(false); } } } diff --git a/src/main/java/forge/card/spellability/AbilityManaPart.java b/src/main/java/forge/card/spellability/AbilityManaPart.java index 9cf483e79db..b8d0aa5dd79 100644 --- a/src/main/java/forge/card/spellability/AbilityManaPart.java +++ b/src/main/java/forge/card/spellability/AbilityManaPart.java @@ -55,7 +55,7 @@ public class AbilityManaPart implements java.io.Serializable { private final transient Card sourceCard; // Spells paid with this mana spell can't be countered. - private boolean cannotCounterSpell; + private String cannotCounterSpell; /** *

@@ -79,7 +79,7 @@ public class AbilityManaPart implements java.io.Serializable { this.manaRestrictions = params.get("RestrictValid"); } - this.cannotCounterSpell = params.containsKey("AddsNoCounter"); + this.cannotCounterSpell = params.get("AddsNoCounter"); } @@ -139,11 +139,17 @@ public class AbilityManaPart implements java.io.Serializable { *

* cannotCounterPaidWith. *

+ * @param saBeingPaid * * @return a {@link java.lang.String} object. */ - public boolean cannotCounterPaidWith() { - return cannotCounterSpell; + public boolean cannotCounterPaidWith(SpellAbility saBeingPaid) { + if (null == cannotCounterSpell) return false; + if ("True".equalsIgnoreCase(cannotCounterSpell)) return true; + + Card source = saBeingPaid.getSourceCard(); + if (source == null) return false; + return source.isValid(cannotCounterSpell, sourceCard.getController(), sourceCard); } /**