diff --git a/.gitattributes b/.gitattributes index a2cefa74f49..50158bf4446 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5002,6 +5002,7 @@ res/cardsfolder/h/hematite_talisman.txt svneol=native#text/plain res/cardsfolder/h/henchfiend_of_ukor.txt svneol=native#text/plain res/cardsfolder/h/henge_guardian.txt svneol=native#text/plain res/cardsfolder/h/henge_of_ramos.txt svneol=native#text/plain +res/cardsfolder/h/herald_of_leshrac.txt -text res/cardsfolder/h/herald_of_serra.txt svneol=native#text/plain res/cardsfolder/h/herald_of_war.txt -text res/cardsfolder/h/herbal_poultice.txt svneol=native#text/plain @@ -14293,6 +14294,7 @@ src/main/java/forge/card/cost/CostDraw.java -text src/main/java/forge/card/cost/CostExile.java -text src/main/java/forge/card/cost/CostExileAndPay.java -text src/main/java/forge/card/cost/CostExiledMoveToGrave.java -text +src/main/java/forge/card/cost/CostGainControl.java -text src/main/java/forge/card/cost/CostGainLife.java -text src/main/java/forge/card/cost/CostMill.java -text src/main/java/forge/card/cost/CostPart.java -text diff --git a/res/cardsfolder/h/herald_of_leshrac.txt b/res/cardsfolder/h/herald_of_leshrac.txt new file mode 100644 index 00000000000..fc4e532ef6a --- /dev/null +++ b/res/cardsfolder/h/herald_of_leshrac.txt @@ -0,0 +1,13 @@ +Name:Herald of Leshrac +ManaCost:6 B +Types:Creature Avatar +PT:2/4 +K:Flying +K:Cumulative upkeep:GainControl<1/Land.YouDontCtrl/land you don't control>:Gain control of a land you don't control. +S:Mode$ Continuous | Affected$ Card.Self | AddPower$ X | AddToughness$ X | References$ X | Description$ CARDNAME gets +1/+1 for each land you control but don't own. +SVar:X:Count$Valid Land.YouCtrl+YouDontOwn +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigRepeat | TriggerDescription$ When CARDNAME leaves the battlefield, each player gains control of each land he or she owns that you control. +SVar:TrigRepeat:AB$ RepeatEach | Cost$ 0 | RepeatSubAbility$ DBGainControl | RepeatCards$ Land.YouCtrl +SVar:DBGainControl:DB$ GainControl | Defined$ Remembered | NewController$ RememberedOwner +SVar:Picture:http://www.wizards.com/global/images/magic/general/herald_of_leshrac.jpg +Oracle:Flying\nCumulative upkeep-Gain control of a land you don't control. (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.)\nHerald of Leshrac gets +1/+1 for each land you control but don't own.\nWhen Herald of Leshrac leaves the battlefield, each player gains control of each land he or she owns that you control. diff --git a/src/main/java/forge/card/cost/Cost.java b/src/main/java/forge/card/cost/Cost.java index 8a207041d8b..62c2224733c 100644 --- a/src/main/java/forge/card/cost/Cost.java +++ b/src/main/java/forge/card/cost/Cost.java @@ -230,6 +230,12 @@ public class Cost { return new CostGainLife(splitStr[0], splitStr[1], cnt); } + if (parse.startsWith("GainControl<")) { + final String[] splitStr = abCostParse(parse, 3); + final String description = splitStr.length > 2 ? splitStr[2] : null; + return new CostGainControl(splitStr[0], splitStr[1], description); + } + if (parse.startsWith("Unattach<")) { // Unattach final String[] splitStr = abCostParse(parse, 2); diff --git a/src/main/java/forge/card/cost/CostGainControl.java b/src/main/java/forge/card/cost/CostGainControl.java new file mode 100644 index 00000000000..da5d14c9053 --- /dev/null +++ b/src/main/java/forge/card/cost/CostGainControl.java @@ -0,0 +1,182 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.card.cost; + +import java.util.ArrayList; +import java.util.List; +import forge.Card; +import forge.CardLists; +import forge.Singletons; +import forge.card.ability.AbilityUtils; +import forge.card.spellability.SpellAbility; +import forge.game.Game; +import forge.game.player.Player; +import forge.game.zone.ZoneType; +import forge.gui.input.InputSelectCards; +import forge.gui.input.InputSelectCardsFromList; + +/** + * The Class CostReturn. + */ +public class CostGainControl extends CostPartWithList { + // GainControl + + /** + * Instantiates a new cost return. + * + * @param amount + * the amount + * @param type + * the type + * @param description + * the description + */ + public CostGainControl(final String amount, final String type, final String description) { + super(amount, type, description); + } + + /* + * (non-Javadoc) + * + * @see forge.card.cost.CostPart#toString() + */ + @Override + public final String toString() { + final StringBuilder sb = new StringBuilder(); + final String desc = this.getTypeDescription() == null ? this.getType() : this.getTypeDescription(); + sb.append("Gain control of ").append(Cost.convertAmountTypeToWords(this.getAmount(), desc)); + return sb.toString(); + } + + /* + * (non-Javadoc) + * + * @see + * forge.card.cost.CostPart#canPay(forge.card.spellability.SpellAbility, + * forge.Card, forge.Player, forge.card.cost.Cost) + */ + @Override + public final boolean canPay(final SpellAbility ability) { + final Player activator = ability.getActivatingPlayer(); + final Card source = ability.getSourceCard(); + List typeList = new ArrayList(activator.getGame().getCardsIn(ZoneType.Battlefield)); + typeList = CardLists.getValidCards(typeList, this.getType().split(";"), activator, source); + + Integer amount = this.convertAmount(); + if (amount == null) { + amount = AbilityUtils.calculateAmount(source, this.getAmount(), ability); + } + if (typeList.size() < amount) { + return false; + } + return true; + } + + /* + * (non-Javadoc) + * + * @see + * forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility, + * forge.Card, forge.card.cost.Cost_Payment) + */ + @Override + public final boolean payHuman(final SpellAbility ability, final Game game) { + final String amount = this.getAmount(); + final Card source = ability.getSourceCard(); + Integer c = this.convertAmount(); + final Player activator = ability.getActivatingPlayer(); + final List list = activator.getGame().getCardsIn(ZoneType.Battlefield); + final String desc = this.getTypeDescription() == null ? this.getType() : this.getTypeDescription(); + + if (c == null) { + c = AbilityUtils.calculateAmount(source, amount, ability); + } + List validCards = CardLists.getValidCards(list, this.getType().split(";"), activator, source); + + InputSelectCards inp = new InputSelectCardsFromList(c, c, validCards); + inp.setMessage("Gain control of %d " + desc); + Singletons.getControl().getInputQueue().setInputAndWait(inp); + if (inp.hasCancelled()) { + return false; + } + for(Card crd : inp.getSelected()) { + executePayment(ability, crd); + } + return true; + } + + /* + * (non-Javadoc) + * + * @see + * forge.card.cost.CostPart#decideAIPayment(forge.card.spellability.SpellAbility + * , forge.Card, forge.card.cost.Cost_Payment) + */ + @Override + public final PaymentDecision decideAIPayment(final Player ai, final SpellAbility ability, final Card source) { + if (this.payCostFromSource()) + return new PaymentDecision(source); + + Integer c = this.convertAmount(); + if (c == null) { + c = AbilityUtils.calculateAmount(source, this.getAmount(), ability); + } + + final List typeList = CardLists.getValidCards(ai.getGame().getCardsIn(ZoneType.Battlefield), this.getType().split(";"), ai, source); + + + if (typeList.size() < c) { + return null; + } + + CardLists.sortByPowerAsc(typeList); + final List res = new ArrayList(); + + for (int i = 0; i < c; i++) { + res.add(typeList.get(i)); + } + return res.isEmpty() ? null : new PaymentDecision(res); + } + + /* (non-Javadoc) + * @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card) + */ + @Override + protected void doPayment(SpellAbility ability, Card targetCard) { + targetCard.setController(ability.getActivatingPlayer(), ability.getActivatingPlayer().getGame().getNextTimestamp()); + } + + /* (non-Javadoc) + * @see forge.card.cost.CostPartWithList#getHashForList() + */ + @Override + public String getHashForList() { + return "ControllGained"; + } + + /* (non-Javadoc) + * @see forge.card.cost.CostPart#payAI(forge.card.cost.PaymentDecision, forge.game.player.AIPlayer, forge.card.spellability.SpellAbility, forge.Card) + */ + @Override + public void payAI(PaymentDecision decision, Player ai, SpellAbility ability, Card source) { + for (final Card c : decision.cards) { + executePayment(ability, c); + } + } + +} diff --git a/src/main/java/forge/game/player/HumanPlay.java b/src/main/java/forge/game/player/HumanPlay.java index 7809c442f2b..3c4681ca125 100644 --- a/src/main/java/forge/game/player/HumanPlay.java +++ b/src/main/java/forge/game/player/HumanPlay.java @@ -25,6 +25,7 @@ import forge.card.cost.CostDamage; import forge.card.cost.CostDiscard; import forge.card.cost.CostDraw; import forge.card.cost.CostExile; +import forge.card.cost.CostGainControl; import forge.card.cost.CostGainLife; import forge.card.cost.CostMill; import forge.card.cost.CostPart; @@ -563,6 +564,11 @@ public class HumanPlay { List list = CardLists.getValidCards(p.getCardsIn(ZoneType.Battlefield), part.getType(), p, source); boolean hasPaid = payCostPart(sourceAbility, (CostPartWithList)part, amount, list, "sacrifice." + orString); if(!hasPaid) return false; + } else if (part instanceof CostGainControl) { + int amount = Integer.parseInt(((CostGainControl)part).getAmount()); + List list = CardLists.getValidCards(p.getGame().getCardsIn(ZoneType.Battlefield), part.getType(), p, source); + boolean hasPaid = payCostPart(sourceAbility, (CostPartWithList)part, amount, list, "gain control." + orString); + if(!hasPaid) return false; } else if (part instanceof CostReturn) { List list = CardLists.getValidCards(p.getCardsIn(ZoneType.Battlefield), part.getType(), p, source); int amount = getAmountFromPartX(part, source, sourceAbility);