mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +00:00
add ExileFromTop<1/Card> (for example) as a Cost.
add Royal Herbalist as an example.
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -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
|
||||
|
||||
9
res/cardsfolder/royal_herbalist.txt
Normal file
9
res/cardsfolder/royal_herbalist.txt
Normal 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
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user