mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
- 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:
@@ -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));
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user