- Added SubCounter<counterType/counterAmount> to Ability_Cost and appropriately pay for it in correct locations.

- Minor checks for Cost_Payment requirements
Note: SubCounter is not in any cards.txt yet, but has been tested with cards locally.
Ex. Triskelion's ability would be: abDamageTgtCP SubCounter<P1P1/1>:1
This commit is contained in:
jendave
2011-08-06 05:53:55 +00:00
parent dcdf12f4e2
commit 14697f5877
4 changed files with 159 additions and 43 deletions

View File

@@ -33,6 +33,16 @@ public class Ability_Cost {
// future expansion of Ability_Cost class: untap, and lifeCost // future expansion of Ability_Cost class: untap, and lifeCost
// private boolean untapCost = false; // private boolean untapCost = false;
private boolean subtractCounterCost = false;
public boolean getSubCounter() { return subtractCounterCost; }
private boolean addCounterCost = false;
public boolean getAddCounter() { return addCounterCost; }
private int counterAmount = 0;
public int getCounterNum() { return counterAmount; }
private Counters counterType;
public Counters getCounterType() { return counterType; }
private boolean lifeCost = false; private boolean lifeCost = false;
private int lifeAmount = 0; private int lifeAmount = 0;
@@ -73,6 +83,22 @@ public class Ability_Cost {
} }
} }
if(parse.contains("SubCounter<")) {
// SubCounter/<Counter Type>/counters removed
subtractCounterCost = true;
int counterPos = parse.indexOf("SubCounter<");
int endPos = parse.indexOf(">", counterPos);
String str = parse.substring(counterPos, endPos+1);
parse = parse.replace(str, "").trim();
str = str.replace("SubCounter<", "");
str = str.replace(">", "");
String[] strSplit = str.split("/");
// convert strSplit[0] to Counter.something
counterType = Counters.valueOf(strSplit[0]);
counterAmount = Integer.parseInt(strSplit[1]);
}
if(parse.contains("Sac-")) { if(parse.contains("Sac-")) {
sacCost = true; sacCost = true;
int sacPos = parse.indexOf("Sac-"); int sacPos = parse.indexOf("Sac-");
@@ -105,6 +131,25 @@ public class Ability_Cost {
cost.append("Tap"); cost.append("Tap");
else else
cost.append(", tap"); cost.append(", tap");
caps = false;
}
if (subtractCounterCost){
if (caps)
cost.append("Remove ");
else
cost.append(", remove ");
if (counterAmount != 1)
cost.append(counterAmount);
else
cost.append("a");
cost.append(" " + counterType.getName());
cost.append(" counter");
if (counterAmount != 1)
cost.append("s");
cost.append(" from CARDNAME");
caps = false;
} }
if (lifeCost){ if (lifeCost){
@@ -113,6 +158,8 @@ public class Ability_Cost {
else else
cost.append(", Pay"); cost.append(", Pay");
cost.append(lifeAmount); cost.append(lifeAmount);
caps = false;
} }
cost.append(sacString(caps)); cost.append(sacString(caps));

View File

@@ -1692,9 +1692,7 @@ public class CardFactory implements NewConstants {
public boolean canPlayAI() { public boolean canPlayAI() {
// temporarily disabled until AI is improved // temporarily disabled until AI is improved
if (abCost.getSacCost()) return false; if (abCost.getSacCost()) return false;
if (abCost.getSubCounter()) return false;
if (abCost.getTap() && (card.isTapped() || card.isSick()))
return false;
if (!ComputerUtil.canPayCost(this)) if (!ComputerUtil.canPayCost(this))
return false; return false;
@@ -1745,10 +1743,8 @@ public class CardFactory implements NewConstants {
@Override @Override
public boolean canPlay() { public boolean canPlay() {
if (abCost.getTap() && (card.isTapped() || card.isSick())) Cost_Payment pay = new Cost_Payment(abCost, this);
return false; return (pay.canPayAdditionalCosts() && CardFactoryUtil.canUseAbility(card) && super.canPlay());
return (CardFactoryUtil.canUseAbility(card) && super.canPlay());
} }
private CardList getCreatures() { private CardList getCreatures() {
@@ -2212,21 +2208,19 @@ public class CardFactory implements NewConstants {
@Override @Override
public boolean canPlay(){ public boolean canPlay(){
if (abCost.getTap() && (card.isTapped() || card.isSick())) Cost_Payment pay = new Cost_Payment(abCost, this);
return false; return (pay.canPayAdditionalCosts() && CardFactoryUtil.canUseAbility(card) && super.canPlay());
return (CardFactoryUtil.canUseAbility(card) && super.canPlay());
} }
@Override @Override
public boolean canPlayAI() { public boolean canPlayAI() {
// temporarily disable sac canPlay until better AI // temporarily disabled until better AI
//if (abCost.getSacCost()) return false; if (abCost.getSacCost()) return false;
if (abCost.getTap() && (card.isTapped() || card.isSick())) if (abCost.getSubCounter()) return false;
return false;
if (!ComputerUtil.canPayCost(this)) if (!ComputerUtil.canPayCost(this))
return false; return false;
damage = getNumDamage(); damage = getNumDamage();
Random r = new Random(); // prevent run-away activations Random r = new Random(); // prevent run-away activations

View File

@@ -216,28 +216,39 @@ public class ComputerUtil
static public boolean canPayAdditionalCosts(SpellAbility sa) static public boolean canPayAdditionalCosts(SpellAbility sa)
{ {
Ability_Cost cost = sa.getPayCosts(); // Add additional cost checks here before attempting to activate abilities
if (cost == null) Ability_Cost cost = sa.getPayCosts();
return true; if (cost == null)
return true;
Card card = sa.getSourceCard();
// check additional costs. if (cost.getTap() && (card.isTapped() || card.isSick()))
if (cost.getSacCost()){ return false;
// if there's a sacrifice in the cost, just because we can Pay it doesn't mean we want to.
if (!cost.getSacThis()){
String type = cost.getSacType();
PlayerZone play = AllZone.getZone(Constant.Zone.Play, Constant.Player.Computer);
CardList typeList = new CardList(play.getCards());
typeList = typeList.getType(type);
Card target = sa.getTargetCard();
if (target != null && target.getController().equals(Constant.Player.Computer)) // don't sacrifice the card we're pumping
typeList.remove(target);
return typeList.size() > 0;
}
else if (cost.getSacThis() && AllZone.GameAction.isCardInPlay(sa.getSourceCard()))
return false;
}
return true; if (cost.getSubCounter()){
Counters c = cost.getCounterType();
if (card.getCounters(c) - cost.getCounterNum() < 0 || !AllZone.GameAction.isCardInPlay(card)){
return false;
}
}
// check additional costs.
if (cost.getSacCost()){
// if there's a sacrifice in the cost, just because we can Pay it doesn't mean we want to.
if (!cost.getSacThis()){
String type = cost.getSacType();
PlayerZone play = AllZone.getZone(Constant.Zone.Play, Constant.Player.Computer);
CardList typeList = new CardList(play.getCards());
typeList = typeList.getType(type);
Card target = sa.getTargetCard();
if (target != null && target.getController().equals(Constant.Player.Computer)) // don't sacrifice the card we're pumping
typeList.remove(target);
return typeList.size() > 0;
}
else if (cost.getSacThis() && !AllZone.GameAction.isCardInPlay(card))
return false;
}
return true;
} }
static public boolean canPayCost(String cost) static public boolean canPayCost(String cost)

View File

@@ -12,6 +12,7 @@ public class Cost_Payment {
private boolean payTap = false; private boolean payTap = false;
private boolean payMana = false; private boolean payMana = false;
private boolean paySubCounter = false;
private boolean paySac = false; private boolean paySac = false;
private boolean bCancel = false; private boolean bCancel = false;
private boolean bCasting = false; private boolean bCasting = false;
@@ -30,9 +31,38 @@ public class Cost_Payment {
card = this.ability.getSourceCard(); card = this.ability.getSourceCard();
payTap = !cost.getTap(); payTap = !cost.getTap();
payMana = cost.hasNoManaCost(); payMana = cost.hasNoManaCost();
paySubCounter = !cost.getSubCounter();
paySac = !cost.getSacCost(); paySac = !cost.getSacCost();
} }
public boolean canPayAdditionalCosts(){
if (cost.getTap() && (card.isTapped() || card.isSick()))
return false;
int countersLeft = 0;
if (cost.getSubCounter()){
Counters c = cost.getCounterType();
countersLeft = card.getCounters(c) - cost.getCounterNum();
if (countersLeft < 0){
return false;
}
}
if (cost.getSacCost()){
if (!cost.getSacThis()){
PlayerZone play = AllZone.getZone(Constant.Zone.Play, card.getController());
CardList typeList = new CardList(play.getCards());
typeList = typeList.getType(cost.getSacType());
if (typeList.size() == 0)
return false;
}
else if (cost.getSacThis() && !AllZone.GameAction.isCardInPlay(card))
return false;
}
return true;
}
public boolean payCost(){ public boolean payCost(){
if (bCancel || bDoneTarget && cost.getNumTargeted() < cost.getMinTargets()){ if (bCancel || bDoneTarget && cost.getNumTargeted() < cost.getMinTargets()){
cancelPayment(); cancelPayment();
@@ -71,8 +101,22 @@ public class Cost_Payment {
if (!payMana && !cost.hasNoManaCost()){ if (!payMana && !cost.hasNoManaCost()){
// pay mana here // pay mana here
changeInput.stopSetNext(new Input_PayCostMana(this)); changeInput.stopSetNext(new Input_PayCostMana(this));
return false;
} }
else if (!paySac && cost.getSacCost()) if (!paySubCounter && cost.getSubCounter()){
// subtract counters here.
Counters c = cost.getCounterType();
int countersLeft = card.getCounters(c) - cost.getCounterNum();
if (countersLeft >= 0){
card.setCounter(c, countersLeft);
paySubCounter = true;
}
else{
cancelPayment();
return false;
}
}
if (!paySac && cost.getSacCost())
{ {
// sacrifice stuff here // sacrifice stuff here
if (cost.getSacThis()) if (cost.getSacThis())
@@ -82,11 +126,15 @@ public class Cost_Payment {
return false; return false;
} }
if (payTap && payMana && paySac) if (isAllPaid())
allPaid(); allPaid();
return true; return true;
} }
public boolean isAllPaid(){
return (payTap && payMana && paySubCounter && paySac);
}
public void allPaid(){ public void allPaid(){
AllZone.ManaPool.clearPay(false); AllZone.ManaPool.clearPay(false);
AllZone.Stack.add(ability); AllZone.Stack.add(ability);
@@ -106,6 +154,14 @@ public class Cost_Payment {
} }
// refund mana // refund mana
AllZone.ManaPool.unpaid(); AllZone.ManaPool.unpaid();
// refund counters
if (cost.getSubCounter() && paySubCounter){
Counters c = cost.getCounterType();
int countersLeft = card.getCounters(c) + cost.getCounterNum();
card.setCounter(c, countersLeft);
}
// can't really unsacrifice things // can't really unsacrifice things
} }
@@ -303,7 +359,7 @@ public class Cost_Payment {
if (cost.doesTarget()) if (cost.doesTarget())
ability.chooseTargetAI(); ability.chooseTargetAI();
// make sure something is there to be sacrificed before going through payments // double check if something can be sacrificed here. Real check is in ComputerUtil.canPayAdditionalCosts()
if (cost.getSacCost()){ if (cost.getSacCost()){
if (cost.getSacThis()) if (cost.getSacThis())
sacCard = card; sacCard = card;
@@ -315,18 +371,26 @@ public class Cost_Payment {
return; return;
} }
} }
// double check if counters available? Real check is in ComputerUtil.canPayAdditionalCosts()
int countersLeft = 0;
if (cost.getSubCounter()){
Counters c = cost.getCounterType();
countersLeft = card.getCounters(c) - cost.getCounterNum();
if (countersLeft < 0){
System.out.println("Not enough " + c.getName() + " on "+card.getName());
return;
}
}
if (cost.getTap()) if (cost.getTap())
card.tap(); card.tap();
if (!cost.hasNoManaCost()) if (!cost.hasNoManaCost())
ComputerUtil.payManaCost(ability); ComputerUtil.payManaCost(ability);
if (cost.getSubCounter())
card.setCounter(cost.getCounterType(), countersLeft);
if (cost.getSacCost()) if (cost.getSacCost())
AllZone.GameAction.sacrifice(sacCard); AllZone.GameAction.sacrifice(sacCard);
AllZone.Stack.add(ability); AllZone.Stack.add(ability);
} }
} }