diff --git a/.gitattributes b/.gitattributes index a5a98ce2322..3ef50bba9ad 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7654,6 +7654,7 @@ res/cardsfolder/p/peace_and_quiet.txt svneol=native#text/plain res/cardsfolder/p/peace_of_mind.txt svneol=native#text/plain res/cardsfolder/p/peace_strider.txt svneol=native#text/plain res/cardsfolder/p/peacekeeper.txt svneol=native#text/plain +res/cardsfolder/p/peacekeeper_avatar.txt -text res/cardsfolder/p/peach_garden_oath.txt svneol=native#text/plain res/cardsfolder/p/pearl_dragon.txt svneol=native#text/plain res/cardsfolder/p/pearl_medallion.txt svneol=native#text/plain @@ -10345,6 +10346,7 @@ res/cardsfolder/s/stonefare_crocodile.txt -text res/cardsfolder/s/stoneforge_mystic.txt svneol=native#text/plain res/cardsfolder/s/stonehands.txt svneol=native#text/plain res/cardsfolder/s/stonehewer_giant.txt -text +res/cardsfolder/s/stonehewer_giant_avatar.txt -text res/cardsfolder/s/stonehorn_dignitary.txt -text res/cardsfolder/s/stonewood_invocation.txt svneol=native#text/plain res/cardsfolder/s/stonewood_invoker.txt svneol=native#text/plain diff --git a/res/cardsfolder/p/peacekeeper_avatar.txt b/res/cardsfolder/p/peacekeeper_avatar.txt new file mode 100644 index 00000000000..5cdb64ff96a --- /dev/null +++ b/res/cardsfolder/p/peacekeeper_avatar.txt @@ -0,0 +1,10 @@ +Name:Peacekeeper Avatar +ManaCost:no cost +Types:Vanguard +HandLifeModifier:+0/+9 +A:AB$ RepeatEach | Cost$ 3 | ActivationZone$ Command | RepeatPlayers$ Player.Opponent | RepeatSubAbility$ ArrestEach | StackDescription$ SpellDescription | SpellDescription$ For each opponent who controls a creature, put a token onto the battlefield that's a copy of a card named Arrest and attach it to a creature that player controls chosen at random. +SVar:ArrestEach:DB$ ChooseCard | Amount$ 1 | Choices$ Creature.RememberedPlayerCtrl | AtRandom$ True | SubAbility$ DBAttach +SVar:DBAttach:DB$ CopyPermanent | NumCopies$ 1 | ValidSupportedCopy$ Card.namedArrest | DefinedName$ Arrest | AttachedTo$ ChosenCard | ConditionDefined$ ChosenCard | ConditionPresent$ Creature | ConditionCompare$ GE1 +SVar:Picture:http://www.cardforge.org/fpics/vgd-lq/peacekeeper_avatar.jpg +Oracle:Hand +0, life +9\n{3}: For each opponent who controls a creature, put a token onto the battlefield that's a copy of a card named Arrest and attach it to a creature that player controls chosen at random. +SetInfo:VAN Special \ No newline at end of file diff --git a/res/cardsfolder/s/stonehewer_giant_avatar.txt b/res/cardsfolder/s/stonehewer_giant_avatar.txt new file mode 100644 index 00000000000..fa1328a2d4a --- /dev/null +++ b/res/cardsfolder/s/stonehewer_giant_avatar.txt @@ -0,0 +1,10 @@ +Name:Stonehewer Giant Avatar +ManaCost:no cost +Types:Vanguard +HandLifeModifier:+1/-5 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.YouCtrl | TriggerZones$ Command | Execute$ TrigCopyEquip | TriggerDescription$ Whenever a creature enters the battlefield under your control, put a token onto the battlefield that's a copy of a random Equipment card with converted mana cost less than or equal to that creature's converted mana cost. Attach that Equipment to that creature. +SVar:TrigCopyEquip:AB$ CopyPermanent | Cost$ 0 | Defined$ TriggeredCard | NumCopies$ 1 | ValidSupportedCopy$ Equipment.cmcLEX | References$ X | RandomCopied$ True | RandomNum$ 1 | RememberCopied$ True | AttachedTo$ TriggeredCard +SVar:X:TriggeredCard$CardManaCost +SVar:Picture:http://www.cardforge.org/fpics/vgd-lq/stonehewer_giant_avatar.jpg +Oracle:Hand +1, life -5\nWhenever a creature enters the battlefield under your control, put a token onto the battlefield that's a copy of a random Equipment card with converted mana cost less than or equal to that creature's converted mana cost. Attach that Equipment to that creature. +SetInfo:VAN Special \ No newline at end of file diff --git a/src/main/java/forge/card/CardRulesPredicates.java b/src/main/java/forge/card/CardRulesPredicates.java index 733fb683029..37a5f18fd6e 100644 --- a/src/main/java/forge/card/CardRulesPredicates.java +++ b/src/main/java/forge/card/CardRulesPredicates.java @@ -462,6 +462,10 @@ public final class CardRulesPredicates { /** The Constant isArtifact. */ public static final Predicate IS_ARTIFACT = CardRulesPredicates .coreType(true, CardCoreType.Artifact); + + /** The Constant isEquipment. */ + public static final Predicate IS_EQUIPMENT = CardRulesPredicates + .subType("Equipment"); /** The Constant isLand. */ public static final Predicate IS_LAND = CardRulesPredicates.coreType(true, CardCoreType.Land); diff --git a/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java b/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java index 81520c3faab..f9cdecb4a34 100644 --- a/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java +++ b/src/main/java/forge/card/ability/effects/CopyPermanentEffect.java @@ -6,10 +6,17 @@ import java.util.List; import org.apache.commons.lang3.StringUtils; +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; + import forge.Card; import forge.CardCharacteristicName; +import forge.CardLists; import forge.Command; import forge.Singletons; +import forge.card.CardRulesPredicates; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.cardfactory.CardFactory; @@ -18,8 +25,15 @@ import forge.card.mana.ManaCost; import forge.card.spellability.Ability; import forge.card.spellability.SpellAbility; import forge.card.spellability.Target; +import forge.game.ai.ComputerUtilCard; +import forge.game.player.HumanPlayer; import forge.game.player.Player; +import forge.game.zone.ZoneType; +import forge.gui.GuiChoose; import forge.item.CardDb; +import forge.item.CardPrinted; +import forge.util.Aggregates; +import forge.util.PredicateString.StringOp; public class CopyPermanentEffect extends SpellAbilityEffect { @@ -36,6 +50,9 @@ public class CopyPermanentEffect extends SpellAbilityEffect { return sb.toString(); } + /* (non-Javadoc) + * @see forge.card.ability.SpellAbilityEffect#resolve(forge.card.spellability.SpellAbility) + */ @Override public void resolve(final SpellAbility sa) { final Card hostCard = sa.getSourceCard(); @@ -46,9 +63,47 @@ public class CopyPermanentEffect extends SpellAbilityEffect { final int numCopies = sa.hasParam("NumCopies") ? AbilityUtils.calculateAmount(hostCard, sa.getParam("NumCopies"), sa) : 1; - final List tgtCards = getTargetCards(sa); + List tgtCards = getTargetCards(sa); final Target tgt = sa.getTarget(); + if (sa.hasParam("ValidSupportedCopy")) { + List cards = Lists.newArrayList(CardDb.instance().getUniqueCards()); + String valid = sa.getParam("ValidSupportedCopy"); + if (valid.contains("X")) { + valid = valid.replace("X", Integer.toString(AbilityUtils.calculateAmount(hostCard, "X", sa))); + } + if (StringUtils.containsIgnoreCase(valid, "creature")) { + Predicate cpp = Predicates.compose(CardRulesPredicates.Presets.IS_CREATURE, CardPrinted.FN_GET_RULES); + cards = Lists.newArrayList(Iterables.filter(cards, cpp)); + } + if (StringUtils.containsIgnoreCase(valid, "equipment")) { + Predicate cpp = Predicates.compose(CardRulesPredicates.Presets.IS_EQUIPMENT, CardPrinted.FN_GET_RULES); + cards = Lists.newArrayList(Iterables.filter(cards, cpp)); + } + if (sa.hasParam("RandomCopied")) { + List copysource = new ArrayList(cards); + List choice = new ArrayList(); + final String num = sa.hasParam("RandomNum") ? sa.getParam("RandomNum") : "1"; + int ncopied = AbilityUtils.calculateAmount(hostCard, num, sa); + while(ncopied > 0) { + final CardPrinted cp = Aggregates.random(copysource); + if (cp.getMatchingForgeCard().isValid(valid, hostCard.getController(), hostCard)) { + choice.add(cp.getMatchingForgeCard()); + copysource.remove(cp); + ncopied -= 1; + } + } + tgtCards = choice; + } else if (sa.hasParam("DefinedName")) { + final String name = sa.getParam("DefinedName"); + Predicate cpp = Predicates.compose(CardRulesPredicates.name(StringOp.EQUALS, name), CardPrinted.FN_GET_RULES); + cards = Lists.newArrayList(Iterables.filter(cards, cpp)); + Card c = cards.get(0).getMatchingForgeCard(); + tgtCards.clear(); + tgtCards.add(c); + } + } + Player controller = null; if (sa.hasParam("Controller")) { List defined = AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("Controller"), sa); @@ -137,6 +192,38 @@ public class CopyPermanentEffect extends SpellAbilityEffect { if (c.isFaceDown()) { c.setState(CardCharacteristicName.FaceDown); } + + if (sa.hasParam("AttachedTo")) { + List list = AbilityUtils.getDefinedCards(hostCard, + sa.getParam("AttachedTo"), sa); + if (list.isEmpty()) { + list = copy.getController().getGame().getCardsIn(ZoneType.Battlefield); + list = CardLists.getValidCards(list, sa.getParam("AttachedTo"), copy.getController(), copy); + } + if (!list.isEmpty()) { + Card attachedTo = null; + if (sa.getActivatingPlayer() instanceof HumanPlayer) { + if (list.size() > 1) { + attachedTo = GuiChoose.one(copy + " - Select a card to attach to.", list); + } else { + attachedTo = list.get(0); + } + } else { // AI player + attachedTo = ComputerUtilCard.getBestAI(list); + } + if (copy.isAura()) { + if (attachedTo.canBeEnchantedBy(copy)) { + copy.enchantEntity(attachedTo); + } else {//can't enchant + continue; + } + } else { //Equipment + copy.equipCard(attachedTo); + } + } else { + continue; + } + } copy = Singletons.getModel().getGame().getAction().moveToPlay(copy); copy.setCloneOrigin(hostCard); @@ -147,6 +234,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect { if (wasInAlt) { c.setState(stateName); } + // have to do this since getTargetCard() might change // if Kiki-Jiki somehow gets untapped again