mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 20:58:03 +00:00
* Costs: removed isUndoable, isReusable backing fields, appropiate values are returned by method overloads in classes
* Costs: joined all CostGainLife implementations. Syntax is: GainLife<LifeAmount/Player.Selector/[cntPlayers|*]> asterisk in last parameter means "all players". * Changed a lot of methods to pass GameState as a parameter rather than get it from Singletons.*
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -13447,7 +13447,6 @@ src/main/java/forge/card/cost/CostDamage.java -text
|
||||
src/main/java/forge/card/cost/CostDiscard.java -text
|
||||
src/main/java/forge/card/cost/CostExile.java -text
|
||||
src/main/java/forge/card/cost/CostGainLife.java -text
|
||||
src/main/java/forge/card/cost/CostGainLifeEachOther.java -text
|
||||
src/main/java/forge/card/cost/CostMana.java -text
|
||||
src/main/java/forge/card/cost/CostMill.java -text
|
||||
src/main/java/forge/card/cost/CostPart.java -text
|
||||
|
||||
@@ -55,6 +55,7 @@ import forge.card.staticability.StaticAbility;
|
||||
import forge.card.trigger.Trigger;
|
||||
import forge.card.trigger.TriggerType;
|
||||
import forge.card.trigger.ZCTrigger;
|
||||
import forge.game.GameState;
|
||||
import forge.game.GlobalRuleChange;
|
||||
import forge.game.event.CounterAddedEvent;
|
||||
import forge.game.event.CardEquippedEvent;
|
||||
@@ -1338,17 +1339,18 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
|
||||
private void playFromSuspend() {
|
||||
final Card c = this;
|
||||
final GameState game = Singletons.getModel().getGame();
|
||||
|
||||
c.setSuspendCast(true);
|
||||
// set activating player for base spell ability
|
||||
c.getSpellAbility()[0].setActivatingPlayer(c.getOwner());
|
||||
// Any trigger should cause the phase not to skip
|
||||
for (Player p : Singletons.getModel().getGame().getPlayers()) {
|
||||
for (Player p : game.getPlayers()) {
|
||||
p.getController().autoPassCancel();
|
||||
}
|
||||
|
||||
if (c.getOwner().isHuman()) {
|
||||
Singletons.getModel().getGame().getAction().playCardWithoutManaCost(c, c.getOwner());
|
||||
game.getAction().playCardWithoutManaCost(c, c.getOwner());
|
||||
} else {
|
||||
final List<SpellAbility> choices = this.getBasicSpells();
|
||||
|
||||
@@ -1364,7 +1366,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ComputerUtil.playSpellAbilityWithoutPayingManaCost(c.getOwner(), sa);
|
||||
ComputerUtil.playSpellAbilityWithoutPayingManaCost(c.getOwner(), sa, game);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -555,10 +555,10 @@ public class GameAction {
|
||||
Player p = recoverable.getController();
|
||||
if (p.isHuman()) {
|
||||
GameActionUtil.payCostDuringAbilityResolve(abRecover, abRecover.getPayCosts(),
|
||||
paidCommand, unpaidCommand, null);
|
||||
paidCommand, unpaidCommand, null, game);
|
||||
} else { // computer
|
||||
if (ComputerUtil.canPayCost(abRecover, p)) {
|
||||
ComputerUtil.playNoStack(p, abRecover);
|
||||
ComputerUtil.playNoStack(p, abRecover, game);
|
||||
} else {
|
||||
Singletons.getModel().getGame().getAction().exile(recoverable);
|
||||
}
|
||||
@@ -820,7 +820,7 @@ public class GameAction {
|
||||
Spell spell = (Spell) miracle;
|
||||
spell.setActivatingPlayer(card.getOwner());
|
||||
if (spell.canPlayFromEffectAI(false, false)) {
|
||||
ComputerUtil.playStack(miracle, card.getOwner());
|
||||
ComputerUtil.playStack(miracle, card.getOwner(), game);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -870,7 +870,7 @@ public class GameAction {
|
||||
} else {
|
||||
Spell spell = (Spell) madness;
|
||||
if (spell.canPlayFromEffectAI(false, false)) {
|
||||
ComputerUtil.playStack(madness, card.getOwner());
|
||||
ComputerUtil.playStack(madness, card.getOwner(), game);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1585,7 +1585,7 @@ public class GameAction {
|
||||
public final void playSpellAbilityForFree(final SpellAbility sa) {
|
||||
if (sa.getPayCosts() != null) {
|
||||
final TargetSelection ts = new TargetSelection(sa.getTarget(), sa);
|
||||
final CostPayment payment = new CostPayment(sa.getPayCosts(), sa);
|
||||
final CostPayment payment = new CostPayment(sa.getPayCosts(), sa, game);
|
||||
|
||||
final SpellAbilityRequirements req = new SpellAbilityRequirements(sa, ts, payment);
|
||||
req.setFree(true);
|
||||
@@ -1891,9 +1891,9 @@ public class GameAction {
|
||||
final TargetSelection ts = new TargetSelection(sa.getTarget(), sa);
|
||||
CostPayment payment = null;
|
||||
if (sa.getPayCosts() == null) {
|
||||
payment = new CostPayment(new Cost(sa.getSourceCard(), "0", sa.isAbility()), sa);
|
||||
payment = new CostPayment(new Cost(sa.getSourceCard(), "0", sa.isAbility()), sa, game);
|
||||
} else {
|
||||
payment = new CostPayment(sa.getPayCosts(), sa);
|
||||
payment = new CostPayment(sa.getPayCosts(), sa, game);
|
||||
}
|
||||
|
||||
final SpellAbilityRequirements req = new SpellAbilityRequirements(sa, ts, payment);
|
||||
@@ -1940,7 +1940,7 @@ public class GameAction {
|
||||
|
||||
if (sa.getPayCosts() != null) {
|
||||
final TargetSelection ts = new TargetSelection(sa.getTarget(), sa);
|
||||
final CostPayment payment = new CostPayment(sa.getPayCosts(), sa);
|
||||
final CostPayment payment = new CostPayment(sa.getPayCosts(), sa, game);
|
||||
|
||||
if (!sa.isTrigger()) {
|
||||
payment.changeCost();
|
||||
|
||||
@@ -53,6 +53,7 @@ import forge.control.input.Input;
|
||||
import forge.control.input.InputPayDiscardCost;
|
||||
import forge.control.input.InputPayManaCostAbility;
|
||||
import forge.control.input.InputPayReturnCost;
|
||||
import forge.game.GameState;
|
||||
import forge.game.event.CardDamagedEvent;
|
||||
import forge.game.event.FlipCoinEvent;
|
||||
import forge.game.event.LifeLossEvent;
|
||||
@@ -135,6 +136,7 @@ public final class GameActionUtil {
|
||||
final Ability ability = new Ability(c, SpellManaCost.ZERO) {
|
||||
@Override
|
||||
public void resolve() {
|
||||
final GameState game = Singletons.getModel().getGame();
|
||||
final List<Card> topOfLibrary = controller.getCardsIn(ZoneType.Library);
|
||||
final List<Card> revealed = new ArrayList<Card>();
|
||||
|
||||
@@ -173,7 +175,7 @@ public final class GameActionUtil {
|
||||
title.toString(), JOptionPane.YES_NO_OPTION);
|
||||
|
||||
if (answer == JOptionPane.YES_OPTION) {
|
||||
Singletons.getModel().getGame().getAction().playCardWithoutManaCost(cascadedCard, p);
|
||||
game.getAction().playCardWithoutManaCost(cascadedCard, p);
|
||||
revealed.remove(cascadedCard);
|
||||
}
|
||||
} else {
|
||||
@@ -192,7 +194,7 @@ public final class GameActionUtil {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ComputerUtil.playSpellAbilityWithoutPayingManaCost(p, sa);
|
||||
ComputerUtil.playSpellAbilityWithoutPayingManaCost(p, sa, game);
|
||||
revealed.remove(cascadedCard);
|
||||
break;
|
||||
}
|
||||
@@ -200,7 +202,7 @@ public final class GameActionUtil {
|
||||
}
|
||||
CardLists.shuffle(revealed);
|
||||
for (final Card bottom : revealed) {
|
||||
Singletons.getModel().getGame().getAction().moveToBottomOfLibrary(bottom);
|
||||
game.getAction().moveToBottomOfLibrary(bottom);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -258,6 +260,7 @@ public final class GameActionUtil {
|
||||
final Ability ability = new Ability(c, SpellManaCost.ZERO) {
|
||||
@Override
|
||||
public void resolve() {
|
||||
final GameState game = Singletons.getModel().getGame();
|
||||
final List<Card> topOfLibrary = controller.getCardsIn(ZoneType.Library);
|
||||
final List<Card> revealed = new ArrayList<Card>();
|
||||
int rippleNumber = rippleCount;
|
||||
@@ -293,7 +296,7 @@ public final class GameActionUtil {
|
||||
JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null,
|
||||
possibleValues, possibleValues[0]);
|
||||
if (q.equals(0)) {
|
||||
Singletons.getModel().getGame().getAction().playCardWithoutManaCost(rippledCards[i], p);
|
||||
game.getAction().playCardWithoutManaCost(rippledCards[i], p);
|
||||
revealed.remove(rippledCards[i]);
|
||||
}
|
||||
} else {
|
||||
@@ -311,7 +314,7 @@ public final class GameActionUtil {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ComputerUtil.playSpellAbilityWithoutPayingManaCost(p, sa);
|
||||
ComputerUtil.playSpellAbilityWithoutPayingManaCost(p, sa, game);
|
||||
revealed.remove(rippledCards[i]);
|
||||
break;
|
||||
}
|
||||
@@ -378,7 +381,7 @@ public final class GameActionUtil {
|
||||
* @param sourceAbility TODO
|
||||
*/
|
||||
public static void payCostDuringAbilityResolve(final SpellAbility ability, final Cost cost, final Command paid,
|
||||
final Command unpaid, SpellAbility sourceAbility) {
|
||||
final Command unpaid, SpellAbility sourceAbility, final GameState game) {
|
||||
final Card source = ability.getSourceCard();
|
||||
final List<CostPart> parts = cost.getCostParts();
|
||||
Player p = Singletons.getControl().getPlayer();
|
||||
@@ -458,7 +461,7 @@ public final class GameActionUtil {
|
||||
int amount = amountString.matches("[0-9][0-9]?") ? Integer.parseInt(amountString)
|
||||
: CardFactoryUtil.xCount(source, source.getSVar(amountString));
|
||||
String plural = amount > 1 ? "s" : "";
|
||||
if (part.canPay(sourceAbility, source, p, cost)
|
||||
if (part.canPay(sourceAbility, source, p, cost, game)
|
||||
&& showYesNoDialog(source, "Do you want to remove " + amount + " " + counterType.getName()
|
||||
+ " counter" + plural + " from " + source + "?")) {
|
||||
source.subtractCounter(counterType, amount);
|
||||
|
||||
@@ -1584,18 +1584,18 @@ public class AbilityFactory {
|
||||
* @param usedStack
|
||||
* a boolean.
|
||||
*/
|
||||
public static void passUnlessCost(final SpellAbility sa, final boolean usedStack) {
|
||||
public static void passUnlessCost(final SpellAbility sa, final boolean usedStack, final GameState game) {
|
||||
final Card source = sa.getSourceCard();
|
||||
final ApiType api = sa.getApi();
|
||||
if (api == null) {
|
||||
sa.resolve();
|
||||
AbilityFactory.resolveSubAbilities(sa, usedStack);
|
||||
AbilityFactory.resolveSubAbilities(sa, usedStack, game);
|
||||
return;
|
||||
}
|
||||
// Nothing to do
|
||||
if (sa.getParam("UnlessCost") == null) {
|
||||
sa.resolve();
|
||||
AbilityFactory.resolveSubAbilities(sa, usedStack);
|
||||
AbilityFactory.resolveSubAbilities(sa, usedStack, game);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1632,7 +1632,7 @@ public class AbilityFactory {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
AbilityFactory.resolveSubAbilities(sa, usedStack);
|
||||
AbilityFactory.resolveSubAbilities(sa, usedStack, game);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1645,7 +1645,7 @@ public class AbilityFactory {
|
||||
if (sa.hasParam("PowerSink")) {
|
||||
GameActionUtil.doPowerSink(sa.getActivatingPlayer());
|
||||
}
|
||||
AbilityFactory.resolveSubAbilities(sa, usedStack);
|
||||
AbilityFactory.resolveSubAbilities(sa, usedStack, game);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1682,7 +1682,7 @@ public class AbilityFactory {
|
||||
// Didn't have any of the data on the original SA to pay dependant costs
|
||||
ability.setActivatingPlayer(payer);
|
||||
ability.setTarget(sa.getTarget());
|
||||
ComputerUtil.playNoStack(payer, ability); // Unless cost was payed - no resolve
|
||||
ComputerUtil.playNoStack(payer, ability, game); // Unless cost was payed - no resolve
|
||||
paid = true;
|
||||
}
|
||||
}
|
||||
@@ -1694,20 +1694,20 @@ public class AbilityFactory {
|
||||
if (paid) {
|
||||
unpaidCommand = paidCommand;
|
||||
}
|
||||
GameActionUtil.payCostDuringAbilityResolve(ability, cost, paidCommand, unpaidCommand, sa);
|
||||
GameActionUtil.payCostDuringAbilityResolve(ability, cost, paidCommand, unpaidCommand, sa, game);
|
||||
waitForInput = true; // wait for the human input
|
||||
break; // multiple human players are not supported
|
||||
}
|
||||
}
|
||||
if (!waitForInput) {
|
||||
if (paid) {
|
||||
AbilityFactory.resolveSubAbilities(sa, usedStack);
|
||||
AbilityFactory.resolveSubAbilities(sa, usedStack, game);
|
||||
} else {
|
||||
sa.resolve();
|
||||
if (sa.hasParam("PowerSink")) {
|
||||
GameActionUtil.doPowerSink(payers.get(0));
|
||||
}
|
||||
AbilityFactory.resolveSubAbilities(sa, usedStack);
|
||||
AbilityFactory.resolveSubAbilities(sa, usedStack, game);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1736,16 +1736,17 @@ public class AbilityFactory {
|
||||
return;
|
||||
}
|
||||
|
||||
final GameState game = Singletons.getModel().getGame();
|
||||
// check conditions
|
||||
if (AbilityFactory.checkConditional(sa)) {
|
||||
if (sa.isWrapper()) {
|
||||
sa.resolve();
|
||||
AbilityFactory.resolveSubAbilities(sa, usedStack);
|
||||
AbilityFactory.resolveSubAbilities(sa, usedStack, game);
|
||||
} else {
|
||||
AbilityFactory.passUnlessCost(sa, usedStack);
|
||||
AbilityFactory.passUnlessCost(sa, usedStack, game);
|
||||
}
|
||||
} else {
|
||||
AbilityFactory.resolveSubAbilities(sa, usedStack);
|
||||
AbilityFactory.resolveSubAbilities(sa, usedStack, game);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1758,7 +1759,7 @@ public class AbilityFactory {
|
||||
* a {@link forge.card.spellability.SpellAbility} object.
|
||||
* @since 1.0.15
|
||||
*/
|
||||
public static void resolveSubAbilities(final SpellAbility sa, boolean usedStack) {
|
||||
public static void resolveSubAbilities(final SpellAbility sa, boolean usedStack, final GameState game) {
|
||||
final AbilitySub abSub = sa.getSubAbility();
|
||||
if (abSub == null || sa.isWrapper()) {
|
||||
// every resolving spellAbility will end here
|
||||
@@ -1770,9 +1771,9 @@ public class AbilityFactory {
|
||||
}
|
||||
// check conditions
|
||||
if (AbilityFactory.checkConditional(abSub)) {
|
||||
AbilityFactory.passUnlessCost(abSub, usedStack);
|
||||
AbilityFactory.passUnlessCost(abSub, usedStack, game);
|
||||
} else {
|
||||
AbilityFactory.resolveSubAbilities(abSub, usedStack);
|
||||
AbilityFactory.resolveSubAbilities(abSub, usedStack, game);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ public class ChangeZoneAi extends SpellAiLogic {
|
||||
if (part instanceof CostDiscard) {
|
||||
CostDiscard cd = (CostDiscard) part;
|
||||
// this is mainly for typecycling
|
||||
if (!cd.getThis() || !ComputerUtil.isWorseThanDraw(ai, source)) {
|
||||
if (!cd.isTargetingThis() || !ComputerUtil.isWorseThanDraw(ai, source)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ public class DestroyAi extends SpellAiLogic {
|
||||
continue;
|
||||
}
|
||||
CostSacrifice sacCost = (CostSacrifice) part;
|
||||
if (sacCost.getThis() && ComputerUtil.canPayCost(ability, c.getController())) {
|
||||
if (sacCost.isTargetingThis() && ComputerUtil.canPayCost(ability, c.getController())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import forge.card.cost.CostPart;
|
||||
import forge.card.spellability.Spell;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.SpellAbilityRestriction;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.ComputerUtil;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -50,6 +51,7 @@ public class PlayEffect extends SpellEffect {
|
||||
|
||||
@Override
|
||||
public void resolve(SpellAbility sa) {
|
||||
final GameState game = Singletons.getModel().getGame();
|
||||
final Card source = sa.getSourceCard();
|
||||
Player activator = sa.getActivatingPlayer();
|
||||
boolean optional = sa.hasParam("Optional");
|
||||
@@ -73,7 +75,7 @@ public class PlayEffect extends SpellEffect {
|
||||
if (sa.hasParam("ValidZone")) {
|
||||
zone = ZoneType.smartValueOf(sa.getParam("ValidZone"));
|
||||
}
|
||||
tgtCards = Singletons.getModel().getGame().getCardsIn(zone);
|
||||
tgtCards = game.getCardsIn(zone);
|
||||
tgtCards = AbilityFactory.filterListByType(tgtCards, sa.getParam("Valid"), sa);
|
||||
}
|
||||
else if (sa.hasParam("Encoded")) {
|
||||
@@ -217,7 +219,7 @@ public class PlayEffect extends SpellEffect {
|
||||
newSA.setPayCosts(cost);
|
||||
newSA.setManaCost(SpellManaCost.NO_COST);
|
||||
newSA.setDescription(newSA.getDescription() + " (without paying its mana cost)");
|
||||
Singletons.getModel().getGame().getAction().playSpellAbility(newSA, activator);
|
||||
game.getAction().playSpellAbility(newSA, activator);
|
||||
if (remember) {
|
||||
source.addRemembered(tgtSA.getSourceCard());
|
||||
}
|
||||
@@ -225,7 +227,7 @@ public class PlayEffect extends SpellEffect {
|
||||
if (tgtSA instanceof Spell) {
|
||||
Spell spell = (Spell) tgtSA;
|
||||
if (spell.canPlayFromEffectAI(!optional, true) || !optional) {
|
||||
ComputerUtil.playSpellAbilityWithoutPayingManaCost(controller, tgtSA);
|
||||
ComputerUtil.playSpellAbilityWithoutPayingManaCost(controller, tgtSA, game);
|
||||
if (remember) {
|
||||
source.addRemembered(tgtSA.getSourceCard());
|
||||
}
|
||||
@@ -234,7 +236,7 @@ public class PlayEffect extends SpellEffect {
|
||||
}
|
||||
} else {
|
||||
if (controller.isHuman()) {
|
||||
Singletons.getModel().getGame().getAction().playSpellAbility(tgtSA, activator);
|
||||
game.getAction().playSpellAbility(tgtSA, activator);
|
||||
if (remember) {
|
||||
source.addRemembered(tgtSA.getSourceCard());
|
||||
}
|
||||
@@ -242,7 +244,7 @@ public class PlayEffect extends SpellEffect {
|
||||
if (tgtSA instanceof Spell) {
|
||||
Spell spell = (Spell) tgtSA;
|
||||
if (spell.canPlayFromEffectAI(!optional, false) || !optional) {
|
||||
ComputerUtil.playStack(tgtSA, controller);
|
||||
ComputerUtil.playStack(tgtSA, controller, game);
|
||||
if (remember) {
|
||||
source.addRemembered(tgtSA.getSourceCard());
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@ import forge.card.trigger.TriggerHandler;
|
||||
import forge.card.trigger.TriggerType;
|
||||
import forge.control.input.Input;
|
||||
import forge.control.input.InputPayManaCostUtil;
|
||||
import forge.game.GameState;
|
||||
import forge.game.event.TokenCreatedEvent;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
import forge.game.phase.PhaseType;
|
||||
@@ -4168,6 +4169,7 @@ public class CardFactoryUtil {
|
||||
|
||||
@Override
|
||||
public void resolve() {
|
||||
final GameState game = Singletons.getModel().getGame();
|
||||
|
||||
String name = card.toString() + " Epic";
|
||||
if (card.getController().getCardsIn(ZoneType.Battlefield, name).isEmpty()) {
|
||||
@@ -4196,15 +4198,15 @@ public class CardFactoryUtil {
|
||||
|
||||
eff.addTrigger(copyTrigger);
|
||||
|
||||
Singletons.getModel().getGame().getTriggerHandler().suppressMode(TriggerType.ChangesZone);
|
||||
Singletons.getModel().getGame().getAction().moveToPlay(eff);
|
||||
Singletons.getModel().getGame().getTriggerHandler().clearSuppression(TriggerType.ChangesZone);
|
||||
game.getTriggerHandler().suppressMode(TriggerType.ChangesZone);
|
||||
game.getAction().moveToPlay(eff);
|
||||
game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone);
|
||||
}
|
||||
|
||||
if (card.getController().isHuman()) {
|
||||
Singletons.getModel().getGame().getAction().playSpellAbilityNoStack(origSA, false);
|
||||
game.getAction().playSpellAbilityNoStack(origSA, false);
|
||||
} else {
|
||||
ComputerUtil.playNoStack(card.getController(), origSA);
|
||||
ComputerUtil.playNoStack(card.getController(), origSA, game);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -212,9 +212,9 @@ public class Cost {
|
||||
if(parse.startsWith("AddCounter<")) {
|
||||
// AddCounter<NumCounters/CounterType>
|
||||
final String[] splitStr = abCostParse(parse, 4);
|
||||
final String type = splitStr.length > 2 ? splitStr[2] : "CARDNAME";
|
||||
final String target = splitStr.length > 2 ? splitStr[2] : "CARDNAME";
|
||||
final String description = splitStr.length > 3 ? splitStr[3] : null;
|
||||
return new CostPutCounter(splitStr[0], CounterType.valueOf(splitStr[1]), type, description);
|
||||
return new CostPutCounter(splitStr[0], CounterType.valueOf(splitStr[1]), target, description);
|
||||
}
|
||||
|
||||
// While no card has "PayLife<2> PayLife<3> there might be a card that
|
||||
@@ -225,16 +225,11 @@ public class Cost {
|
||||
return new CostPayLife(splitStr[0]);
|
||||
}
|
||||
|
||||
if(parse.startsWith("OppGainLife<")) {
|
||||
if(parse.startsWith("GainLife<")) {
|
||||
// PayLife<LifeCost>
|
||||
final String[] splitStr = abCostParse(parse, 1);
|
||||
return new CostGainLife(splitStr[0]);
|
||||
}
|
||||
|
||||
if(parse.startsWith("OthersEachGainLife<")) {
|
||||
// PayLife<LifeCost>
|
||||
final String[] splitStr = abCostParse(parse, 1);
|
||||
return new CostGainLifeEachOther(splitStr[0]);
|
||||
final String[] splitStr = abCostParse(parse, 3);
|
||||
int cnt = splitStr.length > 2 ? "*".equals(splitStr[2]) ? Integer.MAX_VALUE : Integer.parseInt(splitStr[2]) : 1;
|
||||
return new CostGainLife(splitStr[0], splitStr[1], cnt);
|
||||
}
|
||||
|
||||
if(parse.startsWith("DamageYou<")) {
|
||||
|
||||
@@ -21,6 +21,7 @@ import forge.Card;
|
||||
import forge.GameActionUtil;
|
||||
import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.Player;
|
||||
|
||||
/**
|
||||
@@ -70,16 +71,6 @@ public class CostDamage extends CostPart {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.card.cost.CostPart#refund(forge.Card)
|
||||
*/
|
||||
@Override
|
||||
public final void refund(final Card source) {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@@ -88,7 +79,7 @@ public class CostDamage extends CostPart {
|
||||
* forge.Card, forge.Player, forge.card.cost.Cost)
|
||||
*/
|
||||
@Override
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost) {
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost, final GameState game) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -99,7 +90,7 @@ public class CostDamage extends CostPart {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
ability.getActivatingPlayer().addDamage(this.getLastPaidAmount(), source);
|
||||
}
|
||||
|
||||
@@ -111,7 +102,7 @@ public class CostDamage extends CostPart {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
final String amount = this.getAmount();
|
||||
final Player activator = ability.getActivatingPlayer();
|
||||
final int life = activator.getLife();
|
||||
|
||||
@@ -30,6 +30,7 @@ import forge.CardLists;
|
||||
import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.control.input.Input;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.ComputerUtil;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.Zone;
|
||||
@@ -69,7 +70,7 @@ public class CostDiscard extends CostPartWithList {
|
||||
|
||||
final Integer i = this.convertAmount();
|
||||
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
sb.append(this.getType());
|
||||
} else if (this.getType().equals("Hand")) {
|
||||
sb.append("your hand");
|
||||
@@ -95,17 +96,6 @@ public class CostDiscard extends CostPartWithList {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.card.cost.CostPart#refund(forge.Card)
|
||||
*/
|
||||
@Override
|
||||
public void refund(final Card source) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@@ -114,12 +104,12 @@ public class CostDiscard extends CostPartWithList {
|
||||
* forge.Card, forge.Player, forge.card.cost.Cost)
|
||||
*/
|
||||
@Override
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost) {
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost, final GameState game) {
|
||||
List<Card> handList = new ArrayList<Card>(activator.getCardsIn(ZoneType.Hand));
|
||||
String type = this.getType();
|
||||
final Integer amount = this.convertAmount();
|
||||
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
if (!source.isInZone(ZoneType.Hand)) {
|
||||
return false;
|
||||
}
|
||||
@@ -164,7 +154,7 @@ public class CostDiscard extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
for (final Card c : this.getList()) {
|
||||
ai.discard(c, ability);
|
||||
}
|
||||
@@ -178,14 +168,14 @@ public class CostDiscard extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
final Player activator = ability.getActivatingPlayer();
|
||||
List<Card> handList = new ArrayList<Card>(activator.getCardsIn(ZoneType.Hand));
|
||||
String discType = this.getType();
|
||||
final String amount = this.getAmount();
|
||||
this.resetList();
|
||||
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
if (!handList.contains(source)) {
|
||||
return false;
|
||||
}
|
||||
@@ -283,7 +273,7 @@ public class CostDiscard extends CostPartWithList {
|
||||
this.addToList(ai.getLastDrawnCard());
|
||||
}
|
||||
|
||||
else if (this.getThis()) {
|
||||
else if (this.isTargetingThis()) {
|
||||
if (!hand.contains(source)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ public class CostExile extends CostPartWithList {
|
||||
final Integer i = this.convertAmount();
|
||||
sb.append("Exile ");
|
||||
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
sb.append(this.getType());
|
||||
if (!this.from.equals(ZoneType.Battlefield)) {
|
||||
sb.append(" from your ").append(this.from);
|
||||
@@ -113,7 +113,7 @@ public class CostExile extends CostPartWithList {
|
||||
final String desc = this.getTypeDescription() == null ? this.getType() : this.getTypeDescription();
|
||||
|
||||
sb.append(Cost.convertAmountTypeToWords(i, this.getAmount(), desc));
|
||||
if (!this.getThis()) {
|
||||
if (!this.isTargetingThis()) {
|
||||
sb.append(" you control");
|
||||
}
|
||||
return sb.toString();
|
||||
@@ -143,17 +143,6 @@ public class CostExile extends CostPartWithList {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.card.cost.CostPart#refund(forge.Card)
|
||||
*/
|
||||
@Override
|
||||
public void refund(final Card source) {
|
||||
// TODO Currently there's no way to refund an exiled cost
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@@ -162,9 +151,8 @@ public class CostExile extends CostPartWithList {
|
||||
* forge.Card, forge.Player, forge.card.cost.Cost)
|
||||
*/
|
||||
@Override
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost) {
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost, final GameState game) {
|
||||
List<Card> typeList = new ArrayList<Card>();
|
||||
final GameState game = Singletons.getModel().getGame();
|
||||
if (this.getType().equals("All")) {
|
||||
return true; // this will always work
|
||||
}
|
||||
@@ -179,7 +167,7 @@ public class CostExile extends CostPartWithList {
|
||||
typeList = new ArrayList<Card>(activator.getCardsIn(this.getFrom()));
|
||||
}
|
||||
}
|
||||
if (!this.getThis()) {
|
||||
if (!this.isTargetingThis()) {
|
||||
typeList = CardLists.getValidCards(typeList, this.getType().split(";"), activator, source);
|
||||
|
||||
final Integer amount = this.convertAmount();
|
||||
@@ -214,7 +202,7 @@ public class CostExile extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
for (final Card c : this.getList()) {
|
||||
Singletons.getModel().getGame().getAction().exile(c);
|
||||
if (this.from.equals(ZoneType.Stack)) {
|
||||
@@ -237,10 +225,9 @@ public class CostExile extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
final String amount = this.getAmount();
|
||||
Integer c = this.convertAmount();
|
||||
final GameState game = Singletons.getModel().getGame();
|
||||
final Player activator = ability.getActivatingPlayer();
|
||||
List<Card> list;
|
||||
|
||||
@@ -269,7 +256,7 @@ public class CostExile extends CostPartWithList {
|
||||
c = AbilityFactory.calculateAmount(source, amount, ability);
|
||||
}
|
||||
}
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
final Input inp = CostExile.exileThis(ability, payment, this);
|
||||
Singletons.getModel().getMatch().getInput().setInputInterrupt(inp);
|
||||
} else if (this.from.equals(ZoneType.Battlefield) || this.from.equals(ZoneType.Hand)) {
|
||||
@@ -311,7 +298,7 @@ public class CostExile extends CostPartWithList {
|
||||
@Override
|
||||
public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
this.resetList();
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
this.getList().add(source);
|
||||
} else if (this.getType().equals("All")) {
|
||||
this.setList(new ArrayList<Card>(ability.getActivatingPlayer().getCardsIn(this.getFrom())));
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.List;
|
||||
import forge.Card;
|
||||
import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.Player;
|
||||
import forge.gui.GuiChoose;
|
||||
|
||||
@@ -30,6 +31,7 @@ import forge.gui.GuiChoose;
|
||||
* The Class CostGainLife.
|
||||
*/
|
||||
public class CostGainLife extends CostPart {
|
||||
private final int cntPlayers; // MAX_VALUE means ALL/EACH PLAYERS
|
||||
private int lastPaidAmount = 0;
|
||||
|
||||
/**
|
||||
@@ -57,8 +59,9 @@ public class CostGainLife extends CostPart {
|
||||
* @param amount
|
||||
* the amount
|
||||
*/
|
||||
public CostGainLife(final String amount) {
|
||||
this.setAmount(amount);
|
||||
public CostGainLife(final String amount, String playerSelector, int qty) {
|
||||
super(amount, playerSelector, null);
|
||||
cntPlayers = qty;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -73,14 +76,15 @@ public class CostGainLife extends CostPart {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.card.cost.CostPart#refund(forge.Card)
|
||||
*/
|
||||
@Override
|
||||
public void refund(final Card source) {
|
||||
|
||||
private List<Player> getPotentialTargets(final GameState game, final Player payer, final Card source)
|
||||
{
|
||||
List<Player> res = new ArrayList<Player>();
|
||||
for(Player p : game.getPlayers())
|
||||
{
|
||||
if(p.isValid(getType(), payer, source))
|
||||
res.add(p);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -91,19 +95,20 @@ public class CostGainLife extends CostPart {
|
||||
* forge.Card, forge.Player, forge.card.cost.Cost)
|
||||
*/
|
||||
@Override
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost) {
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost, final GameState game) {
|
||||
final Integer amount = this.convertAmount();
|
||||
boolean oppCanGainLife = false;
|
||||
if (amount != null) {
|
||||
for (final Player opp : activator.getOpponents()) {
|
||||
if ( amount == null ) return false;
|
||||
|
||||
int cntAbleToGainLife = 0;
|
||||
List<Player> possibleTargets = getPotentialTargets(game, activator, source);
|
||||
|
||||
for (final Player opp : possibleTargets) {
|
||||
if (opp.canGainLife()) {
|
||||
oppCanGainLife = true;
|
||||
break;
|
||||
}
|
||||
cntAbleToGainLife++;
|
||||
}
|
||||
}
|
||||
|
||||
return oppCanGainLife;
|
||||
return cntPlayers < Integer.MAX_VALUE ? cntAbleToGainLife >= cntPlayers : cntAbleToGainLife == possibleTargets.size();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -113,14 +118,14 @@ public class CostGainLife extends CostPart {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
final List<Player> oppsThatCanGainLife = new ArrayList<Player>();
|
||||
for (final Player opp : ai.getOpponents()) {
|
||||
if (opp.canGainLife()) {
|
||||
oppsThatCanGainLife.add(opp);
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
int playersLeft = cntPlayers;
|
||||
for (final Player opp : getPotentialTargets(game, ai, source)) {
|
||||
if (opp.canGainLife() && playersLeft > 0) {
|
||||
playersLeft--;
|
||||
opp.gainLife(this.getLastPaidAmount(), null);
|
||||
}
|
||||
}
|
||||
oppsThatCanGainLife.get(0).gainLife(this.getLastPaidAmount(), null);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -131,7 +136,7 @@ public class CostGainLife extends CostPart {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
final String amount = this.getAmount();
|
||||
final Player activator = ability.getActivatingPlayer();
|
||||
final int life = activator.getLife();
|
||||
@@ -148,15 +153,24 @@ public class CostGainLife extends CostPart {
|
||||
}
|
||||
|
||||
final List<Player> oppsThatCanGainLife = new ArrayList<Player>();
|
||||
for (final Player opp : activator.getOpponents()) {
|
||||
for (final Player opp : getPotentialTargets(game, activator, source)) {
|
||||
if (opp.canGainLife()) {
|
||||
oppsThatCanGainLife.add(opp);
|
||||
}
|
||||
}
|
||||
|
||||
if(cntPlayers == Integer.MAX_VALUE) { // applied to all players who can gain
|
||||
for(Player opp: oppsThatCanGainLife)
|
||||
opp.gainLife(c, null);
|
||||
payment.setPaidManaPart(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(source.getName()).append(" - Choose an opponent to gain ").append(c).append(" life:");
|
||||
|
||||
|
||||
for(int playersLeft = cntPlayers; playersLeft > 0; playersLeft--) {
|
||||
final Player chosenToGain = GuiChoose.oneOrNone(sb.toString(), oppsThatCanGainLife);
|
||||
if (null == chosenToGain) {
|
||||
payment.setCancel(true);
|
||||
@@ -165,9 +179,10 @@ public class CostGainLife extends CostPart {
|
||||
} else {
|
||||
final Player chosen = chosenToGain;
|
||||
chosen.gainLife(c, null);
|
||||
this.setLastPaidAmount(c);
|
||||
payment.setPaidManaPart(this);
|
||||
}
|
||||
}
|
||||
|
||||
payment.setPaidManaPart(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,197 +0,0 @@
|
||||
/*
|
||||
* 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 forge.Card;
|
||||
import forge.GameActionUtil;
|
||||
import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.player.Player;
|
||||
|
||||
/**
|
||||
* The Class CostGainLife.
|
||||
*/
|
||||
public class CostGainLifeEachOther extends CostPart {
|
||||
private int lastPaidAmount = 0;
|
||||
|
||||
/**
|
||||
* Gets the last paid amount.
|
||||
*
|
||||
* @return the last paid amount
|
||||
*/
|
||||
public final int getLastPaidAmount() {
|
||||
return this.lastPaidAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the last paid amount.
|
||||
*
|
||||
* @param paidAmount
|
||||
* the new last paid amount
|
||||
*/
|
||||
public final void setLastPaidAmount(final int paidAmount) {
|
||||
this.lastPaidAmount = paidAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new cost gain life.
|
||||
*
|
||||
* @param amount
|
||||
* the amount
|
||||
*/
|
||||
public CostGainLifeEachOther(final String amount) {
|
||||
this.setAmount(amount);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.card.cost.CostPart#toString()
|
||||
*/
|
||||
@Override
|
||||
public final String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("Have each other player gain ").append(this.getAmount()).append(" life");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.card.cost.CostPart#refund(forge.Card)
|
||||
*/
|
||||
@Override
|
||||
public void refund(final Card source) {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (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 Card source, final Player activator, final Cost cost) {
|
||||
final Integer amount = this.convertAmount();
|
||||
if (amount != null) {
|
||||
for (final Player otherP : activator.getAllOtherPlayers()) {
|
||||
if (!otherP.canGainLife()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.card.cost.CostPart#payAI(forge.card.spellability.SpellAbility,
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
for (final Player otherP : ai.getAllOtherPlayers()) {
|
||||
otherP.gainLife(this.getLastPaidAmount(), null);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (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 Card source, final CostPayment payment) {
|
||||
final String amount = this.getAmount();
|
||||
final Player activator = ability.getActivatingPlayer();
|
||||
final int life = activator.getLife();
|
||||
|
||||
Integer c = this.convertAmount();
|
||||
if (c == null) {
|
||||
final String sVar = ability.getSVar(amount);
|
||||
// Generalize this
|
||||
if (sVar.equals("XChoice")) {
|
||||
c = CostUtil.chooseXValue(source, ability, life);
|
||||
} else {
|
||||
c = AbilityFactory.calculateAmount(source, amount, ability);
|
||||
}
|
||||
}
|
||||
|
||||
for (final Player other : activator.getAllOtherPlayers()) {
|
||||
// each other player MUST be able to gain life
|
||||
if (!other.canGainLife()) {
|
||||
payment.setCancel(true);
|
||||
payment.getRequirements().finishPaying();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(source.getName()).append(" - Have each other player gain ").append(c).append(" life?");
|
||||
|
||||
if (GameActionUtil.showYesNoDialog(source, sb.toString())) {
|
||||
for (final Player playerToGain : activator.getAllOtherPlayers()) {
|
||||
playerToGain.gainLife(c, null);
|
||||
this.setLastPaidAmount(c);
|
||||
payment.setPaidManaPart(this);
|
||||
}
|
||||
} else {
|
||||
payment.setCancel(true);
|
||||
payment.getRequirements().finishPaying();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* forge.card.cost.CostPart#decideAIPayment(forge.card.spellability.SpellAbility
|
||||
* , forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
|
||||
|
||||
Integer c = this.convertAmount();
|
||||
if (c == null) {
|
||||
final String sVar = ability.getSVar(this.getAmount());
|
||||
// Generalize this
|
||||
if (sVar.equals("XChoice")) {
|
||||
return false;
|
||||
} else {
|
||||
c = AbilityFactory.calculateAmount(source, this.getAmount(), ability);
|
||||
}
|
||||
}
|
||||
|
||||
for (final Player otherP : ai.getAllOtherPlayers()) {
|
||||
if (!otherP.canGainLife()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this.setLastPaidAmount(c);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import forge.card.spellability.SpellAbility;
|
||||
import forge.control.input.Input;
|
||||
import forge.control.input.InputPayManaCost2;
|
||||
import forge.control.input.InputPayManaX;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.ComputerUtil;
|
||||
import forge.game.player.Player;
|
||||
|
||||
@@ -134,6 +135,12 @@ public class CostMana extends CostPart {
|
||||
return this.mana;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReusable() { return true; }
|
||||
|
||||
@Override
|
||||
public boolean isUndoable() { return true; }
|
||||
|
||||
/**
|
||||
* Instantiates a new cost mana.
|
||||
*
|
||||
@@ -146,8 +153,6 @@ public class CostMana extends CostPart {
|
||||
public CostMana(final String mana, final int amount, boolean xCantBe0) {
|
||||
this.mana = mana.trim();
|
||||
this.amountX = amount;
|
||||
this.setUndoable(true);
|
||||
this.setReusable(true);
|
||||
this.setxCantBe0(xCantBe0);
|
||||
}
|
||||
|
||||
@@ -167,17 +172,6 @@ public class CostMana extends CostPart {
|
||||
return sb.toString().trim();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.card.cost.CostPart#refund(forge.Card)
|
||||
*/
|
||||
@Override
|
||||
public void refund(final Card source) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@@ -186,7 +180,7 @@ public class CostMana extends CostPart {
|
||||
* forge.Card, forge.Player, forge.card.cost.Cost)
|
||||
*/
|
||||
@Override
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost) {
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost, final GameState game) {
|
||||
// For now, this will always return true. But this should probably be
|
||||
// checked at some point
|
||||
return true;
|
||||
@@ -199,7 +193,7 @@ public class CostMana extends CostPart {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
ComputerUtil.payManaCost(ai, ability);
|
||||
}
|
||||
|
||||
@@ -211,7 +205,7 @@ public class CostMana extends CostPart {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
int manaToAdd = 0;
|
||||
if (!this.hasNoXManaCost()) {
|
||||
// if X cost is a defined value, other than xPaid
|
||||
|
||||
@@ -27,6 +27,7 @@ import forge.GameActionUtil;
|
||||
import forge.Singletons;
|
||||
import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.PlayerZone;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -56,7 +57,7 @@ public class CostMill extends CostPartWithList {
|
||||
* forge.Card, forge.Player, forge.card.cost.Cost)
|
||||
*/
|
||||
@Override
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost) {
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost, final GameState game) {
|
||||
final PlayerZone zone = activator.getZone(ZoneType.Library);
|
||||
|
||||
Integer i = this.convertAmount();
|
||||
@@ -111,7 +112,7 @@ public class CostMill extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
for (final Card c : this.getList()) {
|
||||
Singletons.getModel().getGame().getAction().moveToGraveyard(c);
|
||||
}
|
||||
@@ -125,7 +126,7 @@ public class CostMill extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
final String amount = this.getAmount();
|
||||
Integer c = this.convertAmount();
|
||||
final Player activator = ability.getActivatingPlayer();
|
||||
@@ -194,12 +195,4 @@ public class CostMill extends CostPartWithList {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.card.cost.CostPart#refund(forge.Card)
|
||||
*/
|
||||
@Override
|
||||
public void refund(final Card source) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package forge.card.cost;
|
||||
|
||||
import forge.Card;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.Player;
|
||||
|
||||
/**
|
||||
@@ -26,31 +27,24 @@ import forge.game.player.Player;
|
||||
*/
|
||||
public abstract class CostPart {
|
||||
|
||||
/** The is reusable. */
|
||||
private boolean isReusable = false;
|
||||
|
||||
/** The is undoable. */
|
||||
private boolean isUndoable = false;
|
||||
|
||||
/** The optional. */
|
||||
// private boolean optional = false;
|
||||
|
||||
/** The optional type. */
|
||||
private String optionalType = null;
|
||||
|
||||
/** The amount. */
|
||||
private String amount = "1";
|
||||
|
||||
/** The type. */
|
||||
private String type = "Card";
|
||||
private final String type;
|
||||
|
||||
/** The type description. */
|
||||
private String typeDescription = null;
|
||||
private final String typeDescription;
|
||||
|
||||
/**
|
||||
* Instantiates a new cost part.
|
||||
*/
|
||||
public CostPart() {
|
||||
type = "Card";
|
||||
typeDescription = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,8 +59,8 @@ public abstract class CostPart {
|
||||
*/
|
||||
public CostPart(final String amount, final String type, final String description) {
|
||||
this.setAmount(amount);
|
||||
this.setType(type);
|
||||
this.setTypeDescription(description);
|
||||
this.type = type;
|
||||
this.typeDescription = description;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,7 +86,7 @@ public abstract class CostPart {
|
||||
*
|
||||
* @return the this
|
||||
*/
|
||||
public final boolean getThis() {
|
||||
public final boolean isTargetingThis() {
|
||||
return this.getType().equals("CARDNAME");
|
||||
}
|
||||
|
||||
@@ -119,8 +113,8 @@ public abstract class CostPart {
|
||||
*
|
||||
* @return true, if is reusable
|
||||
*/
|
||||
public final boolean isReusable() {
|
||||
return this.isReusable;
|
||||
public boolean isReusable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,27 +122,8 @@ public abstract class CostPart {
|
||||
*
|
||||
* @return true, if is undoable
|
||||
*/
|
||||
public final boolean isUndoable() {
|
||||
return this.isUndoable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the optional type.
|
||||
*
|
||||
* @return the optional type
|
||||
*/
|
||||
public final String getOptionalType() {
|
||||
return this.optionalType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the optional type.
|
||||
*
|
||||
* @param optionalType
|
||||
* the new optional type
|
||||
*/
|
||||
public final void setOptionalType(final String optionalType) {
|
||||
this.optionalType = optionalType;
|
||||
public boolean isUndoable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,9 +151,10 @@ public abstract class CostPart {
|
||||
* the activator
|
||||
* @param cost
|
||||
* the cost
|
||||
* @param game
|
||||
* @return true, if successful
|
||||
*/
|
||||
public abstract boolean canPay(SpellAbility ability, Card source, Player activator, Cost cost);
|
||||
public abstract boolean canPay(SpellAbility ability, Card source, Player activator, Cost cost, GameState game);
|
||||
|
||||
/**
|
||||
* Decide ai payment.
|
||||
@@ -198,8 +174,9 @@ public abstract class CostPart {
|
||||
* @param ability {@link forge.card.spellability.SpellAbility}
|
||||
* @param source {@link forge.Card}
|
||||
* @param payment {@link forge.card.cost.CostPayment}
|
||||
* @param game
|
||||
*/
|
||||
public abstract void payAI(final Player ai, SpellAbility ability, Card source, CostPayment payment);
|
||||
public abstract void payAI(final Player ai, SpellAbility ability, Card source, CostPayment payment, GameState game);
|
||||
|
||||
/**
|
||||
* Pay human.
|
||||
@@ -207,9 +184,10 @@ public abstract class CostPart {
|
||||
* @param ability {@link forge.card.spellability.SpellAbility}
|
||||
* @param source {@link forge.Card}
|
||||
* @param payment {@link forge.card.cost.CostPayment}
|
||||
* @param game
|
||||
* @return true, if successful
|
||||
*/
|
||||
public abstract boolean payHuman(SpellAbility ability, Card source, CostPayment payment);
|
||||
public abstract boolean payHuman(SpellAbility ability, Card source, CostPayment payment, GameState game);
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -220,22 +198,13 @@ public abstract class CostPart {
|
||||
public abstract String toString();
|
||||
|
||||
/**
|
||||
* Refund.
|
||||
* Refund. Overridden in classes which know how to refund.
|
||||
*
|
||||
* @param source
|
||||
* the source
|
||||
*/
|
||||
public abstract void refund(Card source);
|
||||
public void refund(Card source) {}
|
||||
|
||||
/**
|
||||
* Sets the reusable.
|
||||
*
|
||||
* @param isReusableIn
|
||||
* the isReusable to set
|
||||
*/
|
||||
public void setReusable(final boolean isReusableIn) {
|
||||
this.isReusable = isReusableIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount.
|
||||
@@ -246,34 +215,4 @@ public abstract class CostPart {
|
||||
public void setAmount(final String amountIn) {
|
||||
this.amount = amountIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type.
|
||||
*
|
||||
* @param typeIn
|
||||
* the type to set
|
||||
*/
|
||||
public void setType(final String typeIn) {
|
||||
this.type = typeIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type description.
|
||||
*
|
||||
* @param typeDescriptionIn
|
||||
* the typeDescription to set
|
||||
*/
|
||||
public void setTypeDescription(final String typeDescriptionIn) {
|
||||
this.typeDescription = typeDescriptionIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the undoable.
|
||||
*
|
||||
* @param isUndoableIn
|
||||
* the isUndoable to set
|
||||
*/
|
||||
public void setUndoable(final boolean isUndoableIn) {
|
||||
this.isUndoable = isUndoableIn;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import forge.Card;
|
||||
import forge.GameActionUtil;
|
||||
import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.Player;
|
||||
|
||||
/**
|
||||
@@ -89,7 +90,7 @@ public class CostPayLife extends CostPart {
|
||||
* forge.Card, forge.Player, forge.card.cost.Cost)
|
||||
*/
|
||||
@Override
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost) {
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost, final GameState game) {
|
||||
final Integer amount = this.convertAmount();
|
||||
if ((amount != null) && !activator.canPayLife(amount)) {
|
||||
return false;
|
||||
@@ -109,7 +110,7 @@ public class CostPayLife extends CostPart {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
ai.payLife(this.getLastPaidAmount(), null);
|
||||
}
|
||||
|
||||
@@ -121,7 +122,7 @@ public class CostPayLife extends CostPart {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
final String amount = this.getAmount();
|
||||
final Player activator = ability.getActivatingPlayer();
|
||||
final int life = activator.getLife();
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.List;
|
||||
import forge.Card;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.SpellAbilityRequirements;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.Player;
|
||||
|
||||
/**
|
||||
@@ -40,6 +41,7 @@ public class CostPayment {
|
||||
private SpellAbilityRequirements req = null;
|
||||
private boolean bCancel = false;
|
||||
private final ArrayList<CostPart> paidCostParts = new ArrayList<CostPart>();
|
||||
private final GameState game;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -129,10 +131,11 @@ public class CostPayment {
|
||||
* @param abil
|
||||
* a {@link forge.card.spellability.SpellAbility} object.
|
||||
*/
|
||||
public CostPayment(final Cost cost, final SpellAbility abil) {
|
||||
public CostPayment(final Cost cost, final SpellAbility abil, final GameState game) {
|
||||
this.cost = cost;
|
||||
this.ability = abil;
|
||||
this.card = abil.getSourceCard();
|
||||
this.game = game;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,7 +149,7 @@ public class CostPayment {
|
||||
* a {@link forge.card.spellability.SpellAbility} object.
|
||||
* @return a boolean.
|
||||
*/
|
||||
public static boolean canPayAdditionalCosts(final Cost cost, final SpellAbility ability) {
|
||||
public static boolean canPayAdditionalCosts(final GameState game, final Cost cost, final SpellAbility ability) {
|
||||
if (cost == null) {
|
||||
return true;
|
||||
}
|
||||
@@ -159,7 +162,7 @@ public class CostPayment {
|
||||
}
|
||||
|
||||
for (final CostPart part : cost.getCostParts()) {
|
||||
if (!part.canPay(ability, card, activator, cost)) {
|
||||
if (!part.canPay(ability, card, activator, cost, game)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -218,7 +221,7 @@ public class CostPayment {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!part.payHuman(this.ability, this.card, this)) {
|
||||
if (!part.payHuman(this.ability, this.card, this, game)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -281,7 +284,7 @@ public class CostPayment {
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
public final boolean payComputerCosts(final Player ai) {
|
||||
public final boolean payComputerCosts(final Player ai, final GameState game) {
|
||||
// canPayAdditionalCosts now Player Agnostic
|
||||
|
||||
// Just in case it wasn't set, but honestly it shouldn't have gotten
|
||||
@@ -303,7 +306,7 @@ public class CostPayment {
|
||||
}
|
||||
|
||||
for (final CostPart part : parts) {
|
||||
part.payAI(ai, this.ability, this.ability.getSourceCard(), this);
|
||||
part.payAI(ai, this.ability, this.ability.getSourceCard(), this, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.control.input.Input;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.match.CMatchUI;
|
||||
@@ -73,14 +74,14 @@ public class CostPutCounter extends CostPartWithList {
|
||||
* the description
|
||||
*/
|
||||
public CostPutCounter(final String amount, final CounterType cntr, final String type, final String description) {
|
||||
this.setReusable(true);
|
||||
this.setAmount(amount);
|
||||
super(amount, type, description);
|
||||
this.counter = cntr;
|
||||
|
||||
this.setType(type);
|
||||
this.setTypeDescription(description);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isReusable() { return true; }
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@@ -89,7 +90,7 @@ public class CostPutCounter extends CostPartWithList {
|
||||
@Override
|
||||
public final String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
if (this.counter.getName().equals("Loyalty")) {
|
||||
if (this.counter == CounterType.LOYALTY) {
|
||||
sb.append("+").append(this.getAmount());
|
||||
} else {
|
||||
sb.append("Put ");
|
||||
@@ -97,7 +98,7 @@ public class CostPutCounter extends CostPartWithList {
|
||||
sb.append(Cost.convertAmountTypeToWords(i, this.getAmount(), this.counter.getName() + " counter"));
|
||||
|
||||
sb.append(" on ");
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
sb.append(this.getType());
|
||||
} else {
|
||||
final String desc = this.getTypeDescription() == null ? this.getType() : this.getTypeDescription();
|
||||
@@ -127,8 +128,8 @@ public class CostPutCounter extends CostPartWithList {
|
||||
* forge.Card, forge.Player, forge.card.cost.Cost)
|
||||
*/
|
||||
@Override
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost) {
|
||||
if (this.getThis()) {
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost, final GameState game) {
|
||||
if (this.isTargetingThis()) {
|
||||
if (source.hasKeyword("CARDNAME can't have counters placed on it.")) {
|
||||
return false;
|
||||
}
|
||||
@@ -155,13 +156,13 @@ public class CostPutCounter extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
Integer c = this.convertAmount();
|
||||
if (c == null) {
|
||||
c = AbilityFactory.calculateAmount(source, this.getAmount(), ability);
|
||||
}
|
||||
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
source.addCounter(this.getCounter(), c, false);
|
||||
} else {
|
||||
// Put counter on chosen card
|
||||
@@ -179,13 +180,13 @@ public class CostPutCounter extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
Integer c = this.convertAmount();
|
||||
if (c == null) {
|
||||
c = AbilityFactory.calculateAmount(source, this.getAmount(), ability);
|
||||
}
|
||||
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
source.addCounter(this.getCounter(), c, false);
|
||||
payment.setPaidManaPart(this);
|
||||
this.addToList(source);
|
||||
@@ -207,7 +208,7 @@ public class CostPutCounter extends CostPartWithList {
|
||||
@Override
|
||||
public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
this.resetList();
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
this.addToList(source);
|
||||
return true;
|
||||
} else {
|
||||
|
||||
@@ -28,6 +28,7 @@ import forge.Singletons;
|
||||
import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.control.input.Input;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.GuiChoose;
|
||||
@@ -97,14 +98,15 @@ public class CostRemoveCounter extends CostPartWithList {
|
||||
*/
|
||||
public CostRemoveCounter(final String amount, final CounterType counter, final String type, final String description, ZoneType zone) {
|
||||
super(amount, type, description);
|
||||
this.setReusable(true);
|
||||
|
||||
this.counter = counter;
|
||||
this.setType(type);
|
||||
this.setTypeDescription(description);
|
||||
this.setZone(zone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReusable() { return true; }
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@@ -126,7 +128,7 @@ public class CostRemoveCounter extends CostPartWithList {
|
||||
|
||||
sb.append(" from ");
|
||||
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
sb.append(this.getType());
|
||||
} else {
|
||||
final String desc = this.getTypeDescription() == null ? this.getType() : this.getTypeDescription();
|
||||
@@ -156,11 +158,11 @@ public class CostRemoveCounter extends CostPartWithList {
|
||||
* forge.Card, forge.Player, forge.card.cost.Cost)
|
||||
*/
|
||||
@Override
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost) {
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost, final GameState game) {
|
||||
final CounterType cntrs = this.getCounter();
|
||||
|
||||
final Integer amount = this.convertAmount();
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
if ((amount != null) && ((source.getCounters(cntrs) - amount) < 0)) {
|
||||
return false;
|
||||
}
|
||||
@@ -187,7 +189,7 @@ public class CostRemoveCounter extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
final String amount = this.getAmount();
|
||||
Integer c = this.convertAmount();
|
||||
if (c == null) {
|
||||
@@ -198,7 +200,7 @@ public class CostRemoveCounter extends CostPartWithList {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
source.subtractCounter(this.counter, c);
|
||||
} else {
|
||||
for (final Card card : this.getList()) {
|
||||
@@ -216,12 +218,12 @@ public class CostRemoveCounter extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
final String amount = this.getAmount();
|
||||
Integer c = this.convertAmount();
|
||||
int maxCounters = 0;
|
||||
|
||||
if (!this.getThis()) {
|
||||
if (!this.isTargetingThis()) {
|
||||
if (this.getZone().equals(ZoneType.Battlefield)) {
|
||||
final Input inp = CostRemoveCounter.removeCounterType(ability, this.getType(), payment, this, c);
|
||||
Singletons.getModel().getMatch().getInput().setInputInterrupt(inp);
|
||||
@@ -287,7 +289,7 @@ public class CostRemoveCounter extends CostPartWithList {
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.getThis()) {
|
||||
if (!this.isTargetingThis()) {
|
||||
this.getList().clear();
|
||||
final List<Card> typeList =
|
||||
CardLists.getValidCards(ai.getCardsIn(this.getZone()), this.getType().split(";"), ai, source);
|
||||
|
||||
@@ -29,6 +29,7 @@ import forge.Singletons;
|
||||
import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.control.input.Input;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.ComputerUtil;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -68,7 +69,7 @@ public class CostReturn extends CostPartWithList {
|
||||
final Integer i = this.convertAmount();
|
||||
String pronoun = "its";
|
||||
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
sb.append(this.getType());
|
||||
} else {
|
||||
final String desc = this.getTypeDescription() == null ? this.getType() : this.getTypeDescription();
|
||||
@@ -87,17 +88,6 @@ public class CostReturn extends CostPartWithList {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.card.cost.CostPart#refund(forge.Card)
|
||||
*/
|
||||
@Override
|
||||
public void refund(final Card source) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@@ -106,8 +96,8 @@ public class CostReturn extends CostPartWithList {
|
||||
* forge.Card, forge.Player, forge.card.cost.Cost)
|
||||
*/
|
||||
@Override
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost) {
|
||||
if (!this.getThis()) {
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost, final GameState game) {
|
||||
if (!this.isTargetingThis()) {
|
||||
List<Card> typeList = new ArrayList<Card>(activator.getCardsIn(ZoneType.Battlefield));
|
||||
typeList = CardLists.getValidCards(typeList, this.getType().split(";"), activator, source);
|
||||
|
||||
@@ -129,7 +119,7 @@ public class CostReturn extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
for (final Card c : this.getList()) {
|
||||
Singletons.getModel().getGame().getAction().moveToHand(c);
|
||||
}
|
||||
@@ -143,7 +133,7 @@ public class CostReturn extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
final String amount = this.getAmount();
|
||||
Integer c = this.convertAmount();
|
||||
final Player activator = ability.getActivatingPlayer();
|
||||
@@ -157,7 +147,7 @@ public class CostReturn extends CostPartWithList {
|
||||
c = AbilityFactory.calculateAmount(source, amount, ability);
|
||||
}
|
||||
}
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
final Input inp = CostReturn.returnThis(ability, payment, this);
|
||||
Singletons.getModel().getMatch().getInput().setInputInterrupt(inp);
|
||||
} else {
|
||||
@@ -177,7 +167,7 @@ public class CostReturn extends CostPartWithList {
|
||||
@Override
|
||||
public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
this.resetList();
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
this.getList().add(source);
|
||||
} else {
|
||||
Integer c = this.convertAmount();
|
||||
|
||||
@@ -27,6 +27,7 @@ import forge.CardLists;
|
||||
import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.control.input.Input;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.ComputerUtil;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.Zone;
|
||||
@@ -63,12 +64,12 @@ public class CostReveal extends CostPartWithList {
|
||||
* forge.Card, forge.Player, forge.card.cost.Cost)
|
||||
*/
|
||||
@Override
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost) {
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost, final GameState game) {
|
||||
List<Card> handList = new ArrayList<Card>(activator.getCardsIn(ZoneType.Hand));
|
||||
final String type = this.getType();
|
||||
final Integer amount = this.convertAmount();
|
||||
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
if (!source.isInZone(ZoneType.Hand)) {
|
||||
return false;
|
||||
}
|
||||
@@ -102,7 +103,7 @@ public class CostReveal extends CostPartWithList {
|
||||
List<Card> hand = new ArrayList<Card>(ai.getCardsIn(ZoneType.Hand));
|
||||
this.resetList();
|
||||
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
if (!hand.contains(source)) {
|
||||
return false;
|
||||
}
|
||||
@@ -135,7 +136,7 @@ public class CostReveal extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
GuiChoose.oneOrNone("Revealed cards:", this.getList());
|
||||
}
|
||||
|
||||
@@ -147,12 +148,12 @@ public class CostReveal extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
final Player activator = ability.getActivatingPlayer();
|
||||
final String amount = this.getAmount();
|
||||
this.resetList();
|
||||
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
this.addToList(source);
|
||||
payment.setPaidManaPart(this);
|
||||
} else if (this.getType().equals("Hand")) {
|
||||
@@ -196,7 +197,7 @@ public class CostReveal extends CostPartWithList {
|
||||
|
||||
final Integer i = this.convertAmount();
|
||||
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
sb.append(this.getType());
|
||||
} else if (this.getType().equals("Hand")) {
|
||||
return ("Reveal you hand");
|
||||
@@ -217,16 +218,6 @@ public class CostReveal extends CostPartWithList {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.card.cost.CostPart#refund(forge.Card)
|
||||
*/
|
||||
@Override
|
||||
public void refund(final Card source) {
|
||||
|
||||
}
|
||||
|
||||
// Inputs
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,6 +29,7 @@ import forge.Singletons;
|
||||
import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.control.input.Input;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.ComputerUtil;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -66,7 +67,7 @@ public class CostSacrifice extends CostPartWithList {
|
||||
|
||||
final Integer i = this.convertAmount();
|
||||
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
sb.append(this.getType());
|
||||
} else {
|
||||
final String desc = this.getTypeDescription() == null ? this.getType() : this.getTypeDescription();
|
||||
@@ -79,17 +80,6 @@ public class CostSacrifice extends CostPartWithList {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.card.cost.CostPart#refund(forge.Card)
|
||||
*/
|
||||
@Override
|
||||
public void refund(final Card source) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@@ -98,9 +88,9 @@ public class CostSacrifice extends CostPartWithList {
|
||||
* forge.Card, forge.Player, forge.card.cost.Cost)
|
||||
*/
|
||||
@Override
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost) {
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost, final GameState game) {
|
||||
// You can always sac all
|
||||
if (!this.getThis()) {
|
||||
if (!this.isTargetingThis()) {
|
||||
List<Card> typeList = new ArrayList<Card>(activator.getCardsIn(ZoneType.Battlefield));
|
||||
typeList = CardLists.getValidCards(typeList, this.getType().split(";"), activator, source);
|
||||
|
||||
@@ -137,7 +127,7 @@ public class CostSacrifice extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
this.addListToHash(ability, "Sacrificed");
|
||||
for (final Card c : this.getList()) {
|
||||
Singletons.getModel().getGame().getAction().sacrifice(c, ability);
|
||||
@@ -152,7 +142,7 @@ public class CostSacrifice extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
final String amount = this.getAmount();
|
||||
final String type = this.getType();
|
||||
final Player activator = ability.getActivatingPlayer();
|
||||
@@ -162,7 +152,7 @@ public class CostSacrifice extends CostPartWithList {
|
||||
list = CardLists.getNotType(list, "Creature");
|
||||
}
|
||||
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
final Input inp = CostSacrifice.sacrificeThis(ability, payment, this);
|
||||
Singletons.getModel().getMatch().getInput().setInputInterrupt(inp);
|
||||
} else if (amount.equals("All")) {
|
||||
@@ -203,7 +193,7 @@ public class CostSacrifice extends CostPartWithList {
|
||||
public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
this.resetList();
|
||||
final Player activator = ability.getActivatingPlayer();
|
||||
if (this.getThis()) {
|
||||
if (this.isTargetingThis()) {
|
||||
this.getList().add(source);
|
||||
} else if (this.getAmount().equals("All")) {
|
||||
List<Card> typeList = new ArrayList<Card>(activator.getCardsIn(ZoneType.Battlefield));
|
||||
|
||||
@@ -19,6 +19,7 @@ package forge.card.cost;
|
||||
|
||||
import forge.Card;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.Player;
|
||||
|
||||
/**
|
||||
@@ -30,10 +31,16 @@ public class CostTap extends CostPart {
|
||||
* Instantiates a new cost tap.
|
||||
*/
|
||||
public CostTap() {
|
||||
this.setReusable(true);
|
||||
this.setUndoable(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUndoable() { return true; }
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isReusable() { return true; }
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@@ -62,7 +69,7 @@ public class CostTap extends CostPart {
|
||||
* forge.Card, forge.Player, forge.card.cost.Cost)
|
||||
*/
|
||||
@Override
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost) {
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost, final GameState game) {
|
||||
return source.isUntapped() && (!source.isSick() || source.hasKeyword("CARDNAME may activate abilities as though it has haste."));
|
||||
}
|
||||
|
||||
@@ -73,7 +80,7 @@ public class CostTap extends CostPart {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
source.tap();
|
||||
}
|
||||
|
||||
@@ -85,7 +92,7 @@ public class CostTap extends CostPart {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
// if (!canPay(ability, source, ability.getActivatingPlayer(),
|
||||
// payment.getCost()))
|
||||
// return false;
|
||||
|
||||
@@ -28,6 +28,7 @@ import forge.Singletons;
|
||||
import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.control.input.Input;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.ComputerUtil;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.Zone;
|
||||
@@ -52,9 +53,12 @@ public class CostTapType extends CostPartWithList {
|
||||
*/
|
||||
public CostTapType(final String amount, final String type, final String description) {
|
||||
super(amount, type, description);
|
||||
this.setReusable(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReusable() { return true; }
|
||||
|
||||
|
||||
/**
|
||||
* Gets the description.
|
||||
*
|
||||
@@ -84,16 +88,6 @@ public class CostTapType extends CostPartWithList {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the to tapped list.
|
||||
*
|
||||
* @param c
|
||||
* the c
|
||||
*/
|
||||
public final void addToTappedList(final Card c) {
|
||||
this.getList().add(c);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@@ -116,7 +110,7 @@ public class CostTapType extends CostPartWithList {
|
||||
* forge.Card, forge.Player, forge.card.cost.Cost)
|
||||
*/
|
||||
@Override
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost) {
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost, final GameState game) {
|
||||
List<Card> typeList = new ArrayList<Card>(activator.getCardsIn(ZoneType.Battlefield));
|
||||
|
||||
typeList = CardLists.getValidCards(typeList, this.getType().split(";"), activator, source);
|
||||
@@ -141,7 +135,7 @@ public class CostTapType extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
for (final Card c : this.getList()) {
|
||||
c.tap();
|
||||
}
|
||||
@@ -155,7 +149,7 @@ public class CostTapType extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
List<Card> typeList = new ArrayList<Card>(ability.getActivatingPlayer().getCardsIn(ZoneType.Battlefield));
|
||||
typeList = CardLists.getValidCards(typeList, this.getType().split(";"), ability.getActivatingPlayer(), ability.getSourceCard());
|
||||
typeList = CardLists.filter(typeList, Presets.UNTAPPED);
|
||||
|
||||
@@ -19,6 +19,7 @@ package forge.card.cost;
|
||||
|
||||
import forge.Card;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.Player;
|
||||
|
||||
/**
|
||||
@@ -30,10 +31,15 @@ public class CostUntap extends CostPart {
|
||||
* Instantiates a new cost untap.
|
||||
*/
|
||||
public CostUntap() {
|
||||
this.setReusable(true);
|
||||
this.setUndoable(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReusable() { return true; }
|
||||
|
||||
@Override
|
||||
public boolean isUndoable() { return true; }
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@@ -62,7 +68,7 @@ public class CostUntap extends CostPart {
|
||||
* forge.Card, forge.Player, forge.card.cost.Cost)
|
||||
*/
|
||||
@Override
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost) {
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost, final GameState game) {
|
||||
return source.isTapped() && (!source.isSick() || source.hasKeyword("CARDNAME may activate abilities as though it has haste."));
|
||||
}
|
||||
|
||||
@@ -73,7 +79,7 @@ public class CostUntap extends CostPart {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
source.untap();
|
||||
}
|
||||
|
||||
@@ -85,7 +91,7 @@ public class CostUntap extends CostPart {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
// if (!canPay(ability, source, ability.getActivatingPlayer(),
|
||||
// payment.getCost()))
|
||||
// return false;
|
||||
|
||||
@@ -27,6 +27,7 @@ import forge.Singletons;
|
||||
import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.control.input.Input;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.ComputerUtil;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.Zone;
|
||||
@@ -51,9 +52,12 @@ public class CostUntapType extends CostPartWithList {
|
||||
*/
|
||||
public CostUntapType(final String amount, final String type, final String description) {
|
||||
super(amount, type, description);
|
||||
this.setReusable(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReusable() { return true; }
|
||||
|
||||
|
||||
/**
|
||||
* Gets the description.
|
||||
*
|
||||
@@ -119,7 +123,7 @@ public class CostUntapType extends CostPartWithList {
|
||||
* forge.Card, forge.Player, forge.card.cost.Cost)
|
||||
*/
|
||||
@Override
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost) {
|
||||
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost, final GameState game) {
|
||||
List<Card> typeList = Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield);
|
||||
|
||||
typeList = CardLists.getValidCards(typeList, this.getType().split(";"), activator, source);
|
||||
@@ -144,7 +148,7 @@ public class CostUntapType extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final void payAI(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
for (final Card c : this.getList()) {
|
||||
c.untap();
|
||||
}
|
||||
@@ -158,7 +162,7 @@ public class CostUntapType extends CostPartWithList {
|
||||
* forge.Card, forge.card.cost.Cost_Payment)
|
||||
*/
|
||||
@Override
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment) {
|
||||
public final boolean payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
|
||||
final boolean untap = payment.getCost().hasUntapCost();
|
||||
List<Card> typeList = Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield);
|
||||
typeList = CardLists.getValidCards(typeList, this.getType().split(";"), ability.getActivatingPlayer(), ability.getSourceCard());
|
||||
|
||||
@@ -109,7 +109,7 @@ public class CostUtil {
|
||||
for (final CostPart part : cost.getCostParts()) {
|
||||
if (part instanceof CostSacrifice) {
|
||||
final CostSacrifice sac = (CostSacrifice) part;
|
||||
if (sac.getThis() && source.isCreature()) {
|
||||
if (sac.isTargetingThis() && source.isCreature()) {
|
||||
return false;
|
||||
}
|
||||
final String type = sac.getType();
|
||||
@@ -257,7 +257,7 @@ public class CostUtil {
|
||||
final CounterType type = remCounter.getCounter();
|
||||
final double percent = type.name().equals("P1P1") ? p1p1Percent : otherPercent;
|
||||
final int currentNum = source.getCounters(type);
|
||||
if (!part.getThis()) {
|
||||
if (!part.isTargetingThis()) {
|
||||
if (type.name().equals("P1P1")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import forge.GameActionUtil;
|
||||
import forge.Singletons;
|
||||
import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.ComputerUtil;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -42,6 +43,7 @@ public class ReplacementHandler {
|
||||
|
||||
public ReplacementResult run(final HashMap<String, Object> runParams) {
|
||||
final Object affected = runParams.get("Affected");
|
||||
final GameState game = Singletons.getModel().getGame();
|
||||
Player decider = null;
|
||||
|
||||
// Figure out who decides which of multiple replacements to apply
|
||||
@@ -53,25 +55,25 @@ public class ReplacementHandler {
|
||||
}
|
||||
|
||||
if (runParams.get("Event").equals("Moved")) {
|
||||
ReplacementResult res = run(runParams, ReplacementLayer.Control, decider);
|
||||
ReplacementResult res = run(runParams, ReplacementLayer.Control, decider, game);
|
||||
if (res != ReplacementResult.NotReplaced) {
|
||||
return res;
|
||||
}
|
||||
res = run(runParams, ReplacementLayer.Copy, decider);
|
||||
res = run(runParams, ReplacementLayer.Copy, decider, game);
|
||||
if (res != ReplacementResult.NotReplaced) {
|
||||
return res;
|
||||
}
|
||||
res = run(runParams, ReplacementLayer.Other, decider);
|
||||
res = run(runParams, ReplacementLayer.Other, decider, game);
|
||||
if (res != ReplacementResult.NotReplaced) {
|
||||
return res;
|
||||
}
|
||||
res = run(runParams, ReplacementLayer.None, decider);
|
||||
res = run(runParams, ReplacementLayer.None, decider, game);
|
||||
if (res != ReplacementResult.NotReplaced) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ReplacementResult res = run(runParams, ReplacementLayer.None, decider);
|
||||
ReplacementResult res = run(runParams, ReplacementLayer.None, decider, game);
|
||||
if (res != ReplacementResult.NotReplaced) {
|
||||
return res;
|
||||
}
|
||||
@@ -89,7 +91,7 @@ public class ReplacementHandler {
|
||||
* the run params,same as for triggers.
|
||||
* @return true if the event was replaced.
|
||||
*/
|
||||
public ReplacementResult run(final HashMap<String, Object> runParams, final ReplacementLayer layer, final Player decider) {
|
||||
public ReplacementResult run(final HashMap<String, Object> runParams, final ReplacementLayer layer, final Player decider, final GameState game) {
|
||||
|
||||
final List<ReplacementEffect> possibleReplacers = new ArrayList<ReplacementEffect>();
|
||||
// Round up Non-static replacement effects ("Until EOT," or
|
||||
@@ -101,7 +103,7 @@ public class ReplacementHandler {
|
||||
}*/
|
||||
|
||||
// Round up Static replacement effects
|
||||
for (final Player p : Singletons.getModel().getGame().getPlayers()) {
|
||||
for (final Player p : game.getPlayers()) {
|
||||
for (final Card crd : p.getAllCards()) {
|
||||
for (final ReplacementEffect replacementEffect : crd.getReplacementEffects()) {
|
||||
if (!replacementEffect.hasRun()
|
||||
@@ -109,7 +111,7 @@ public class ReplacementHandler {
|
||||
&& replacementEffect.requirementsCheck()
|
||||
&& replacementEffect.canReplace(runParams)
|
||||
&& !possibleReplacers.contains(replacementEffect)
|
||||
&& replacementEffect.zonesCheck(Singletons.getModel().getGame().getZoneOf(crd))) {
|
||||
&& replacementEffect.zonesCheck(game.getZoneOf(crd))) {
|
||||
possibleReplacers.add(replacementEffect);
|
||||
}
|
||||
}
|
||||
@@ -141,7 +143,7 @@ public class ReplacementHandler {
|
||||
|
||||
if (chosenRE != null) {
|
||||
chosenRE.setHasRun(true);
|
||||
ReplacementResult res = this.executeReplacement(runParams, chosenRE, decider);
|
||||
ReplacementResult res = this.executeReplacement(runParams, chosenRE, decider, game);
|
||||
if (res != ReplacementResult.NotReplaced) {
|
||||
chosenRE.setHasRun(false);
|
||||
Singletons.getModel().getGame().getGameLog().add("ReplacementEffect", chosenRE.toString(), 2);
|
||||
@@ -171,7 +173,7 @@ public class ReplacementHandler {
|
||||
* the replacement effect to run
|
||||
*/
|
||||
private ReplacementResult executeReplacement(final HashMap<String, Object> runParams,
|
||||
final ReplacementEffect replacementEffect, final Player decider) {
|
||||
final ReplacementEffect replacementEffect, final Player decider, final GameState game) {
|
||||
final HashMap<String, String> mapParams = replacementEffect.getMapParams();
|
||||
|
||||
SpellAbility effectSA = null;
|
||||
@@ -234,9 +236,9 @@ public class ReplacementHandler {
|
||||
|
||||
Player player = replacementEffect.getHostCard().getController();
|
||||
if (player.isHuman()) {
|
||||
Singletons.getModel().getGame().getAction().playSpellAbilityNoStack(effectSA, false);
|
||||
game.getAction().playSpellAbilityNoStack(effectSA, false);
|
||||
} else {
|
||||
ComputerUtil.playNoStack(player, effectSA);
|
||||
ComputerUtil.playNoStack(player, effectSA, game);
|
||||
}
|
||||
|
||||
return ReplacementResult.Replaced;
|
||||
|
||||
@@ -25,6 +25,7 @@ import forge.Singletons;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.cost.CostPayment;
|
||||
import forge.card.staticability.StaticAbility;
|
||||
import forge.game.GameState;
|
||||
import forge.game.GlobalRuleChange;
|
||||
import forge.game.zone.ZoneType;
|
||||
|
||||
@@ -82,7 +83,8 @@ public abstract class AbilityActivated extends SpellAbility implements java.io.S
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public boolean canPlay() {
|
||||
if (Singletons.getModel().getGame().getStack().isSplitSecondOnStack() && !this.isManaAbility()) {
|
||||
final GameState game = Singletons.getModel().getGame();
|
||||
if (game.getStack().isSplitSecondOnStack() && !this.isManaAbility()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -115,7 +117,7 @@ public abstract class AbilityActivated extends SpellAbility implements java.io.S
|
||||
return false;
|
||||
}
|
||||
|
||||
return CostPayment.canPayAdditionalCosts(this.getPayCosts(), this);
|
||||
return CostPayment.canPayAdditionalCosts(game, this.getPayCosts(), this);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -29,6 +29,7 @@ import forge.card.cost.Cost;
|
||||
import forge.card.cost.CostPayment;
|
||||
import forge.card.staticability.StaticAbility;
|
||||
import forge.error.ErrorViewer;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.Expressions;
|
||||
@@ -86,7 +87,8 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public boolean canPlay() {
|
||||
if (Singletons.getModel().getGame().getStack().isSplitSecondOnStack()) {
|
||||
final GameState game = Singletons.getModel().getGame();
|
||||
if (game.getStack().isSplitSecondOnStack()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -113,13 +115,13 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
|
||||
}
|
||||
|
||||
if (this.getPayCosts() != null) {
|
||||
if (!CostPayment.canPayAdditionalCosts(this.getPayCosts(), this)) {
|
||||
if (!CostPayment.canPayAdditionalCosts(game, this.getPayCosts(), this)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// CantBeCast static abilities
|
||||
final List<Card> allp = new ArrayList<Card>(Singletons.getModel().getGame().getCardsIn(ZoneType.listValueOf("Battlefield,Command")));
|
||||
final List<Card> allp = new ArrayList<Card>(game.getCardsIn(ZoneType.listValueOf("Battlefield,Command")));
|
||||
allp.add(card);
|
||||
for (final Card ca : allp) {
|
||||
final ArrayList<StaticAbility> staticAbilities = ca.getStaticAbilities();
|
||||
|
||||
@@ -546,7 +546,7 @@ public class TriggerHandler {
|
||||
game.getAction().playSpellAbilityNoStack(wrapperAbility, false);
|
||||
} else {
|
||||
wrapperAbility.doTrigger(isMandatory);
|
||||
ComputerUtil.playNoStack(wrapperAbility.getActivatingPlayer(), wrapperAbility);
|
||||
ComputerUtil.playNoStack(wrapperAbility.getActivatingPlayer(), wrapperAbility, game);
|
||||
}
|
||||
} else {
|
||||
game.getStack().addSimultaneousStackEntry(wrapperAbility);
|
||||
|
||||
@@ -19,6 +19,7 @@ import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.SpellAbilityRestriction;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.control.input.Input;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.ComputerUtil;
|
||||
import forge.game.player.Player;
|
||||
|
||||
@@ -454,6 +455,7 @@ public class WrappedAbility extends Ability implements ISpellAbility {
|
||||
// //////////////////////////////////////
|
||||
@Override
|
||||
public void resolve() {
|
||||
final GameState game = Singletons.getModel().getGame();
|
||||
if (!(regtrig instanceof TriggerAlways)) {
|
||||
// State triggers
|
||||
// don't do the whole
|
||||
@@ -463,7 +465,7 @@ public class WrappedAbility extends Ability implements ISpellAbility {
|
||||
return;
|
||||
}
|
||||
}
|
||||
TriggerHandler th = Singletons.getModel().getGame().getTriggerHandler();
|
||||
TriggerHandler th = game.getTriggerHandler();
|
||||
Map<String, String> triggerParams = regtrig.getMapParams();
|
||||
|
||||
if (decider != null) {
|
||||
@@ -508,12 +510,12 @@ public class WrappedAbility extends Ability implements ISpellAbility {
|
||||
}
|
||||
|
||||
if (getActivatingPlayer().isHuman()) {
|
||||
Singletons.getModel().getGame().getAction().playSpellAbilityNoStack(sa, true);
|
||||
game.getAction().playSpellAbilityNoStack(sa, true);
|
||||
} else {
|
||||
// commented out because i don't think this should be called
|
||||
// again here
|
||||
// sa.doTrigger(isMandatory);
|
||||
ComputerUtil.playNoStack(getActivatingPlayer(), sa);
|
||||
ComputerUtil.playNoStack(getActivatingPlayer(), sa, game);
|
||||
}
|
||||
|
||||
// Add eventual delayed trigger.
|
||||
|
||||
@@ -160,7 +160,7 @@ public class InputMulligan extends Input {
|
||||
// Is there a better way for the AI to decide this?
|
||||
if (effect.doTrigger(false)) {
|
||||
GameActionUtil.showInfoDialg("Computer reveals " + c.getName() + "(" + c.getUniqueNumber() + ").");
|
||||
ComputerUtil.playNoStack(p, effect);
|
||||
ComputerUtil.playNoStack(p, effect, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,13 +69,13 @@ public class GameState {
|
||||
private final List<Card> communalPlanarDeck = new ArrayList<Card>();
|
||||
private Card activePlane = null;
|
||||
|
||||
private final Cleanup cleanup = new Cleanup();
|
||||
private final EndOfTurn endOfTurn = new EndOfTurn();
|
||||
private final EndOfCombat endOfCombat = new EndOfCombat();
|
||||
private final Untap untap = new Untap();
|
||||
private final Upkeep upkeep = new Upkeep();
|
||||
public final Cleanup cleanup;
|
||||
public final EndOfTurn endOfTurn;
|
||||
public final EndOfCombat endOfCombat;
|
||||
public final Untap untap;
|
||||
public final Upkeep upkeep;
|
||||
private final PhaseHandler phaseHandler;
|
||||
private final MagicStack stack;
|
||||
public final MagicStack stack;
|
||||
private final StaticEffects staticEffects = new StaticEffects();
|
||||
private final TriggerHandler triggerHandler = new TriggerHandler();
|
||||
private final ReplacementHandler replacementHandler = new ReplacementHandler();
|
||||
@@ -89,7 +89,7 @@ public class GameState {
|
||||
private final Zone stackZone = new Zone(ZoneType.Stack);
|
||||
|
||||
private long timestamp = 0;
|
||||
private final GameAction action;
|
||||
public final GameAction action;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -109,6 +109,12 @@ public class GameState {
|
||||
stack = new MagicStack(this);
|
||||
phaseHandler = new PhaseHandler(this);
|
||||
|
||||
untap = new Untap(this);
|
||||
upkeep = new Upkeep(this);
|
||||
cleanup = new Cleanup(this);
|
||||
endOfTurn = new EndOfTurn(this);
|
||||
endOfCombat = new EndOfCombat(this);
|
||||
|
||||
events.register(Singletons.getControl().getSoundSystem());
|
||||
events.register(gameLog);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
package forge.game.phase;
|
||||
|
||||
import forge.game.GameState;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Handles "until your next turn" effects and Cleanup hardcoded triggers.
|
||||
@@ -26,7 +28,10 @@ package forge.game.phase;
|
||||
*/
|
||||
public class Cleanup extends Phase {
|
||||
|
||||
|
||||
/** Constant <code>serialVersionUID=-6993476643509826990L</code>. */
|
||||
private static final long serialVersionUID = -6993476643509826990L;
|
||||
|
||||
public Cleanup(final GameState game) { super(game); }
|
||||
|
||||
} // end class Cleanup
|
||||
|
||||
@@ -55,6 +55,7 @@ import forge.card.staticability.StaticAbility;
|
||||
import forge.card.trigger.Trigger;
|
||||
import forge.card.trigger.TriggerHandler;
|
||||
import forge.card.trigger.TriggerType;
|
||||
import forge.game.GameState;
|
||||
import forge.game.GlobalRuleChange;
|
||||
import forge.game.player.ComputerUtil;
|
||||
import forge.game.player.ComputerUtilBlock;
|
||||
@@ -2706,11 +2707,12 @@ public class CombatUtil {
|
||||
*/
|
||||
public static void checkPropagandaEffects(final Card c, final boolean bLast) {
|
||||
Cost attackCost = new Cost(c, "0", true);
|
||||
final GameState game = Singletons.getModel().getGame();
|
||||
// Sort abilities to apply them in proper order
|
||||
for (Card card : Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield)) {
|
||||
final ArrayList<StaticAbility> staticAbilities = card.getStaticAbilities();
|
||||
for (final StaticAbility stAb : staticAbilities) {
|
||||
Cost additionalCost = stAb.getCostAbility("CantAttackUnless", c, Singletons.getModel().getGame().getCombat().getDefenderByAttacker(c));
|
||||
Cost additionalCost = stAb.getCostAbility("CantAttackUnless", c, game.getCombat().getDefenderByAttacker(c));
|
||||
attackCost = CostUtil.combineCosts(attackCost, additionalCost);
|
||||
}
|
||||
}
|
||||
@@ -2727,7 +2729,8 @@ public class CombatUtil {
|
||||
|
||||
final Card crd = c;
|
||||
|
||||
final PhaseType phase = Singletons.getModel().getGame().getPhaseHandler().getPhase();
|
||||
|
||||
final PhaseType phase = game.getPhaseHandler().getPhase();
|
||||
|
||||
if (phase == PhaseType.COMBAT_DECLARE_ATTACKERS || phase == PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) {
|
||||
final Ability ability = new AbilityStatic(c, attackCost, null) {
|
||||
@@ -2743,7 +2746,7 @@ public class CombatUtil {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
Singletons.getModel().getGame().getCombat().removeFromCombat(crd);
|
||||
game.getCombat().removeFromCombat(crd);
|
||||
|
||||
if (bLast) {
|
||||
PhaseUtil.handleAttackingTriggers();
|
||||
@@ -2768,17 +2771,17 @@ public class CombatUtil {
|
||||
};
|
||||
|
||||
if (c.getController().isHuman()) {
|
||||
GameActionUtil.payCostDuringAbilityResolve(ability, attackCost, paidCommand, unpaidCommand, null);
|
||||
GameActionUtil.payCostDuringAbilityResolve(ability, attackCost, paidCommand, unpaidCommand, null, game);
|
||||
} else { // computer
|
||||
if (ComputerUtil.canPayCost(ability, c.getController())) {
|
||||
ComputerUtil.playNoStack(c.getController(), ability);
|
||||
ComputerUtil.playNoStack(c.getController(), ability, game);
|
||||
if (!crd.hasKeyword("Vigilance")) {
|
||||
crd.tap();
|
||||
}
|
||||
} else {
|
||||
// TODO remove the below line after Propaganda occurs
|
||||
// during Declare_Attackers
|
||||
Singletons.getModel().getGame().getCombat().removeFromCombat(crd);
|
||||
game.getCombat().removeFromCombat(crd);
|
||||
}
|
||||
if (bLast) {
|
||||
PhaseUtil.handleAttackingTriggers();
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
package forge.game.phase;
|
||||
|
||||
import forge.game.GameState;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Handles "until end of combat" effects and "at end of combat" hardcoded triggers.
|
||||
@@ -30,4 +32,6 @@ public class EndOfCombat extends Phase {
|
||||
/** Constant <code>serialVersionUID=3035250030566186842L</code>. */
|
||||
private static final long serialVersionUID = 3035250030566186842L;
|
||||
|
||||
public EndOfCombat(final GameState game) { super(game); }
|
||||
|
||||
} // end class EndOfCombat
|
||||
|
||||
@@ -24,6 +24,7 @@ import forge.card.SpellManaCost;
|
||||
import forge.card.spellability.Ability;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.GameLossReason;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
|
||||
@@ -40,6 +41,7 @@ public class EndOfTurn extends Phase {
|
||||
/** Constant <code>serialVersionUID=-3656715295379727275L</code>. */
|
||||
private static final long serialVersionUID = -3656715295379727275L;
|
||||
|
||||
public EndOfTurn(final GameState game) { super(game); }
|
||||
/**
|
||||
* <p>
|
||||
* Handles all the hardcoded events that happen "at end of turn".
|
||||
@@ -48,11 +50,11 @@ public class EndOfTurn extends Phase {
|
||||
@Override
|
||||
public final void executeAt() {
|
||||
// reset mustAttackEntity for me
|
||||
Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn().setMustAttackEntity(null);
|
||||
game.getPhaseHandler().getPlayerTurn().setMustAttackEntity(null);
|
||||
|
||||
Singletons.getModel().getGame().getStaticEffects().rePopulateStateBasedList();
|
||||
game.getStaticEffects().rePopulateStateBasedList();
|
||||
|
||||
for (final Card c : Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield)) {
|
||||
for (final Card c : game.getCardsIn(ZoneType.Battlefield)) {
|
||||
if (!c.isFaceDown() && c.hasKeyword("At the beginning of the end step, sacrifice CARDNAME.")) {
|
||||
final Card card = c;
|
||||
final SpellAbility sac = new Ability(card, SpellManaCost.ZERO) {
|
||||
@@ -68,7 +70,7 @@ public class EndOfTurn extends Phase {
|
||||
sac.setStackDescription(sb.toString());
|
||||
sac.setDescription(sb.toString());
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(sac);
|
||||
game.getStack().addSimultaneousStackEntry(sac);
|
||||
|
||||
}
|
||||
if (!c.isFaceDown() && c.hasKeyword("At the beginning of the end step, exile CARDNAME.")) {
|
||||
@@ -86,7 +88,7 @@ public class EndOfTurn extends Phase {
|
||||
exile.setStackDescription(sb.toString());
|
||||
exile.setDescription(sb.toString());
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(exile);
|
||||
game.getStack().addSimultaneousStackEntry(exile);
|
||||
|
||||
}
|
||||
if (!c.isFaceDown() && c.hasKeyword("At the beginning of the end step, destroy CARDNAME.")) {
|
||||
@@ -95,7 +97,7 @@ public class EndOfTurn extends Phase {
|
||||
@Override
|
||||
public void resolve() {
|
||||
if (card.isInPlay()) {
|
||||
Singletons.getModel().getGame().getAction().destroy(card);
|
||||
game.getAction().destroy(card);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -104,7 +106,7 @@ public class EndOfTurn extends Phase {
|
||||
destroy.setStackDescription(sb.toString());
|
||||
destroy.setDescription(sb.toString());
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(destroy);
|
||||
game.getStack().addSimultaneousStackEntry(destroy);
|
||||
|
||||
}
|
||||
// Berserk is using this, so don't check isFaceDown()
|
||||
@@ -115,7 +117,7 @@ public class EndOfTurn extends Phase {
|
||||
@Override
|
||||
public void resolve() {
|
||||
if (card.isInPlay()) {
|
||||
Singletons.getModel().getGame().getAction().destroy(card);
|
||||
game.getAction().destroy(card);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -124,7 +126,7 @@ public class EndOfTurn extends Phase {
|
||||
sac.setStackDescription(sb.toString());
|
||||
sac.setDescription(sb.toString());
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(sac);
|
||||
game.getStack().addSimultaneousStackEntry(sac);
|
||||
|
||||
} else {
|
||||
c.removeAllExtrinsicKeyword("At the beginning of the next end step, "
|
||||
@@ -133,13 +135,13 @@ public class EndOfTurn extends Phase {
|
||||
}
|
||||
|
||||
if (c.hasKeyword("At the beginning of your end step, return CARDNAME to its owner's hand.")
|
||||
&& Singletons.getModel().getGame().getPhaseHandler().isPlayerTurn(c.getController())) {
|
||||
&& game.getPhaseHandler().isPlayerTurn(c.getController())) {
|
||||
final Card source = c;
|
||||
final SpellAbility change = new Ability(source, SpellManaCost.ZERO) {
|
||||
@Override
|
||||
public void resolve() {
|
||||
if (source.isInPlay()) {
|
||||
Singletons.getModel().getGame().getAction().moveToHand(source);
|
||||
game.getAction().moveToHand(source);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -148,12 +150,12 @@ public class EndOfTurn extends Phase {
|
||||
change.setStackDescription(sb.toString());
|
||||
change.setDescription(sb.toString());
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(change);
|
||||
game.getStack().addSimultaneousStackEntry(change);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Player activePlayer = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
Player activePlayer = game.getPhaseHandler().getPlayerTurn();
|
||||
if (activePlayer.hasKeyword("At the beginning of this turn's end step, you lose the game.")) {
|
||||
final Card source = new Card();
|
||||
final SpellAbility change = new Ability(source, SpellManaCost.ZERO) {
|
||||
@@ -166,7 +168,7 @@ public class EndOfTurn extends Phase {
|
||||
change.setDescription("At the beginning of this turn's end step, you lose the game.");
|
||||
change.setActivatingPlayer(activePlayer);
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(change);
|
||||
game.getStack().addSimultaneousStackEntry(change);
|
||||
}
|
||||
|
||||
this.execute(this.getAt());
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.HashMap;
|
||||
import forge.Command;
|
||||
import forge.CommandList;
|
||||
import forge.Singletons;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.Player;
|
||||
|
||||
|
||||
@@ -39,6 +40,11 @@ public abstract class Phase implements java.io.Serializable {
|
||||
|
||||
/** The at. */
|
||||
private final CommandList at = new CommandList();
|
||||
protected final GameState game;
|
||||
|
||||
public Phase(final GameState game0) {
|
||||
game = game0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the at.
|
||||
|
||||
@@ -33,6 +33,7 @@ import forge.GameEntity;
|
||||
import forge.Singletons;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.control.input.Input;
|
||||
import forge.game.GameState;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.Zone;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -51,9 +52,12 @@ import forge.view.ButtonUtil;
|
||||
* @version $Id: Untap 12482 2011-12-06 11:14:11Z Sloth $
|
||||
*/
|
||||
public class Untap extends Phase {
|
||||
|
||||
private static final long serialVersionUID = 4515266331266259123L;
|
||||
|
||||
public Untap(final GameState game0) {
|
||||
super(game0);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Executes any hardcoded triggers that happen "at end of combat".
|
||||
@@ -63,7 +67,7 @@ public class Untap extends Phase {
|
||||
public void executeAt() {
|
||||
this.execute(this.getAt());
|
||||
|
||||
final Player turn = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
final Player turn = game.getPhaseHandler().getPlayerTurn();
|
||||
Untap.doPhasing(turn);
|
||||
|
||||
Untap.doUntap();
|
||||
|
||||
@@ -69,6 +69,8 @@ import forge.view.ButtonUtil;
|
||||
public class Upkeep extends Phase {
|
||||
private static final long serialVersionUID = 6906459482978819354L;
|
||||
|
||||
public Upkeep(final GameState game) { super(game); }
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Handles all the hardcoded events that happen at the beginning of each
|
||||
@@ -80,29 +82,30 @@ public class Upkeep extends Phase {
|
||||
*/
|
||||
@Override
|
||||
public final void executeAt() {
|
||||
Singletons.getModel().getGame().getStack().freezeStack();
|
||||
Upkeep.upkeepBraidOfFire();
|
||||
|
||||
Upkeep.upkeepSlowtrips(); // for "Draw a card at the beginning of the next turn's upkeep."
|
||||
Upkeep.upkeepUpkeepCost(); // sacrifice unless upkeep cost is paid
|
||||
Upkeep.upkeepEcho();
|
||||
game.getStack().freezeStack();
|
||||
Upkeep.upkeepBraidOfFire(game);
|
||||
|
||||
Upkeep.upkeepTheAbyss();
|
||||
Upkeep.upkeepDropOfHoney();
|
||||
Upkeep.upkeepDemonicHordes();
|
||||
Upkeep.upkeepTangleWire();
|
||||
Upkeep.upkeepSlowtrips(game); // for "Draw a card at the beginning of the next turn's upkeep."
|
||||
Upkeep.upkeepUpkeepCost(game); // sacrifice unless upkeep cost is paid
|
||||
Upkeep.upkeepEcho(game);
|
||||
|
||||
Upkeep.upkeepKarma();
|
||||
Upkeep.upkeepOathOfDruids();
|
||||
Upkeep.upkeepOathOfGhouls();
|
||||
Upkeep.upkeepSuspend();
|
||||
Upkeep.upkeepVanishing();
|
||||
Upkeep.upkeepFading();
|
||||
Upkeep.upkeepBlazeCounters();
|
||||
Upkeep.upkeepCurseOfMisfortunes();
|
||||
Upkeep.upkeepPowerSurge();
|
||||
Upkeep.upkeepTheAbyss(game);
|
||||
Upkeep.upkeepDropOfHoney(game);
|
||||
Upkeep.upkeepDemonicHordes(game);
|
||||
Upkeep.upkeepTangleWire(game);
|
||||
|
||||
Singletons.getModel().getGame().getStack().unfreezeStack();
|
||||
Upkeep.upkeepKarma(game);
|
||||
Upkeep.upkeepOathOfDruids(game);
|
||||
Upkeep.upkeepOathOfGhouls(game);
|
||||
Upkeep.upkeepSuspend(game);
|
||||
Upkeep.upkeepVanishing(game);
|
||||
Upkeep.upkeepFading(game);
|
||||
Upkeep.upkeepBlazeCounters(game);
|
||||
Upkeep.upkeepCurseOfMisfortunes(game);
|
||||
Upkeep.upkeepPowerSurge(game);
|
||||
|
||||
game.getStack().unfreezeStack();
|
||||
}
|
||||
|
||||
// UPKEEP CARDS:
|
||||
@@ -112,8 +115,8 @@ public class Upkeep extends Phase {
|
||||
* upkeepBraidOfFire.
|
||||
* </p>
|
||||
*/
|
||||
private static void upkeepBraidOfFire() {
|
||||
final Player player = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
private static void upkeepBraidOfFire(final GameState game) {
|
||||
final Player player = game.getPhaseHandler().getPlayerTurn();
|
||||
|
||||
final List<Card> braids = player.getCardsIn(ZoneType.Battlefield, "Braid of Fire");
|
||||
|
||||
@@ -138,14 +141,14 @@ public class Upkeep extends Phase {
|
||||
} else if (GameActionUtil.showYesNoDialog(c, sb.toString())) {
|
||||
abMana.produceMana(this);
|
||||
} else {
|
||||
Singletons.getModel().getGame().getAction().sacrifice(c, null);
|
||||
game.getAction().sacrifice(c, null);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
upkeepAbility.setStackDescription(sb.toString());
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(upkeepAbility);
|
||||
game.getStack().addSimultaneousStackEntry(upkeepAbility);
|
||||
|
||||
}
|
||||
} // upkeepBraidOfFire
|
||||
@@ -155,8 +158,8 @@ public class Upkeep extends Phase {
|
||||
* upkeepEcho.
|
||||
* </p>
|
||||
*/
|
||||
private static void upkeepEcho() {
|
||||
List<Card> list = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn().getCardsIn(ZoneType.Battlefield);
|
||||
private static void upkeepEcho(final GameState game) {
|
||||
List<Card> list = game.getPhaseHandler().getPlayerTurn().getCardsIn(ZoneType.Battlefield);
|
||||
list = CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
@@ -175,7 +178,7 @@ public class Upkeep extends Phase {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
Singletons.getModel().getGame().getAction().sacrifice(c, null);
|
||||
game.getAction().sacrifice(c, null);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -187,15 +190,16 @@ public class Upkeep extends Phase {
|
||||
final Ability sacAbility = new Ability(c, SpellManaCost.ZERO) {
|
||||
@Override
|
||||
public void resolve() {
|
||||
|
||||
Player controller = c.getController();
|
||||
if (controller.isHuman()) {
|
||||
Cost cost = new Cost(c, c.getEchoCost().trim(), true);
|
||||
GameActionUtil.payCostDuringAbilityResolve(blankAbility, cost, paidCommand, unpaidCommand, null);
|
||||
GameActionUtil.payCostDuringAbilityResolve(blankAbility, cost, paidCommand, unpaidCommand, null, game);
|
||||
} else { // computer
|
||||
if (ComputerUtil.canPayCost(blankAbility, controller)) {
|
||||
ComputerUtil.playNoStack(controller, blankAbility);
|
||||
ComputerUtil.playNoStack(controller, blankAbility, game);
|
||||
} else {
|
||||
Singletons.getModel().getGame().getAction().sacrifice(c, null);
|
||||
game.getAction().sacrifice(c, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -203,7 +207,7 @@ public class Upkeep extends Phase {
|
||||
sacAbility.setStackDescription(sb.toString());
|
||||
sacAbility.setDescription(sb.toString());
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(sacAbility);
|
||||
game.getStack().addSimultaneousStackEntry(sacAbility);
|
||||
|
||||
c.removeAllExtrinsicKeyword("(Echo unpaid)");
|
||||
}
|
||||
@@ -215,20 +219,20 @@ public class Upkeep extends Phase {
|
||||
* upkeepSlowtrips. Draw a card at the beginning of the next turn's upkeep.
|
||||
* </p>
|
||||
*/
|
||||
private static void upkeepSlowtrips() {
|
||||
Player turnOwner = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
private static void upkeepSlowtrips(final GameState game) {
|
||||
Player turnOwner = game.getPhaseHandler().getPlayerTurn();
|
||||
|
||||
// does order matter here?
|
||||
drawForSlowtrips(turnOwner);
|
||||
for (Player p : Singletons.getModel().getGame().getPlayers()) {
|
||||
drawForSlowtrips(turnOwner, game);
|
||||
for (Player p : game.getPlayers()) {
|
||||
if (p == turnOwner) {
|
||||
continue;
|
||||
}
|
||||
drawForSlowtrips(p);
|
||||
drawForSlowtrips(p, game);
|
||||
}
|
||||
}
|
||||
|
||||
public static void drawForSlowtrips(final Player player) {
|
||||
public static void drawForSlowtrips(final Player player, final GameState game) {
|
||||
List<Card> list = player.getSlowtripList();
|
||||
|
||||
for (Card card : list) {
|
||||
@@ -244,7 +248,7 @@ public class Upkeep extends Phase {
|
||||
slowtrip.setStackDescription(card + " - Draw a card.");
|
||||
slowtrip.setDescription(card + " - Draw a card.");
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(slowtrip);
|
||||
game.getStack().addSimultaneousStackEntry(slowtrip);
|
||||
|
||||
}
|
||||
player.clearSlowtripList();
|
||||
@@ -255,8 +259,9 @@ public class Upkeep extends Phase {
|
||||
* upkeepUpkeepCost.
|
||||
* </p>
|
||||
*/
|
||||
private static void upkeepUpkeepCost() {
|
||||
final List<Card> list = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn().getCardsIn(ZoneType.Battlefield);
|
||||
private static void upkeepUpkeepCost(final GameState game) {
|
||||
|
||||
final List<Card> list = game.getPhaseHandler().getPlayerTurn().getCardsIn(ZoneType.Battlefield);
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
final Card c = list.get(i);
|
||||
@@ -278,7 +283,7 @@ public class Upkeep extends Phase {
|
||||
if (c.getName().equals("Cosmic Horror")) {
|
||||
controller.addDamage(7, c);
|
||||
}
|
||||
Singletons.getModel().getGame().getAction().destroy(c);
|
||||
game.getAction().destroy(c);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -295,12 +300,12 @@ public class Upkeep extends Phase {
|
||||
GameActionUtil.payManaDuringAbilityResolve(sb.toString(), upkeepCost, paidCommand, unpaidCommand);
|
||||
} else { // computer
|
||||
if (ComputerUtil.canPayCost(aiPaid, controller) && !c.hasKeyword("Indestructible")) {
|
||||
ComputerUtil.playNoStack(controller, aiPaid);
|
||||
ComputerUtil.playNoStack(controller, aiPaid, game);
|
||||
} else {
|
||||
if (c.getName().equals("Cosmic Horror")) {
|
||||
controller.addDamage(7, c);
|
||||
}
|
||||
Singletons.getModel().getGame().getAction().destroy(c);
|
||||
game.getAction().destroy(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -308,7 +313,7 @@ public class Upkeep extends Phase {
|
||||
upkeepAbility.setStackDescription(sb.toString());
|
||||
upkeepAbility.setDescription(sb.toString());
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(upkeepAbility);
|
||||
game.getStack().addSimultaneousStackEntry(upkeepAbility);
|
||||
} // destroy
|
||||
|
||||
// sacrifice
|
||||
@@ -337,7 +342,7 @@ public class Upkeep extends Phase {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
Singletons.getModel().getGame().getAction().sacrifice(c, null);
|
||||
game.getAction().sacrifice(c, null);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -350,12 +355,12 @@ public class Upkeep extends Phase {
|
||||
public void resolve() {
|
||||
if (controller.isHuman()) {
|
||||
GameActionUtil.payCostDuringAbilityResolve(blankAbility, blankAbility.getPayCosts(),
|
||||
paidCommand, unpaidCommand, null);
|
||||
paidCommand, unpaidCommand, null, game);
|
||||
} else { // computer
|
||||
if (ComputerUtil.shouldPayCost(controller, c, upkeepCost) && ComputerUtil.canPayCost(blankAbility, controller)) {
|
||||
ComputerUtil.playNoStack(controller, blankAbility);
|
||||
ComputerUtil.playNoStack(controller, blankAbility, game);
|
||||
} else {
|
||||
Singletons.getModel().getGame().getAction().sacrifice(c, null);
|
||||
game.getAction().sacrifice(c, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -363,7 +368,7 @@ public class Upkeep extends Phase {
|
||||
upkeepAbility.setStackDescription(sb.toString());
|
||||
upkeepAbility.setDescription(sb.toString());
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(upkeepAbility);
|
||||
game.getStack().addSimultaneousStackEntry(upkeepAbility);
|
||||
} // sacrifice
|
||||
|
||||
// destroy
|
||||
@@ -397,7 +402,7 @@ public class Upkeep extends Phase {
|
||||
} else { // computers
|
||||
if (ComputerUtil.canPayCost(aiPaid, controller)
|
||||
&& (controller.predictDamage(upkeepDamage, c, false) > 0)) {
|
||||
ComputerUtil.playNoStack(controller, aiPaid);
|
||||
ComputerUtil.playNoStack(controller, aiPaid, game);
|
||||
} else {
|
||||
controller.addDamage(upkeepDamage, c);
|
||||
}
|
||||
@@ -407,7 +412,7 @@ public class Upkeep extends Phase {
|
||||
upkeepAbility.setStackDescription(sb.toString());
|
||||
upkeepAbility.setDescription(sb.toString());
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(upkeepAbility);
|
||||
game.getStack().addSimultaneousStackEntry(upkeepAbility);
|
||||
} // destroy
|
||||
}
|
||||
|
||||
@@ -442,15 +447,15 @@ public class Upkeep extends Phase {
|
||||
* upkeepTheAbyss.
|
||||
* </p>
|
||||
*/
|
||||
private static void upkeepTheAbyss() {
|
||||
private static void upkeepTheAbyss(final GameState game) {
|
||||
/*
|
||||
* At the beginning of each player's upkeep, destroy target nonartifact
|
||||
* creature that player controls of his or her choice. It can't be
|
||||
* regenerated.
|
||||
*/
|
||||
final Player player = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
final List<Card> the = CardLists.filter(Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("The Abyss"));
|
||||
final List<Card> magus = CardLists.filter(Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("Magus of the Abyss"));
|
||||
final Player player = game.getPhaseHandler().getPlayerTurn();
|
||||
final List<Card> the = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("The Abyss"));
|
||||
final List<Card> magus = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("Magus of the Abyss"));
|
||||
|
||||
final List<Card> cards = new ArrayList<Card>();
|
||||
cards.addAll(the);
|
||||
@@ -480,7 +485,7 @@ public class Upkeep extends Phase {
|
||||
|
||||
@Override
|
||||
protected Input onDone() {
|
||||
Singletons.getModel().getGame().getAction().destroyNoRegeneration(selected.get(0));
|
||||
game.getAction().destroyNoRegeneration(selected.get(0));
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@@ -490,13 +495,13 @@ public class Upkeep extends Phase {
|
||||
|
||||
final List<Card> indestruct = CardLists.getKeyword(targets, "Indestructible");
|
||||
if (indestruct.size() > 0) {
|
||||
Singletons.getModel().getGame().getAction().destroyNoRegeneration(indestruct.get(0));
|
||||
game.getAction().destroyNoRegeneration(indestruct.get(0));
|
||||
} else if (targets.size() > 0) {
|
||||
final Card target = CardFactoryUtil.getWorstCreatureAI(targets);
|
||||
if (null == target) {
|
||||
// must be nothing valid to destroy
|
||||
} else {
|
||||
Singletons.getModel().getGame().getAction().destroyNoRegeneration(target);
|
||||
game.getAction().destroyNoRegeneration(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -506,7 +511,7 @@ public class Upkeep extends Phase {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(abyss.getName()).append(" - destroy a nonartifact creature of your choice.");
|
||||
sacrificeCreature.setStackDescription(sb.toString());
|
||||
Singletons.getModel().getGame().getStack().addAndUnfreeze(sacrificeCreature);
|
||||
game.getStack().addAndUnfreeze(sacrificeCreature);
|
||||
} // end for
|
||||
} // The Abyss
|
||||
|
||||
@@ -515,13 +520,13 @@ public class Upkeep extends Phase {
|
||||
* upkeepDropOfHoney.
|
||||
* </p>
|
||||
*/
|
||||
private static void upkeepDropOfHoney() {
|
||||
private static void upkeepDropOfHoney(final GameState game) {
|
||||
/*
|
||||
* At the beginning of your upkeep, destroy the creature with the least
|
||||
* power. It can't be regenerated. If two or more creatures are tied for
|
||||
* least power, you choose one of them.
|
||||
*/
|
||||
final Player player = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
final Player player = game.getPhaseHandler().getPlayerTurn();
|
||||
final List<Card> drops = player.getCardsIn(ZoneType.Battlefield, "Drop of Honey");
|
||||
drops.addAll(player.getCardsIn(ZoneType.Battlefield, "Porphyry Nodes"));
|
||||
final List<Card> cards = drops;
|
||||
@@ -532,7 +537,7 @@ public class Upkeep extends Phase {
|
||||
final Ability ability = new Ability(c, SpellManaCost.NO_COST) {
|
||||
@Override
|
||||
public void resolve() {
|
||||
final List<Card> creatures = CardLists.filter(Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield), Presets.CREATURES);
|
||||
final List<Card> creatures = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), Presets.CREATURES);
|
||||
if (creatures.size() > 0) {
|
||||
CardLists.sortAttackLowFirst(creatures);
|
||||
final int power = creatures.get(0).getNetAttack();
|
||||
@@ -542,7 +547,7 @@ public class Upkeep extends Phase {
|
||||
"Select creature with power: " + power + " to sacrifice."));
|
||||
} else { // computer
|
||||
final Card compyTarget = this.getCompyCardToDestroy(creatures);
|
||||
Singletons.getModel().getGame().getAction().destroyNoRegeneration(compyTarget);
|
||||
game.getAction().destroyNoRegeneration(compyTarget);
|
||||
}
|
||||
}
|
||||
} // resolve
|
||||
@@ -580,7 +585,7 @@ public class Upkeep extends Phase {
|
||||
sb.append(c.getName()).append(" - destroy 1 creature with lowest power.");
|
||||
ability.setStackDescription(sb.toString());
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(ability);
|
||||
game.getStack().addSimultaneousStackEntry(ability);
|
||||
|
||||
} // end for
|
||||
} // upkeepDropOfHoney()
|
||||
@@ -590,14 +595,14 @@ public class Upkeep extends Phase {
|
||||
* upkeepDemonicHordes.
|
||||
* </p>
|
||||
*/
|
||||
private static void upkeepDemonicHordes() {
|
||||
private static void upkeepDemonicHordes(final GameState game) {
|
||||
|
||||
/*
|
||||
* At the beginning of your upkeep, unless you pay BBB, tap Demonic
|
||||
* Hordes and sacrifice a land of an opponent's choice.
|
||||
*/
|
||||
|
||||
final Player player = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
final Player player = game.getPhaseHandler().getPlayerTurn();
|
||||
final List<Card> cards = player.getCardsIn(ZoneType.Battlefield, "Demonic Hordes");
|
||||
|
||||
for (int i = 0; i < cards.size(); i++) {
|
||||
@@ -625,7 +630,7 @@ public class Upkeep extends Phase {
|
||||
} else {
|
||||
target = CardFactoryUtil.getBestLandAI(playerLand);
|
||||
}
|
||||
Singletons.getModel().getGame().getAction().sacrifice(target, null);
|
||||
game.getAction().sacrifice(target, null);
|
||||
} // end resolve()
|
||||
}; // end noPay ability
|
||||
|
||||
@@ -636,7 +641,7 @@ public class Upkeep extends Phase {
|
||||
final Ability pay = new Ability(c, SpellManaCost.ZERO) {
|
||||
@Override
|
||||
public void resolve() {
|
||||
if (Singletons.getModel().getGame().getZoneOf(c).is(ZoneType.Battlefield)) {
|
||||
if (game.getZoneOf(c).is(ZoneType.Battlefield)) {
|
||||
final StringBuilder coststring = new StringBuilder();
|
||||
coststring.append("Pay cost for ").append(c).append("\r\n");
|
||||
GameActionUtil.payManaDuringAbilityResolve(coststring.toString(), cost.getManaCost(),
|
||||
@@ -647,7 +652,7 @@ public class Upkeep extends Phase {
|
||||
pay.setStackDescription("Demonic Hordes - Upkeep Cost");
|
||||
pay.setDescription("Demonic Hordes - Upkeep Cost");
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(pay);
|
||||
game.getStack().addSimultaneousStackEntry(pay);
|
||||
|
||||
} // end choice
|
||||
else {
|
||||
@@ -655,7 +660,7 @@ public class Upkeep extends Phase {
|
||||
sb.append(c.getName()).append(" - is tapped and you must sacrifice a land of opponent's choice");
|
||||
noPay.setStackDescription(sb.toString());
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(noPay);
|
||||
game.getStack().addSimultaneousStackEntry(noPay);
|
||||
|
||||
}
|
||||
} // end human
|
||||
@@ -670,10 +675,10 @@ public class Upkeep extends Phase {
|
||||
};
|
||||
computerPay.setStackDescription("Computer pays Demonic Hordes upkeep cost");
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(computerPay);
|
||||
game.getStack().addSimultaneousStackEntry(computerPay);
|
||||
} else {
|
||||
noPay.setStackDescription("Demonic Hordes - Upkeep Cost");
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(noPay);
|
||||
game.getStack().addSimultaneousStackEntry(noPay);
|
||||
|
||||
}
|
||||
} // end computer
|
||||
@@ -687,8 +692,8 @@ public class Upkeep extends Phase {
|
||||
* upkeepSuspend.
|
||||
* </p>
|
||||
*/
|
||||
private static void upkeepSuspend() {
|
||||
final Player player = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
private static void upkeepSuspend(final GameState game) {
|
||||
final Player player = game.getPhaseHandler().getPlayerTurn();
|
||||
|
||||
List<Card> list = player.getCardsIn(ZoneType.Exile);
|
||||
|
||||
@@ -716,9 +721,9 @@ public class Upkeep extends Phase {
|
||||
* upkeepVanishing.
|
||||
* </p>
|
||||
*/
|
||||
private static void upkeepVanishing() {
|
||||
private static void upkeepVanishing(final GameState game) {
|
||||
|
||||
final Player player = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
final Player player = game.getPhaseHandler().getPlayerTurn();
|
||||
List<Card> list = player.getCardsIn(ZoneType.Battlefield);
|
||||
list = CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
@@ -743,7 +748,7 @@ public class Upkeep extends Phase {
|
||||
ability.setDescription(sb.toString());
|
||||
ability.setActivatingPlayer(card.getController());
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(ability);
|
||||
game.getStack().addSimultaneousStackEntry(ability);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -754,9 +759,9 @@ public class Upkeep extends Phase {
|
||||
* upkeepFading.
|
||||
* </p>
|
||||
*/
|
||||
private static void upkeepFading() {
|
||||
private static void upkeepFading(final GameState game) {
|
||||
|
||||
final Player player = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
final Player player = game.getPhaseHandler().getPlayerTurn();
|
||||
List<Card> list = player.getCardsIn(ZoneType.Battlefield);
|
||||
list = CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
@@ -772,7 +777,7 @@ public class Upkeep extends Phase {
|
||||
public void resolve() {
|
||||
final int fadeCounters = card.getCounters(CounterType.FADE);
|
||||
if (fadeCounters <= 0) {
|
||||
Singletons.getModel().getGame().getAction().sacrifice(card, null);
|
||||
game.getAction().sacrifice(card, null);
|
||||
} else {
|
||||
card.subtractCounter(CounterType.FADE, 1);
|
||||
}
|
||||
@@ -786,7 +791,7 @@ public class Upkeep extends Phase {
|
||||
ability.setDescription(sb.toString());
|
||||
ability.setActivatingPlayer(card.getController());
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(ability);
|
||||
game.getStack().addSimultaneousStackEntry(ability);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -797,14 +802,14 @@ public class Upkeep extends Phase {
|
||||
* upkeepOathOfDruids.
|
||||
* </p>
|
||||
*/
|
||||
private static void upkeepOathOfDruids() {
|
||||
final List<Card> oathList = CardLists.filter(Singletons.getModel().getGame()
|
||||
private static void upkeepOathOfDruids(final GameState game) {
|
||||
final List<Card> oathList = CardLists.filter(game
|
||||
.getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("Oath of Druids"));
|
||||
if (oathList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Player player = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
final Player player = game.getPhaseHandler().getPlayerTurn();
|
||||
|
||||
if (GameState.compareTypeAmountInPlay(player, "Creature") < 0) {
|
||||
for (int i = 0; i < oathList.size(); i++) {
|
||||
@@ -845,10 +850,10 @@ public class Upkeep extends Phase {
|
||||
for (final Card c : libraryList) {
|
||||
cardsToReveal.add(c);
|
||||
if (c.isCreature()) {
|
||||
Singletons.getModel().getGame().getAction().moveTo(battlefield, c);
|
||||
game.getAction().moveTo(battlefield, c);
|
||||
break;
|
||||
} else {
|
||||
Singletons.getModel().getGame().getAction().moveToGraveyard(c);
|
||||
game.getAction().moveToGraveyard(c);
|
||||
}
|
||||
} // for loop
|
||||
if (cardsToReveal.size() > 0) {
|
||||
@@ -869,7 +874,7 @@ public class Upkeep extends Phase {
|
||||
ability.setDescription(sb.toString());
|
||||
ability.setActivatingPlayer(oath.getController());
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(ability);
|
||||
game.getStack().addSimultaneousStackEntry(ability);
|
||||
}
|
||||
}
|
||||
} // upkeepOathOfDruids()
|
||||
@@ -879,13 +884,13 @@ public class Upkeep extends Phase {
|
||||
* upkeepOathOfGhouls.
|
||||
* </p>
|
||||
*/
|
||||
private static void upkeepOathOfGhouls() {
|
||||
final List<Card> oathList = CardLists.filter(Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("Oath of Ghouls"));
|
||||
private static void upkeepOathOfGhouls(final GameState game) {
|
||||
final List<Card> oathList = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("Oath of Ghouls"));
|
||||
if (oathList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Player player = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
final Player player = game.getPhaseHandler().getPlayerTurn();
|
||||
|
||||
if (GameState.compareTypeAmountInGraveyard(player, "Creature") > 0) {
|
||||
for (int i = 0; i < oathList.size(); i++) {
|
||||
@@ -901,12 +906,12 @@ public class Upkeep extends Phase {
|
||||
if (o != null) {
|
||||
final Card card = o;
|
||||
|
||||
Singletons.getModel().getGame().getAction().moveToHand(card);
|
||||
game.getAction().moveToHand(card);
|
||||
}
|
||||
} else if (player.isComputer()) {
|
||||
final Card card = graveyardCreatures.get(0);
|
||||
|
||||
Singletons.getModel().getGame().getAction().moveToHand(card);
|
||||
game.getAction().moveToHand(card);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -919,7 +924,7 @@ public class Upkeep extends Phase {
|
||||
ability.setDescription(sb.toString());
|
||||
ability.setActivatingPlayer(oathList.get(0).getController());
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(ability);
|
||||
game.getStack().addSimultaneousStackEntry(ability);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -930,10 +935,10 @@ public class Upkeep extends Phase {
|
||||
* upkeepKarma.
|
||||
* </p>
|
||||
*/
|
||||
private static void upkeepKarma() {
|
||||
final Player player = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
private static void upkeepKarma(final GameState game) {
|
||||
final Player player = game.getPhaseHandler().getPlayerTurn();
|
||||
final List<Card> karmas =
|
||||
CardLists.filter(Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("Karma"));
|
||||
CardLists.filter(game.getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("Karma"));
|
||||
final List<Card> swamps = CardLists.getType(player.getCardsIn(ZoneType.Battlefield), "Swamp");
|
||||
|
||||
// determine how much damage to deal the current player
|
||||
@@ -959,7 +964,7 @@ public class Upkeep extends Phase {
|
||||
ability.setDescription(sb.toString());
|
||||
ability.setActivatingPlayer(karma.getController());
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(ability);
|
||||
game.getStack().addSimultaneousStackEntry(ability);
|
||||
}
|
||||
}
|
||||
} // if
|
||||
@@ -970,14 +975,14 @@ public class Upkeep extends Phase {
|
||||
* upkeepPowerSurge.
|
||||
* </p>
|
||||
*/
|
||||
private static void upkeepPowerSurge() {
|
||||
private static void upkeepPowerSurge(final GameState game) {
|
||||
/*
|
||||
* At the beginning of each player's upkeep, Power Surge deals X damage
|
||||
* to that player, where X is the number of untapped lands he or she
|
||||
* controlled at the beginning of this turn.
|
||||
*/
|
||||
final Player player = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
final List<Card> list = CardLists.filter(Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("Power Surge"));
|
||||
final Player player = game.getPhaseHandler().getPlayerTurn();
|
||||
final List<Card> list = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("Power Surge"));
|
||||
final int damage = player.getNumPowerSurgeLands();
|
||||
|
||||
for (final Card surge : list) {
|
||||
@@ -995,7 +1000,7 @@ public class Upkeep extends Phase {
|
||||
ability.setDescription(sb.toString());
|
||||
|
||||
if (damage > 0) {
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(ability);
|
||||
game.getStack().addSimultaneousStackEntry(ability);
|
||||
}
|
||||
} // for
|
||||
} // upkeepPowerSurge()
|
||||
@@ -1005,9 +1010,9 @@ public class Upkeep extends Phase {
|
||||
* upkeepTangleWire.
|
||||
* </p>
|
||||
*/
|
||||
private static void upkeepTangleWire() {
|
||||
final Player player = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
final List<Card> wires = CardLists.filter(Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("Tangle Wire"));
|
||||
private static void upkeepTangleWire(final GameState game) {
|
||||
final Player player = game.getPhaseHandler().getPlayerTurn();
|
||||
final List<Card> wires = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("Tangle Wire"));
|
||||
|
||||
for (final Card source : wires) {
|
||||
final SpellAbility ability = new Ability(source, SpellManaCost.ZERO) {
|
||||
@@ -1064,7 +1069,7 @@ public class Upkeep extends Phase {
|
||||
|
||||
@Override
|
||||
public void selectCard(final Card card) {
|
||||
Zone zone = Singletons.getModel().getGame().getZoneOf(card);
|
||||
Zone zone = game.getZoneOf(card);
|
||||
if (zone.is(ZoneType.Battlefield, player) && list.contains(card)) {
|
||||
card.tap();
|
||||
list.remove(card);
|
||||
@@ -1081,7 +1086,7 @@ public class Upkeep extends Phase {
|
||||
ability.setDescription(source.getName() + " - " + player
|
||||
+ " taps X artifacts, creatures or lands he or she controls.");
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(ability);
|
||||
game.getStack().addSimultaneousStackEntry(ability);
|
||||
|
||||
} // foreach(wire)
|
||||
} // upkeepTangleWire()
|
||||
@@ -1091,8 +1096,8 @@ public class Upkeep extends Phase {
|
||||
* upkeepBlazeCounters.
|
||||
* </p>
|
||||
*/
|
||||
private static void upkeepBlazeCounters() {
|
||||
final Player player = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
private static void upkeepBlazeCounters(final GameState game) {
|
||||
final Player player = game.getPhaseHandler().getPlayerTurn();
|
||||
|
||||
List<Card> blaze = player.getCardsIn(ZoneType.Battlefield);
|
||||
blaze = CardLists.filter(blaze, new Predicate<Card>() {
|
||||
@@ -1116,7 +1121,7 @@ public class Upkeep extends Phase {
|
||||
sb.append(player).append(".");
|
||||
ability.setStackDescription(sb.toString());
|
||||
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(ability);
|
||||
game.getStack().addSimultaneousStackEntry(ability);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1126,8 +1131,8 @@ public class Upkeep extends Phase {
|
||||
* upkeepCurseOfMisfortunes.
|
||||
* </p>
|
||||
*/
|
||||
private static void upkeepCurseOfMisfortunes() {
|
||||
final Player player = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||
private static void upkeepCurseOfMisfortunes(final GameState game) {
|
||||
final Player player = game.getPhaseHandler().getPlayerTurn();
|
||||
|
||||
final List<Card> misfortunes = player.getCardsIn(ZoneType.Battlefield, "Curse of Misfortunes");
|
||||
|
||||
@@ -1163,8 +1168,8 @@ public class Upkeep extends Phase {
|
||||
enchantment = CardFactoryUtil.getBestEnchantmentAI(enchantmentsInLibrary, this, false);
|
||||
}
|
||||
if (enchantment != null) {
|
||||
Singletons.getModel().getGame().getAction().changeZone(
|
||||
Singletons.getModel().getGame().getZoneOf(enchantment),
|
||||
game.getAction().changeZone(
|
||||
game.getZoneOf(enchantment),
|
||||
enchantment.getOwner().getZone(ZoneType.Battlefield), enchantment, null);
|
||||
enchantment.enchantEntity(source.getEnchantingPlayer());
|
||||
}
|
||||
@@ -1178,7 +1183,7 @@ public class Upkeep extends Phase {
|
||||
+ " the same name as a Curse attached to enchanted player, "
|
||||
+ "put it onto the battlefield attached to that player, then shuffle you library.");
|
||||
ability.setStackDescription(sb.toString());
|
||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(ability);
|
||||
game.getStack().addSimultaneousStackEntry(ability);
|
||||
}
|
||||
} // upkeepCurseOfMisfortunes
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ public class ComputerAIGeneral implements Computer {
|
||||
private void playSpellAbilitiesStackEmpty() {
|
||||
final List<Card> list = getAvailableCards();
|
||||
|
||||
final boolean nextPhase = ComputerUtil.playSpellAbilities(player, getSpellAbilities(list));
|
||||
final boolean nextPhase = ComputerUtil.playSpellAbilities(player, getSpellAbilities(list), game);
|
||||
|
||||
if (nextPhase) {
|
||||
game.getPhaseHandler().passPriority();
|
||||
@@ -360,7 +360,7 @@ public class ComputerAIGeneral implements Computer {
|
||||
|
||||
possibleCounters.clear();
|
||||
possibleCounters = this.getPossibleETBCounters();
|
||||
if ((possibleCounters.size() > 0) && !ComputerUtil.playSpellAbilities(player, possibleCounters)) {
|
||||
if ((possibleCounters.size() > 0) && !ComputerUtil.playSpellAbilities(player, possibleCounters, game)) {
|
||||
// Responding Permanent w/ ETB Counter is on the Stack
|
||||
// If playSpellAbilities returns false, a Spell is hitting the Stack
|
||||
return;
|
||||
@@ -368,7 +368,7 @@ public class ComputerAIGeneral implements Computer {
|
||||
final ArrayList<SpellAbility> sas = this.getSpellAbilities(cards);
|
||||
if (sas.size() > 0) {
|
||||
// Spell not Countered
|
||||
if (!ComputerUtil.playSpellAbilities(player, sas)) {
|
||||
if (!ComputerUtil.playSpellAbilities(player, sas, game)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.control.input.InputPayManaCostUtil;
|
||||
import forge.error.ErrorViewer;
|
||||
import forge.game.GameState;
|
||||
import forge.game.phase.Combat;
|
||||
import forge.game.phase.CombatUtil;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
@@ -90,7 +91,7 @@ public class ComputerUtil {
|
||||
* objects.
|
||||
* @return a boolean.
|
||||
*/
|
||||
public static boolean playSpellAbilities(final Player ai, final List<SpellAbility> all) {
|
||||
public static boolean playSpellAbilities(final Player ai, final List<SpellAbility> all, final GameState game) {
|
||||
// not sure "playing biggest spell" matters?
|
||||
ComputerUtil.sortSpellAbilityByCost(all);
|
||||
ArrayList<SpellAbility> abilities = new ArrayList<SpellAbility>();
|
||||
@@ -113,7 +114,7 @@ public class ComputerUtil {
|
||||
}
|
||||
sa.setActivatingPlayer(ai);
|
||||
|
||||
if (ComputerUtil.canBePlayedAndPayedByAI(ai, sa) && ComputerUtil.handlePlayingSpellAbility(ai, sa)) {
|
||||
if (ComputerUtil.canBePlayedAndPayedByAI(ai, sa) && ComputerUtil.handlePlayingSpellAbility(ai, sa, game)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -129,26 +130,26 @@ public class ComputerUtil {
|
||||
* a {@link forge.card.spellability.SpellAbility} object.
|
||||
* @return a boolean.
|
||||
*/
|
||||
public static boolean handlePlayingSpellAbility(final Player ai, final SpellAbility sa) {
|
||||
public static boolean handlePlayingSpellAbility(final Player ai, final SpellAbility sa, final GameState game) {
|
||||
|
||||
if (sa instanceof AbilityStatic) {
|
||||
final Cost cost = sa.getPayCosts();
|
||||
if (cost == null && ComputerUtil.payManaCost(sa, ai, false, 0, true)) {
|
||||
sa.resolve();
|
||||
} else {
|
||||
final CostPayment pay = new CostPayment(cost, sa);
|
||||
if (pay.payComputerCosts(ai)) {
|
||||
final CostPayment pay = new CostPayment(cost, sa, game);
|
||||
if (pay.payComputerCosts(ai, game)) {
|
||||
sa.resolve();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Singletons.getModel().getGame().getStack().freezeStack();
|
||||
game.getStack().freezeStack();
|
||||
final Card source = sa.getSourceCard();
|
||||
|
||||
if (sa.isSpell() && !source.isCopiedSpell()) {
|
||||
sa.setSourceCard(Singletons.getModel().getGame().getAction().moveToStack(source));
|
||||
sa.setSourceCard(game.getAction().moveToStack(source));
|
||||
}
|
||||
|
||||
if (sa.getApi() == ApiType.Charm && !sa.isWrapper()) {
|
||||
@@ -160,12 +161,12 @@ public class ComputerUtil {
|
||||
if (cost == null) {
|
||||
ComputerUtil.payManaCost(ai, sa);
|
||||
sa.getBeforePayManaAI().execute();
|
||||
Singletons.getModel().getGame().getStack().addAndUnfreeze(sa);
|
||||
game.getStack().addAndUnfreeze(sa);
|
||||
return true;
|
||||
} else {
|
||||
final CostPayment pay = new CostPayment(cost, sa);
|
||||
if (pay.payComputerCosts(ai)) {
|
||||
Singletons.getModel().getGame().getStack().addAndUnfreeze(sa);
|
||||
final CostPayment pay = new CostPayment(cost, sa, game);
|
||||
if (pay.payComputerCosts(ai, game)) {
|
||||
game.getStack().addAndUnfreeze(sa);
|
||||
if (sa.getSplicedCards() != null && !sa.getSplicedCards().isEmpty()) {
|
||||
GuiChoose.oneOrNone("Computer reveals spliced cards:", sa.getSplicedCards());
|
||||
}
|
||||
@@ -259,6 +260,7 @@ public class ComputerUtil {
|
||||
* @return a boolean.
|
||||
*/
|
||||
public static boolean playCounterSpell(final Player ai, final ArrayList<SpellAbility> possibleCounters) {
|
||||
final GameState game = Singletons.getModel().getGame();
|
||||
SpellAbility bestSA = null;
|
||||
int bestRestriction = Integer.MIN_VALUE;
|
||||
final ArrayList<SpellAbility> newAbilities = new ArrayList<SpellAbility>();
|
||||
@@ -301,11 +303,11 @@ public class ComputerUtil {
|
||||
// TODO - "Look" at Targeted SA and "calculate" the threshold
|
||||
// if (bestRestriction < targetedThreshold) return false;
|
||||
|
||||
Singletons.getModel().getGame().getStack().freezeStack();
|
||||
game.getStack().freezeStack();
|
||||
final Card source = bestSA.getSourceCard();
|
||||
|
||||
if (bestSA.isSpell() && !source.isCopiedSpell()) {
|
||||
bestSA.setSourceCard(Singletons.getModel().getGame().getAction().moveToStack(source));
|
||||
bestSA.setSourceCard(game.getAction().moveToStack(source));
|
||||
}
|
||||
|
||||
final Cost cost = bestSA.getPayCosts();
|
||||
@@ -314,11 +316,11 @@ public class ComputerUtil {
|
||||
// Honestly Counterspells shouldn't use this branch
|
||||
ComputerUtil.payManaCost(ai, bestSA);
|
||||
bestSA.getBeforePayManaAI().execute();
|
||||
Singletons.getModel().getGame().getStack().addAndUnfreeze(bestSA);
|
||||
game.getStack().addAndUnfreeze(bestSA);
|
||||
} else {
|
||||
final CostPayment pay = new CostPayment(cost, bestSA);
|
||||
if (pay.payComputerCosts(ai)) {
|
||||
Singletons.getModel().getGame().getStack().addAndUnfreeze(bestSA);
|
||||
final CostPayment pay = new CostPayment(cost, bestSA, game);
|
||||
if (pay.payComputerCosts(ai, game)) {
|
||||
game.getStack().addAndUnfreeze(bestSA);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,21 +336,21 @@ public class ComputerUtil {
|
||||
* @param sa
|
||||
* a {@link forge.card.spellability.SpellAbility} object.
|
||||
*/
|
||||
public static final void playStack(final SpellAbility sa, final Player ai) {
|
||||
public static final void playStack(final SpellAbility sa, final Player ai, final GameState game) {
|
||||
sa.setActivatingPlayer(ai);
|
||||
if (ComputerUtil.canPayCost(sa, ai)) {
|
||||
final Card source = sa.getSourceCard();
|
||||
if (sa.isSpell() && !source.isCopiedSpell()) {
|
||||
sa.setSourceCard(Singletons.getModel().getGame().getAction().moveToStack(source));
|
||||
sa.setSourceCard(game.getAction().moveToStack(source));
|
||||
}
|
||||
final Cost cost = sa.getPayCosts();
|
||||
if (cost == null) {
|
||||
ComputerUtil.payManaCost(ai, sa);
|
||||
Singletons.getModel().getGame().getStack().add(sa);
|
||||
game.getStack().add(sa);
|
||||
} else {
|
||||
final CostPayment pay = new CostPayment(cost, sa);
|
||||
if (pay.payComputerCosts(ai)) {
|
||||
Singletons.getModel().getGame().getStack().add(sa);
|
||||
final CostPayment pay = new CostPayment(cost, sa, game);
|
||||
if (pay.payComputerCosts(ai, game)) {
|
||||
game.getStack().add(sa);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -381,7 +383,7 @@ public class ComputerUtil {
|
||||
* @param sa
|
||||
* a {@link forge.card.spellability.SpellAbility} object.
|
||||
*/
|
||||
public static final void playSpellAbilityWithoutPayingManaCost(final Player ai, final SpellAbility sa) {
|
||||
public static final void playSpellAbilityWithoutPayingManaCost(final Player ai, final SpellAbility sa, final GameState game) {
|
||||
final SpellAbility newSA = sa.copy();
|
||||
final Cost cost = new Cost(sa.getSourceCard(), "", false);
|
||||
if (newSA.getPayCosts() != null) {
|
||||
@@ -398,19 +400,19 @@ public class ComputerUtil {
|
||||
newSA.setDescription(sb.toString());
|
||||
newSA.setActivatingPlayer(ai);
|
||||
|
||||
if (!ComputerUtil.canPayAdditionalCosts(newSA, ai)) {
|
||||
if (!ComputerUtil.canPayAdditionalCosts(newSA, ai, game)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Card source = newSA.getSourceCard();
|
||||
if (newSA.isSpell() && !source.isCopiedSpell()) {
|
||||
newSA.setSourceCard(Singletons.getModel().getGame().getAction().moveToStack(source));
|
||||
newSA.setSourceCard(game.getAction().moveToStack(source));
|
||||
}
|
||||
|
||||
final CostPayment pay = new CostPayment(cost, newSA);
|
||||
pay.payComputerCosts(ai);
|
||||
final CostPayment pay = new CostPayment(cost, newSA, game);
|
||||
pay.payComputerCosts(ai, game);
|
||||
|
||||
Singletons.getModel().getGame().getStack().add(newSA);
|
||||
game.getStack().add(newSA);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -421,13 +423,12 @@ public class ComputerUtil {
|
||||
* @param sa
|
||||
* a {@link forge.card.spellability.SpellAbility} object.
|
||||
*/
|
||||
public static final void playNoStack(final Player ai, final SpellAbility sa) {
|
||||
public static final void playNoStack(final Player ai, final SpellAbility sa, final GameState game) {
|
||||
// TODO: We should really restrict what doesn't use the Stack
|
||||
|
||||
if (ComputerUtil.canPayCost(sa, ai)) {
|
||||
final Card source = sa.getSourceCard();
|
||||
if (sa.isSpell() && !source.isCopiedSpell()) {
|
||||
sa.setSourceCard(Singletons.getModel().getGame().getAction().moveToStack(source));
|
||||
sa.setSourceCard(game.getAction().moveToStack(source));
|
||||
}
|
||||
|
||||
sa.setActivatingPlayer(ai);
|
||||
@@ -436,14 +437,14 @@ public class ComputerUtil {
|
||||
if (cost == null) {
|
||||
ComputerUtil.payManaCost(ai, sa);
|
||||
} else {
|
||||
final CostPayment pay = new CostPayment(cost, sa);
|
||||
pay.payComputerCosts(ai);
|
||||
final CostPayment pay = new CostPayment(cost, sa, game);
|
||||
pay.payComputerCosts(ai, game);
|
||||
}
|
||||
|
||||
AbilityFactory.resolve(sa, false);
|
||||
|
||||
// destroys creatures if they have lethal damage, etc..
|
||||
Singletons.getModel().getGame().getAction().checkStateEffects();
|
||||
game.getAction().checkStateEffects();
|
||||
}
|
||||
} // play()
|
||||
|
||||
@@ -504,6 +505,7 @@ public class ComputerUtil {
|
||||
*/
|
||||
public static boolean canPayCost(final SpellAbility sa, final Player player) {
|
||||
|
||||
final GameState game = Singletons.getModel().getGame();
|
||||
// Check for stuff like Nether Void
|
||||
int extraManaNeeded = 0;
|
||||
if (sa instanceof Spell && player.isComputer()) {
|
||||
@@ -525,7 +527,7 @@ public class ComputerUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ComputerUtil.canPayAdditionalCosts(sa, player);
|
||||
return ComputerUtil.canPayAdditionalCosts(sa, player, game);
|
||||
} // canPayCost()
|
||||
|
||||
/**
|
||||
@@ -565,7 +567,7 @@ public class ComputerUtil {
|
||||
* a {@link forge.game.player.Player} object.
|
||||
* @return a boolean.
|
||||
*/
|
||||
public static boolean canPayAdditionalCosts(final SpellAbility sa, final Player player) {
|
||||
public static boolean canPayAdditionalCosts(final SpellAbility sa, final Player player, final GameState game) {
|
||||
if (sa.getActivatingPlayer() == null) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(sa.getSourceCard());
|
||||
@@ -573,7 +575,7 @@ public class ComputerUtil {
|
||||
System.out.println(sb.toString());
|
||||
sa.setActivatingPlayer(player);
|
||||
}
|
||||
return CostPayment.canPayAdditionalCosts(sa.getPayCosts(), sa);
|
||||
return CostPayment.canPayAdditionalCosts(game, sa.getPayCosts(), sa);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -610,6 +612,7 @@ public class ComputerUtil {
|
||||
final int extraMana, boolean checkPlayable) {
|
||||
ManaCostBeingPaid cost = calculateManaCost(sa, test, extraMana);
|
||||
|
||||
final GameState game = Singletons.getModel().getGame();
|
||||
final ManaPool manapool = ai.getManaPool();
|
||||
|
||||
cost = manapool.payManaFromPool(sa, cost);
|
||||
@@ -659,7 +662,7 @@ public class ComputerUtil {
|
||||
ma.setActivatingPlayer(ai);
|
||||
// if the AI can't pay the additional costs skip the mana ability
|
||||
if (ma.getPayCosts() != null && checkPlayable) {
|
||||
if (!ComputerUtil.canPayAdditionalCosts(ma, ai)) {
|
||||
if (!ComputerUtil.canPayAdditionalCosts(ma, ai, game)) {
|
||||
continue;
|
||||
}
|
||||
} else if (sourceCard.isTapped() && checkPlayable) {
|
||||
@@ -729,8 +732,8 @@ public class ComputerUtil {
|
||||
if (!test) {
|
||||
// Pay additional costs
|
||||
if (ma.getPayCosts() != null) {
|
||||
final CostPayment pay = new CostPayment(ma.getPayCosts(), ma);
|
||||
if (!pay.payComputerCosts(ai)) {
|
||||
final CostPayment pay = new CostPayment(ma.getPayCosts(), ma, game);
|
||||
if (!pay.payComputerCosts(ai, game)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
@@ -991,6 +994,7 @@ public class ComputerUtil {
|
||||
* @return a {@link forge.CardList} object.
|
||||
*/
|
||||
public static List<Card> getAvailableMana(final Player ai, final boolean checkPlayable) {
|
||||
final GameState game = Singletons.getModel().getGame();
|
||||
final List<Card> list = ai.getCardsIn(ZoneType.Battlefield);
|
||||
final List<Card> manaSources = CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
@@ -1054,7 +1058,7 @@ public class ComputerUtil {
|
||||
// ability
|
||||
m.setActivatingPlayer(ai);
|
||||
if (cost != null) {
|
||||
if (!ComputerUtil.canPayAdditionalCosts(m, ai)) {
|
||||
if (!ComputerUtil.canPayAdditionalCosts(m, ai, game)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -519,7 +519,7 @@ public class MagicStack extends MyObservable {
|
||||
final int neededDamage = CardFactoryUtil.getNeededXDamage(sa);
|
||||
|
||||
while (ComputerUtil.canPayCost(ability, player) && (neededDamage != sa.getSourceCard().getXManaCostPaid())) {
|
||||
ComputerUtil.playNoStack(player, ability);
|
||||
ComputerUtil.playNoStack(player, ability, game);
|
||||
}
|
||||
this.push(sa);
|
||||
}
|
||||
@@ -620,7 +620,7 @@ public class MagicStack extends MyObservable {
|
||||
// computer
|
||||
|
||||
while (ComputerUtil.canPayCost(ability, activating)) {
|
||||
ComputerUtil.playNoStack(activating, ability);
|
||||
ComputerUtil.playNoStack(activating, ability, game);
|
||||
}
|
||||
|
||||
this.push(sa);
|
||||
@@ -684,7 +684,7 @@ public class MagicStack extends MyObservable {
|
||||
} else {
|
||||
// computer
|
||||
while (ComputerUtil.canPayCost(ability, controller)) {
|
||||
ComputerUtil.playNoStack(controller, ability);
|
||||
ComputerUtil.playNoStack(controller, ability, game);
|
||||
}
|
||||
|
||||
this.push(sa);
|
||||
@@ -1340,7 +1340,7 @@ public class MagicStack extends MyObservable {
|
||||
if (activePlayer.isComputer()) {
|
||||
for (final SpellAbility sa : activePlayerSAs) {
|
||||
sa.doTrigger(sa.isMandatory());
|
||||
ComputerUtil.playStack(sa, activePlayer);
|
||||
ComputerUtil.playStack(sa, activePlayer, game);
|
||||
}
|
||||
} else {
|
||||
// If only one, just add as necessary
|
||||
|
||||
Reference in New Issue
Block a user