diff --git a/.gitattributes b/.gitattributes index 98b942c3c8a..d8491f9be60 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5194,6 +5194,7 @@ res/cardsfolder/m/mad_dog.txt -text svneol=unset#text/plain res/cardsfolder/m/madblind_mountain.txt -text res/cardsfolder/m/maddening_wind.txt svneol=native#text/plain res/cardsfolder/m/madrush_cyclops.txt svneol=native#text/plain +res/cardsfolder/m/maelstrom_archangel.txt -text res/cardsfolder/m/maelstrom_djinn.txt svneol=native#text/plain res/cardsfolder/m/maelstrom_nexus.txt svneol=native#text/plain res/cardsfolder/m/maelstrom_pulse.txt svneol=native#text/plain diff --git a/res/cardsfolder/j/jaddi_lifestrider.txt b/res/cardsfolder/j/jaddi_lifestrider.txt index f3d47142c61..ba4c0742fc8 100644 --- a/res/cardsfolder/j/jaddi_lifestrider.txt +++ b/res/cardsfolder/j/jaddi_lifestrider.txt @@ -13,4 +13,6 @@ SVar:JaddiLifestriderZ:SVar$JaddiLifestriderY/Times.2 SVar:PlayMain1:FALSE SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/jaddi_lifestrider.jpg +SetInfo:ROE|Uncommon|http://magiccards.info/scans/en/roe/189.jpg +Oracle:When Jaddi Lifestrider enters the battlefield, you may tap any number of untapped creatures you control. You gain 2 life for each creature tapped this way. End \ No newline at end of file diff --git a/res/cardsfolder/m/maelstrom_archangel.txt b/res/cardsfolder/m/maelstrom_archangel.txt new file mode 100644 index 00000000000..c3d49182eae --- /dev/null +++ b/res/cardsfolder/m/maelstrom_archangel.txt @@ -0,0 +1,13 @@ +Name:Maelstrom Archangel +ManaCost:W U B R G +Types:Creature Angel +Text:no text +PT:5/5 +K:Flying +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigPlay | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you may cast a nonland card from your hand without paying its mana cost. +SVar:TrigPlay:DB$ Play | Valid$ Card.nonLand+YouCtrl | ValidZone$ Hand | WithoutManaCost$ True +SVar:Rarity:Mythic +SVar:Picture:http://www.wizards.com/global/images/magic/general/maelstrom_archangel.jpg +SetInfo:CFX|Mythic|http://magiccards.info/scans/en/cfx/115.jpg +Oracle:Flying\nWhenever Maelstrom Archangel deals combat damage to a player, you may cast a nonland card from your hand without paying its mana cost. +End \ No newline at end of file diff --git a/res/cardsfolder/s/sisters_of_stone_death.txt b/res/cardsfolder/s/sisters_of_stone_death.txt index d15707d12ef..fb4a3d62d2a 100644 --- a/res/cardsfolder/s/sisters_of_stone_death.txt +++ b/res/cardsfolder/s/sisters_of_stone_death.txt @@ -12,4 +12,6 @@ SVar:RemAIDeck:True SVar:RemRandomDeck:True SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/sisters_of_stone_death.jpg +SetInfo:RAV|Rare|http://magiccards.info/scans/en/rav/231.jpg +Oracle:{G}: Target creature blocks Sisters of Stone Death this turn if able.\n{B}{G}: Exile target creature blocking or blocked by Sisters of Stone Death.\n{2}{B}: Put a creature card exiled with Sisters of Stone Death onto the battlefield under your control. End \ No newline at end of file diff --git a/res/cardsfolder/t/toshiro_umezawa.txt b/res/cardsfolder/t/toshiro_umezawa.txt index fdf3d0f932e..08413439dfd 100644 --- a/res/cardsfolder/t/toshiro_umezawa.txt +++ b/res/cardsfolder/t/toshiro_umezawa.txt @@ -10,4 +10,6 @@ SVar:TrigPlay:DB$ Play | Defined$ Targeted SVar:RemAIDeck:True SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/toshiro_umezawa.jpg +SetInfo:BOK|Rare|http://magiccards.info/scans/en/bok/89.jpg +Oracle:Bushido 1 (When this blocks or becomes blocked, it gets +1/+1 until end of turn.)\nWhenever a creature an opponent controls dies, you may cast target instant card from your graveyard. If that card would be put into a graveyard this turn, exile it instead. End \ No newline at end of file diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryPlay.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryPlay.java index d39b51aa644..0fea24e9805 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryPlay.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryPlay.java @@ -40,6 +40,7 @@ import forge.card.spellability.AbilitySub; import forge.card.spellability.Spell; import forge.card.spellability.SpellAbility; import forge.card.spellability.Target; +import forge.gui.GuiUtils; import forge.util.MyRandom; /** *

@@ -275,7 +276,7 @@ public final class AbilityFactoryPlay { return false; } tgt.addTarget(CardFactoryUtil.getBestAI(cards)); - } else { + } else if (!params.containsKey("Valid")) { cards = new CardList(AbilityFactory.getDefinedCards(sa.getSourceCard(), params.get("Defined"), sa)); if (cards.isEmpty()) { return false; @@ -299,7 +300,11 @@ public final class AbilityFactoryPlay { */ private static boolean playTriggerAI(final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { - return false; + if (mandatory) { + return true; + } + + return playCanPlayAI(af, sa); } /** @@ -314,71 +319,92 @@ public final class AbilityFactoryPlay { */ private static void playResolve(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card card = af.getHostCard(); + final Card source = sa.getSourceCard(); Player controller = sa.getActivatingPlayer(); - - if (params.containsKey("Controller")) { - controller = AbilityFactory.getDefinedPlayers(card, params.get("Controller"), sa).get(0); + int amount = 1; + if (params.containsKey("Amount")) { + amount = AbilityFactory.calculateAmount(source, params.get("Amount"), sa); } - ArrayList tgtCards; + if (params.containsKey("Controller")) { + controller = AbilityFactory.getDefinedPlayers(source, params.get("Controller"), sa).get(0); + } + + CardList tgtCards = new CardList(); final Target tgt = sa.getTarget(); - if (tgt != null) { - tgtCards = tgt.getTargetCards(); - } else { - tgtCards = AbilityFactory.getDefinedCards(sa.getSourceCard(), params.get("Defined"), sa); + if (params.containsKey("Valid")) { + Zone zone = Zone.Hand; + if (params.containsKey("ValidZone")) { + zone = Zone.smartValueOf(params.get("ValidZone")); + } + tgtCards = AllZoneUtil.getCardsIn(zone); + tgtCards = tgtCards.getValidCards(params.get("Valid"), controller, source); + } else if (params.containsKey("Defined")) { + tgtCards = new CardList(AbilityFactory.getDefinedCards(sa.getSourceCard(), params.get("Defined"), sa)); + } else if (tgt != null) { + tgtCards = new CardList(tgt.getTargetCards()); } if (tgtCards.isEmpty()) { return; } - Card tgtCard = tgtCards.get(0); - final StringBuilder sb = new StringBuilder(); - sb.append("Do you want to play " + tgtCard + "?"); - if (controller.isHuman() && params.containsKey("Optional") && !GameActionUtil.showYesNoDialog(card, sb.toString())) { - return; - } - if (tgtCard.isLand()) { - controller.playLand(tgtCard); - return; - } - - ArrayList sas = tgtCard.getBasicSpells(); - if (sas.isEmpty()) { - return; - } - SpellAbility tgtSA = sas.get(0); - - if (params.containsKey("WithoutManaCost")) { - if (controller.isHuman()) { - final SpellAbility newSA = tgtSA.copy(); - final Cost cost = new Cost("", tgtCard.getName(), false); - for (final CostPart part : newSA.getPayCosts().getCostParts()) { - if (!(part instanceof CostMana)) { - cost.getCostParts().add(part); - } - } - cost.setNoManaCostChange(true); - newSA.setPayCosts(cost); - newSA.setManaCost(""); - newSA.setDescription(sa.getDescription() + " (without paying its mana cost)"); - AllZone.getGameAction().playSpellAbility(newSA); - } else { - if (tgtSA instanceof Spell) { - Spell spell = (Spell) tgtSA; - if (spell.canPlayFromEffectAI(false, true)) { - //System.out.println("canPlayFromEffectAI: " + this.getHostCard()); - ComputerUtil.playSpellAbilityWithoutPayingManaCost(tgtSA); - } + for (int i = 0; i < amount; i++) { + Card tgtCard = tgtCards.get(0); + if (tgtCards.size() > 1) { + if (controller.isHuman()) { + tgtCard = (Card) GuiUtils.getChoice("Select a card to play", tgtCards.toArray()); + } else { + tgtCard = CardFactoryUtil.getBestAI(tgtCards); } } - } else { - if (controller.isHuman()) { - AllZone.getGameAction().playSpellAbility(tgtSA); - } else if (tgtSA.canPlayAI()) { - ComputerUtil.playStack(tgtSA); + final StringBuilder sb = new StringBuilder(); + sb.append("Do you want to play " + tgtCard + "?"); + if (controller.isHuman() && params.containsKey("Optional") + && !GameActionUtil.showYesNoDialog(source, sb.toString())) { + return; + } + if (tgtCard.isLand()) { + controller.playLand(tgtCard); + return; + } + + ArrayList sas = tgtCard.getBasicSpells(); + if (sas.isEmpty()) { + return; + } + SpellAbility tgtSA = sas.get(0); + + if (params.containsKey("WithoutManaCost")) { + if (controller.isHuman()) { + final SpellAbility newSA = tgtSA.copy(); + final Cost cost = new Cost("", tgtCard.getName(), false); + for (final CostPart part : newSA.getPayCosts().getCostParts()) { + if (!(part instanceof CostMana)) { + cost.getCostParts().add(part); + } + } + cost.setNoManaCostChange(true); + newSA.setPayCosts(cost); + newSA.setManaCost(""); + newSA.setDescription(sa.getDescription() + " (without paying its mana cost)"); + AllZone.getGameAction().playSpellAbility(newSA); + } else { + if (tgtSA instanceof Spell) { + Spell spell = (Spell) tgtSA; + if (spell.canPlayFromEffectAI(false, true)) { + //System.out.println("canPlayFromEffectAI: " + this.getHostCard()); + ComputerUtil.playSpellAbilityWithoutPayingManaCost(tgtSA); + } + } + } + } else { + if (controller.isHuman()) { + AllZone.getGameAction().playSpellAbility(tgtSA); + } else if (tgtSA.canPlayAI()) { + ComputerUtil.playStack(tgtSA); + } } } } // end resolve