mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 03:08:02 +00:00
- Added Battlefield Scrounger, Leashling, and Penance
This commit is contained in:
4
.gitattributes
vendored
4
.gitattributes
vendored
@@ -848,6 +848,7 @@ res/cardsfolder/b/battle_strain.txt svneol=native#text/plain
|
|||||||
res/cardsfolder/b/battlefield_forge.txt svneol=native#text/plain
|
res/cardsfolder/b/battlefield_forge.txt svneol=native#text/plain
|
||||||
res/cardsfolder/b/battlefield_medic.txt svneol=native#text/plain
|
res/cardsfolder/b/battlefield_medic.txt svneol=native#text/plain
|
||||||
res/cardsfolder/b/battlefield_percher.txt svneol=native#text/plain
|
res/cardsfolder/b/battlefield_percher.txt svneol=native#text/plain
|
||||||
|
res/cardsfolder/b/battlefield_scrounger.txt -text
|
||||||
res/cardsfolder/b/battleflight_eagle.txt -text
|
res/cardsfolder/b/battleflight_eagle.txt -text
|
||||||
res/cardsfolder/b/battlegate_mimic.txt svneol=native#text/plain
|
res/cardsfolder/b/battlegate_mimic.txt svneol=native#text/plain
|
||||||
res/cardsfolder/b/battlegrace_angel.txt svneol=native#text/plain
|
res/cardsfolder/b/battlegrace_angel.txt svneol=native#text/plain
|
||||||
@@ -6109,6 +6110,7 @@ res/cardsfolder/l/leap.txt svneol=native#text/plain
|
|||||||
res/cardsfolder/l/leap_of_faith.txt -text
|
res/cardsfolder/l/leap_of_faith.txt -text
|
||||||
res/cardsfolder/l/leap_of_flame.txt svneol=native#text/plain
|
res/cardsfolder/l/leap_of_flame.txt svneol=native#text/plain
|
||||||
res/cardsfolder/l/leaping_lizard.txt svneol=native#text/plain
|
res/cardsfolder/l/leaping_lizard.txt svneol=native#text/plain
|
||||||
|
res/cardsfolder/l/leashling.txt -text
|
||||||
res/cardsfolder/l/leatherback_baloth.txt svneol=native#text/plain
|
res/cardsfolder/l/leatherback_baloth.txt svneol=native#text/plain
|
||||||
res/cardsfolder/l/leave_no_trace.txt svneol=native#text/plain
|
res/cardsfolder/l/leave_no_trace.txt svneol=native#text/plain
|
||||||
res/cardsfolder/l/leech_bonder.txt -text
|
res/cardsfolder/l/leech_bonder.txt -text
|
||||||
@@ -7881,6 +7883,7 @@ res/cardsfolder/p/pegasus_refuge.txt svneol=native#text/plain
|
|||||||
res/cardsfolder/p/pegasus_stampede.txt svneol=native#text/plain
|
res/cardsfolder/p/pegasus_stampede.txt svneol=native#text/plain
|
||||||
res/cardsfolder/p/pelakka_wurm.txt svneol=native#text/plain
|
res/cardsfolder/p/pelakka_wurm.txt svneol=native#text/plain
|
||||||
res/cardsfolder/p/pemmins_aura.txt svneol=native#text/plain
|
res/cardsfolder/p/pemmins_aura.txt svneol=native#text/plain
|
||||||
|
res/cardsfolder/p/penance.txt -text
|
||||||
res/cardsfolder/p/pendelhaven.txt svneol=native#text/plain
|
res/cardsfolder/p/pendelhaven.txt svneol=native#text/plain
|
||||||
res/cardsfolder/p/pendelhaven_elder.txt svneol=native#text/plain
|
res/cardsfolder/p/pendelhaven_elder.txt svneol=native#text/plain
|
||||||
res/cardsfolder/p/pendrell_drake.txt svneol=native#text/plain
|
res/cardsfolder/p/pendrell_drake.txt svneol=native#text/plain
|
||||||
@@ -14188,6 +14191,7 @@ src/main/java/forge/card/cost/CostPartMana.java -text
|
|||||||
src/main/java/forge/card/cost/CostPartWithList.java -text
|
src/main/java/forge/card/cost/CostPartWithList.java -text
|
||||||
src/main/java/forge/card/cost/CostPayLife.java -text
|
src/main/java/forge/card/cost/CostPayLife.java -text
|
||||||
src/main/java/forge/card/cost/CostPayment.java svneol=native#text/plain
|
src/main/java/forge/card/cost/CostPayment.java svneol=native#text/plain
|
||||||
|
src/main/java/forge/card/cost/CostPutCardToLib.java -text
|
||||||
src/main/java/forge/card/cost/CostPutCounter.java -text
|
src/main/java/forge/card/cost/CostPutCounter.java -text
|
||||||
src/main/java/forge/card/cost/CostRemoveCounter.java -text
|
src/main/java/forge/card/cost/CostRemoveCounter.java -text
|
||||||
src/main/java/forge/card/cost/CostReturn.java -text
|
src/main/java/forge/card/cost/CostReturn.java -text
|
||||||
|
|||||||
8
res/cardsfolder/b/battlefield_scrounger.txt
Normal file
8
res/cardsfolder/b/battlefield_scrounger.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Name:Battlefield Scrounger
|
||||||
|
ManaCost:3 G G
|
||||||
|
Types:Creature Centaur
|
||||||
|
PT:3/3
|
||||||
|
A:AB$ Pump | Cost$ PutCardToLibFromGrave<3/-1/Card> | Activation$ Threshold | ActivationLimit$ 1 | NumAtt$ +3 | NumDef$ +3 | PrecostDesc$ Threshold - | SpellDescription$ CARDNAME gets +3/+3 until end of turn. Activate this ability only once each turn, and only if seven or more cards are in your graveyard.
|
||||||
|
SVar:RemAIDeck:True
|
||||||
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/battlefield_scrounger.jpg
|
||||||
|
Oracle:Threshold - Put three cards from your graveyard on the bottom of your library: Battlefield Scrounger gets +3/+3 until end of turn. Activate this ability only once each turn, and only if seven or more cards are in your graveyard.
|
||||||
7
res/cardsfolder/l/leashling.txt
Normal file
7
res/cardsfolder/l/leashling.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Name:Leashling
|
||||||
|
ManaCost:6
|
||||||
|
Types:Artifact Creature Hound
|
||||||
|
PT:3/3
|
||||||
|
A:AB$ ChangeZone | Cost$ PutCardToLibFromHand<1/0/Card> | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return CARDNAME to its owner's hand.
|
||||||
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/leashling.jpg
|
||||||
|
Oracle:Put a card from your hand on top of your library: Return Leashling to its owner's hand.
|
||||||
11
res/cardsfolder/p/penance.txt
Normal file
11
res/cardsfolder/p/penance.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Name:Penance
|
||||||
|
ManaCost:2 W
|
||||||
|
Types:Enchantment
|
||||||
|
A:AB$ ChooseSource | Cost$ PutCardToLibFromHand<1/0/Card> | Choices$ Card.Red,Card.Black | RememberChosen$ True | AILogic$ NeedsPrevention | SubAbility$ DBEffect | SpellDescription$ The next time a black or red source of your choice would deal damage this turn, prevent that damage.
|
||||||
|
SVar:DBEffect:DB$ Effect | ReplacementEffects$ RPreventNextFromSource | RememberObjects$ Remembered | SVars$ RPreventNextFromSource,ExileEffect | SubAbility$ DBCleanup | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ GE1
|
||||||
|
SVar:RPreventNextFromSource:Event$ DamageDone | ValidSource$ Card.IsRemembered | ReplaceWith$ ExileEffect | PreventionEffect$ True | Description$ The next time the chosen source deals damage, prevent that damage.
|
||||||
|
SVar:ExileEffect:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
|
||||||
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
|
SVar:RemRandomDeck:True
|
||||||
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/penance.jpg
|
||||||
|
Oracle:Put a card from your hand on top of your library: The next time a black or red source of your choice would deal damage this turn, prevent that damage.
|
||||||
@@ -317,6 +317,24 @@ public class Cost {
|
|||||||
return new CostReveal(splitStr[0], splitStr[1], description);
|
return new CostReveal(splitStr[0], splitStr[1], description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(parse.startsWith("PutCardToLibFromHand<")) {
|
||||||
|
final String[] splitStr = abCostParse(parse, 4);
|
||||||
|
final String description = splitStr.length > 3 ? splitStr[3] : null;
|
||||||
|
return new CostPutCardToLib(splitStr[0], splitStr[1], splitStr[2], description, ZoneType.Hand);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(parse.startsWith("PutCardToLibFromGrave<")) {
|
||||||
|
final String[] splitStr = abCostParse(parse, 4);
|
||||||
|
final String description = splitStr.length > 3 ? splitStr[3] : null;
|
||||||
|
return new CostPutCardToLib(splitStr[0], splitStr[1], splitStr[2], description, ZoneType.Graveyard);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(parse.startsWith("PutCardToLibFromSameGrave<")) {
|
||||||
|
final String[] splitStr = abCostParse(parse, 4);
|
||||||
|
final String description = splitStr.length > 3 ? splitStr[3] : null;
|
||||||
|
return new CostPutCardToLib(splitStr[0], splitStr[1], splitStr[2], description, ZoneType.Graveyard, true);
|
||||||
|
}
|
||||||
|
|
||||||
// These won't show up with multiples
|
// These won't show up with multiples
|
||||||
if (parse.equals("Untap") || parse.equals("Q")) {
|
if (parse.equals("Untap") || parse.equals("Q")) {
|
||||||
return new CostUntap();
|
return new CostUntap();
|
||||||
|
|||||||
339
src/main/java/forge/card/cost/CostPutCardToLib.java
Normal file
339
src/main/java/forge/card/cost/CostPutCardToLib.java
Normal file
@@ -0,0 +1,339 @@
|
|||||||
|
/*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package forge.card.cost;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import forge.Card;
|
||||||
|
import forge.CardLists;
|
||||||
|
import forge.CardPredicates;
|
||||||
|
import forge.Singletons;
|
||||||
|
import forge.card.ability.AbilityUtils;
|
||||||
|
import forge.card.spellability.SpellAbility;
|
||||||
|
import forge.game.Game;
|
||||||
|
import forge.game.ai.ComputerUtil;
|
||||||
|
import forge.game.player.Player;
|
||||||
|
import forge.game.zone.ZoneType;
|
||||||
|
import forge.gui.GuiChoose;
|
||||||
|
import forge.gui.input.InputSelectCards;
|
||||||
|
import forge.gui.input.InputSelectCardsFromList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is for the "PutCardToLib" Cost.
|
||||||
|
*/
|
||||||
|
public class CostPutCardToLib extends CostPartWithList {
|
||||||
|
// PutCardToLibFromHand<Num/LibPos/Type{/TypeDescription}>
|
||||||
|
// PutCardToLibFromSameGrave<Num/LibPos/Type{/TypeDescription}>
|
||||||
|
// PutCardToLibFromGrave<Num/LibPos/Type{/TypeDescription}>
|
||||||
|
|
||||||
|
private ZoneType from = ZoneType.Hand;
|
||||||
|
private boolean sameZone = false;
|
||||||
|
private String libPosition = "0";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the from.
|
||||||
|
*
|
||||||
|
* @return the from
|
||||||
|
*/
|
||||||
|
public final ZoneType getFrom() {
|
||||||
|
return this.from;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the libposition.
|
||||||
|
*
|
||||||
|
* @return the libposition
|
||||||
|
*/
|
||||||
|
public final String getLibPos() {
|
||||||
|
return this.libPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new cost exile.
|
||||||
|
*
|
||||||
|
* @param amount
|
||||||
|
* the amount
|
||||||
|
* @param type
|
||||||
|
* the type
|
||||||
|
* @param description
|
||||||
|
* the description
|
||||||
|
* @param from
|
||||||
|
* the from
|
||||||
|
*/
|
||||||
|
public CostPutCardToLib(final String amount, final String libpos,
|
||||||
|
final String type, final String description, final ZoneType from) {
|
||||||
|
super(amount, type, description);
|
||||||
|
if (from != null) {
|
||||||
|
this.from = from;
|
||||||
|
}
|
||||||
|
this.libPosition = libpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CostPutCardToLib(final String amount, final String libpos, final String type,
|
||||||
|
final String description, final ZoneType from, final boolean sameZone) {
|
||||||
|
this(amount, libpos, type, description, from);
|
||||||
|
this.sameZone = sameZone;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see forge.card.cost.CostPart#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final String toString() {
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
final Integer i = this.convertAmount();
|
||||||
|
sb.append("Put ");
|
||||||
|
|
||||||
|
final String desc = this.getTypeDescription() == null ? this.getType() : this.getTypeDescription();
|
||||||
|
sb.append(Cost.convertAmountTypeToWords(i, this.getAmount(), desc));
|
||||||
|
|
||||||
|
if (this.sameZone) {
|
||||||
|
sb.append(" from the same ");
|
||||||
|
} else {
|
||||||
|
sb.append(" from your ");
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append(this.from).append(" on ");
|
||||||
|
|
||||||
|
if (this.libPosition.equals("0")) {
|
||||||
|
sb.append("top of");
|
||||||
|
} else {
|
||||||
|
sb.append("the bottom of");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.sameZone) {
|
||||||
|
sb.append(" their owner's library");
|
||||||
|
} else {
|
||||||
|
sb.append(" your library");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see forge.card.cost.CostPartWithList#getHashForList()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getHashForList() {
|
||||||
|
return "CardPutToLib";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (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();
|
||||||
|
final Game game = activator.getGame();
|
||||||
|
|
||||||
|
Integer i = this.convertAmount();
|
||||||
|
|
||||||
|
if (i == null) {
|
||||||
|
final String sVar = ability.getSVar(this.getAmount());
|
||||||
|
if (sVar.equals("XChoice")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
i = AbilityUtils.calculateAmount(source, this.getAmount(), ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Card> typeList = new ArrayList<Card>();
|
||||||
|
if (this.sameZone) {
|
||||||
|
typeList = new ArrayList<Card>(game.getCardsIn(this.getFrom()));
|
||||||
|
} else {
|
||||||
|
typeList = new ArrayList<Card>(activator.getCardsIn(this.getFrom()));
|
||||||
|
}
|
||||||
|
|
||||||
|
typeList = CardLists.getValidCards(typeList, this.getType().split(";"), activator, source);
|
||||||
|
|
||||||
|
if (typeList.size() < i) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.sameZone) {
|
||||||
|
boolean foundPayable = false;
|
||||||
|
List<Player> players = game.getPlayers();
|
||||||
|
for (Player p : players) {
|
||||||
|
if (CardLists.filter(typeList, CardPredicates.isController(p)).size() >= i) {
|
||||||
|
foundPayable = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundPayable) {
|
||||||
|
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();
|
||||||
|
Integer c = this.convertAmount();
|
||||||
|
final Card source = ability.getSourceCard();
|
||||||
|
final Player activator = ability.getActivatingPlayer();
|
||||||
|
|
||||||
|
List<Card> list;
|
||||||
|
|
||||||
|
if (this.sameZone) {
|
||||||
|
list = new ArrayList<Card>(game.getCardsIn(this.getFrom()));
|
||||||
|
} else {
|
||||||
|
list = new ArrayList<Card>(activator.getCardsIn(this.getFrom()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == null) {
|
||||||
|
final String sVar = ability.getSVar(amount);
|
||||||
|
// Generalize this
|
||||||
|
if (sVar.equals("XChoice")) {
|
||||||
|
c = Cost.chooseXValue(source, ability, this.getList().size());
|
||||||
|
} else {
|
||||||
|
c = AbilityUtils.calculateAmount(source, amount, ability);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list = CardLists.getValidCards(list, this.getType().split(";"), activator, source);
|
||||||
|
|
||||||
|
if (this.from == ZoneType.Hand) {
|
||||||
|
InputSelectCards inp = new InputSelectCardsFromList(c, c, list);
|
||||||
|
inp.setMessage("Put %d card(s) from your " + from );
|
||||||
|
inp.setCancelAllowed(true);
|
||||||
|
Singletons.getControl().getInputQueue().setInputAndWait(inp);
|
||||||
|
return !inp.hasCancelled() && executePayment(ability, inp.getSelected());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.sameZone){
|
||||||
|
List<Player> players = game.getPlayers();
|
||||||
|
List<Player> payableZone = new ArrayList<Player>();
|
||||||
|
for (Player p : players) {
|
||||||
|
List<Card> enoughType = CardLists.filter(list, CardPredicates.isOwner(p));
|
||||||
|
if (enoughType.size() < c) {
|
||||||
|
list.removeAll(enoughType);
|
||||||
|
} else {
|
||||||
|
payableZone.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PutFromSame(list, c, payableZone);
|
||||||
|
} else {//Graveyard
|
||||||
|
return PutFromMiscZone(ability, c, list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Write javadoc for this method.
|
||||||
|
* @param sa
|
||||||
|
* @param nNeeded
|
||||||
|
* @param typeList
|
||||||
|
* @return a boolean
|
||||||
|
*/
|
||||||
|
private boolean PutFromMiscZone(SpellAbility sa, int nNeeded, List<Card> typeList) {
|
||||||
|
for (int i = 0; i < nNeeded; i++) {
|
||||||
|
if (typeList.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Card c = GuiChoose.oneOrNone("Put from " + getFrom() + " to library", typeList);
|
||||||
|
|
||||||
|
if (c != null) {
|
||||||
|
typeList.remove(c);
|
||||||
|
executePayment(sa, c);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean PutFromSame(List<Card> list, int nNeeded, List<Player> payableZone) {
|
||||||
|
if (nNeeded == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
final Player p = GuiChoose.oneOrNone(String.format("Put cards from whose %s?", getFrom()), payableZone);
|
||||||
|
if (p == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Card> typeList = CardLists.filter(list, CardPredicates.isOwner(p));
|
||||||
|
|
||||||
|
for (int i = 0; i < nNeeded; i++) {
|
||||||
|
if (typeList.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Card c = GuiChoose.oneOrNone("Put cards from " + getFrom() + " to Library", typeList);
|
||||||
|
|
||||||
|
if (c != null) {
|
||||||
|
typeList.remove(c);
|
||||||
|
executePayment(null, c);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void doPayment(SpellAbility ability, Card targetCard) {
|
||||||
|
ability.getActivatingPlayer().getGame().getAction().moveToLibrary(targetCard, Integer.parseInt(getLibPos()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see forge.card.cost.CostPart#decideAIPayment(forge.game.player.AIPlayer, forge.card.spellability.SpellAbility, forge.Card)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public PaymentDecision decideAIPayment(Player ai, SpellAbility ability, Card source) {
|
||||||
|
Integer c = this.convertAmount();
|
||||||
|
if (c == null) {
|
||||||
|
final String sVar = ability.getSVar(this.getAmount());
|
||||||
|
// Generalize this
|
||||||
|
if (sVar.equals("XChoice")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = AbilityUtils.calculateAmount(source, this.getAmount(), ability);
|
||||||
|
}
|
||||||
|
if (this.sameZone) {
|
||||||
|
// TODO Determine exile from same zone for AI
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
List<Card> chosen = ComputerUtil.choosePutToLibraryFrom(ai, this.getFrom(), this.getType(), source, ability.getTargetCard(), c);
|
||||||
|
return null == chosen ? null : new PaymentDecision(chosen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -506,6 +506,51 @@ public class ComputerUtil {
|
|||||||
return exileList;
|
return exileList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* choosePutToLibraryFrom.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param zone
|
||||||
|
* a {@link java.lang.String} object.
|
||||||
|
* @param type
|
||||||
|
* a {@link java.lang.String} object.
|
||||||
|
* @param activate
|
||||||
|
* a {@link forge.Card} object.
|
||||||
|
* @param target
|
||||||
|
* a {@link forge.Card} object.
|
||||||
|
* @param amount
|
||||||
|
* a int.
|
||||||
|
* @return a {@link forge.CardList} object.
|
||||||
|
*/
|
||||||
|
public static List<Card> choosePutToLibraryFrom(final Player ai, final ZoneType zone, final String type, final Card activate,
|
||||||
|
final Card target, final int amount) {
|
||||||
|
List<Card> typeList = ai.getCardsIn(zone);
|
||||||
|
|
||||||
|
typeList = CardLists.getValidCards(typeList, type.split(","), activate.getController(), activate);
|
||||||
|
|
||||||
|
if ((target != null) && target.getController() == ai && typeList.contains(target)) {
|
||||||
|
typeList.remove(target); // don't move the card we're pumping
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeList.size() < amount) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
CardLists.sortByPowerAsc(typeList);
|
||||||
|
final List<Card> list = new ArrayList<Card>();
|
||||||
|
|
||||||
|
if (zone != ZoneType.Hand) {
|
||||||
|
Collections.reverse(typeList);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < amount; i++) {
|
||||||
|
list.add(typeList.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* chooseTapType.
|
* chooseTapType.
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.CardLists;
|
import forge.CardLists;
|
||||||
import forge.CardPredicates.Presets;
|
import forge.CardPredicates.Presets;
|
||||||
|
import forge.CardPredicates;
|
||||||
import forge.CounterType;
|
import forge.CounterType;
|
||||||
import forge.FThreads;
|
import forge.FThreads;
|
||||||
import forge.GameLogEntryType;
|
import forge.GameLogEntryType;
|
||||||
@@ -26,6 +27,7 @@ import forge.card.cost.CostPartMana;
|
|||||||
import forge.card.cost.CostPartWithList;
|
import forge.card.cost.CostPartWithList;
|
||||||
import forge.card.cost.CostPayLife;
|
import forge.card.cost.CostPayLife;
|
||||||
import forge.card.cost.CostPayment;
|
import forge.card.cost.CostPayment;
|
||||||
|
import forge.card.cost.CostPutCardToLib;
|
||||||
import forge.card.cost.CostPutCounter;
|
import forge.card.cost.CostPutCounter;
|
||||||
import forge.card.cost.CostRemoveCounter;
|
import forge.card.cost.CostRemoveCounter;
|
||||||
import forge.card.cost.CostReturn;
|
import forge.card.cost.CostReturn;
|
||||||
@@ -397,6 +399,46 @@ public class HumanPlay {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (part instanceof CostPutCardToLib) {
|
||||||
|
//Jotun Grunt
|
||||||
|
int amount = Integer.parseInt(((CostPutCardToLib) part).getAmount());
|
||||||
|
final ZoneType from = ((CostPutCardToLib) part).getFrom();
|
||||||
|
List<Card> list = CardLists.getValidCards(p.getGame().getCardsIn(from), part.getType().split(","), p, source);
|
||||||
|
List<Player> players = p.getGame().getPlayers();
|
||||||
|
List<Player> payableZone = new ArrayList<Player>();
|
||||||
|
for (Player player : players) {
|
||||||
|
List<Card> enoughType = CardLists.filter(list, CardPredicates.isOwner(player));
|
||||||
|
if (enoughType.size() < amount) {
|
||||||
|
list.removeAll(enoughType);
|
||||||
|
} else {
|
||||||
|
payableZone.add(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Player chosen = GuiChoose.oneOrNone(String.format("Put cards from whose %s?",
|
||||||
|
((CostPutCardToLib) part).getFrom()), payableZone);
|
||||||
|
if (chosen == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Card> typeList = CardLists.filter(list, CardPredicates.isOwner(chosen));
|
||||||
|
|
||||||
|
for (int i = 0; i < amount; i++) {
|
||||||
|
if (typeList.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Card c = GuiChoose.oneOrNone("Put cards to Library", typeList);
|
||||||
|
|
||||||
|
if (c != null) {
|
||||||
|
typeList.remove(c);
|
||||||
|
p.getGame().getAction().moveToLibrary(c, Integer.parseInt(((CostPutCardToLib) part).getLibPos()));
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
else if (part instanceof CostSacrifice) {
|
else if (part instanceof CostSacrifice) {
|
||||||
int amount = Integer.parseInt(((CostSacrifice)part).getAmount());
|
int amount = Integer.parseInt(((CostSacrifice)part).getAmount());
|
||||||
List<Card> list = CardLists.getValidCards(p.getCardsIn(ZoneType.Battlefield), part.getType(), p, source);
|
List<Card> list = CardLists.getValidCards(p.getCardsIn(ZoneType.Battlefield), part.getType(), p, source);
|
||||||
|
|||||||
Reference in New Issue
Block a user