From 310073fd48ed36dc97c77370e5f5de3df77b6218 Mon Sep 17 00:00:00 2001 From: jendave Date: Sat, 6 Aug 2011 03:19:08 +0000 Subject: [PATCH] - New cards: Wasteland, Strip Mine, Stifle, Rebuild, Spell Pierce and Mystical Tutor - Disabled blurred image and multipass resizing, should be faster to display images on slower computers - Fix images download progress bar not updating - Automatic date and revision in main.properties via SVN keywords $Date$ and $Revision$ --- .classpath | 8 + res/cards.txt | 35 ++++- res/main.properties | 2 +- src/forge/CardFactory.java | 181 +++++++++++++++++++++-- src/forge/CardFactory_Lands.java | 104 +++++++++++++ src/forge/ComputerAI_counterSpells2.java | 9 ++ src/forge/GuiDisplay3.java | 27 +--- src/forge/Gui_DownloadPictures.java | 20 ++- src/forge/Gui_DownloadPictures_LQ.java | 19 ++- 9 files changed, 362 insertions(+), 43 deletions(-) diff --git a/.classpath b/.classpath index 18d70f02cb8..c4a47895836 100644 --- a/.classpath +++ b/.classpath @@ -2,5 +2,13 @@ + + + + + + + + diff --git a/res/cards.txt b/res/cards.txt index 179e7319e7d..ba3819a899b 100644 --- a/res/cards.txt +++ b/res/cards.txt @@ -1461,7 +1461,7 @@ no text Timbermaw Larva 3 G Creature Beast -Whenever Timbermaw Larva attacks, it gets +1/+1 until end of turn for each Forest you control. +Whenever Timbermaw Larva attacks, it gets +1/+1 until end of turn for each you control. 2/2 Ghastlord of Fugue @@ -18007,4 +18007,37 @@ Warrior's Honor Instant Creatures you control get +1/+1 until end of turn. +Stifle +U +Instant +Counter target activated or triggered ability. + +Spell Pierce +U +Instant +Counter target noncreature spell unless its controller pays 2. + +Mystical Tutor +U +Instant +Search your library for an instant or sorcery card and reveal that card. Shuffle your library, then put the card on top of it. + +Rebuild +2 U +Instant +no text +Cycling:2 + +Wasteland +no cost +Land +no text +tap: add 1 + +Strip Mine +no cost +Land +no text +tap: add 1 + End \ No newline at end of file diff --git a/res/main.properties b/res/main.properties index 857b9db867f..2fdfc6cb19d 100644 --- a/res/main.properties +++ b/res/main.properties @@ -1,6 +1,6 @@ program/mail=mtgerror@yahoo.com program/forum=http://www.slightlymagic.net/forum/viewforum.php?f=26 -program/version=Forge -- official beta: 10/01/17, SVN revision: 323 +program/version=Forge -- official beta: $Date$, SVN revision: $Revision$ tokens--file=AllTokens.txt diff --git a/src/forge/CardFactory.java b/src/forge/CardFactory.java index 8ea211b3b33..1e5b0ed2a6d 100644 --- a/src/forge/CardFactory.java +++ b/src/forge/CardFactory.java @@ -8910,25 +8910,56 @@ public class CardFactory implements NewConstants { //is spell?, did opponent play it?, is this a creature spell? return sa.isSpell() && opponent.equals(sa.getSourceCard().getController()) && - sa.getSourceCard().getType().contains("Creature"); + sa.getSourceCard().getType().contains("Creature") && + CardFactoryUtil.isCounterable(sa.getSourceCard()); }//canPlay() }; card.clearSpellAbility(); card.addSpellAbility(spell); }//*************** END ************ END ************************** - - //*************** START *********** START ************************** - else if(cardName.equals("Counterspell") || cardName.equals("Cancel") || cardName.equals("Last Word") || cardName.equals("Traumatic Visions")) + //*************** START *********** START ************************** + else if(cardName.equals("Spell Pierce")) { SpellAbility spell = new Spell(card) { - private static final long serialVersionUID = -2489268054171391552L; + private static final long serialVersionUID = 4685055135070191326L; public void resolve() { - SpellAbility sa = AllZone.Stack.pop(); - AllZone.GameAction.moveToGraveyard(sa.getSourceCard()); + String manaCost = "2"; + Ability ability = new Ability(card, manaCost){ + public void resolve() + { + ; + } + }; + + final Command unpaidCommand = new Command() + { + private static final long serialVersionUID = 8094833091127334678L; + + public void execute() + { + SpellAbility sa = AllZone.Stack.pop(); + AllZone.GameAction.moveToGraveyard(sa.getSourceCard()); + } + }; + + if (card.getController().equals(Constant.Player.Computer)) + { + AllZone.InputControl.setInput(new Input_PayManaCost_Ability(card +"\r\n", ability.getManaCost(), Command.Blank, unpaidCommand)); + } + else + { + if (ComputerUtil.canPayCost(ability)) + ComputerUtil.playNoStack(ability); + else + { + SpellAbility sa = AllZone.Stack.pop(); + AllZone.GameAction.moveToGraveyard(sa.getSourceCard()); + } + } } public boolean canPlay() { @@ -8939,6 +8970,43 @@ public class CardFactory implements NewConstants { String opponent = AllZone.GameAction.getOpponent(card.getController()); SpellAbility sa = AllZone.Stack.peek(); + //is spell?, did opponent play it?, is this a creature spell? + return sa.isSpell() && + opponent.equals(sa.getSourceCard().getController()) && + !sa.getSourceCard().getType().contains("Creature") && + CardFactoryUtil.isCounterable(sa.getSourceCard()); + }//canPlay() + }; + card.clearSpellAbility(); + card.addSpellAbility(spell); + }//*************** END ************ END ************************** + + //*************** START *********** START ************************** + else if(cardName.equals("Counterspell") || cardName.equals("Cancel") || cardName.equals("Last Word") || cardName.equals("Traumatic Visions") || cardName.equals("Stifle")) + { + SpellAbility spell = new Spell(card) + { + private static final long serialVersionUID = -2489268054171391552L; + + public void resolve() + { + SpellAbility sa = AllZone.Stack.pop(); + if(!cardName.equals("Stifle")) + AllZone.GameAction.moveToGraveyard(sa.getSourceCard()); + } + public boolean canPlay() + { + if(AllZone.Stack.size() == 0) + return false; + + //see if spell is on stack and that opponent played it + String opponent = AllZone.GameAction.getOpponent(card.getController()); + SpellAbility sa = AllZone.Stack.peek(); + + if(cardName.equals("Stifle")) + return !sa.isSpell() && CardFactoryUtil.isCounterable(sa.getSourceCard()); + + return sa.isSpell() && opponent.equals(sa.getSourceCard().getController()) && CardFactoryUtil.isCounterable(sa.getSourceCard()); } @@ -8949,8 +9017,14 @@ public class CardFactory implements NewConstants { { desc = "Last Word can't be countered by spells or abilities.\r\n"; } - spell.setDescription(desc + "Counter target spell."); - spell.setStackDescription(card.getName() + " - Counters target spell."); + if(cardName.equals("Stifle")){ + spell.setDescription(desc + "Counter target triggered or activated ability."); + spell.setStackDescription(card.getName() + " - Counters target triggered or activated ability."); + } else + { + spell.setDescription(desc + "Counter target spell."); + spell.setStackDescription(card.getName() + " - Counters target spell."); + } card.addSpellAbility(spell); }//*************** END ************ END ************************** @@ -9545,7 +9619,7 @@ public class CardFactory implements NewConstants { //*************** START *********** START ************************** - else if(cardName.equals("Evacuation")) + else if(cardName.equals("Evacuation") || cardName.equals("Rebuild")) { SpellAbility spell = new Spell(card) { @@ -9556,7 +9630,10 @@ public class CardFactory implements NewConstants { CardList all = new CardList(); all.addAll(AllZone.Human_Play.getCards()); all.addAll(AllZone.Computer_Play.getCards()); - all = all.getType("Creature"); + if(cardName.equals("Rebuild")) + all = all.getType("Artifact"); + else + all = all.getType("Creature"); for(int i = 0; i < all.size(); i++) { @@ -9577,6 +9654,11 @@ public class CardFactory implements NewConstants { return AllZone.getZone(Constant.Zone.Hand, c.getOwner()); } }; + if(cardName.equals("Rebuild")) + { + spell.setDescription("Return all artifacts to their owners' hands."); + spell.setStackDescription(card.getName() + " - return all artifacts to their owners' hands."); + } card.clearSpellAbility(); card.addSpellAbility(spell); }//*************** END ************ END ************************** @@ -9915,6 +9997,83 @@ public class CardFactory implements NewConstants { card.addSpellAbility(spell); }//*************** END ************ END ************************** + //*************** START *********** START ************************** + else if(cardName.equals("Mystical Tutor")) + { + SpellAbility spell = new Spell(card) + { + private static final long serialVersionUID = 2281623056004772379L; + public boolean canPlayAI() + { + return 4 < AllZone.Phase.getTurn(); + } + + public void resolve() + { + String player = card.getController(); + if(player.equals(Constant.Player.Human)) + humanResolve(); + else + computerResolve(); + } + public void computerResolve() + { + CardList list = new CardList(AllZone.Computer_Library.getCards()); + CardList instantsAndSorceries = new CardList(); + + for (int i=0;i 0 && AllZone.GameAction.isCardInPlay(card)) + return true; + else + return false; + + }//canPlay() + public void resolve() + { + if(card.getOwner().equals(Constant.Player.Human)) + humanResolve(); + //else + // computerResolve(); + } + + public void humanResolve() + { + Card target = getTargetCard(); + if(target != null) + AllZone.GameAction.destroy(target); + }//resolve() + };//SpellAbility + + Input runtime = new Input() + { + + private static final long serialVersionUID = -7328086812286814833L; + boolean once = true; + public void showMessage() + { + //this is necessary in order not to have a StackOverflowException + //because this updates a card, it creates a circular loop of observers + if(once) + { + once = false; + String player = card.getController(); + + PlayerZone compBattlezone = AllZone.getZone(Constant.Zone.Play, Constant.Player.Computer); + PlayerZone playerBattlezone = AllZone.getZone(Constant.Zone.Play, Constant.Player.Human); + CardList list = new CardList(compBattlezone.getCards()); + list.addAll(playerBattlezone.getCards()); + + list = list.filter(new CardListFilter() + { + public boolean addCard(Card c) + { + if(card.getName().equals("Wasteland")) + return c.getType().contains("Land") && !c.getType().contains("Basic"); + else + return c.getType().contains("Land"); + } + }); + + Object o = AllZone.Display.getChoice("Choose a " + (card.getName().equals("Wasteland") ? "nonbasic" : "") + "land to destroy", list.toArray()); + ability.setTargetCard((Card)o); + + AllZone.GameAction.sacrifice(card); + + //ability.setStackDescription(card.getController() +" - Destroy target " + (card.getName().equals("Wasteland") ? "nonbasic" : "") + "land."); + + AllZone.Stack.add(ability); + + stop(); + } + }//showMessage() + }; + card.addSpellAbility(ability); + ability.setDescription("Tap, Sacrifice " + card.getName() +": Destroy target " + (card.getName().equals("Wasteland") ? "nonbasic" : "") + "land."); + ability.setBeforePayMana(runtime); + }//*************** END ************ END ************************** //*************** START *********** START ************************** else if(cardName.equals("Arid Mesa") || cardName.equals("Marsh Flats") || cardName.equals("Misty Rainforest") || diff --git a/src/forge/ComputerAI_counterSpells2.java b/src/forge/ComputerAI_counterSpells2.java index f9ece8591bb..0a82b58a129 100644 --- a/src/forge/ComputerAI_counterSpells2.java +++ b/src/forge/ComputerAI_counterSpells2.java @@ -37,6 +37,10 @@ public class ComputerAI_counterSpells2 { "" }; + final String[] nonCreatureUnlessPay2 = { + "Spell Pierce" + }; + final String[] unlessPay1 = { "Force Spike", "Daze", "Runeboggle", "Spell Snip" }; @@ -86,6 +90,11 @@ public class ComputerAI_counterSpells2 { return true; } + else if (!sa.getSourceCard().isCreature() && usableManaSources < 2) { + if (checkArray(c, nonCreatureUnlessPay2)) + return true; + } + if (checkArray(c, basic)) return true; diff --git a/src/forge/GuiDisplay3.java b/src/forge/GuiDisplay3.java index 5047d9a212e..2c00830e6cf 100644 --- a/src/forge/GuiDisplay3.java +++ b/src/forge/GuiDisplay3.java @@ -70,6 +70,7 @@ import com.google.common.collect.MapMaker; //import org.omg.CORBA.portable.InputStream; import arcane.ui.ScaledImagePanel; +import arcane.ui.ScaledImagePanel.MultipassType; import arcane.ui.ScaledImagePanel.ScalingType; import forge.error.ErrorViewer; @@ -662,9 +663,8 @@ public class GuiDisplay3 extends JFrame implements Display, NewConstants, NewCon else { InputStream stream; try { - //stream = new URL(GuiDisplayUtil.getURL(c)).openStream(); stream = GuiDisplayUtil.getURL(c).openStream(); - srcImage = ImageIO.read(stream); + srcImage = arcane.ui.util.ImageUtil.getImage(stream); imageCache.put(imageName, srcImage); } catch (MalformedURLException e) { // TODO Auto-generated catch block @@ -675,25 +675,9 @@ public class GuiDisplay3 extends JFrame implements Display, NewConstants, NewCon } } - //BufferedImage srcImageBlurred = arcane.ui.util.ImageUtil.getBlurredImage(srcImage, 3, 1.0f); // get a blurred image - cardImagePanel.setImage(srcImage, srcImage); - cardImagePanel.repaint(); - /* - BufferedInputStream stream = (BufferedInputStream) GuiDisplayUtil.getPictureStream(c); - BufferedImage srcImage; - try { - srcImage = arcane.ui.util.ImageUtil.getImage(stream); - BufferedImage srcImageBlurred = arcane.ui.util.ImageUtil.getBlurredImage(srcImage, 3, 1.0f); // get a blurred image - - cardImagePanel.setImage(srcImage, srcImageBlurred); - cardImagePanel.repaint(); - - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } // only need stream - */ + cardImagePanel.setImage(srcImage, null); + cardImagePanel.repaint(); //System.out.println(picturePanel.getComponentCount()); }//updateCardDetail() @@ -1274,9 +1258,10 @@ public class GuiDisplay3 extends JFrame implements Display, NewConstants, NewCon pane.add(new ExternalPanel(picturePanel), "picture"); */ - cardImagePanel.setScalingBlur(true); //use blured image if scaling down more than 50% + cardImagePanel.setScalingBlur(false); //use blured image if scaling down more than 50% cardImagePanel.setScaleLarger(true); //upscale if needed true cardImagePanel.setScalingType(ScalingType.bicubic); // type of scaling bicubic has good quality / speed ratio + cardImagePanel.setScalingMultiPassType(MultipassType.none); cardImagePanel.setLayout(new BoxLayout(cardImagePanel, BoxLayout.Y_AXIS)); cardImagePanel.setBackground(c1); diff --git a/src/forge/Gui_DownloadPictures.java b/src/forge/Gui_DownloadPictures.java index 5f80b13362e..3615181e7ff 100644 --- a/src/forge/Gui_DownloadPictures.java +++ b/src/forge/Gui_DownloadPictures.java @@ -5,6 +5,7 @@ import static javax.swing.JOptionPane.*; import java.awt.Component; import java.awt.Dimension; +import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedInputStream; @@ -181,11 +182,20 @@ public class Gui_DownloadPictures extends DefaultBoundedRangeModel implements Ru private void update(int card) { this.card = card; - fireStateChanged(); - bar.setString(String.format(ForgeProps.getLocalized(card == cards.length? BAR_CLOSE:BAR_WAIT), this.card, - cards.length)); - System.out.println(card + "/" + cards.length); - + final class Worker implements Runnable{ + private int card; + Worker(int card){ + this.card = card; + } + + public void run() { + fireStateChanged(); + bar.setString(String.format(ForgeProps.getLocalized(card == cards.length? BAR_CLOSE:BAR_WAIT), card, + cards.length)); + System.out.println(card + "/" + cards.length); + } + }; + EventQueue.invokeLater(new Worker(card)); } public JDialog getDlg(JFrame frame) { diff --git a/src/forge/Gui_DownloadPictures_LQ.java b/src/forge/Gui_DownloadPictures_LQ.java index c1f5cb5db47..7bcaa9e718e 100644 --- a/src/forge/Gui_DownloadPictures_LQ.java +++ b/src/forge/Gui_DownloadPictures_LQ.java @@ -4,6 +4,7 @@ import static java.lang.Integer.*; import static javax.swing.JOptionPane.*; import java.awt.Dimension; +import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedInputStream; @@ -146,10 +147,20 @@ public class Gui_DownloadPictures_LQ extends DefaultBoundedRangeModel implements private void update(int card) { this.card = card; - fireStateChanged(); - bar.setString(String.format(ForgeProps.getLocalized(card == cards.length? BAR_CLOSE:BAR_WAIT), this.card, - cards.length)); - System.out.println(card + "/" + cards.length); + final class Worker implements Runnable{ + private int card; + Worker(int card){ + this.card = card; + } + + public void run() { + fireStateChanged(); + bar.setString(String.format(ForgeProps.getLocalized(card == cards.length? BAR_CLOSE:BAR_WAIT), card, + cards.length)); + System.out.println(card + "/" + cards.length); + } + }; + EventQueue.invokeLater(new Worker(card)); } public JDialog getDlg(JFrame frame) {