mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +00:00
MagicStack - cleanup (made some methods private, inlined whatever is short and single-time used or was accessor to field)
AbilityUtils.resolve does not need extra parameter usedStack - Stack class can call finishResolving from its own code HumanPlaySpellAbility - managed to simplify the code by groupping all prerequisites collection into a single exression
This commit is contained in:
@@ -1020,7 +1020,7 @@ public class AbilityUtils {
|
|||||||
// BELOW ARE resove() METHOD AND ITS DEPENDANTS, CONSIDER MOVING TO DEDICATED CLASS
|
// BELOW ARE resove() METHOD AND ITS DEPENDANTS, CONSIDER MOVING TO DEDICATED CLASS
|
||||||
//
|
//
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
public static void resolve(final SpellAbility sa, final boolean usedStack) {
|
public static void resolve(final SpellAbility sa) {
|
||||||
if (sa == null) {
|
if (sa == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1028,44 +1028,38 @@ public class AbilityUtils {
|
|||||||
if (api == null) {
|
if (api == null) {
|
||||||
sa.resolve();
|
sa.resolve();
|
||||||
if (sa.getSubAbility() != null) {
|
if (sa.getSubAbility() != null) {
|
||||||
resolve(sa.getSubAbility(), usedStack);
|
resolve(sa.getSubAbility());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbilityUtils.resolveApiAbility(sa, usedStack, sa.getActivatingPlayer().getGame());
|
AbilityUtils.resolveApiAbility(sa, sa.getActivatingPlayer().getGame());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void resolveSubAbilities(final SpellAbility sa, boolean usedStack, final Game game) {
|
private static void resolveSubAbilities(final SpellAbility sa, final Game game) {
|
||||||
final AbilitySub abSub = sa.getSubAbility();
|
final AbilitySub abSub = sa.getSubAbility();
|
||||||
if (abSub == null || sa.isWrapper()) {
|
if (abSub == null || sa.isWrapper()) {
|
||||||
// every resolving spellAbility will end here
|
|
||||||
if (usedStack) {
|
|
||||||
SpellAbility root = sa.getRootAbility();
|
|
||||||
// static abilities will get refreshed from SBE check.
|
|
||||||
game.getStack().finishResolving(root, false);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
game.getAction().checkStaticAbilities(); // this will refresh continuous abilities for players and permanents.
|
game.getAction().checkStaticAbilities(); // this will refresh continuous abilities for players and permanents.
|
||||||
AbilityUtils.resolveApiAbility(abSub, usedStack, game);
|
AbilityUtils.resolveApiAbility(abSub, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void resolveApiAbility(final SpellAbility sa, boolean usedStack, final Game game) {
|
private static void resolveApiAbility(final SpellAbility sa, final Game game) {
|
||||||
// check conditions
|
// check conditions
|
||||||
if (sa.getConditions().areMet(sa)) {
|
if (sa.getConditions().areMet(sa)) {
|
||||||
if (sa.isWrapper() || StringUtils.isBlank(sa.getParam("UnlessCost"))) {
|
if (sa.isWrapper() || StringUtils.isBlank(sa.getParam("UnlessCost"))) {
|
||||||
sa.resolve();
|
sa.resolve();
|
||||||
} else {
|
} else {
|
||||||
handleUnlessCost(sa, usedStack, game);
|
handleUnlessCost(sa, game);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resolveSubAbilities(sa, usedStack, game);
|
resolveSubAbilities(sa, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void handleUnlessCost(final SpellAbility sa, final boolean usedStack, final Game game) {
|
private static void handleUnlessCost(final SpellAbility sa, final Game game) {
|
||||||
final Card source = sa.getSourceCard();
|
final Card source = sa.getSourceCard();
|
||||||
String unlessCost = sa.getParam("UnlessCost");
|
String unlessCost = sa.getParam("UnlessCost");
|
||||||
unlessCost = unlessCost.trim();
|
unlessCost = unlessCost.trim();
|
||||||
@@ -1084,7 +1078,7 @@ public class AbilityUtils {
|
|||||||
} else if (unlessCost.equals("RememberedCostMinus2")) {
|
} else if (unlessCost.equals("RememberedCostMinus2")) {
|
||||||
if (source.getRemembered().isEmpty() || !(source.getRemembered().get(0) instanceof Card)) {
|
if (source.getRemembered().isEmpty() || !(source.getRemembered().get(0) instanceof Card)) {
|
||||||
sa.resolve();
|
sa.resolve();
|
||||||
resolveSubAbilities(sa, usedStack, game);
|
resolveSubAbilities(sa, game);
|
||||||
}
|
}
|
||||||
Card rememberedCard = (Card) source.getRemembered().get(0);
|
Card rememberedCard = (Card) source.getRemembered().get(0);
|
||||||
unlessCost = rememberedCard.getManaCost().toString();
|
unlessCost = rememberedCard.getManaCost().toString();
|
||||||
@@ -1124,10 +1118,7 @@ public class AbilityUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( paid && execSubsWhenPaid || !paid && execSubsWhenNotPaid ) { // switched refers only to main ability!
|
if ( paid && execSubsWhenPaid || !paid && execSubsWhenNotPaid ) { // switched refers only to main ability!
|
||||||
resolveSubAbilities(sa, usedStack, game);
|
resolveSubAbilities(sa, game);
|
||||||
} else if (usedStack) {
|
|
||||||
SpellAbility root = sa.getRootAbility();
|
|
||||||
game.getStack().finishResolving(root, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ import forge.game.player.Player;
|
|||||||
final AbilitySub abSub = sa.getSubAbility();
|
final AbilitySub abSub = sa.getSubAbility();
|
||||||
if (abSub != null) {
|
if (abSub != null) {
|
||||||
sa.setUndoable(false);
|
sa.setUndoable(false);
|
||||||
AbilityUtils.resolve(abSub, false);
|
AbilityUtils.resolve(abSub);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public class ChooseGenericEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
chosenSA.setActivatingPlayer(sa.getSourceCard().getController());
|
chosenSA.setActivatingPlayer(sa.getSourceCard().getController());
|
||||||
((AbilitySub) chosenSA).setParent(sa);
|
((AbilitySub) chosenSA).setParent(sa);
|
||||||
AbilityUtils.resolve(chosenSA, false);
|
AbilityUtils.resolve(chosenSA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class ClashEffect extends SpellAbilityEffect {
|
|||||||
win.setActivatingPlayer(sa.getSourceCard().getController());
|
win.setActivatingPlayer(sa.getSourceCard().getController());
|
||||||
((AbilitySub) win).setParent(sa);
|
((AbilitySub) win).setParent(sa);
|
||||||
|
|
||||||
AbilityUtils.resolve(win, false);
|
AbilityUtils.resolve(win);
|
||||||
}
|
}
|
||||||
runParams.put("Won", "True");
|
runParams.put("Won", "True");
|
||||||
} else {
|
} else {
|
||||||
@@ -53,7 +53,7 @@ public class ClashEffect extends SpellAbilityEffect {
|
|||||||
otherwise.setActivatingPlayer(sa.getSourceCard().getController());
|
otherwise.setActivatingPlayer(sa.getSourceCard().getController());
|
||||||
((AbilitySub) otherwise).setParent(sa);
|
((AbilitySub) otherwise).setParent(sa);
|
||||||
|
|
||||||
AbilityUtils.resolve(otherwise, false);
|
AbilityUtils.resolve(otherwise);
|
||||||
}
|
}
|
||||||
runParams.put("Won", "False");
|
runParams.put("Won", "False");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ public class CountersRemoveEffect extends SpellAbilityEffect {
|
|||||||
// better logic to pick a counter type and probably
|
// better logic to pick a counter type and probably
|
||||||
// an initial target
|
// an initial target
|
||||||
// find first nonzero counter on target
|
// find first nonzero counter on target
|
||||||
for (Object key : tgtCounters.keySet()) {
|
for (CounterType key : tgtCounters.keySet()) {
|
||||||
if (tgtCounters.get(key) > 0) {
|
if (tgtCounters.get(key) > 0) {
|
||||||
chosenType = (CounterType) key;
|
chosenType = (CounterType) key;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public class FlipCoinEffect extends SpellAbilityEffect {
|
|||||||
heads.setActivatingPlayer(player);
|
heads.setActivatingPlayer(player);
|
||||||
((AbilitySub) heads).setParent(sa);
|
((AbilitySub) heads).setParent(sa);
|
||||||
|
|
||||||
AbilityUtils.resolve(heads, false);
|
AbilityUtils.resolve(heads);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (sa.hasParam("TailsSubAbility")) {
|
if (sa.hasParam("TailsSubAbility")) {
|
||||||
@@ -84,7 +84,7 @@ public class FlipCoinEffect extends SpellAbilityEffect {
|
|||||||
tails.setActivatingPlayer(player);
|
tails.setActivatingPlayer(player);
|
||||||
((AbilitySub) tails).setParent(sa);
|
((AbilitySub) tails).setParent(sa);
|
||||||
|
|
||||||
AbilityUtils.resolve(tails, false);
|
AbilityUtils.resolve(tails);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -97,7 +97,7 @@ public class FlipCoinEffect extends SpellAbilityEffect {
|
|||||||
win.setActivatingPlayer(player);
|
win.setActivatingPlayer(player);
|
||||||
((AbilitySub) win).setParent(sa);
|
((AbilitySub) win).setParent(sa);
|
||||||
|
|
||||||
AbilityUtils.resolve(win, false);
|
AbilityUtils.resolve(win);
|
||||||
}
|
}
|
||||||
// runParams.put("Won","True");
|
// runParams.put("Won","True");
|
||||||
} else {
|
} else {
|
||||||
@@ -109,7 +109,7 @@ public class FlipCoinEffect extends SpellAbilityEffect {
|
|||||||
lose.setActivatingPlayer(player);
|
lose.setActivatingPlayer(player);
|
||||||
((AbilitySub) lose).setParent(sa);
|
((AbilitySub) lose).setParent(sa);
|
||||||
|
|
||||||
AbilityUtils.resolve(lose, false);
|
AbilityUtils.resolve(lose);
|
||||||
}
|
}
|
||||||
// runParams.put("Won","False");
|
// runParams.put("Won","False");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ public class RepeatEachEffect extends SpellAbilityEffect {
|
|||||||
source.addRemembered(card);
|
source.addRemembered(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
AbilityUtils.resolve(repeat, false);
|
AbilityUtils.resolve(repeat);
|
||||||
if (useImprinted) {
|
if (useImprinted) {
|
||||||
source.removeImprinted(card);
|
source.removeImprinted(card);
|
||||||
} else {
|
} else {
|
||||||
@@ -84,7 +84,7 @@ public class RepeatEachEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
for (Player player : repeatPlayers) {
|
for (Player player : repeatPlayers) {
|
||||||
source.addRemembered(player);
|
source.addRemembered(player);
|
||||||
AbilityUtils.resolve(repeat, false);
|
AbilityUtils.resolve(repeat);
|
||||||
source.removeRemembered(player);
|
source.removeRemembered(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,7 +100,7 @@ public class RepeatEachEffect extends SpellAbilityEffect {
|
|||||||
sb.append("Number$").append(target.getCounters(type));
|
sb.append("Number$").append(target.getCounters(type));
|
||||||
source.setSVar("RepeatSVarCounter", type.getName().toUpperCase());
|
source.setSVar("RepeatSVarCounter", type.getName().toUpperCase());
|
||||||
source.setSVar("RepeatCounterAmount", sb.toString());
|
source.setSVar("RepeatCounterAmount", sb.toString());
|
||||||
AbilityUtils.resolve(repeat, false);
|
AbilityUtils.resolve(repeat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class RepeatEffect extends SpellAbilityEffect {
|
|||||||
//execute repeat ability at least once
|
//execute repeat ability at least once
|
||||||
int count = 0;
|
int count = 0;
|
||||||
do {
|
do {
|
||||||
AbilityUtils.resolve(repeat, false);
|
AbilityUtils.resolve(repeat);
|
||||||
count++;
|
count++;
|
||||||
if (maxRepeat != null && maxRepeat <= count) {
|
if (maxRepeat != null && maxRepeat <= count) {
|
||||||
// TODO Replace Infinite Loop Break with a game draw. Here are the scenarios that can cause this:
|
// TODO Replace Infinite Loop Break with a game draw. Here are the scenarios that can cause this:
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ public class TwoPilesEffect extends SpellAbilityEffect {
|
|||||||
action.setActivatingPlayer(sa.getActivatingPlayer());
|
action.setActivatingPlayer(sa.getActivatingPlayer());
|
||||||
((AbilitySub) action).setParent(sa);
|
((AbilitySub) action).setParent(sa);
|
||||||
|
|
||||||
AbilityUtils.resolve(action, false);
|
AbilityUtils.resolve(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
// take action on the chosen pile
|
// take action on the chosen pile
|
||||||
@@ -160,7 +160,7 @@ public class TwoPilesEffect extends SpellAbilityEffect {
|
|||||||
action.setActivatingPlayer(sa.getActivatingPlayer());
|
action.setActivatingPlayer(sa.getActivatingPlayer());
|
||||||
((AbilitySub) action).setParent(sa);
|
((AbilitySub) action).setParent(sa);
|
||||||
|
|
||||||
AbilityUtils.resolve(action, false);
|
AbilityUtils.resolve(action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,59 +64,50 @@ public class HumanPlaySpellAbility {
|
|||||||
// freeze Stack. No abilities should go onto the stack while I'm filling requirements.
|
// freeze Stack. No abilities should go onto the stack while I'm filling requirements.
|
||||||
game.getStack().freezeStack();
|
game.getStack().freezeStack();
|
||||||
|
|
||||||
// Announce things like how many times you want to Multikick or the value of X
|
// This line makes use of short-circuit evaluation of boolean values, that is each subsequent argument
|
||||||
if (!this.announceRequirements()) {
|
// is only executed or evaluated if the first argument does not suffice to determine the value of the expression
|
||||||
|
boolean prerequisitesMet = this.announceValuesLikeX()
|
||||||
|
&& ( isAlreadyTargeted || setupTargets() )
|
||||||
|
&& ( isFree || this.payment.payCost(game) );
|
||||||
|
|
||||||
|
|
||||||
|
if (!prerequisitesMet) {
|
||||||
rollbackAbility(fromZone, zonePosition);
|
rollbackAbility(fromZone, zonePosition);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip to paying if parent ability doesn't target and has no
|
|
||||||
// subAbilities.
|
|
||||||
// (or trigger case where its already targeted)
|
|
||||||
if (!isAlreadyTargeted) {
|
|
||||||
|
|
||||||
SpellAbility beingTargeted = ability;
|
if (isFree || this.payment.isFullyPaid()) {
|
||||||
do {
|
if (skipStack) {
|
||||||
Target tgt = beingTargeted.getTarget();
|
AbilityUtils.resolve(this.ability);
|
||||||
if( tgt != null && tgt.doesTarget()) {
|
} else {
|
||||||
clearTargets(beingTargeted);
|
this.enusureAbilityHasDescription(this.ability);
|
||||||
final TargetSelection select = new TargetSelection(beingTargeted);
|
this.ability.getActivatingPlayer().getManaPool().clearManaPaid(this.ability, false);
|
||||||
if (!select.chooseTargets() ) {
|
game.getStack().addAndUnfreeze(this.ability);
|
||||||
rollbackAbility(fromZone, zonePosition);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
beingTargeted = beingTargeted.getSubAbility();
|
|
||||||
} while (beingTargeted != null);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Payment
|
|
||||||
boolean paymentMade = isFree;
|
|
||||||
|
|
||||||
if (!paymentMade) {
|
|
||||||
paymentMade = this.payment.payCost(game);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!paymentMade) {
|
|
||||||
rollbackAbility(fromZone, zonePosition);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (isFree || this.payment.isFullyPaid()) {
|
|
||||||
if (skipStack) {
|
|
||||||
AbilityUtils.resolve(this.ability, false);
|
|
||||||
} else {
|
|
||||||
this.enusureAbilityHasDescription(this.ability);
|
|
||||||
this.ability.getActivatingPlayer().getManaPool().clearManaPaid(this.ability, false);
|
|
||||||
game.getStack().addAndUnfreeze(this.ability);
|
|
||||||
}
|
|
||||||
|
|
||||||
// no worries here. The same thread must resolve, and by this moment ability will have been resolved already
|
|
||||||
clearTargets(ability);
|
|
||||||
//game.getAction().checkStateEffects();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// no worries here. The same thread must resolve, and by this moment ability will have been resolved already
|
||||||
|
clearTargets(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private final boolean setupTargets() {
|
||||||
|
// Skip to paying if parent ability doesn't target and has no subAbilities.
|
||||||
|
// (or trigger case where its already targeted)
|
||||||
|
SpellAbility beingTargeted = ability;
|
||||||
|
do {
|
||||||
|
Target tgt = beingTargeted.getTarget();
|
||||||
|
if( tgt != null && tgt.doesTarget()) {
|
||||||
|
clearTargets(beingTargeted);
|
||||||
|
final TargetSelection select = new TargetSelection(beingTargeted);
|
||||||
|
if (!select.chooseTargets() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
beingTargeted = beingTargeted.getSubAbility();
|
||||||
|
} while (beingTargeted != null);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void clearTargets(SpellAbility ability) {
|
public final void clearTargets(SpellAbility ability) {
|
||||||
@@ -147,11 +138,10 @@ public class HumanPlaySpellAbility {
|
|||||||
this.ability.resetOnceResolved();
|
this.ability.resetOnceResolved();
|
||||||
this.payment.refundPayment();
|
this.payment.refundPayment();
|
||||||
game.getStack().clearFrozen();
|
game.getStack().clearFrozen();
|
||||||
// Singletons.getModel().getGame().getStack().removeFromFrozenStack(this.ability);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean announceRequirements() {
|
private boolean announceValuesLikeX() {
|
||||||
// Announcing Requirements like Choosing X or Multikicker
|
// Announcing Requirements like Choosing X or Multikicker
|
||||||
// SA Params as comma delimited list
|
// SA Params as comma delimited list
|
||||||
String announce = ability.getParam("Announce");
|
String announce = ability.getParam("Announce");
|
||||||
|
|||||||
@@ -318,7 +318,7 @@ public class ComputerUtil {
|
|||||||
pay.payComputerCosts(ai, game);
|
pay.payComputerCosts(ai, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
AbilityUtils.resolve(sa, false);
|
AbilityUtils.resolve(sa);
|
||||||
|
|
||||||
// destroys creatures if they have lethal damage, etc..
|
// destroys creatures if they have lethal damage, etc..
|
||||||
//game.getAction().checkStateEffects();
|
//game.getAction().checkStateEffects();
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ public class ComputerUtilMana {
|
|||||||
saPayment.getSourceCard().tap();
|
saPayment.getSourceCard().tap();
|
||||||
}
|
}
|
||||||
|
|
||||||
AbilityUtils.resolve(saPayment, false);
|
AbilityUtils.resolve(saPayment);
|
||||||
// subtract mana from mana pool
|
// subtract mana from mana pool
|
||||||
manapool.payManaFromAbility(sa, cost, saPayment);
|
manapool.payManaFromAbility(sa, cost, saPayment);
|
||||||
|
|
||||||
|
|||||||
@@ -477,8 +477,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
|||||||
*/
|
*/
|
||||||
private Player handleNextTurn() {
|
private Player handleNextTurn() {
|
||||||
|
|
||||||
game.getStack().setCardsCastLastTurn();
|
game.getStack().onNextTurn();
|
||||||
game.getStack().clearCardsCastThisTurn();
|
|
||||||
|
|
||||||
for (final Player p1 : game.getPlayers()) {
|
for (final Player p1 : game.getPlayers()) {
|
||||||
for (final ZoneType z : Player.ALL_ZONES) {
|
for (final ZoneType z : Player.ALL_ZONES) {
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import forge.card.cost.CostSacrifice;
|
|||||||
import forge.card.cost.CostTapType;
|
import forge.card.cost.CostTapType;
|
||||||
import forge.card.mana.ManaCost;
|
import forge.card.mana.ManaCost;
|
||||||
import forge.card.mana.ManaCostBeingPaid;
|
import forge.card.mana.ManaCostBeingPaid;
|
||||||
import forge.card.mana.ManaCostShard;
|
|
||||||
import forge.card.spellability.Ability;
|
import forge.card.spellability.Ability;
|
||||||
import forge.card.spellability.HumanPlaySpellAbility;
|
import forge.card.spellability.HumanPlaySpellAbility;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
@@ -210,8 +209,7 @@ public class HumanPlay {
|
|||||||
sa.setSourceCard(game.getAction().moveToStack(c));
|
sa.setSourceCard(game.getAction().moveToStack(c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
boolean x = sa.getSourceCard().getManaCost().getShardCount(ManaCostShard.X) > 0;
|
game.getStack().add(sa);
|
||||||
game.getStack().add(sa, x);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +236,7 @@ public class HumanPlay {
|
|||||||
req.fillRequirements(useOldTargets, false, true);
|
req.fillRequirements(useOldTargets, false, true);
|
||||||
} else {
|
} else {
|
||||||
if (payManaCostIfNeeded(player, sa)) {
|
if (payManaCostIfNeeded(player, sa)) {
|
||||||
AbilityUtils.resolve(sa, false);
|
AbilityUtils.resolve(sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1313,14 +1313,14 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
SpellAbility saMill = AbilityFactory.getAbility(c.getSVar("MillOne"), c);
|
SpellAbility saMill = AbilityFactory.getAbility(c.getSVar("MillOne"), c);
|
||||||
saMill.setActivatingPlayer(c.getController());
|
saMill.setActivatingPlayer(c.getController());
|
||||||
saMill.setTarget(target);
|
saMill.setTarget(target);
|
||||||
AbilityUtils.resolve(saMill, false);
|
AbilityUtils.resolve(saMill);
|
||||||
|
|
||||||
return drawn; // Draw is cancelled
|
return drawn; // Draw is cancelled
|
||||||
} else {
|
} else {
|
||||||
SpellAbility saDiscard = AbilityFactory.getAbility(c.getSVar("DiscardOne"), c);
|
SpellAbility saDiscard = AbilityFactory.getAbility(c.getSVar("DiscardOne"), c);
|
||||||
saDiscard.setActivatingPlayer(c.getController());
|
saDiscard.setActivatingPlayer(c.getController());
|
||||||
saDiscard.setTarget(target);
|
saDiscard.setTarget(target);
|
||||||
AbilityUtils.resolve(saDiscard, false);
|
AbilityUtils.resolve(saDiscard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
this.lastTurnCast.clear();
|
this.lastTurnCast.clear();
|
||||||
this.thisTurnCast.clear();
|
this.thisTurnCast.clear();
|
||||||
this.curResolvingCard = null;
|
this.curResolvingCard = null;
|
||||||
this.getFrozenStack().clear();
|
this.frozenStack.clear();
|
||||||
this.updateObservers();
|
this.updateObservers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,8 +200,8 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
this.frozen = false;
|
this.frozen = false;
|
||||||
|
|
||||||
// Add all Frozen Abilities onto the stack
|
// Add all Frozen Abilities onto the stack
|
||||||
while (!this.getFrozenStack().isEmpty()) {
|
while (!this.frozenStack.isEmpty()) {
|
||||||
final SpellAbility sa = this.getFrozenStack().pop().getSpellAbility();
|
final SpellAbility sa = this.frozenStack.pop().getSpellAbility();
|
||||||
this.add(sa);
|
this.add(sa);
|
||||||
}
|
}
|
||||||
// Add all waiting triggers onto the stack
|
// Add all waiting triggers onto the stack
|
||||||
@@ -222,7 +222,7 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
// TODO: frozen triggered abilities and undoable costs have nasty
|
// TODO: frozen triggered abilities and undoable costs have nasty
|
||||||
// consequences
|
// consequences
|
||||||
this.frozen = false;
|
this.frozen = false;
|
||||||
this.getFrozenStack().clear();
|
this.frozenStack.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -234,8 +234,8 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
*/
|
*/
|
||||||
public final void removeFromFrozenStack(SpellAbility sa) {
|
public final void removeFromFrozenStack(SpellAbility sa) {
|
||||||
SpellAbilityStackInstance si = this.getInstanceFromSpellAbility(sa);
|
SpellAbilityStackInstance si = this.getInstanceFromSpellAbility(sa);
|
||||||
this.getFrozenStack().remove(si);
|
this.frozenStack.remove(si);
|
||||||
if (this.getFrozenStack().isEmpty()) {
|
if (this.frozenStack.isEmpty()) {
|
||||||
clearFrozen();
|
clearFrozen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,37 +266,6 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
return this.bResolving;
|
return this.bResolving;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* add.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param sp
|
|
||||||
* a {@link forge.card.spellability.SpellAbility} object.
|
|
||||||
* @param useX
|
|
||||||
* a boolean.
|
|
||||||
*/
|
|
||||||
public final void add(final SpellAbility sp, final boolean useX) {
|
|
||||||
if (!useX) {
|
|
||||||
this.add(sp);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// TODO: make working triggered abilities!
|
|
||||||
if (sp.isManaAbility() || (sp instanceof AbilityTriggered)) {
|
|
||||||
AbilityUtils.resolve(sp, false);
|
|
||||||
//sp.resolve();
|
|
||||||
} else {
|
|
||||||
this.push(sp);
|
|
||||||
/*
|
|
||||||
* if (sp.getTargetCard() != null)
|
|
||||||
* CardFactoryUtil.checkTargetingEffects(sp,
|
|
||||||
* sp.getTargetCard());
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* add.
|
* add.
|
||||||
@@ -309,7 +278,7 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
FThreads.assertExecutedByEdt(false);
|
FThreads.assertExecutedByEdt(false);
|
||||||
|
|
||||||
if (sp.isManaAbility()) { // Mana Abilities go straight through
|
if (sp.isManaAbility()) { // Mana Abilities go straight through
|
||||||
AbilityUtils.resolve(sp, false);
|
AbilityUtils.resolve(sp);
|
||||||
//sp.resolve();
|
//sp.resolve();
|
||||||
sp.resetOnceResolved();
|
sp.resetOnceResolved();
|
||||||
game.getGameLog().add(GameLogEntryType.MANA, sp.getSourceCard() + " - " + sp.getDescription());
|
game.getGameLog().add(GameLogEntryType.MANA, sp.getSourceCard() + " - " + sp.getDescription());
|
||||||
@@ -326,7 +295,7 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
|
|
||||||
if (this.frozen) {
|
if (this.frozen) {
|
||||||
final SpellAbilityStackInstance si = new SpellAbilityStackInstance(sp);
|
final SpellAbilityStackInstance si = new SpellAbilityStackInstance(sp);
|
||||||
this.getFrozenStack().push(si);
|
this.frozenStack.push(si);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,7 +425,7 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.getSimultaneousStackEntryList().isEmpty()) {
|
if (!this.simultaneousStackEntryList.isEmpty()) {
|
||||||
chooseOrderOfSimultaneousStackEntryAll();
|
chooseOrderOfSimultaneousStackEntryAll();
|
||||||
// Why should we pass priority after adding something to a stack?
|
// Why should we pass priority after adding something to a stack?
|
||||||
// game.getPhaseHandler().passPriority();
|
// game.getPhaseHandler().passPriority();
|
||||||
@@ -520,9 +489,6 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
public final void resolveStack() {
|
public final void resolveStack() {
|
||||||
// Resolving the Stack
|
// Resolving the Stack
|
||||||
|
|
||||||
// TODO: change to use forge.view.FView?
|
|
||||||
//GuiDisplayUtil.updateGUI();
|
|
||||||
|
|
||||||
// freeze the stack while we're in the middle of resolving
|
// freeze the stack while we're in the middle of resolving
|
||||||
this.freezeStack();
|
this.freezeStack();
|
||||||
this.setResolving(true);
|
this.setResolving(true);
|
||||||
@@ -543,67 +509,100 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
if (thisHasFizzled) { // Fizzle
|
if (thisHasFizzled) { // Fizzle
|
||||||
// TODO: Spell fizzles, what's the best way to alert player?
|
// TODO: Spell fizzles, what's the best way to alert player?
|
||||||
Log.debug(source.getName() + " ability fizzles.");
|
Log.debug(source.getName() + " ability fizzles.");
|
||||||
this.finishResolving(sa, true);
|
|
||||||
} else if (sa.getApi() != null) {
|
} else if (sa.getApi() != null) {
|
||||||
AbilityUtils.handleRemembering(sa);
|
AbilityUtils.handleRemembering(sa);
|
||||||
AbilityUtils.resolve(sa, true);
|
AbilityUtils.resolve(sa);
|
||||||
} else {
|
} else {
|
||||||
sa.resolve();
|
sa.resolve();
|
||||||
this.finishResolving(sa, false);
|
|
||||||
// do creatures ETB from here?
|
// do creatures ETB from here?
|
||||||
}
|
}
|
||||||
sa.getSourceCard().setXManaCostPaid(0);
|
this.finishResolving(sa, thisHasFizzled);
|
||||||
|
|
||||||
game.fireEvent(new GameEventSpellResolved(sa, thisHasFizzled));
|
game.fireEvent(new GameEventSpellResolved(sa, thisHasFizzled));
|
||||||
|
|
||||||
if (source.hasStartOfKeyword("Haunt") && !source.isCreature()
|
if (source.hasStartOfKeyword("Haunt") && !source.isCreature() && game.getZoneOf(source).is(ZoneType.Graveyard)) {
|
||||||
&& game.getZoneOf(source).is(ZoneType.Graveyard)) {
|
handleHauntForNonPermanents(sa);
|
||||||
final List<Card> creats = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), Presets.CREATURES);
|
}
|
||||||
final Ability haunterDiesWork = new Ability(source, ManaCost.ZERO) {
|
}
|
||||||
@Override
|
|
||||||
public void resolve() {
|
|
||||||
game.getAction().exile(source);
|
|
||||||
this.getTargetCard().addHauntedBy(source);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
for (int i = 0; i < creats.size(); i++) {
|
|
||||||
haunterDiesWork.setActivatingPlayer(sa.getActivatingPlayer());
|
|
||||||
if (!creats.get(i).canBeTargetedBy(haunterDiesWork)) {
|
|
||||||
creats.remove(i);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!creats.isEmpty()) {
|
|
||||||
haunterDiesWork.setDescription("");
|
|
||||||
|
|
||||||
if (source.getController().isHuman()) {
|
private void handleHauntForNonPermanents(final SpellAbility sa) {
|
||||||
final InputSelectCards targetHaunted = new InputSelectCardsFromList(1,1, creats);
|
final Card source = sa.getSourceCard();
|
||||||
targetHaunted.setMessage("Choose target creature to haunt.");
|
final List<Card> creats = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), Presets.CREATURES);
|
||||||
Singletons.getControl().getInputQueue().setInputAndWait(targetHaunted);
|
final Ability haunterDiesWork = new Ability(source, ManaCost.ZERO) {
|
||||||
haunterDiesWork.setTargetCard(targetHaunted.getSelected().get(0));
|
@Override
|
||||||
MagicStack.this.add(haunterDiesWork);
|
public void resolve() {
|
||||||
} else {
|
game.getAction().exile(source);
|
||||||
// AI choosing what to haunt
|
this.getTargetCard().addHauntedBy(source);
|
||||||
final List<Card> oppCreats = CardLists.filterControlledBy(creats, source.getController().getOpponents());
|
}
|
||||||
haunterDiesWork.setTargetCard(ComputerUtilCard.getWorstCreatureAI(oppCreats.isEmpty() ? creats : oppCreats));
|
};
|
||||||
this.add(haunterDiesWork);
|
for (int i = 0; i < creats.size(); i++) {
|
||||||
}
|
haunterDiesWork.setActivatingPlayer(sa.getActivatingPlayer());
|
||||||
|
if (!creats.get(i).canBeTargetedBy(haunterDiesWork)) {
|
||||||
|
creats.remove(i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!creats.isEmpty()) {
|
||||||
|
haunterDiesWork.setDescription("");
|
||||||
|
|
||||||
|
if (source.getController().isHuman()) {
|
||||||
|
final InputSelectCards targetHaunted = new InputSelectCardsFromList(1,1, creats);
|
||||||
|
targetHaunted.setMessage("Choose target creature to haunt.");
|
||||||
|
Singletons.getControl().getInputQueue().setInputAndWait(targetHaunted);
|
||||||
|
haunterDiesWork.setTargetCard(targetHaunted.getSelected().get(0));
|
||||||
|
MagicStack.this.add(haunterDiesWork);
|
||||||
|
} else {
|
||||||
|
// AI choosing what to haunt
|
||||||
|
final List<Card> oppCreats = CardLists.filterControlledBy(creats, source.getController().getOpponents());
|
||||||
|
haunterDiesWork.setTargetCard(ComputerUtilCard.getWorstCreatureAI(oppCreats.isEmpty() ? creats : oppCreats));
|
||||||
|
this.add(haunterDiesWork);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
private final void finishResolving(final SpellAbility sa, final boolean fizzle) {
|
||||||
* removeCardFromStack.
|
|
||||||
* </p>
|
// remove SA and card from the stack
|
||||||
*
|
this.removeCardFromStack(sa, fizzle);
|
||||||
* @param sa
|
// SpellAbility is removed from the stack here
|
||||||
* a {@link forge.card.spellability.SpellAbility} object.
|
// temporarily removed removing SA after resolution
|
||||||
* @param fizzle
|
final SpellAbilityStackInstance si = this.getInstanceFromSpellAbility(sa);
|
||||||
* a boolean.
|
|
||||||
* @since 1.0.15
|
if (si != null) {
|
||||||
*/
|
this.remove(si);
|
||||||
public final void removeCardFromStack(final SpellAbility sa, final boolean fizzle) {
|
}
|
||||||
|
|
||||||
|
// After SA resolves we have to do a handful of things
|
||||||
|
this.setResolving(false);
|
||||||
|
this.unfreezeStack();
|
||||||
|
sa.resetOnceResolved();
|
||||||
|
|
||||||
|
game.getAction().checkStateEffects();
|
||||||
|
|
||||||
|
game.getPhaseHandler().onStackResolved();
|
||||||
|
|
||||||
|
this.curResolvingCard = null;
|
||||||
|
|
||||||
|
this.updateObservers();
|
||||||
|
|
||||||
|
// TODO: this is a huge hack. Why is this necessary?
|
||||||
|
// hostCard in AF is not the same object that's on the battlefield
|
||||||
|
// verified by System.identityHashCode(card);
|
||||||
|
final Card tmp = sa.getSourceCard();
|
||||||
|
tmp.setCanCounter(true); // reset mana pumped counter magic flag
|
||||||
|
if (tmp.getClones().size() > 0) {
|
||||||
|
for (final Card c : game.getCardsIn(ZoneType.Battlefield)) {
|
||||||
|
if (c.equals(tmp)) {
|
||||||
|
c.setClones(tmp.getClones());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sa.getSourceCard().setXManaCostPaid(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final void removeCardFromStack(final SpellAbility sa, final boolean fizzle) {
|
||||||
Card source = sa.getSourceCard();
|
Card source = sa.getSourceCard();
|
||||||
|
|
||||||
// do nothing
|
// do nothing
|
||||||
@@ -644,54 +643,6 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* finishResolving.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param sa
|
|
||||||
* a {@link forge.card.spellability.SpellAbility} object.
|
|
||||||
* @param fizzle
|
|
||||||
* a boolean.
|
|
||||||
* @since 1.0.15
|
|
||||||
*/
|
|
||||||
public final void finishResolving(final SpellAbility sa, final boolean fizzle) {
|
|
||||||
|
|
||||||
// remove SA and card from the stack
|
|
||||||
this.removeCardFromStack(sa, fizzle);
|
|
||||||
// SpellAbility is removed from the stack here
|
|
||||||
// temporarily removed removing SA after resolution
|
|
||||||
this.remove(sa);
|
|
||||||
|
|
||||||
// After SA resolves we have to do a handful of things
|
|
||||||
this.setResolving(false);
|
|
||||||
this.unfreezeStack();
|
|
||||||
sa.resetOnceResolved();
|
|
||||||
|
|
||||||
game.getAction().checkStateEffects();
|
|
||||||
|
|
||||||
game.getPhaseHandler().onStackResolved();
|
|
||||||
|
|
||||||
this.curResolvingCard = null;
|
|
||||||
|
|
||||||
// TODO: change to use forge.view.FView?
|
|
||||||
//GuiDisplayUtil.updateGUI();
|
|
||||||
this.updateObservers();
|
|
||||||
|
|
||||||
// TODO: this is a huge hack. Why is this necessary?
|
|
||||||
// hostCard in AF is not the same object that's on the battlefield
|
|
||||||
// verified by System.identityHashCode(card);
|
|
||||||
final Card tmp = sa.getSourceCard();
|
|
||||||
tmp.setCanCounter(true); // reset mana pumped counter magic flag
|
|
||||||
if (tmp.getClones().size() > 0) {
|
|
||||||
for (final Card c : game.getCardsIn(ZoneType.Battlefield)) {
|
|
||||||
if (c.equals(tmp)) {
|
|
||||||
c.setClones(tmp.getClones());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -704,7 +655,7 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
* a {@link forge.Card} object.
|
* a {@link forge.Card} object.
|
||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public final boolean hasFizzled(final SpellAbility sa, final Card source, final boolean parentFizzled) {
|
private final boolean hasFizzled(final SpellAbility sa, final Card source, final boolean parentFizzled) {
|
||||||
// Can't fizzle unless there are some targets
|
// Can't fizzle unless there are some targets
|
||||||
boolean fizzle = false;
|
boolean fizzle = false;
|
||||||
|
|
||||||
@@ -770,60 +721,16 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
return hasFizzled(sa.getSubAbility(), source, fizzle) && fizzle;
|
return hasFizzled(sa.getSubAbility(), source, fizzle) && fizzle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* peekAbility.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @return a {@link forge.card.spellability.SpellAbility} object.
|
|
||||||
*/
|
|
||||||
public final SpellAbility peekAbility() {
|
public final SpellAbility peekAbility() {
|
||||||
return this.stack.peekFirst().getSpellAbility();
|
return this.stack.peekFirst().getSpellAbility();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* remove.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param sa
|
|
||||||
* a {@link forge.card.spellability.SpellAbility} object.
|
|
||||||
*/
|
|
||||||
public final void remove(final SpellAbility sa) {
|
|
||||||
final SpellAbilityStackInstance si = this.getInstanceFromSpellAbility(sa);
|
|
||||||
|
|
||||||
if (si == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.remove(si);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* remove.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param si
|
|
||||||
* a {@link forge.card.spellability.SpellAbilityStackInstance}
|
|
||||||
* object.
|
|
||||||
*/
|
|
||||||
public final void remove(final SpellAbilityStackInstance si) {
|
public final void remove(final SpellAbilityStackInstance si) {
|
||||||
this.stack.remove(si);
|
this.stack.remove(si);
|
||||||
this.getFrozenStack().remove(si);
|
this.frozenStack.remove(si);
|
||||||
this.updateObservers();
|
this.updateObservers();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getInstanceFromSpellAbility.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param sa
|
|
||||||
* a {@link forge.card.spellability.SpellAbility} object.
|
|
||||||
* @return a {@link forge.card.spellability.SpellAbilityStackInstance}
|
|
||||||
* object.
|
|
||||||
*/
|
|
||||||
public final SpellAbilityStackInstance getInstanceFromSpellAbility(final SpellAbility sa) {
|
public final SpellAbilityStackInstance getInstanceFromSpellAbility(final SpellAbility sa) {
|
||||||
// TODO: Confirm this works!
|
// TODO: Confirm this works!
|
||||||
for (final SpellAbilityStackInstance si : this.stack) {
|
for (final SpellAbilityStackInstance si : this.stack) {
|
||||||
@@ -834,38 +741,19 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* hasSimultaneousStackEntries.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @return a boolean.
|
|
||||||
*/
|
|
||||||
public final boolean hasSimultaneousStackEntries() {
|
public final boolean hasSimultaneousStackEntries() {
|
||||||
return this.getSimultaneousStackEntryList().size() > 0;
|
return !this.simultaneousStackEntryList.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void clearSimultaneousStack() {
|
public final void clearSimultaneousStack() {
|
||||||
this.simultaneousStackEntryList.clear();
|
this.simultaneousStackEntryList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* addSimultaneousStackEntry.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param sa
|
|
||||||
* a {@link forge.card.spellability.SpellAbility} object.
|
|
||||||
*/
|
|
||||||
public final void addSimultaneousStackEntry(final SpellAbility sa) {
|
public final void addSimultaneousStackEntry(final SpellAbility sa) {
|
||||||
this.getSimultaneousStackEntryList().add(sa);
|
this.simultaneousStackEntryList.add(sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* chooseOrderOfSimultaneousStackEntryAll.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
public final void chooseOrderOfSimultaneousStackEntryAll() {
|
public final void chooseOrderOfSimultaneousStackEntryAll() {
|
||||||
final Player playerTurn = game.getPhaseHandler().getPlayerTurn();
|
final Player playerTurn = game.getPhaseHandler().getPlayerTurn();
|
||||||
|
|
||||||
@@ -879,33 +767,26 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
private final void chooseOrderOfSimultaneousStackEntry(final Player activePlayer) {
|
||||||
* chooseOrderOfSimultaneousStackEntry.
|
if (this.simultaneousStackEntryList.isEmpty()) {
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param activePlayer
|
|
||||||
* a {@link forge.game.player.Player} object.
|
|
||||||
*/
|
|
||||||
public final void chooseOrderOfSimultaneousStackEntry(final Player activePlayer) {
|
|
||||||
if (this.getSimultaneousStackEntryList().isEmpty()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<SpellAbility> activePlayerSAs = new ArrayList<SpellAbility>();
|
final List<SpellAbility> activePlayerSAs = new ArrayList<SpellAbility>();
|
||||||
for (int i = 0; i < this.getSimultaneousStackEntryList().size(); i++) {
|
for (int i = 0; i < this.simultaneousStackEntryList.size(); i++) {
|
||||||
SpellAbility sa = this.getSimultaneousStackEntryList().get(i);
|
SpellAbility sa = this.simultaneousStackEntryList.get(i);
|
||||||
Player activator = sa.getActivatingPlayer();
|
Player activator = sa.getActivatingPlayer();
|
||||||
if (activator == null) {
|
if (activator == null) {
|
||||||
if (sa.getSourceCard().getController().equals(activePlayer)) {
|
if (sa.getSourceCard().getController().equals(activePlayer)) {
|
||||||
activePlayerSAs.add(sa);
|
activePlayerSAs.add(sa);
|
||||||
this.getSimultaneousStackEntryList().remove(i);
|
this.simultaneousStackEntryList.remove(i);
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (activator.equals(activePlayer)) {
|
if (activator.equals(activePlayer)) {
|
||||||
activePlayerSAs.add(sa);
|
activePlayerSAs.add(sa);
|
||||||
this.getSimultaneousStackEntryList().remove(i);
|
this.simultaneousStackEntryList.remove(i);
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -966,24 +847,6 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the simultaneous stack entry list.
|
|
||||||
*
|
|
||||||
* @return the simultaneousStackEntryList
|
|
||||||
*/
|
|
||||||
public final List<SpellAbility> getSimultaneousStackEntryList() {
|
|
||||||
return this.simultaneousStackEntryList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the frozen stack.
|
|
||||||
*
|
|
||||||
* @return the frozenStack
|
|
||||||
*/
|
|
||||||
public final Stack<SpellAbilityStackInstance> getFrozenStack() {
|
|
||||||
return this.frozenStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accessor for the field thisTurnCast.
|
* Accessor for the field thisTurnCast.
|
||||||
*
|
*
|
||||||
@@ -996,16 +859,9 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
|
|||||||
/**
|
/**
|
||||||
* clearCardsCastThisTurn.
|
* clearCardsCastThisTurn.
|
||||||
*/
|
*/
|
||||||
public final void clearCardsCastThisTurn() {
|
public final void onNextTurn() {
|
||||||
this.thisTurnCast.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* setCardsCastLastTurn.
|
|
||||||
*/
|
|
||||||
public final void setCardsCastLastTurn() {
|
|
||||||
this.lastTurnCast = new ArrayList<Card>(this.thisTurnCast);
|
this.lastTurnCast = new ArrayList<Card>(this.thisTurnCast);
|
||||||
|
this.thisTurnCast.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user