diff --git a/.gitattributes b/.gitattributes index 9c0d47c0879..2cdf4f0031b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5411,6 +5411,7 @@ res/cardsfolder/verdant_force.txt -text svneol=native#text/plain res/cardsfolder/verdigris.txt -text svneol=native#text/plain res/cardsfolder/verduran_enchantress.txt -text svneol=native#text/plain res/cardsfolder/vermiculos.txt -text svneol=native#text/plain +res/cardsfolder/vesuvan_doppelganger.txt -text svneol=native#text/plain res/cardsfolder/veteran_armorer.txt -text svneol=native#text/plain res/cardsfolder/veteran_armorsmith.txt -text svneol=native#text/plain res/cardsfolder/veteran_cavalier.txt -text svneol=native#text/plain diff --git a/res/cardsfolder/vesuvan_doppelganger.txt b/res/cardsfolder/vesuvan_doppelganger.txt new file mode 100644 index 00000000000..be280c01345 --- /dev/null +++ b/res/cardsfolder/vesuvan_doppelganger.txt @@ -0,0 +1,9 @@ +Name:Vesuvan Doppelganger +ManaCost:3 U U +Types:Creature Shapeshifter +Text:You may have CARDNAME enter the battlefield as a copy of any creature on the battlefield except it doesn't copy that creature's color and it gains "At the beginning of your upkeep, you may have this creature become a copy of target creature except it doesn't copy that creature's color. If you do, this creature gains this ability." +PT:0/0 +SVar:RemAIDeck:True +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/vesuvan_doppelganger.jpg +End \ No newline at end of file diff --git a/src/forge/Card.java b/src/forge/Card.java index cb0c46dec44..c3785fe8374 100644 --- a/src/forge/Card.java +++ b/src/forge/Card.java @@ -139,7 +139,9 @@ public class Card extends MyObservable { private String namedCard = ""; private String topCardName = ""; private String reflectableMana = ""; - private String cloneOrigin = ""; + private Card cloneOrigin = null; + private Card currentlyCloningCard = null; + private Command cloneLeavesPlayCommand = null; private ArrayList gainControlTargets = new ArrayList(); private ArrayList gainControlReleaseCommands = new ArrayList();; @@ -311,14 +313,30 @@ public class Card extends MyObservable { return sirenAttackOrDestroy; } - public String getCloneOrigin() { + public Card getCloneOrigin() { return cloneOrigin; } - public void setCloneOrigin(String name) { + public void setCloneOrigin(Card name) { cloneOrigin = name; } + public Command getCloneLeavesPlayCommand() { + return cloneLeavesPlayCommand; + } + + public void setCloneLeavesPlayCommand(Command com) { + cloneLeavesPlayCommand = com; + } + + public Card getCurrentlyCloningCard() { + return currentlyCloningCard; + } + + public void setCurrentlyCloningCard(Card c) { + currentlyCloningCard = c; + } + public boolean getSacrificeAtEOT() { return sacrificeAtEOT || getKeyword().contains("At the beginning of the end step, sacrifice CARDNAME."); } @@ -1308,6 +1326,10 @@ public class Card extends MyObservable { if(t.trigger.equals(type) && t.isBasic()) AllZone.Stack.add(t); } + public void clearTriggers() { + zcTriggers.clear(); + } + public void addComesIntoPlayCommand(Command c) { addTrigger(c, ZCTrigger.ENTERFIELD); } diff --git a/src/forge/CardFactory_Creatures.java b/src/forge/CardFactory_Creatures.java index 256a6d749a2..f3d66f56a2d 100644 --- a/src/forge/CardFactory_Creatures.java +++ b/src/forge/CardFactory_Creatures.java @@ -13280,7 +13280,7 @@ public class CardFactory_Creatures { //*************** START *********** START ************************** - else if(cardName.equals("Clone")) { + else if(cardName.equals("Clone") || cardName.equals("Vesuvan Doppelganger")) { final CardFactory cfact = cf; final Card[] copyTarget = new Card[1]; final Card[] cloned = new Card[1]; @@ -13288,10 +13288,10 @@ public class CardFactory_Creatures { final SpellAbility copyBack = new Ability(card, "0") { @Override public void resolve() { - Card orig = cfact.getCard(cloned[0].getCloneOrigin(), card.getController()); - PlayerZone dest = AllZone.getZone(cloned[0]); + Card orig = cfact.getCard(card.getName(), card.getController()); + PlayerZone dest = AllZone.getZone(card.getCurrentlyCloningCard()); AllZone.GameAction.moveTo(dest, orig); - dest.remove(cloned[0]); + dest.remove(card.getCurrentlyCloningCard()); } };//SpellAbility @@ -13300,11 +13300,10 @@ public class CardFactory_Creatures { public void execute() { StringBuilder sb = new StringBuilder(); - sb.append(card.getName()).append(" - reverting "+cloned[0].getName()+" to "+card.getName()+"."); + sb.append(card.getName()).append(" - reverting self to "+card.getName()+"."); copyBack.setStackDescription(sb.toString()); AllZone.Stack.add(copyBack); - } }; @@ -13313,37 +13312,28 @@ public class CardFactory_Creatures { @Override public void resolve() { - - if (card.getController().equals(AllZone.ComputerPlayer)) { - - CardList AICreatures = AllZoneUtil.getCreaturesInPlay(AllZone.ComputerPlayer); - CardList PlayerCreatures = AllZoneUtil.getCreaturesInPlay(AllZone.HumanPlayer); - if (!AICreatures.isEmpty()) { - - copyTarget[0] = AICreatures.iterator().next(); - + if (card.getController().isComputer()) { + CardList creatures = AllZoneUtil.getCreaturesInPlay(); + if(!creatures.isEmpty()) { + copyTarget[0] = CardFactoryUtil.AI_getBestCreature(creatures); } - - else if (!PlayerCreatures.isEmpty()) { - - copyTarget[0] = PlayerCreatures.iterator().next(); - - } - } if (copyTarget[0] != null) { - - cloned[0] = cfact.getCard(copyTarget[0].getName(), card.getController()); - cloned[0].setCloneOrigin(card.getName()); - cloned[0].addLeavesPlayCommand(leaves); - cloned[0].setCurSetCode(copyTarget[0].getCurSetCode()); - cloned[0].setImageFilename(copyTarget[0].getImageFilename()); - PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, card.getController()); - play.add(cloned[0]); - + cloned[0] = cfact.getCard(copyTarget[0].getName(), card.getController()); + cloned[0].setCloneOrigin(card); + cloned[0].addLeavesPlayCommand(leaves); + cloned[0].setCloneLeavesPlayCommand(leaves); + cloned[0].setCurSetCode(copyTarget[0].getCurSetCode()); + cloned[0].setImageFilename(copyTarget[0].getImageFilename()); + if(cardName.equals("Vesuvan Doppelganger")) { + cloned[0].addExtrinsicKeyword("At the beginning of your upkeep, you may have this creature become a copy of target creature except it doesn't copy that creature's color. If you do, this creature gains this ability."); + cloned[0].addColor("U", cloned[0], false, true); + } + PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, card.getController()); + play.add(cloned[0]); + card.setCurrentlyCloningCard(cloned[0]); } - } };//SpellAbility @@ -13353,7 +13343,11 @@ public class CardFactory_Creatures { @Override public void showMessage() { AllZone.Display.showMessage(cardName+" - Select a creature on the battlefield"); + ButtonUtil.enableOnlyCancel(); } + + @Override + public void selectButtonCancel() { stop(); } @Override public void selectCard(Card c, PlayerZone z) { @@ -13379,7 +13373,7 @@ public class CardFactory_Creatures { final SpellAbility copyBack = new Ability(card, "0") { @Override public void resolve() { - Card orig = cfact.getCard(cloned[0].getCloneOrigin(), card.getController()); + Card orig = cfact.getCard(cloned[0].getCloneOrigin().getName(), card.getController()); PlayerZone dest = AllZone.getZone(cloned[0]); AllZone.GameAction.moveTo(dest, orig); dest.remove(cloned[0]); @@ -13424,15 +13418,15 @@ public class CardFactory_Creatures { } if (copyTarget[0] != null) { - - cloned[0] = cfact.getCard(copyTarget[0].getName(), card.getController()); - cloned[0].setCloneOrigin(card.getName()); - cloned[0].addLeavesPlayCommand(leaves); - cloned[0].setBaseDefense(7); - cloned[0].setBaseAttack(7); - PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, card.getController()); - play.add(cloned[0]); - + + cloned[0] = cfact.getCard(copyTarget[0].getName(), card.getController()); + cloned[0].setCloneOrigin(card); + cloned[0].addLeavesPlayCommand(leaves); + cloned[0].setBaseDefense(7); + cloned[0].setBaseAttack(7); + PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, card.getController()); + play.add(cloned[0]); + card.setCurrentlyCloningCard(cloned[0]); } } diff --git a/src/forge/GameActionUtil.java b/src/forge/GameActionUtil.java index 37f2886d409..bf80f6775da 100644 --- a/src/forge/GameActionUtil.java +++ b/src/forge/GameActionUtil.java @@ -77,6 +77,7 @@ public class GameActionUtil { upkeep_Anowon(); upkeep_Cunning_Lethemancer(); upkeep_Shapeshifter(); + upkeep_Vesuvan_Doppelganger_Keyword(); upkeep_Ink_Dissolver(); upkeep_Kithkin_Zephyrnaut(); @@ -10119,6 +10120,88 @@ public class GameActionUtil { }//foreach(Card) }//upkeep_Shapeshifter + private static void upkeep_Vesuvan_Doppelganger_Keyword() { + final Player player = AllZone.Phase.getPlayerTurn(); + final String keyword = "At the beginning of your upkeep, you may have this creature become a copy of target creature except it doesn't copy that creature's color. If you do, this creature gains this ability."; + CardList list = AllZoneUtil.getPlayerCardsInPlay(player); + list = list.filter(AllZoneUtil.getKeywordFilter(keyword)); + + for(final Card c:list) { + final SpellAbility ability = new Ability(c, "0") { + @Override + public void resolve() { + final Card[] newTarget = new Card[1]; + newTarget[0] = null; + + final Ability switchTargets = new Ability(c, "0") { + public void resolve() { + if(newTarget[0] != null) { + /* + * 1. need to select new card - DONE + * 1a. need to create the newly copied card with pic and setinfo + * 2. need to add the leaves play command + * 3. need to transfer the keyword + * 4. need to update the clone origin of new card and old card + * 5. remove clone leaves play commands from old + * 5a. remove old from play + * 6. add new to play + */ + + Card newCopy = AllZone.CardFactory.getCard(newTarget[0].getName(), player); + newCopy.setCurSetCode(newTarget[0].getCurSetCode()); + newCopy.setImageFilename(newTarget[0].getImageFilename()); + + //need to add the leaves play command (2) + newCopy.addLeavesPlayCommand(c.getCloneLeavesPlayCommand()); + c.removeTrigger(c.getCloneLeavesPlayCommand(), ZCTrigger.LEAVEFIELD); + newCopy.setCloneLeavesPlayCommand(c.getCloneLeavesPlayCommand()); + + newCopy.addExtrinsicKeyword(keyword); + newCopy.setCloneOrigin(c.getCloneOrigin()); + newCopy.getCloneOrigin().setCurrentlyCloningCard(newCopy); + c.setCloneOrigin(null); + + //5 + PlayerZone play = AllZone.getZone(c); + play.remove(c); + + play.add(newCopy); + } + } + }; + + AllZone.InputControl.setInput(new Input() { + private static final long serialVersionUID = 5662272658873063221L; + + @Override + public void showMessage() { + AllZone.Display.showMessage(c.getName()+" - Select new target creature. (Click Cancel to remain as is.)"); + ButtonUtil.enableOnlyCancel(); + } + + @Override + public void selectButtonCancel() { stop(); } + + @Override + public void selectCard(Card selectedCard, PlayerZone z) { + if(z.is(Constant.Zone.Battlefield) && selectedCard.isCreature() + && CardFactoryUtil.canTarget(c, selectedCard)) { + newTarget[0] = selectedCard; + StringBuilder sb = new StringBuilder(); + sb.append(c.getCloneOrigin()).append(" - switching to copy "+selectedCard.getName()+"."); + switchTargets.setStackDescription(sb.toString()); + AllZone.Stack.add(switchTargets); + stop(); + } + } + }); + } + }; + ability.setStackDescription(c.getName()+" - you may have this creature become a copy of target creature."); + AllZone.Stack.add(ability); + }//foreach(Card) + }//upkeep_Vesuvan_Doppelganger_Keyword + private static void upkeep_Tangle_Wire() { final Player player = AllZone.Phase.getPlayerTurn(); CardList wires = AllZoneUtil.getCardsInPlay("Tangle Wire"); diff --git a/src/forge/gui/game/CardDetailPanel.java b/src/forge/gui/game/CardDetailPanel.java index 2ed556616af..028ab220f8f 100644 --- a/src/forge/gui/game/CardDetailPanel.java +++ b/src/forge/gui/game/CardDetailPanel.java @@ -298,10 +298,10 @@ public class CardDetailPanel extends JPanel implements CardContainer { } //cloned via - if(card.getCloneOrigin() != "") { + if(card.getCloneOrigin() != null) { if(area.length() != 0) area.append("\n"); area.append("^Cloned via: "); - area.append(card.getCloneOrigin()); + area.append(card.getCloneOrigin().getName()); area.append("^"); }