add ExileFromTop<1/Card> (for example) as a Cost.

add Royal Herbalist as an example.
This commit is contained in:
jendave
2011-08-06 21:25:58 +00:00
parent e0ecb88f78
commit 3909cea01c
6 changed files with 208 additions and 4 deletions

1
.gitattributes vendored
View File

@@ -5407,6 +5407,7 @@ res/cardsfolder/rowan_treefolk.txt -text svneol=native#text/plain
res/cardsfolder/royal_assassin.txt -text svneol=native#text/plain
res/cardsfolder/royal_decree.txt -text svneol=native#text/plain
res/cardsfolder/royal_falcon.txt -text svneol=native#text/plain
res/cardsfolder/royal_herbalist.txt -text svneol=native#text/plain
res/cardsfolder/royal_trooper.txt -text svneol=native#text/plain
res/cardsfolder/rubinia_soulsinger.txt -text svneol=native#text/plain
res/cardsfolder/ruby_leech.txt -text svneol=native#text/plain

View File

@@ -0,0 +1,9 @@
Name:Royal Herbalist
ManaCost:W
Types:Creature Human Cleric
Text:no text
PT:1/1
A:AB$GainLife | Cost$ 2 ExileFromTop<1/Card> | LifeAmount$ 1 | SpellDescription$ You gain 1 life.
SVar:Rarity:Common
SVar:Picture:http://www.wizards.com/global/images/magic/general/royal_herbalist.jpg
End

View File

@@ -245,6 +245,10 @@ public class AllZoneUtil {
return PlayerZoneUtil.isCardInZone(AllZone.getZone(Constant.Zone.Hand, player), card);
}
public static boolean isCardInPlayerLibrary(Player player, Card card) {
return PlayerZoneUtil.isCardInZone(AllZone.getZone(Constant.Zone.Library, player), card);
}
////////////// EXILE
/**

View File

@@ -425,6 +425,21 @@ public class ComputerUtil
return false;
}
if(cost.getExileFromTopCost()){
if(!cost.getExileFromTopThis()){
CardList typeList = AllZoneUtil.getPlayerCardsInLibrary(AllZone.ComputerPlayer);
typeList = typeList.getValidCards(cost.getExileFromTopType().split(","), sa.getActivatingPlayer(), sa.getSourceCard());
Card target = sa.getTargetCard();
if (target != null && target.getController().equals(AllZone.ComputerPlayer)) // don't exile the card we're pumping
typeList.remove(target);
if (cost.getExileFromTopAmount() > typeList.size())
return false;
}
else if (cost.getExileFromTopThis() && !AllZoneUtil.isCardInPlayerLibrary(card.getController(), card))
return false;
}
if (cost.getReturnCost()){
// if there's a return in the cost, just because we can Pay it doesn't mean we want to.
if (!cost.getReturnThis()){
@@ -720,6 +735,10 @@ public class ComputerUtil
return chooseExileFrom(Constant.Zone.Graveyard, type, activate, target, amount);
}
static public CardList chooseExileFromTopType(String type, Card activate, Card target, int amount){
return chooseExileFrom(Constant.Zone.Library, type, activate, target, amount);
}
static public CardList chooseExileFrom(String zone, String type, Card activate, Card target, int amount){
PlayerZone grave = AllZone.getZone(zone, AllZone.ComputerPlayer);
CardList typeList = new CardList(grave.getCards());

View File

@@ -45,6 +45,15 @@ public class Cost {
public boolean getExileFromGraveThis() { return exileFromGraveThis; }
private int exileFromGraveAmount = 0;
public int getExileFromGraveAmount() { return exileFromGraveAmount; }
private boolean exileFromTopCost = false;
public boolean getExileFromTopCost() { return exileFromTopCost; }
private String exileFromTopType = ""; // <type> or CARDNAME
public String getExileFromTopType() { return exileFromTopType; }
private boolean exileFromTopThis = false;
public boolean getExileFromTopThis() { return exileFromTopThis; }
private int exileFromTopAmount = 0;
public int getExileFromTopAmount() { return exileFromTopAmount; }
private boolean tapCost = false;
public boolean getTap() { return tapCost; }
@@ -105,8 +114,8 @@ public class Cost {
public void setXMana(int xCost) { manaXCost = xCost; }
public boolean isOnlyManaCost() {
return !sacCost && !exileCost && !exileFromHandCost && !exileFromGraveCost && !tapCost && !tapXTypeCost &&
!untapCost && !subtractCounterCost && !addCounterCost && !lifeCost && !discardCost && !returnCost;
return !sacCost && !exileCost && !exileFromHandCost && !exileFromGraveCost && !exileFromTopCost && !tapCost &&
!tapXTypeCost && !untapCost && !subtractCounterCost && !addCounterCost && !lifeCost && !discardCost && !returnCost;
}
public String getTotalMana() {
@@ -232,6 +241,17 @@ public class Cost {
exileFromGraveThis = (exileFromGraveType.equals("CARDNAME"));
}
String exileFromTopStr = "ExileFromTop<";
if(parse.contains(exileFromTopStr)) {
exileFromTopCost = true;
String[] splitStr = abCostParse(parse, exileFromTopStr, 2);
parse = abUpdateParse(parse, exileFromTopStr);
exileFromTopAmount = Integer.parseInt(splitStr[0]);
exileFromTopType = splitStr[1];
exileFromTopThis = false;
}
String returnStr = "Return<";
if(parse.contains(returnStr)) {
returnCost = true;
@@ -310,7 +330,7 @@ public class Cost {
public boolean isUndoable() {
return !(sacCost || exileCost || exileFromHandCost || exileFromGraveCost || tapXTypeCost || discardCost ||
returnCost || lifeCost) && hasNoXManaCost() && hasNoManaCost();
returnCost || lifeCost || exileFromTopCost) && hasNoXManaCost() && hasNoManaCost();
}
@@ -399,6 +419,11 @@ public class Cost {
first = false;
}
if(exileFromTopCost) {
cost.append(exileFromTopString(first));
first = false;
}
if (returnCost){
cost.append(returnString(first));
first = false;
@@ -526,6 +551,11 @@ public class Cost {
first = false;
}
if( exileFromTopCost ) {
cost.append( exileFromTopString(first) );
first = false;
}
if (returnCost){
cost.append(returnString(first));
first = false;
@@ -656,6 +686,32 @@ public class Cost {
}
return cost.toString();
}
public String exileFromTopString(boolean first) {
StringBuilder cost = new StringBuilder();
if(first) {
if(isAbility)
cost.append("Exile ");
else
cost.append("exile ");
}
else {
cost.append(", Exile ");
}
if(exileType.equals("CARDNAME"))
cost.append(name).append(" ");
else {
cost.append("the top");
if(exileFromTopAmount != 1) {
cost.append(convertIntAndTypeToWords(exileFromTopAmount, exileFromTopType));
}
cost.append(" card");
if(exileFromTopAmount != 1) cost.append("s");
cost.append(" of your library");
}
return cost.toString();
}
public String returnString(boolean first)
{

View File

@@ -44,6 +44,7 @@ public class Cost_Payment {
private boolean payExile;
private boolean payExileFromHand;
private boolean payExileFromGrave;
private boolean payExileFromTop;
private boolean payLife;
private boolean payDiscard;
private boolean payTapXType;
@@ -65,6 +66,7 @@ public class Cost_Payment {
public void setPayExile(boolean bExile) { payExile = bExile; }
public void setPayExileFromHand(boolean bExileFromHand) { payExileFromHand = bExileFromHand; }
public void setPayExileFromGrave(boolean bExileFromGrave) { payExileFromGrave = bExileFromGrave; }
public void setPayExileFromTop(boolean bExileFromTop) { payExileFromTop = bExileFromTop; }
public void setPayTapXType(boolean bTapX) { payTapXType = bTapX; }
public void setPayReturn(boolean bReturn){ payReturn = bReturn; }
@@ -82,6 +84,7 @@ public class Cost_Payment {
payExile = !cost.getExileCost();
payExileFromHand = !cost.getExileFromHandCost();
payExileFromGrave = !cost.getExileFromGraveCost();
payExileFromTop = !cost.getExileFromTopCost();
payLife = !cost.getLifeCost();
payDiscard = !cost.getDiscardCost();
payTapXType = !cost.getTapXTypeCost();
@@ -215,6 +218,18 @@ public class Cost_Payment {
return false;
}
if (cost.getExileFromTopCost()){
if (!cost.getExileFromTopThis()){
CardList typeList = AllZoneUtil.getPlayerCardsInLibrary(card.getController());
typeList = typeList.getValidCards(cost.getExileFromTopType().split(";"), ability.getActivatingPlayer(), ability.getSourceCard());
if (typeList.size() < cost.getExileFromTopAmount())
return false;
}
else if (!AllZoneUtil.isCardInPlayerLibrary(card.getController(), card))
return false;
}
if (cost.getReturnCost()){
if (!cost.getReturnThis()){
PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, card.getController());
@@ -399,6 +414,14 @@ public class Cost_Payment {
return false;
}
if(!payExileFromTop && cost.getExileFromTopCost()) { // exile stuff here
if (cost.getExileFromTopThis())
setInput(exileFromTopThis(ability, this));
else
setInput(exileFromTopType(ability, cost.getExileFromTopType(), this));
return false;
}
if (!payReturn && cost.getReturnCost()){ // return stuff here
if (cost.getReturnThis())
setInput(returnThis(ability, this));
@@ -416,7 +439,7 @@ public class Cost_Payment {
// if you add a new Cost type add it here
return (payTap && payUntap && payMana && payXMana && paySubCounter && payAddCounter &&
paySac && payExile && payLife && payDiscard && payTapXType && payReturn &&
payExileFromHand && payExileFromGrave);
payExileFromHand && payExileFromGrave && payExileFromTop);
}
public void resetUndoList(){
@@ -478,6 +501,7 @@ public class Cost_Payment {
CardList exileCard = new CardList();
CardList exileFromHandCard = new CardList();
CardList exileFromGraveCard = new CardList();
CardList exileFromTopCard = new CardList();
CardList tapXCard = new CardList();
CardList returnCard = new CardList();
ability.setActivatingPlayer(AllZone.ComputerPlayer);
@@ -536,6 +560,18 @@ public class Cost_Payment {
}
}
if (cost.getExileFromTopCost()){
if (cost.getExileFromTopThis())
exileFromTopCard.add(card);
else
exileFromTopCard = ComputerUtil.chooseExileFromTopType(cost.getExileFromTopType(), card, ability.getTargetCard(), cost.getExileFromTopAmount());
if (exileFromTopCard.size() != cost.getExileFromTopAmount()){
System.out.println("Couldn't find a valid card to exile for: "+card.getName());
return;
}
}
if (cost.getReturnCost()){
if (cost.getReturnThis())
returnCard.add(card);
@@ -643,6 +679,11 @@ public class Cost_Payment {
AllZone.GameAction.exile(c);
}
if(cost.getExileFromTopCost()) {
for(Card c : exileFromTopCard)
AllZone.GameAction.exile(c);
}
if (cost.getReturnCost()){
for(Card c : returnCard)
AllZone.GameAction.moveToHand(c);
@@ -1022,6 +1063,33 @@ public class Cost_Payment {
return target;
}//input_exile()
public static Input exileFromTopThis(final SpellAbility spell, final Cost_Payment payment) {
Input target = new Input() {
private static final long serialVersionUID = 3416809678763443014L;
@Override
public void showMessage() {
Card card = spell.getSourceCard();
if(card.getController().equals(AllZone.HumanPlayer) && AllZoneUtil.isCardInPlayerHand(card.getController(), card)) {
//This can't really happen, but if for some reason it could....
if(AllZoneUtil.getPlayerCardsInLibrary(card.getController()).size() > 0) {
payment.setPayExileFromTop(true);
payment.getAbility().addExiledCost(card);
AllZone.GameAction.exile(card);
stop();
payment.payCost();
}
else{
payment.setCancel(true);
stop();
payment.payCost();
}
}
}
};
return target;
}//input_exile()
public static Input exileFromGraveThis(final SpellAbility spell, final Cost_Payment payment) {
Input target = new Input() {
private static final long serialVersionUID = 6237561876518762902L;
@@ -1229,6 +1297,53 @@ public class Cost_Payment {
return target;
}//exileFromGraveType()
public static Input exileFromTopType(final SpellAbility spell, final String type, final Cost_Payment payment){
Input target = new Input() {
private static final long serialVersionUID = -4764871768555887091L;
@Override
public void showMessage() {
//Card card = spell.getSourceCard();
CardList typeList;
int nNeeded = payment.getCost().getExileFromTopAmount();
PlayerZone lib = AllZone.getZone(Constant.Zone.Library, spell.getSourceCard().getController());
typeList = new CardList(lib.getCards());
typeList = typeList.getValidCards(type.split(";"), spell.getActivatingPlayer(), spell.getSourceCard());
for (int i=0; i < nNeeded; i++) {
if (typeList.size() == 0)
cancel();
if(lib.size() > 0) {
Card c = typeList.get(0);
typeList.remove(c);
payment.getAbility().addExiledCost(c);
AllZone.GameAction.exile(c);
if (i == nNeeded-1) done();
}
}
}
@Override
public void selectButtonCancel() {
cancel();
}
public void done(){
payment.setPayExileFromTop(true);
stop();
payment.payCost();
}
public void cancel(){
payment.setCancel(true);
stop();
payment.payCost();
}
};
return target;
}//exileFromTopType()
public static Input input_tapXCost(final int nCards, final String cardType, final CardList cardList, SpellAbility sa, final Cost_Payment payment) {
//final SpellAbility sp = sa;
Input target = new Input() {