From b66c63bdcec667193266c7742b14ccea93f90eef Mon Sep 17 00:00:00 2001 From: jendave Date: Sat, 6 Aug 2011 03:05:59 +0000 Subject: [PATCH] - Untap should happen before the AIs upkeep phase now (I hope changing that didn't break anything). - Added Echo, Upkeep and Cumulative Upkeep functionality. - Thelonite Hermit should also give +1/+1 to creatures with Changeling. - Added Donate, Illusions of Grandeur, Drifting Djinn, Drifter il-Dal, Karmic Guide, Avalanche Riders, Basalt Gargoyle, Keldon Vandals, Vaevictis Asmadi, Palladia-Mors, Nicol Bolas, Goblin Patrol, Goblin Marshal, Mogg War Marshal, Urza's Blueprints, Deranged Hermit, Winding Wurm, Vug Lizard, Viashino Outrider, Uktabi Drake, Thran War Machine, Tectonic Fiend, Simian Grunts, Shivan Raptor, Radiant's Dragoons, Pouncing Jaguar, Multani's Acolyte, Lightning Dragon, Herald of Serra, Henchfiend of Ukor, Goblin War Buggy, Cradle Guard, Citanul Centaurs, Albino Troll, Acridian. --- res/cards.txt | 273 +++++++++++++++++ res/main.properties | 2 +- src/forge/Card.java | 15 +- src/forge/CardFactory.java | 149 ++++++++++ src/forge/CardFactoryUtil.java | 46 +++ src/forge/CardFactory_Creatures.java | 363 ++++++++++++++++++++++- src/forge/GameAction.java | 7 + src/forge/GameActionUtil.java | 295 ++++++++++++++++-- src/forge/InputControl.java | 3 +- src/forge/Input_PayManaCost_Ability.java | 37 ++- src/forge/Input_Untap.java | 4 +- src/forge/SpellAbility.java | 11 + src/forge/StateBasedEffects.java | 1 + 13 files changed, 1161 insertions(+), 45 deletions(-) diff --git a/res/cards.txt b/res/cards.txt index 27dedc64c48..9529f48b923 100644 --- a/res/cards.txt +++ b/res/cards.txt @@ -1,3 +1,276 @@ +Donate +2 U +Sorcery +Target player gains control of target permanent you control. + +Illusions of Grandeur +3 U +Enchantment +When Illusions of Grandeur enters the battlefield, you gain 20 life. When Illusions of Grandeur leaves the battlefield, you lose 20 life. +Cumulative upkeep:2 + +Drifting Djinn +4 U U +Creature Djinn +At the beginning of your upkeep, sacrifice Drifting Djinn unless you pay:1 U +5/5 +Flying +Cycling:2 + +Drifter il-Dal +U +Creature Human Wizard +At the beginning of your upkeep, sacrifice Drifter il-Dal unless you pay:U +2/1 +Shadow + +Karmic Guide +3 W W +Creature Angel Spirit +When Karmic Guide enters the battlefield, return target creature card from your graveyard to the battlefield. +2/2 +Flying +Protection from black +Echo:3 W W + +Avalanche Riders +3 R +Creature Human Nomad +When Avalanche Riders enters the battlefield, destroy target land. +2/2 +Haste +Echo:3 R + +Basalt Gargoyle +2 R +Creature Gargoyle +no text +3/2 +Flying +Echo:2 R +abPump R:+0/+1 + +Keldon Vandals +2 R +Creature Human Rogue +When Keldon Vandals enters the battlefield, destroy target artifact. +4/1 +Echo:2 R + +Vaevictis Asmadi +2 B B R R G G +Legendary Creature Elder Dragon +no text +7/7 +Flying +At the beginning of your upkeep, sacrifice Vaevictis Asmadi unless you pay:B R G +abPump B:+1/+0 +abPump R:+1/+0 +abPump G:+1/+0 + +Palladia-Mors +2 W W R R G G +Legendary Creature Elder Dragon +no text +7/7 +Flying +At the beginning of your upkeep, sacrifice Palladia-Mors unless you pay:R G W + +Nicol Bolas +2 U U B B R R +Legendary Creature Elder Dragon +Whenever Nicol Bolas deals damage to an opponent, that player discards his or her hand. +7/7 +Flying +At the beginning of your upkeep, sacrifice Nicol Bolas unless you pay:U B R + +Goblin Patrol +R +Creature Goblin +no text +2/1 +Echo:R + +Goblin Marshal +4 R R +Creature Goblin Warrior +When Goblin Marshal enters the battlefield or is put into a graveyard from the battlefield, put two 1/1 red Goblin creature tokens onto the battlefield. +3/3 +Echo:4 R R + +Mogg War Marshal +1 R +Creature Goblin Warrior +When Mogg War Marshal enters the battlefield or is put into a graveyard from the battlefield, put a 1/1 red Goblin creature token onto the battlefield. +1/1 +Echo:1 R + +Urza's Blueprints +6 +Artifact +no text +Echo:6 + +Deranged Hermit +3 G G +Creature Elf +When Deranged Hermit enters the battlefield, put four 1/1 green Squirrel creature tokens onto the battlefield. Squirrel creatures get +1/+1. +1/1 +Echo:3 G G + +Winding Wurm +4 G +Creature Wurm +no text +6/6 +Echo:4 G + +Vug Lizard +1 R R +Creature Lizard +no text +3/4 +Mountainwalk +Echo:1 R R + +Viashino Outrider +2 R +Creature Viashino +no text +4/3 +Echo:2 R + +Uktabi Drake +G +Creature Drake +no text +2/1 +Flying +Haste +Echo:1 G G + +Thran War Machine +4 +Artifact Creature Construct +no text +4/5 +This card attacks each turn if able. +Echo:4 + +Tectonic Fiend +4 R R +Creature Elemental +no text +7/7 +This card attacks each turn if able. +Echo:4 R R + +Simian Grunts +2 G +Creature Ape +no text +3/4 +Flash +Echo:2 G + +Shivan Raptor +2 R +Creature Lizard +no text +3/1 +First Strike +Haste +Echo:2 R + +Radiant's Dragoons +3 W +Creature Human Soldier +no text +2/5 +Echo:3 W + +Pouncing Jaguar +G +Creature Cat +no text +2/2 +Echo:G + +Multani's Acolyte +G G +Creature Elf +no text +2/1 +When this card comes into play, draw a card. +Echo:G G + +Lightning Dragon +2 R R +Creature Dragon +no text +4/4 +Flying +Haste +Echo:2 R R +abPump R:+1/+0 + +Herald of Serra +2 W W +Creature Angel +no text +3/4 +Flying +Vigilance +Echo:2 W W + +Henchfiend of Ukor +3 R +Creature Ogre +no text +3/2 +Haste +Echo:1 B +abPump BR:+1/+0 + +Goblin War Buggy +1 R +Creature Goblin +no text +2/2 +Haste +Echo:1 R + +Cradle Guard +1 G G +Creature Treefolk +no text +4/4 +Trample +Echo:1 G G + +Citanul Centaurs +3 G +Creature Centaur +no text +6/3 +Echo:3 G +Shroud + +Albino Troll +1 G +Creature Ape +no text +3/3 +Echo:1 G +RegenerateMe:1 G + +Acridian +1 G +Creature Insect +no text +2/4 +Echo:1 G + Feral Animist 1 R G Creature Goblic Shaman diff --git a/res/main.properties b/res/main.properties index aebf2332863..615c8015111 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: 09/12/14, SVN revision: 221 +program/version=Forge -- official beta: 09/12/14, SVN revision: 225 tokens--file=AllTokens.txt diff --git a/src/forge/Card.java b/src/forge/Card.java index 92d2b355bf1..5396f7080cf 100644 --- a/src/forge/Card.java +++ b/src/forge/Card.java @@ -43,7 +43,6 @@ public class Card extends MyObservable private boolean dealtDmgToOppThisTurn = false; private boolean exaltedBonus = false; private boolean faceDown = false; - private boolean echoPaid = false; private boolean sacrificeAtEOT = false; private boolean firstStrike = false; @@ -81,6 +80,8 @@ public class Card extends MyObservable private String rarity = ""; private String text = ""; private String manaCost = ""; + private String upkeepCost = ""; + private String echoCost = ""; private String chosenType = ""; private String chosenColor = ""; private String namedCard = ""; @@ -243,12 +244,16 @@ public class Card extends MyObservable public int getTurnInZone() {return turnInZone;} public void setTurnInZone(int turn) {turnInZone = turn;} - public boolean getEchoPaid() {return echoPaid;} - public void setEchoPaid(boolean b) {echoPaid = b;} - + public void setEchoCost(String s) {echoCost = s;} + public String getEchoCost() {return echoCost;} + public void setManaCost(String s) {manaCost = s;} public String getManaCost() {return manaCost;} - + + public void setUpkeepCost(String s) {upkeepCost = s;} + public String getUpkeepCost() {return upkeepCost;} + public boolean hasUpkeepCost(){return upkeepCost.length() > 0 && !upkeepCost.equals("0");} + //used for cards like Belbe's Portal, Conspiracy, Cover of Darkness, etc. public String getChosenType() { return chosenType;} public void setChosenType(String s) {chosenType = s;} diff --git a/src/forge/CardFactory.java b/src/forge/CardFactory.java index cee587e154d..b074b73b2a4 100644 --- a/src/forge/CardFactory.java +++ b/src/forge/CardFactory.java @@ -18463,6 +18463,155 @@ return land.size() > 1 && CardFactoryUtil.AI_isMainPhase(); card.addSpellAbility(ability); }//*************** END ************ END ************************** + + + //*************** START *********** START ************************** + else if(cardName.equals("Urza's Blueprints")) + { + final SpellAbility ability = new Ability_Tap(card, "0") + { + private static final long serialVersionUID = -1802481790805608497L; + + public boolean canPlayAI() {return AllZone.Phase.getPhase().equals(Constant.Phase.Main1);} + + public void resolve() + { + AllZone.GameAction.drawCard(card.getController()); + } + };//SpellAbility + card.addSpellAbility(ability); + ability.setDescription("tap: Draw a card."); + ability.setStackDescription(card.getName() + " - draw a card."); + }//*************** END ************ END ************************** + + //*************** START *********** START ************************** + else if(cardName.equals("Illusions of Grandeur")) + { + final SpellAbility gainLife = new Ability(card, "0") + { + public void resolve() + { + Card c = card; + PlayerLife life = AllZone.GameAction.getPlayerLife(c.getController()); + life.addLife(20); + } + }; + + final SpellAbility loseLife = new Ability(card, "0") + { + public void resolve() + { + Card c = card; + PlayerLife life = AllZone.GameAction.getPlayerLife(c.getController()); + life.subtractLife(20); + } + }; + + Command intoPlay = new Command() + { + private static final long serialVersionUID = 502892931516451254L; + + public void execute() + { + gainLife.setStackDescription(card.getController() +" gains 20 life"); + AllZone.Stack.add(gainLife); + } + }; + + Command leavesPlay = new Command() + { + private static final long serialVersionUID = 5772999389072757369L; + + public void execute() + { + loseLife.setStackDescription(card.getController() +" loses 20 life"); + AllZone.Stack.add(loseLife); + } + }; + + card.addComesIntoPlayCommand(intoPlay); + card.addLeavesPlayCommand(leavesPlay); + + }//*************** END ************ END ************************** + + //*************** START *********** START ************************** + else if(cardName.equals("Donate")) + { + final SpellAbility spell = new Spell(card) + { + private static final long serialVersionUID = 782912579034503349L; + + public void resolve() + { + Card c = getTargetCard(); + + if (c!=null && AllZone.GameAction.isCardInPlay(c) && CardFactoryUtil.canTarget(card, c)) + { + if (!c.isAura()) + { + ((PlayerZone_ComesIntoPlay)AllZone.Human_Play).setTriggers(false); + ((PlayerZone_ComesIntoPlay)AllZone.Computer_Play).setTriggers(false); + + PlayerZone from = AllZone.getZone(c); + from.remove(c); + + c.setController(AllZone.GameAction.getOpponent(card.getController())); + + PlayerZone to = AllZone.getZone(Constant.Zone.Play, AllZone.GameAction.getOpponent(card.getController())); + to.add(c); + + ((PlayerZone_ComesIntoPlay)AllZone.Human_Play).setTriggers(true); + ((PlayerZone_ComesIntoPlay)AllZone.Computer_Play).setTriggers(true); + } + else //Aura + { + c.setController(AllZone.GameAction.getOpponent(card.getController())); + } + } + } + + public boolean canPlayAI() + { + CardList list = new CardList(AllZone.Computer_Play.getCards()); + list = list.getName("Illusions of Grandeur"); + + if (list.size() > 0){ + setTargetCard(list.get(0)); + return true; + } + return false; + } + }; + + Input runtime = new Input() + { + private static final long serialVersionUID = -7823269301012427007L; + + public void showMessage() + { + PlayerZone play = AllZone.getZone(Constant.Zone.Play, Constant.Player.Human); + + CardList perms = new CardList(); + perms.addAll(play.getCards()); + perms = perms.filter(new CardListFilter() + { + public boolean addCard(Card c) + { + return c.isPermanent() && !c.getName().equals("Mana Pool"); + } + }); + + stopSetNext(CardFactoryUtil.input_targetSpecific(spell, perms, "Select a permanent you control", true)); + + }//showMessage() + };//Input + + spell.setBeforePayMana(runtime); + + card.clearSpellAbility(); + card.addSpellAbility(spell); + }//*************** END ************ END ************************** + // Cards with Cycling abilities // -1 means keyword "Cycling" not found diff --git a/src/forge/CardFactoryUtil.java b/src/forge/CardFactoryUtil.java index 76b06bcc641..d4a8ad7c4fd 100644 --- a/src/forge/CardFactoryUtil.java +++ b/src/forge/CardFactoryUtil.java @@ -2117,6 +2117,42 @@ public class CardFactoryUtil } return count; } + + public static String multiplyManaCost(String manacost, int multiplier) + { + if (multiplier == 0) + return ""; + if (multiplier == 1) + return manacost; + + String result = ""; + String tokenized[] = manacost.split("\\s"); + + if (Character.isDigit(tokenized[0].charAt(0))) //manacost starts with "colorless" number cost + { + int cost = Integer.parseInt(tokenized[0]); + cost = multiplier * cost; + tokenized[0] = "" + cost; + result = result + " " + tokenized[0]; + } + else { + for (int i=0; i 2; + } + }); + + if (creats.size() > 0) + return true; + else + return false; + } + }); + }//*************** END ************ END ************************** + + //*************** START *********** START ************************** else if(cardName.equals("Gravedigger")) @@ -14065,7 +14174,8 @@ public class CardFactory_Creatures { //*************** START *********** START ************************** - else if(cardName.equals("Viridian Shaman") || cardName.equals("Uktabi Orangutan") || cardName.equals("Vithian Renegades")) + else if(cardName.equals("Viridian Shaman") || cardName.equals("Uktabi Orangutan") || cardName.equals("Vithian Renegades") || + cardName.equals("Keldon Vandals")) { final SpellAbility ability = new Ability(card, "0") { @@ -14149,6 +14259,83 @@ public class CardFactory_Creatures { }); }//*************** END ************ END ************************** + + //*************** START *********** START ************************** + else if(cardName.equals("Avalanche Riders")) + { + final SpellAbility ability = new Ability(card, "0") + { + public void resolve() + { + Card c = getTargetCard(); + + if(AllZone.GameAction.isCardInPlay(c) && CardFactoryUtil.canTarget(card, getTargetCard()) ) + AllZone.GameAction.destroy(c); + } + }; + Command intoPlay = new Command() + { + private static final long serialVersionUID = -8270520707155953207L; + + public void execute() + { + CardList all = new CardList(); + all.addAll(AllZone.Human_Play.getCards()); + all.addAll(AllZone.Computer_Play.getCards()); + all = all.filter(new CardListFilter(){ + public boolean addCard(Card c) + { + return c.isLand() && CardFactoryUtil.canTarget(card, c); + } + }); + + CardList humanList = new CardList(AllZone.Human_Play.getCards()); + humanList = humanList.getType("Land"); + + if (all.size() != 0) { + + if(card.getController().equals(Constant.Player.Human)) { + AllZone.InputControl.setInput(CardFactoryUtil.input_targetSpecific(ability, all, "Select target artifact.", true)); + ButtonUtil.disableAll(); + } + else if (card.getController().equals(Constant.Player.Computer)) { + if (humanList.size() > 0 ){ + ability.setTargetCard(humanList.get(0)); + AllZone.Stack.add(ability); + } + else + { + Card comp = CardFactoryUtil.AI_getCheapestPermanent(all, card, true); + ability.setTargetCard(comp); + AllZone.Stack.add(ability); + } + } + } + + }//execute() + };//Command + card.addComesIntoPlayCommand(intoPlay); + + card.clearSpellAbility(); + + card.addSpellAbility(new Spell_Permanent(card) + { + private static final long serialVersionUID = -517667816379595978L; + + public boolean canPlayAI() + { + CardList lands = new CardList(); + lands.addAll(AllZone.Human_Play.getCards()); + lands = lands.getType("Land"); + + if (lands.size() > 0) + return true; + else + return false; + } + }); + }//*************** END ************ END ************************** + //*************** START *********** START ************************** else if(cardName.equals("Aven Cloudchaser") || cardName.equals("Cloudchaser Eagle") || cardName.equals("Monk Realist")) { @@ -14580,6 +14767,106 @@ public class CardFactory_Creatures { }; card.addComesIntoPlayCommand(intoPlay); + }//*************** END ************ END ************************** + + //*************** START *********** START ************************** + else if(cardName.equals("Deranged Hermit")) + { + final SpellAbility ability = new Ability(card, "0") + { + public void resolve() + { + for (int i=0;i<4;i++) + makeToken(); + }//resolve() + + void makeToken() + { + Card c = new Card(); + + c.setOwner(card.getController()); + c.setController(card.getController()); + + c.setName("Squirrel"); + c.setImageName("G 1 1 Squirrel"); + c.setManaCost("G"); + c.setToken(true); + + c.addType("Creature"); + c.addType("Squirrel"); + + c.setBaseAttack(1); + c.setBaseDefense(1); + + PlayerZone play = AllZone.getZone(Constant.Zone.Play, card.getController()); + play.add(c); + } + }; + Command intoPlay = new Command() + { + private static final long serialVersionUID = 7299232424224916928L; + + public void execute() + { + ability.setStackDescription("Deranged Hermit - put four green 1/1 Squirrel creature tokens onto the battlefield."); + AllZone.Stack.add(ability); + } + }; + card.addComesIntoPlayCommand(intoPlay); + + }//*************** END ************ END ************************** + + //*************** START *********** START ************************** + else if(cardName.equals("Mogg War Marshal") || cardName.equals("Goblin Marshal")) + { + final SpellAbility ability = new Ability(card, "0") + { + public void resolve() + { + makeToken(); + if (card.getName().equals("Goblin Marshal")) + makeToken(); + }//resolve() + + void makeToken() + { + Card c = new Card(); + + c.setOwner(card.getController()); + c.setController(card.getController()); + + c.setName("Goblin"); + c.setImageName("R 1 1 Goblin"); + c.setManaCost("R"); + c.setToken(true); + + c.addType("Creature"); + c.addType("Goblin"); + + c.setBaseAttack(1); + c.setBaseDefense(1); + + PlayerZone play = AllZone.getZone(Constant.Zone.Play, card.getController()); + play.add(c); + } + }; + Command intoPlayDestroy = new Command() + { + private static final long serialVersionUID = 5554242458006247407L; + + public void execute() + { + if (card.getName().equals("Mogg War Marshal")) + ability.setStackDescription("Mogg War Marshal - put a red 1/1 Goblin creature token onto the battlefield."); + else if (card.getName().equals("Goblin Marshal")) + ability.setStackDescription("Goblin Marshal - put two red 1/1 Goblin creature tokens onto the battlefield."); + + AllZone.Stack.add(ability); + } + }; + card.addComesIntoPlayCommand(intoPlayDestroy); + card.addDestroyCommand(intoPlayDestroy); + }//*************** END ************ END ************************** //*************** START *********** START ************************** @@ -18924,6 +19211,23 @@ public class CardFactory_Creatures { return newCard; }//*************** END ************ END ************************** + /* + else if (cardName.equals("Acridian")) + { + card.setEchoCost(card.getManaCost()); + + final Command intoPlay = new Command() + { + private static final long serialVersionUID = 8930023870127082001L; + + public void execute() { + card.addIntrinsicKeyword("(Echo unpaid)"); + } + }; + card.addComesIntoPlayCommand(intoPlay); + } + */ + // Cards with Cycling abilities // -1 means keyword "Cycling" not found @@ -19004,6 +19308,59 @@ public class CardFactory_Creatures { } }//Vanishing + if (hasKeyword(card, "Echo") != -1) + { + int n = hasKeyword(card, "Echo"); + if (n != -1) + { + String parse = card.getKeyword().get(n).toString(); + //card.removeIntrinsicKeyword(parse); + + String k[] = parse.split(":"); + final String manacost = k[1]; + + card.setEchoCost(manacost); + + final Command intoPlay = new Command() + { + private static final long serialVersionUID = 8930023870127082001L; + + public void execute() { + card.addIntrinsicKeyword("(Echo unpaid)"); + } + }; + card.addComesIntoPlayCommand(intoPlay); + + } + }//echo + + /* + if (hasKeyword(card, "Upkeep") != -1) + { + int n = hasKeyword(card, "Upkeep"); + if (n != -1) + { + String parse = card.getKeyword().get(n).toString(); + card.removeIntrinsicKeyword(parse); + + String k[] = parse.split(":"); + final String manacost = k[1]; + card.addIntrinsicKeyword("At the beginning of your upkeep, sacrifice " + card.getName() + " unless you pay " + manacost+"."); + + final Command intoPlay = new Command() + { + private static final long serialVersionUID = 925179072354331141L; + + public void execute() { + card.setUpkeepCost(manacost); + } + }; + card.addComesIntoPlayCommand(intoPlay); + + } + }//upkeep + */ + return card; } } \ No newline at end of file diff --git a/src/forge/GameAction.java b/src/forge/GameAction.java index 1f766a87dfb..fa2ba7edfea 100644 --- a/src/forge/GameAction.java +++ b/src/forge/GameAction.java @@ -130,6 +130,13 @@ private Card getCurrentCard(int ID) else AI_discardNumUnless(numDiscard, uType); } + + public void discardHand(String player) + { + PlayerZone hand = AllZone.getZone(Constant.Zone.Hand, player); + for (int i=0;i a = c.getKeyword(); + for (int i = 0; i < a.size(); i++) + { + if (a.get(i).toString().startsWith("At the beginning of your upkeep, sacrifice ")) + { + String k[] = a.get(i).toString().split(":"); + c.setUpkeepCost(k[1]); + return true; + } + } + return false; + } + }); + + for (int i=0; i a = c.getKeyword(); + for (int i = 0; i < a.size(); i++) + { + if (a.get(i).toString().startsWith("Cumulative upkeep")) + { + String k[] = a.get(i).toString().split(":"); + c.addCounter(Counters.AGE, 1); + c.setUpkeepCost(CardFactoryUtil.multiplyManaCost(k[1], c.getCounters(Counters.AGE))); + //c.setUpkeepCost(k[1]); + return true; + } + } + return false; + } + }); + + for (int i=0; i 0) + { + Ability ability = new Ability(c, "0") + { + public void resolve() + { + opp[0] = AllZone.GameAction.getOpponent(crd.getController()); + AllZone.GameAction.discardHand(opp[0]); + } + }; + opp[0] = AllZone.GameAction.getOpponent(c.getController()); + ability.setStackDescription(c.getName() + " - " + opp[0] + + " discards his or her hand."); + AllZone.Stack.add(ability); + } + }//nicol bolas private static void playerCombatDamage_Shadowmage_Infiltrator(Card c) { @@ -15088,26 +15290,72 @@ public class GameActionUtil CardList creature = new CardList(); creature.addAll(AllZone.Human_Play.getCards()); creature.addAll(AllZone.Computer_Play.getCards()); - creature = creature.getType("Creature"); - + creature = creature.filter(new CardListFilter(){ + public boolean addCard(Card c) + { + return c.getType().contains("Saproling") || c.getKeyword().contains("Changeling"); + } + }); + for (int i = 0; i < creature.size(); i++) { c = creature.get(i); - if (c.getType().contains("Saproling")) - { - c.addSemiPermanentAttackBoost(1); - c.addSemiPermanentDefenseBoost(1); - - gloriousAnthemList.add(c); - - } - + c.addSemiPermanentAttackBoost(1); + c.addSemiPermanentDefenseBoost(1); + gloriousAnthemList.add(c); }// for inner }// for outer }// execute() };// Thelonite Hermit + public static Command Deranged_Hermit = new Command() + { + private static final long serialVersionUID = -6105987998040015344L; + CardList gloriousAnthemList = new CardList(); + + public void execute() + { + CardList list = gloriousAnthemList; + Card c; + // reset all cards in list - aka "old" cards + for (int i = 0; i < list.size(); i++) + { + c = list.get(i); + c.addSemiPermanentAttackBoost(-1); + c.addSemiPermanentDefenseBoost(-1); + + } + + // add +1/+1 to black cards + list.clear(); + PlayerZone[] zone = getZone("Deranged Hermit"); + + for (int outer = 0; outer < zone.length; outer++) + { + // CardList creature = new CardList(zone[outer].getCards()); + CardList creature = new CardList(); + creature.addAll(AllZone.Human_Play.getCards()); + creature.addAll(AllZone.Computer_Play.getCards()); + creature = creature.filter(new CardListFilter(){ + public boolean addCard(Card c) + { + return c.getType().contains("Squirrel") || c.getKeyword().contains("Changeling"); + } + }); + + for (int i = 0; i < creature.size(); i++) + { + c = creature.get(i); + c.addSemiPermanentAttackBoost(1); + c.addSemiPermanentDefenseBoost(1); + + gloriousAnthemList.add(c); + }// for inner + }// for outer + }// execute() + };// Deranged Hermit + public static Command Muraganda_Petroglyphs = new Command() @@ -15461,6 +15709,7 @@ public class GameActionUtil commands.put("Night_of_Souls_Betrayal", Night_of_Souls_Betrayal); commands.put("Thelonite_Hermit", Thelonite_Hermit); + commands.put("Deranged_Hermit", Deranged_Hermit); commands.put("Jacques", Jacques); commands.put("Kaysa", Kaysa); commands.put("Meng_Huo", Meng_Huo); diff --git a/src/forge/InputControl.java b/src/forge/InputControl.java index 21c82ef6e43..3c568fb5df8 100644 --- a/src/forge/InputControl.java +++ b/src/forge/InputControl.java @@ -185,6 +185,7 @@ import java.util.*; { System.out.println("Cache size: " + ImageCache.cache.size()); + /* CardList visibleCards = new CardList(); PlayerZone hPlay = AllZone.Human_Play; PlayerZone hand = AllZone.Human_Hand; @@ -211,7 +212,7 @@ import java.util.*; ImageCache.cache.remove(s); System.out.println("Removing " + s + " from cache."); } - + */ if(AllZone.Display.stopEOT()) return new Input_EOT(); diff --git a/src/forge/Input_PayManaCost_Ability.java b/src/forge/Input_PayManaCost_Ability.java index adb327a9c99..b541bc76ed5 100644 --- a/src/forge/Input_PayManaCost_Ability.java +++ b/src/forge/Input_PayManaCost_Ability.java @@ -7,6 +7,7 @@ public class Input_PayManaCost_Ability extends Input private static final long serialVersionUID = 3836655722696348713L; private String originalManaCost; + private String message = ""; private ManaCost manaCost; //private ArrayList tappedLand = new ArrayList(); @@ -15,6 +16,7 @@ public class Input_PayManaCost_Ability extends Input @SuppressWarnings("unused") // isPaid private boolean isPaid; + //for Abilities that don't tap public Input_PayManaCost_Ability(String manaCost, Command paid) { @@ -25,15 +27,28 @@ public class Input_PayManaCost_Ability extends Input //or AllZone.Input.setState() with new InputState public Input_PayManaCost_Ability(String manaCost_2, Command paidCommand_2, Command unpaidCommand_2) { - originalManaCost = manaCost_2; - - manaCost = new ManaCost(originalManaCost); - paidCommand = paidCommand_2; - unpaidCommand = unpaidCommand_2; + originalManaCost = manaCost_2; + message = ""; + + manaCost = new ManaCost(originalManaCost); + paidCommand = paidCommand_2; + unpaidCommand = unpaidCommand_2; } + + public Input_PayManaCost_Ability(String m, String manaCost_2, Command paidCommand_2, Command unpaidCommand_2) + { + originalManaCost = manaCost_2; + message = m; + + manaCost = new ManaCost(originalManaCost); + paidCommand = paidCommand_2; + unpaidCommand = unpaidCommand_2; + } + + public void resetManaCost() { - manaCost = new ManaCost(originalManaCost); + manaCost = new ManaCost(originalManaCost); } public void selectCard(Card card, PlayerZone zone) { @@ -59,15 +74,15 @@ public class Input_PayManaCost_Ability extends Input public void selectButtonCancel() { - resetManaCost(); - AllZone.ManaPool.unpaid(); - unpaidCommand.execute(); - stop(); + resetManaCost(); + AllZone.ManaPool.unpaid(); + unpaidCommand.execute(); + stop(); } public void showMessage() { ButtonUtil.enableOnlyCancel(); - AllZone.Display.showMessage("Pay Mana Cost: \r\n" +manaCost.toString()); + AllZone.Display.showMessage(message + "Pay Mana Cost: \r\n" +manaCost.toString()); } diff --git a/src/forge/Input_Untap.java b/src/forge/Input_Untap.java index 209ba3e48a6..9146d1d5dbb 100644 --- a/src/forge/Input_Untap.java +++ b/src/forge/Input_Untap.java @@ -5,7 +5,7 @@ public class Input_Untap extends Input public void showMessage() { - GameActionUtil.executeUpkeepEffects(); + //GameActionUtil.executeUpkeepEffects(); PlayerZone p = AllZone.getZone(Constant.Zone.Play, AllZone.Phase.getActivePlayer()); Card[] c = p.getCards(); @@ -18,6 +18,8 @@ public class Input_Untap extends Input else regularUntap(); + GameActionUtil.executeUpkeepEffects(); + //otherwise land seems to stay tapped when it is really untapped AllZone.Human_Play.updateObservers(); diff --git a/src/forge/SpellAbility.java b/src/forge/SpellAbility.java index 831fde9169a..8f1ee9d849f 100644 --- a/src/forge/SpellAbility.java +++ b/src/forge/SpellAbility.java @@ -1,4 +1,5 @@ package forge; + //only SpellAbility can go on the stack //override any methods as needed public abstract class SpellAbility @@ -26,6 +27,8 @@ public abstract class SpellAbility private Input beforePayMana; private Input afterResolve; private Input afterPayMana; + + private Command cancelCommand = null; private CommandArgs randomTarget = new CommandArgs() { @@ -154,4 +157,12 @@ public void execute(Object o) {}}; setStackDescription(getSourceCard().getName() +" - targeting " +p); } public String getTargetPlayer() {return targetPlayer;} + + public Command getCancelCommand() { + return cancelCommand; + } + + public void setCancelCommand(Command cancelCommand) { + this.cancelCommand = cancelCommand; + } } \ No newline at end of file diff --git a/src/forge/StateBasedEffects.java b/src/forge/StateBasedEffects.java index 712b3ea5a78..f8f2134daab 100644 --- a/src/forge/StateBasedEffects.java +++ b/src/forge/StateBasedEffects.java @@ -111,6 +111,7 @@ public class StateBasedEffects cardToEffectsList.put("Engineered Plague", new String[] {"Engineered_Plague"}); cardToEffectsList.put("Night of Souls' Betrayal", new String[] {"Night_of_Souls_Betrayal"}); cardToEffectsList.put("Thelonite Hermit", new String[] {"Thelonite_Hermit"}); + cardToEffectsList.put("Deranged Hermit", new String[] {"Deranged_Hermit"}); cardToEffectsList.put("Jacques le Vert", new String[] {"Jacques"}); cardToEffectsList.put("Kaysa", new String[] {"Kaysa"}); cardToEffectsList.put("Meng Huo, Barbarian King", new String[] {"Meng_Huo"});