diff --git a/.gitattributes b/.gitattributes index 8ab3ba53ef8..e0e90ec1507 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3044,6 +3044,7 @@ res/cardsfolder/g/gargoyle_sentinel.txt svneol=native#text/plain res/cardsfolder/g/garruk_primal_hunter.txt svneol=native#text/plain res/cardsfolder/g/garruk_wildspeaker.txt svneol=native#text/plain res/cardsfolder/g/garruks_companion.txt svneol=native#text/plain +res/cardsfolder/g/garruks_horde.txt -text res/cardsfolder/g/garruks_packleader.txt svneol=native#text/plain res/cardsfolder/g/garza_zol_plague_queen.txt svneol=native#text/plain res/cardsfolder/g/gaseous_form.txt svneol=native#text/plain diff --git a/res/cardsfolder/g/garruks_horde.txt b/res/cardsfolder/g/garruks_horde.txt new file mode 100644 index 00000000000..7c8f6f73ca3 --- /dev/null +++ b/res/cardsfolder/g/garruks_horde.txt @@ -0,0 +1,13 @@ +Name:Garruk's Horde +ManaCost:5 G G +Types:Creature Beast +Text:no text +PT:7/7 +K:Trample +K:Play with the top card of your library revealed. +S:Mode$ Continuous | Affected$ Creature.TopLibrary | AffectedZone$ Library | AddHiddenKeyword$ HIDDEN May be played | Description$ You may cast the top card of your library if it's a creature card. (Do this only any time you could cast that creature card. You still pay the spell's costs.) +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/garruks_horde.jpg +SetInfo:M12|Rare|http://magiccards.info/scans/en/m12/176.jpg +Oracle:Trample\nPlay with the top card of your library revealed.\nYou may cast the top card of your library if it's a creature card. (Do this only any time you could cast that creature card. You still pay the spell's costs.) +End \ No newline at end of file diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index ba43be87349..e8569f88ff3 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -5057,21 +5057,25 @@ public class Card extends GameEntity implements Comparable { CardList list = this.getOwner().getCardsIn(Zone.Graveyard); if (!list.getAbove(source, this)) return false; - }else if (Property.startsWith("DirectlyAbove")){ // "Are Directly Above" Source + } else if (Property.startsWith("DirectlyAbove")){ // "Are Directly Above" Source CardList list = this.getOwner().getCardsIn(Zone.Graveyard); if (!list.getDirectlyAbove(source, this)) return false; - }else if (Property.startsWith("TopGraveyardCreature")){ + } else if (Property.startsWith("TopGraveyardCreature")){ CardList list = this.getOwner().getCardsIn(Zone.Graveyard); list = list.getType("Creature"); list.reverse(); if (list.isEmpty() || !this.equals(list.get(0))) return false; - }else if (Property.startsWith("TopGraveyard")){ + } else if (Property.startsWith("TopGraveyard")){ CardList list = this.getOwner().getCardsIn(Zone.Graveyard); list.reverse(); if (list.isEmpty() || !this.equals(list.get(0))) return false; + } else if (Property.startsWith("TopLibrary")){ + CardList list = this.getOwner().getCardsIn(Zone.Library); + if (list.isEmpty() || !this.equals(list.get(0))) + return false; } else if (Property.startsWith("Cloned")) { if (cloneOrigin == null || !cloneOrigin.equals(source)) return false; } else if (Property.startsWith("DamagedBy")) { diff --git a/src/main/java/forge/ComputerUtil.java b/src/main/java/forge/ComputerUtil.java index 4672cec4695..386a4d5bbf8 100644 --- a/src/main/java/forge/ComputerUtil.java +++ b/src/main/java/forge/ComputerUtil.java @@ -797,7 +797,7 @@ public class ComputerUtil { CardList lands = computer.getCardsIn(Zone.Graveyard).getType("Land"); for (Card crd : lands){ - if (crd.isLand() && crd.hasKeyword("May be played")) + if (crd.isLand() && crd.hasStartOfKeyword("May be played")) landList.add(crd); } diff --git a/src/main/java/forge/GameAction.java b/src/main/java/forge/GameAction.java index c275151caa0..c493754f216 100644 --- a/src/main/java/forge/GameAction.java +++ b/src/main/java/forge/GameAction.java @@ -1584,7 +1584,7 @@ public class GameAction { if (c.isLand() && human.canPlayLand()) { PlayerZone zone = AllZone.getZoneOf(c); - if (zone.is(Zone.Hand) || (!zone.is(Zone.Battlefield)) && c.hasKeyword("May be played")) { + if (zone.is(Zone.Hand) || (!zone.is(Zone.Battlefield)) && c.hasStartOfKeyword("May be played")) { choices.add("Play land"); } } @@ -1630,23 +1630,10 @@ public class GameAction { * @param c a {@link forge.Card} object. */ public final void playCardNoCost(final Card c) { - //SpellAbility[] choices = (SpellAbility[]) c.getSpells().toArray(); ArrayList choices = c.getBasicSpells(); SpellAbility sa; //TODO add Buyback, Kicker, ... , spells here - /* - ArrayList additional = c.getAdditionalCostSpells(); - for (SpellAbility s : additional) - { - - } - */ - /* - System.out.println(choices.length); - for(int i = 0; i < choices.length; i++) - System.out.println(choices[i]); - */ if (choices.size() == 0) { return; } else if (choices.size() == 1) { diff --git a/src/main/java/forge/card/abilityFactory/AbilityFactory_Pump.java b/src/main/java/forge/card/abilityFactory/AbilityFactory_Pump.java index 342d3de6eb9..06720fba973 100644 --- a/src/main/java/forge/card/abilityFactory/AbilityFactory_Pump.java +++ b/src/main/java/forge/card/abilityFactory/AbilityFactory_Pump.java @@ -718,13 +718,16 @@ public class AbilityFactory_Pump { } } + Zone pumpZone = params.containsKey("PumpZone") ? Zone.smartValueOf(params.get("PumpZone")) : Zone.Battlefield; + int size = tgtCards.size(); for (int j = 0; j < size; j++) { final Card tgtC = tgtCards.get(j); - // only pump things in play - if (!AllZoneUtil.isCardInPlay(tgtC)) + // only pump things in PumpZone + if (!AllZoneUtil.getCardsIn(pumpZone).contains(tgtC)) { continue; + } // if pump is a target, make sure we can still target now if (tgt != null && !CardFactoryUtil.canTarget(AF.getHostCard(), tgtC)) @@ -736,8 +739,10 @@ public class AbilityFactory_Pump { for(int i=0;i sb = new ArrayList(3); sb.add(Constant.Zone.Graveyard); sb.add(Constant.Zone.Exile); + sb.add(Constant.Zone.Library); sb.add(Constant.Zone.Command); CardList cl = player.getCardsIn(sb); cl.addAll(AllZone.getStackZone().getCards()); @@ -2661,20 +2662,21 @@ public class CardFactoryUtil { } - if (c.isLand() && !zone.is(Constant.Zone.Battlefield) && c.hasKeyword("May be played")) { + if (c.isLand() && !zone.is(Constant.Zone.Battlefield) && c.hasStartOfKeyword("May be played")) { return true; } for (SpellAbility sa : c.getSpellAbility()) { - if (AllZone.getZoneOf(c).is(sa.getRestrictions().getZone())) { + Zone restrictZone = sa.getRestrictions().getZone(); + if (zone.is(restrictZone)) { return true; } - // TODO - Yawgmoth's Will check here, lots of testing before adding - // this though - // if (!zone.is(Constant.Zone.Battlefield) && - // c.hasKeyword("May be played") && sa.isSpell()) - // return true; + if (sa.isSpell() && !zone.is(Zone.Battlefield) && c.hasStartOfKeyword("May be played") + && restrictZone.equals(Zone.Hand)) + { + return true; + } } return false; diff --git a/src/main/java/forge/card/spellability/SpellAbility_Restriction.java b/src/main/java/forge/card/spellability/SpellAbility_Restriction.java index 96b4ec7c139..6111f48fd26 100644 --- a/src/main/java/forge/card/spellability/SpellAbility_Restriction.java +++ b/src/main/java/forge/card/spellability/SpellAbility_Restriction.java @@ -147,8 +147,21 @@ public class SpellAbility_Restriction extends SpellAbility_Variables { * @return a boolean. */ public boolean canPlay(Card c, SpellAbility sa) { - if (!AllZone.getZoneOf(c).is(zone) || c.isPhasedOut()) + if (c.isPhasedOut()) { return false; + } + + PlayerZone cardZone = AllZone.getZoneOf(c); + if (!cardZone.is(zone)) { + // If Card is not in the default activating zone, do some additional checks + // Not a Spell, or on Battlefield, return false + if (!sa.isSpell() || cardZone.is(Zone.Battlefield)) { + return false; + } + else if (!c.hasStartOfKeyword("May be played") || !zone.equals(Zone.Hand)) { + return false; + } + } Player activator = sa.getActivatingPlayer(); if (activator == null) {