diff --git a/.gitattributes b/.gitattributes index 557e35a7bbb..92e673e3787 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1616,6 +1616,7 @@ res/cardsfolder/dakmor_scorpion.txt -text svneol=native#text/plain res/cardsfolder/dakmor_sorceress.txt -text svneol=native#text/plain res/cardsfolder/damnation.txt -text svneol=native#text/plain res/cardsfolder/damping_field.txt -text svneol=native#text/plain +res/cardsfolder/dance_of_many.txt svneol=native#text/plain res/cardsfolder/dance_of_shadows.txt -text svneol=native#text/plain res/cardsfolder/dance_of_the_dead.txt -text svneol=native#text/plain res/cardsfolder/dancing_scimitar.txt -text svneol=native#text/plain diff --git a/res/cardsfolder/dance_of_many.txt b/res/cardsfolder/dance_of_many.txt new file mode 100644 index 00000000000..8613e253919 --- /dev/null +++ b/res/cardsfolder/dance_of_many.txt @@ -0,0 +1,15 @@ +Name:Dance of Many +ManaCost:U U +Types:Enchantment +Text:no text +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigCopy | TriggerDescription$ When CARDNAME enters the battlefield, put a token that's a copy of target nontoken creature onto the battlefield. +SVar:TrigCopy:AB$ CopyPermanent | Cost$ 0 | ValidTgts$ Creature.nonToken | TgtPrompt$ Select target nontoken creature +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME leaves the battlefield, exile the token. +SVar:TrigExile:AB$ ChangeZone | Cost$ 0 | Defined$ Clones | Origin$ Battlefield | Destination$ Exile +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Cloned | Execute$ TrigSac | TriggerDescription$ When the token leaves the battlefield, sacrifice CARDNAME. +SVar:TrigSac:AB$ Sacrifice | Cost$ 0 | Defined$ Self +K:At the beginning of your upkeep, sacrifice CARDNAME unless you pay U U +SVar:RemAIDeck:True +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/dance_of_many.jpg +End \ No newline at end of file diff --git a/src/forge/Card.java b/src/forge/Card.java index 1527d2896f7..2ac7c384af6 100644 --- a/src/forge/Card.java +++ b/src/forge/Card.java @@ -157,6 +157,7 @@ public class Card extends MyObservable { private String topCardName = ""; private String reflectableMana = ""; private Card cloneOrigin = null; + private ArrayList clones = new ArrayList(); private Card currentlyCloningCard = null; private Command cloneLeavesPlayCommand = null; private ArrayList gainControlTargets = new ArrayList(); @@ -426,6 +427,27 @@ public class Card extends MyObservable { return sirenAttackOrDestroy; } + public ArrayList getClones() { + return clones; + } + + public void setClones(ArrayList c) { + clones.clear(); + clones.addAll(c); + } + + public void addClone(Card c) { + clones.add(c); + } + + public void addClones(ArrayList c) { + clones.addAll(c); + } + + public void clearClones() { + clones.clear(); + } + public Card getCloneOrigin() { return cloneOrigin; } @@ -2808,6 +2830,10 @@ public class Card extends MyObservable { if (!equippedBy.contains(source) && !enchantedBy.contains(source)) return false; } else if (Property.startsWith("Attached")) { if (!equipping.contains(source) && !enchanting.contains(source)) return false; } + + else if(Property.startsWith("Cloned")) { + if(cloneOrigin == null || !cloneOrigin.equals(source)) return false; + } else if (Property.startsWith("DamagedBy")) { if(!receivedDamageFromThisTurn.containsKey(source)) return false; } diff --git a/src/forge/MagicStack.java b/src/forge/MagicStack.java index e2acf2904e5..abdae02382f 100644 --- a/src/forge/MagicStack.java +++ b/src/forge/MagicStack.java @@ -748,6 +748,19 @@ public class MagicStack extends MyObservable { CombatUtil.showCombat(); GuiDisplayUtil.updateGUI(); + + //TODO - this is a huge hack. Why is this necessary? + //hostCard in AF is not the same object that's on the battlefield + //verified by System.identityHashCode(card); + Card tmp = sa.getSourceCard(); + if(tmp.getClones().size() > 0) { + for(Card c : AllZoneUtil.getCardsInPlay()) { + if(c.equals(tmp)) { + c.setClones(tmp.getClones()); + } + } + + } } public boolean hasFizzled(SpellAbility sa, Card source){ diff --git a/src/forge/card/abilityFactory/AbilityFactory.java b/src/forge/card/abilityFactory/AbilityFactory.java index 265fb7c15ea..8f49fa5a214 100644 --- a/src/forge/card/abilityFactory/AbilityFactory.java +++ b/src/forge/card/abilityFactory/AbilityFactory.java @@ -1026,6 +1026,12 @@ public class AbilityFactory { } } + else if (defined.equals("Clones")){ + for(Card clone : hostCard.getClones()){ + cards.add(AllZoneUtil.getCardState(clone)); + } + } + else if (defined.equals("Imprinted")){ for(Card imprint : hostCard.getImprinted()){ cards.add(AllZoneUtil.getCardState(imprint)); diff --git a/src/forge/card/abilityFactory/AbilityFactory_Copy.java b/src/forge/card/abilityFactory/AbilityFactory_Copy.java index 0955de45520..71cbb67f0d3 100644 --- a/src/forge/card/abilityFactory/AbilityFactory_Copy.java +++ b/src/forge/card/abilityFactory/AbilityFactory_Copy.java @@ -227,12 +227,12 @@ public class AbilityFactory_Copy { private static void copyPermanentResolve(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - Card card = af.getHostCard(); + Card hostCard = af.getHostCard(); ArrayList keywords = new ArrayList(); if(params.containsKey("Keywords")) { keywords.addAll(Arrays.asList(params.get("Keywords").split(" & "))); } - int numCopies = params.containsKey("NumCopies") ? AbilityFactory.calculateAmount(card, params.get("NumCopies"), sa) : 1; + int numCopies = params.containsKey("NumCopies") ? AbilityFactory.calculateAmount(hostCard, params.get("NumCopies"), sa) : 1; ArrayList tgtCards; @@ -240,13 +240,15 @@ public class AbilityFactory_Copy { if (tgt != null) tgtCards = tgt.getTargetCards(); else - tgtCards = AbilityFactory.getDefinedCards(sa.getSourceCard(), af.getMapParams().get("Defined"), sa); + tgtCards = AbilityFactory.getDefinedCards(sa.getSourceCard(), params.get("Defined"), sa); + + hostCard.clearClones(); for(Card c : tgtCards) { - if (tgt == null || CardFactoryUtil.canTarget(card, c)) { + if (tgt == null || CardFactoryUtil.canTarget(hostCard, c)) { //start copied Kiki code - int multiplier = AllZoneUtil.getDoublingSeasonMagnitude(card.getController()); + int multiplier = AllZoneUtil.getDoublingSeasonMagnitude(hostCard.getController()); multiplier *= numCopies; Card[] crds = new Card[multiplier]; @@ -310,12 +312,13 @@ public class AbilityFactory_Copy { copy.setCurSetCode(""); copy.setImageFilename("morph.jpg"); } - - AllZone.GameAction.moveToPlay(copy); + copy = AllZone.GameAction.moveToPlay(copy); + + copy.setCloneOrigin(hostCard); + sa.getSourceCard().addClone(copy); crds[i] = copy; } - //have to do this since getTargetCard() might change //if Kiki-Jiki somehow gets untapped again final Card[] target = new Card[multiplier];