*Beginning stages of Simultaneous Trigger Ordering.

Hardcoded triggers should either use the actual Trigger objects, or use AllZone.Stack.addSimultaneousStackEntry(SpellAbility) whenever they need to add itself to the stack. The Simultaneous Stack Entries are "flushed" onto the stack when priority is passed or a new phase is entered.
This commit is contained in:
jendave
2011-08-06 22:10:04 +00:00
parent 4881fc7e78
commit 3ba4a9dc32
20 changed files with 702 additions and 309 deletions

View File

@@ -542,6 +542,7 @@ public class Card extends MyObservable {
runParams.put("CounterType", counterName); runParams.put("CounterType", counterName);
AllZone.TriggerHandler.runTrigger("CounterAdded", runParams); AllZone.TriggerHandler.runTrigger("CounterAdded", runParams);
AllZone.GameAction.checkStateEffects(); AllZone.GameAction.checkStateEffects();
this.updateObservers(); this.updateObservers();
@@ -1423,7 +1424,7 @@ public class Card extends MyObservable {
public void executeTrigger(ZCTrigger type) { public void executeTrigger(ZCTrigger type) {
for(Ability_Triggered t:zcTriggers) for(Ability_Triggered t:zcTriggers)
if(t.trigger.equals(type) && t.isBasic()) AllZone.Stack.add(t); if(t.trigger.equals(type) && t.isBasic()) AllZone.Stack.addSimultaneousStackEntry(t);
} }
public void clearTriggers() { public void clearTriggers() {
@@ -2091,6 +2092,8 @@ public class Card extends MyObservable {
HashMap<String,Object> runParams = new HashMap<String,Object>(); HashMap<String,Object> runParams = new HashMap<String,Object>();
runParams.put("Card", this); runParams.put("Card", this);
AllZone.TriggerHandler.runTrigger("Taps", runParams); AllZone.TriggerHandler.runTrigger("Taps", runParams);
} }
setTapped(true); setTapped(true);
} }
@@ -2101,11 +2104,13 @@ public class Card extends MyObservable {
HashMap<String,Object> runParams = new HashMap<String,Object>(); HashMap<String,Object> runParams = new HashMap<String,Object>();
runParams.put("Card", this); runParams.put("Card", this);
AllZone.TriggerHandler.runTrigger("Untaps", runParams); AllZone.TriggerHandler.runTrigger("Untaps", runParams);
} }
for(Command var:untapCommandList) { for(Command var:untapCommandList) {
var.execute(); var.execute();
} }
setTapped(false); setTapped(false);
} }

View File

@@ -398,6 +398,8 @@ public class Combat {
HashMap<String,Object> runParams = new HashMap<String,Object>(); HashMap<String,Object> runParams = new HashMap<String,Object>();
runParams.put("Attacker", attacker); runParams.put("Attacker", attacker);
AllZone.TriggerHandler.runTrigger("AttackerUnblocked", runParams); AllZone.TriggerHandler.runTrigger("AttackerUnblocked", runParams);
} }
} }
} }
@@ -624,6 +626,9 @@ public class Combat {
damageMap.clear(); damageMap.clear();
c.clearAssignedDamage(); c.clearAssignedDamage();
} }
//This was deeper before,but that resulted in the stack entry acting like before.
} }
public boolean isUnblocked(Card att){ public boolean isUnblocked(Card att){

View File

@@ -1811,6 +1811,7 @@ public class CombatUtil {
} }
a.setCreatureGotBlockedThisCombat(true); a.setCreatureGotBlockedThisCombat(true);
} }
public static void executeExaltedAbility(Card c, int magnitude) { public static void executeExaltedAbility(Card c, int magnitude) {
@@ -1846,7 +1847,7 @@ public class CombatUtil {
sb.append(c).append(" - (Exalted) gets +1/+1 until EOT."); sb.append(c).append(" - (Exalted) gets +1/+1 until EOT.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
Player phasingPlayer = c.getController(); Player phasingPlayer = c.getController();
@@ -1864,7 +1865,7 @@ public class CombatUtil {
sbUntap.append(c).append(" - (Exalted) untap."); sbUntap.append(c).append(" - (Exalted) untap.");
fhUntap.setStackDescription(sbUntap.toString()); fhUntap.setStackDescription(sbUntap.toString());
AllZone.Stack.add(fhUntap); AllZone.Stack.addSimultaneousStackEntry(fhUntap);
// If any Finest Hours, queue up a new combat phase // If any Finest Hours, queue up a new combat phase
for (int ix = 0; ix < AllZoneUtil.getPlayerCardsInPlay(phasingPlayer, "Finest Hour").size(); ix++) { for (int ix = 0; ix < AllZoneUtil.getPlayerCardsInPlay(phasingPlayer, "Finest Hour").size(); ix++) {
@@ -1878,7 +1879,7 @@ public class CombatUtil {
sbACom.append(c).append(" - (Exalted) ").append(phasingPlayer).append(" gets Extra Combat Phase."); sbACom.append(c).append(" - (Exalted) ").append(phasingPlayer).append(" gets Extra Combat Phase.");
fhAddCombat.setStackDescription(sbACom.toString()); fhAddCombat.setStackDescription(sbACom.toString());
AllZone.Stack.add(fhAddCombat); AllZone.Stack.addSimultaneousStackEntry(fhAddCombat);
} }
} }
@@ -1929,7 +1930,7 @@ public class CombatUtil {
sb4.append("put it onto the battlefield attached to that creature, then shuffles library."); sb4.append("put it onto the battlefield attached to that creature, then shuffles library.");
ability4.setStackDescription(sb4.toString()); ability4.setStackDescription(sb4.toString());
AllZone.Stack.add(ability4); AllZone.Stack.addSimultaneousStackEntry(ability4);
} // For } // For
} }
} }

View File

@@ -573,6 +573,8 @@ public class ComputerUtil
} }
if(!cost.isPaid()) if(!cost.isPaid())
throw new RuntimeException("ComputerUtil : payManaCost() cost was not paid for " + sa.getSourceCard().getName()); throw new RuntimeException("ComputerUtil : payManaCost() cost was not paid for " + sa.getSourceCard().getName());
}//payManaCost() }//payManaCost()

View File

@@ -47,8 +47,9 @@ public class EndOfTurn implements java.io.Serializable
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("Sacrifice ").append(card); sb.append("Sacrifice ").append(card);
sac.setStackDescription(sb.toString()); sac.setStackDescription(sb.toString());
AllZone.Stack.add(sac); AllZone.Stack.addSimultaneousStackEntry(sac);
} }
if(!c.isFaceDown() && c.getKeyword().contains("At the beginning of the end step, exile CARDNAME.")) { if(!c.isFaceDown() && c.getKeyword().contains("At the beginning of the end step, exile CARDNAME.")) {
final Card card = c; final Card card = c;
@@ -61,8 +62,9 @@ public class EndOfTurn implements java.io.Serializable
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("Exile ").append(card); sb.append("Exile ").append(card);
exile.setStackDescription(sb.toString()); exile.setStackDescription(sb.toString());
AllZone.Stack.add(exile); AllZone.Stack.addSimultaneousStackEntry(exile);
} }
if(!c.isFaceDown() && c.getKeyword().contains("At the beginning of the end step, destroy CARDNAME.")) { if(!c.isFaceDown() && c.getKeyword().contains("At the beginning of the end step, destroy CARDNAME.")) {
final Card card = c; final Card card = c;
@@ -75,8 +77,9 @@ public class EndOfTurn implements java.io.Serializable
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("Destroy ").append(card); sb.append("Destroy ").append(card);
destroy.setStackDescription(sb.toString()); destroy.setStackDescription(sb.toString());
AllZone.Stack.add(destroy); AllZone.Stack.addSimultaneousStackEntry(destroy);
} }
//Berserk is using this, so don't check isFaceDown() //Berserk is using this, so don't check isFaceDown()
if(c.getKeyword().contains("At the beginning of the next end step, destroy CARDNAME if it attacked this turn.")) { if(c.getKeyword().contains("At the beginning of the next end step, destroy CARDNAME if it attacked this turn.")) {
@@ -91,8 +94,9 @@ public class EndOfTurn implements java.io.Serializable
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("Sacrifice ").append(card); sb.append("Sacrifice ").append(card);
sac.setStackDescription(sb.toString()); sac.setStackDescription(sb.toString());
AllZone.Stack.add(sac); AllZone.Stack.addSimultaneousStackEntry(sac);
} }
else { else {
c.removeExtrinsicKeyword("At the beginning of the next end step, destroy CARDNAME if it attacked this turn."); c.removeExtrinsicKeyword("At the beginning of the next end step, destroy CARDNAME if it attacked this turn.");
@@ -113,8 +117,9 @@ public class EndOfTurn implements java.io.Serializable
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(vale.getName()).append(" changes controllers."); sb.append(vale.getName()).append(" changes controllers.");
change.setStackDescription(sb.toString()); change.setStackDescription(sb.toString());
AllZone.Stack.add(change); AllZone.Stack.addSimultaneousStackEntry(change);
} }
if(c.getName().equals("Erg Raiders") && !c.getCreatureAttackedThisTurn() && if(c.getName().equals("Erg Raiders") && !c.getCreatureAttackedThisTurn() &&
!(c.getTurnInZone() == AllZone.Phase.getTurn()) && AllZone.Phase.isPlayerTurn(c.getController())) { !(c.getTurnInZone() == AllZone.Phase.getTurn()) && AllZone.Phase.isPlayerTurn(c.getController())) {
@@ -130,8 +135,9 @@ public class EndOfTurn implements java.io.Serializable
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(raider.getName()).append(" deals 2 damage to controller."); sb.append(raider.getName()).append(" deals 2 damage to controller.");
change.setStackDescription(sb.toString()); change.setStackDescription(sb.toString());
AllZone.Stack.add(change); AllZone.Stack.addSimultaneousStackEntry(change);
} }
if(c.hasKeyword("At the beginning of your end step, sacrifice this creature unless it attacked this turn.") if(c.hasKeyword("At the beginning of your end step, sacrifice this creature unless it attacked this turn.")
&& !c.getCreatureAttackedThisTurn() && !c.getCreatureAttackedThisTurn()
@@ -149,13 +155,18 @@ public class EndOfTurn implements java.io.Serializable
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(source.getName()).append(" - sacrifice ").append(source.getName()).append("."); sb.append(source.getName()).append(" - sacrifice ").append(source.getName()).append(".");
change.setStackDescription(sb.toString()); change.setStackDescription(sb.toString());
AllZone.Stack.add(change); AllZone.Stack.addSimultaneousStackEntry(change);
} }
} }
execute(at); execute(at);
CardList all2 = AllZoneUtil.getCardsInPlay(); CardList all2 = AllZoneUtil.getCardsInPlay();
for(Card c:all2) { for(Card c:all2) {
if(c.getCreatureAttackedThisTurn()) c.setCreatureAttackedThisTurn(false); if(c.getCreatureAttackedThisTurn()) c.setCreatureAttackedThisTurn(false);

View File

@@ -100,6 +100,8 @@ public class GameAction {
runParams.put("Destination", zone.getZoneName()); runParams.put("Destination", zone.getZoneName());
AllZone.TriggerHandler.runTrigger("ChangesZone", runParams); AllZone.TriggerHandler.runTrigger("ChangesZone", runParams);
return c; return c;
} }
@@ -618,6 +620,8 @@ public class GameAction {
HashMap<String,Object> runParams = new HashMap<String,Object>(); HashMap<String,Object> runParams = new HashMap<String,Object>();
runParams.put("Card", c); runParams.put("Card", c);
AllZone.TriggerHandler.runTrigger("Sacrificed", runParams); AllZone.TriggerHandler.runTrigger("Sacrificed", runParams);
} }
public void destroyNoRegeneration(Card c) { public void destroyNoRegeneration(Card c) {
@@ -2142,7 +2146,9 @@ public class GameAction {
GameActionUtil.executeVampiricEffects(crd); GameActionUtil.executeVampiricEffects(crd);
} }
} }
this.sacrificeDestroy(c); this.sacrificeDestroy(c);
return true; return true;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -16,10 +16,13 @@ import forge.card.spellability.Ability_Triggered;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.Spell_Permanent; import forge.card.spellability.Spell_Permanent;
import forge.card.spellability.Target; import forge.card.spellability.Target;
import forge.gui.GuiUtils;
import forge.gui.input.Input; import forge.gui.input.Input;
import forge.gui.input.Input_PayManaCost_Ability; import forge.gui.input.Input_PayManaCost_Ability;
public class MagicStack extends MyObservable { public class MagicStack extends MyObservable {
private ArrayList<SpellAbility> simultaneousStackEntryList = new ArrayList<SpellAbility>();
private ArrayList<SpellAbility> stack = new ArrayList<SpellAbility>(); private ArrayList<SpellAbility> stack = new ArrayList<SpellAbility>();
private ArrayList<SpellAbility> frozenStack = new ArrayList<SpellAbility>(); private ArrayList<SpellAbility> frozenStack = new ArrayList<SpellAbility>();
private boolean frozen = false; private boolean frozen = false;
@@ -422,6 +425,7 @@ public class MagicStack extends MyObservable {
runParams.put("Card", sp.getSourceCard()); runParams.put("Card", sp.getSourceCard());
AllZone.TriggerHandler.runTrigger("Cycled", runParams); AllZone.TriggerHandler.runTrigger("Cycled", runParams);
} }
} }
if(sp instanceof Spell_Permanent && sp.getSourceCard().getName().equals("Mana Vortex")) { if(sp instanceof Spell_Permanent && sp.getSourceCard().getName().equals("Mana Vortex")) {
@@ -851,4 +855,91 @@ public class MagicStack extends MyObservable {
return ComputerCreatureSpellCount; return ComputerCreatureSpellCount;
} }
public void addSimultaneousStackEntry(SpellAbility sa)
{
simultaneousStackEntryList.add(sa);
/*
*Debug output.
System.out.println("STO add! Size:" + simultaneousStackEntryList.size());
*/
}
public void chooseOrderOfSimultaneousStackEntryAll()
{
/*
*Debug output.
if(simultaneousStackEntryList.size() > 0)
{
System.out.println("STO run! Size:" + simultaneousStackEntryList.size());
}
*/
chooseOrderOfSimultaneousStackEntry(AllZone.Phase.getPlayerTurn());
chooseOrderOfSimultaneousStackEntry(AllZone.Phase.getPlayerTurn().getOpponent());
}
public void chooseOrderOfSimultaneousStackEntry(Player activePlayer)
{
if(simultaneousStackEntryList.size() == 0)
return;
ArrayList<SpellAbility> activePlayerSAs = new ArrayList<SpellAbility>();
for(int i=0;i<simultaneousStackEntryList.size();i++)
{
if(simultaneousStackEntryList.get(i).getActivatingPlayer() == null)
{
if(simultaneousStackEntryList.get(i).getSourceCard().getController().equals(activePlayer))
{
activePlayerSAs.add(simultaneousStackEntryList.get(i));
simultaneousStackEntryList.remove(i);
i--;
}
}
else
{
if(simultaneousStackEntryList.get(i).getActivatingPlayer().equals(activePlayer))
{
activePlayerSAs.add(simultaneousStackEntryList.get(i));
simultaneousStackEntryList.remove(i);
i--;
}
}
}
if(activePlayerSAs.size() == 0)
return;
if(activePlayer.isComputer())
{
for(SpellAbility sa : activePlayerSAs)
{
sa.doTrigger(sa.isMandatory());
ComputerUtil.playStack(sa);
}
}
else
{
while(activePlayerSAs.size() > 1)
{
SpellAbility next = (SpellAbility) GuiUtils.getChoice("Choose which spell or ability to put on the stack next.", activePlayerSAs.toArray());
activePlayerSAs.remove(next);
if(next.isTrigger())
{
System.out.println("Stack order: AllZone.GameAction.playSpellAbility(next)");
AllZone.GameAction.playSpellAbility(next);
}
else
{
System.out.println("Stack order: AllZone.Stack.add(next)");
add(next);
}
}
if(activePlayerSAs.get(0).isTrigger())
AllZone.GameAction.playSpellAbility(activePlayerSAs.get(0));
else
add(activePlayerSAs.get(0));
//AllZone.GameAction.playSpellAbility(activePlayerSAs.get(0));
}
}
} }

View File

@@ -293,6 +293,8 @@ public class Phase extends MyObservable
AllZone.TriggerHandler.runTrigger("Phase", runParams); AllZone.TriggerHandler.runTrigger("Phase", runParams);
} }
//This line fixes Combat Damage triggers not going off when they should //This line fixes Combat Damage triggers not going off when they should
AllZone.Stack.unfreezeStack(); AllZone.Stack.unfreezeStack();
@@ -377,6 +379,8 @@ public class Phase extends MyObservable
AllZone.Phase.setNeedToNextPhase(false); AllZone.Phase.setNeedToNextPhase(false);
AllZone.Phase.nextPhase(); AllZone.Phase.nextPhase();
} }
AllZone.Stack.chooseOrderOfSimultaneousStackEntryAll();
} }
private Player handleNextTurn() { private Player handleNextTurn() {
@@ -513,6 +517,7 @@ public class Phase extends MyObservable
// pass the priority to other player // pass the priority to other player
setPriorityPlayer(actingPlayer.getOpponent()); setPriorityPlayer(actingPlayer.getOpponent());
AllZone.InputControl.resetInput(); AllZone.InputControl.resetInput();
AllZone.Stack.chooseOrderOfSimultaneousStackEntryAll();
} }
else{ else{
if (AllZone.Stack.size() == 0){ if (AllZone.Stack.size() == 0){
@@ -523,6 +528,7 @@ public class Phase extends MyObservable
else{ else{
AllZone.Stack.resolveStack(); AllZone.Stack.resolveStack();
} }
AllZone.Stack.chooseOrderOfSimultaneousStackEntryAll();
} }
} }

View File

@@ -158,8 +158,9 @@ public class PlayerZone_ComesIntoPlay extends DefaultPlayerZone {
sb.append(source).append(" - tap all lands "); sb.append(source).append(" - tap all lands ");
sb.append(tisLand.getController()).append(" controls."); sb.append(tisLand.getController()).append(" controls.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
CardList les = AllZoneUtil.getPlayerCardsInPlay(c.getOwner().getOpponent(), "Land Equilibrium"); CardList les = AllZoneUtil.getPlayerCardsInPlay(c.getOwner().getOpponent(), "Land Equilibrium");
@@ -181,7 +182,8 @@ public class PlayerZone_ComesIntoPlay extends DefaultPlayerZone {
CardList oLands = AllZoneUtil.getPlayerLandsInPlay(lesLand.getOwner().getOpponent()); CardList oLands = AllZoneUtil.getPlayerLandsInPlay(lesLand.getOwner().getOpponent());
//(pLands - 1) because this land is in play, and the ability is before it is in play //(pLands - 1) because this land is in play, and the ability is before it is in play
if(oLands.size() <= (pLands.size() - 1)) { if(oLands.size() <= (pLands.size() - 1)) {
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
} }
@@ -238,10 +240,13 @@ public class PlayerZone_ComesIntoPlay extends DefaultPlayerZone {
sb.append("return Sword of the Meek from your graveyard to the battlefield, then attach it to that creature."); sb.append("return Sword of the Meek from your graveyard to the battlefield, then attach it to that creature.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
} }
/* /*
for (String effect : AllZone.StateBasedEffects.getStateBasedMap().keySet() ) { for (String effect : AllZone.StateBasedEffects.getStateBasedMap().keySet() ) {
Command com = GameActionUtil.commands.get(effect); Command com = GameActionUtil.commands.get(effect);
@@ -313,6 +318,8 @@ public class PlayerZone_ComesIntoPlay extends DefaultPlayerZone {
Command com = GameActionUtil.commands.get(effect); Command com = GameActionUtil.commands.get(effect);
com.execute(); com.execute();
} }
} }
public void setTrigger(boolean b) { public void setTrigger(boolean b) {

View File

@@ -341,7 +341,7 @@ public class AbilityFactory_GainControl {
if(bNoRegen) sb.append(" It can't be regenerated."); if(bNoRegen) sb.append(" It can't be regenerated.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };

View File

@@ -557,7 +557,8 @@ public class CardFactory implements NewConstants {
sb.append(card.getController()).append(" loses "+num+" life"); sb.append(card.getController()).append(" loses "+num+" life");
etbLoseLifeAbility.setStackDescription(sb.toString()); etbLoseLifeAbility.setStackDescription(sb.toString());
AllZone.Stack.add(etbLoseLifeAbility); AllZone.Stack.addSimultaneousStackEntry(etbLoseLifeAbility);
} }
}; };
card.addComesIntoPlayCommand(etbLoseLife); card.addComesIntoPlayCommand(etbLoseLife);
@@ -865,7 +866,8 @@ public class CardFactory implements NewConstants {
} }
numCreatures[0] = count; numCreatures[0] = count;
} }
AllZone.Stack.add(devour); AllZone.Stack.addSimultaneousStackEntry(devour);
} }
}; };
@@ -924,7 +926,8 @@ public class CardFactory implements NewConstants {
if (ability.getTargetCard() != null){ if (ability.getTargetCard() != null){
ability.setStackDescription("Put " + card.getCounters(Counters.P1P1) ability.setStackDescription("Put " + card.getCounters(Counters.P1P1)
+ " +1/+1 counter/s from " + card + " on " + ability.getTargetCard()); + " +1/+1 counter/s from " + card + " on " + ability.getTargetCard());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
} }
} }
@@ -1126,7 +1129,8 @@ public class CardFactory implements NewConstants {
sb.append("When ").append(card.getName()).append(" enters the battlefield, choose a creature type."); sb.append("When ").append(card.getName()).append(" enters the battlefield, choose a creature type.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
card.addComesIntoPlayCommand(intoPlay); card.addComesIntoPlayCommand(intoPlay);
@@ -1210,7 +1214,9 @@ public class CardFactory implements NewConstants {
public void execute() { public void execute() {
ability.setStackDescription("As Sarpadian Empires, Vol. VII enters the battlefield, choose white Citizen, blue Camarid, black Thrull, red Goblin, or green Saproling."); ability.setStackDescription("As Sarpadian Empires, Vol. VII enters the battlefield, choose white Citizen, blue Camarid, black Thrull, red Goblin, or green Saproling.");
AllZone.Stack.add(ability);
AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
card.setText("As Sarpadian Empires, Vol. VII enters the battlefield, choose white Citizen, blue Camarid, black Thrull, red Goblin, or green Saproling.\r\n" card.setText("As Sarpadian Empires, Vol. VII enters the battlefield, choose white Citizen, blue Camarid, black Thrull, red Goblin, or green Saproling.\r\n"
@@ -1273,8 +1279,9 @@ public class CardFactory implements NewConstants {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(card.getName()).append(" - returning creature to the battlefield"); sb.append(card.getName()).append(" - returning creature to the battlefield");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
}//execute() }//execute()
};//Command };//Command
@@ -1385,7 +1392,9 @@ public class CardFactory implements NewConstants {
Card c = (Card)o; Card c = (Card)o;
necrogen.setTargetCard(c); necrogen.setTargetCard(c);
once = true; once = true;
AllZone.Stack.add(necrogen);
AllZone.Stack.addSimultaneousStackEntry(necrogen);
} }
} }
stop(); stop();
@@ -1474,7 +1483,9 @@ public class CardFactory implements NewConstants {
AllZone.GameAction.exile(c); AllZone.GameAction.exile(c);
AllZone.GameAction.exile(c2); AllZone.GameAction.exile(c2);
once = true; once = true;
AllZone.Stack.add(nightSoil);
AllZone.Stack.addSimultaneousStackEntry(nightSoil);
} }
} }
} }
@@ -1811,7 +1822,8 @@ public class CardFactory implements NewConstants {
public void execute() { public void execute() {
ability.setStackDescription("If Mox Diamond would enter the battlefield, you may discard a land card instead. If you do, put Mox Diamond onto the battlefield. If you don't, put it into its owner's graveyard."); ability.setStackDescription("If Mox Diamond would enter the battlefield, you may discard a land card instead. If you do, put Mox Diamond onto the battlefield. If you don't, put it into its owner's graveyard.");
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
SpellAbility spell = new Spell_Permanent(card) { SpellAbility spell = new Spell_Permanent(card) {
@@ -2151,8 +2163,9 @@ public class CardFactory implements NewConstants {
sb.append("Imprint - ").append(card.getController()); sb.append("Imprint - ").append(card.getController());
sb.append(" may exile an instant card with converted mana cost 2 or less from their hand."); sb.append(" may exile an instant card with converted mana cost 2 or less from their hand.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
@@ -2458,7 +2471,8 @@ public class CardFactory implements NewConstants {
private static final long serialVersionUID = -6417019967914398902L; private static final long serialVersionUID = -6417019967914398902L;
public void execute() { public void execute() {
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
};//Command };//Command
@@ -2546,8 +2560,9 @@ public class CardFactory implements NewConstants {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(card.getName()).append(" - choose a creature type. Creatures of that type do not untap during their controller's untap step."); sb.append(card.getName()).append(" - choose a creature type. Creatures of that type do not untap during their controller's untap step.");
comesIntoPlayAbility.setStackDescription(sb.toString()); comesIntoPlayAbility.setStackDescription(sb.toString());
AllZone.Stack.add(comesIntoPlayAbility); AllZone.Stack.addSimultaneousStackEntry(comesIntoPlayAbility);
} }
}; };
@@ -2810,7 +2825,8 @@ public class CardFactory implements NewConstants {
private static final long serialVersionUID = 2266471224097876143L; private static final long serialVersionUID = 2266471224097876143L;
public void execute() { public void execute() {
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
@@ -2879,8 +2895,9 @@ public class CardFactory implements NewConstants {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("As ").append(card.getName()).append(" enters the battlefield, pay any amount of life."); sb.append("As ").append(card.getName()).append(" enters the battlefield, pay any amount of life.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
card.addComesIntoPlayCommand(intoPlay); card.addComesIntoPlayCommand(intoPlay);
@@ -3147,8 +3164,9 @@ public class CardFactory implements NewConstants {
sb.append("exile all creatures you control. "); sb.append("exile all creatures you control. ");
sb.append("Then put that many 5/5 red Dragon creature tokens with flying onto the battlefield."); sb.append("Then put that many 5/5 red Dragon creature tokens with flying onto the battlefield.");
exileAll.setStackDescription(sb.toString()); exileAll.setStackDescription(sb.toString());
AllZone.Stack.add(exileAll); AllZone.Stack.addSimultaneousStackEntry(exileAll);
} }
}; };
@@ -3176,8 +3194,9 @@ public class CardFactory implements NewConstants {
sb.append("sacrifice all Dragons you control. "); sb.append("sacrifice all Dragons you control. ");
sb.append("Then return the exiled cards to the battlefield under your control."); sb.append("Then return the exiled cards to the battlefield under your control.");
returnAll.setStackDescription(sb.toString()); returnAll.setStackDescription(sb.toString());
AllZone.Stack.add(returnAll); AllZone.Stack.addSimultaneousStackEntry(returnAll);
} }
}; };
@@ -3205,8 +3224,9 @@ public class CardFactory implements NewConstants {
sb.append(cardName).append(" - ").append(card.getController()); sb.append(cardName).append(" - ").append(card.getController());
sb.append(" loses life equal to his or her life total."); sb.append(" loses life equal to his or her life total.");
loseAllLife.setStackDescription(sb.toString()); loseAllLife.setStackDescription(sb.toString());
AllZone.Stack.add(loseAllLife); AllZone.Stack.addSimultaneousStackEntry(loseAllLife);
} }
}; };
@@ -3226,8 +3246,9 @@ public class CardFactory implements NewConstants {
sb.append(cardName).append(" - ").append(card.getController()); sb.append(cardName).append(" - ").append(card.getController());
sb.append("loses the game."); sb.append("loses the game.");
loseGame.setStackDescription(sb.toString()); loseGame.setStackDescription(sb.toString());
AllZone.Stack.add(loseGame); AllZone.Stack.addSimultaneousStackEntry(loseGame);
} }
}; };

View File

@@ -1431,7 +1431,7 @@ public class CardFactoryUtil {
Object o = GuiUtils.getChoiceOptional("Select a card", sameType.toArray()); Object o = GuiUtils.getChoiceOptional("Select a card", sameType.toArray());
if(o != null) { if(o != null) {
//ability.setTargetCard((Card)o); //ability.setTargetCard((Card)o);
//AllZone.Stack.add(ability);
sourceCard.getController().discard(sourceCard, this); sourceCard.getController().discard(sourceCard, this);
Card c1 = (Card) o; Card c1 = (Card) o;
AllZone.GameAction.moveToHand(c1); AllZone.GameAction.moveToHand(c1);
@@ -1505,7 +1505,7 @@ public class CardFactoryUtil {
Object o = GuiUtils.getChoiceOptional("Select a card", sameCost.toArray()); Object o = GuiUtils.getChoiceOptional("Select a card", sameCost.toArray());
if(o != null) { if(o != null) {
//ability.setTargetCard((Card)o); //ability.setTargetCard((Card)o);
//AllZone.Stack.add(ability);
sourceCard.getController().discard(sourceCard, this); sourceCard.getController().discard(sourceCard, this);
Card c1 = (Card) o; Card c1 = (Card) o;
@@ -4417,7 +4417,9 @@ public class CardFactoryUtil {
} }
}; };
ability.setStackDescription("Fastbond - Deals 1 damage to you."); ability.setStackDescription("Fastbond - Deals 1 damage to you.");
AllZone.Stack.add(ability);
AllZone.Stack.addSimultaneousStackEntry(ability);
} }
} }
@@ -4430,7 +4432,9 @@ public class CardFactoryUtil {
} }
}; };
ability.setStackDescription(city.getName()+" - sacrifice "+city.getName()); ability.setStackDescription(city.getName()+" - sacrifice "+city.getName());
AllZone.Stack.add(ability);
AllZone.Stack.addSimultaneousStackEntry(ability);
} }
} }

View File

@@ -1521,7 +1521,8 @@ class CardFactory_Auras {
private static final long serialVersionUID = 3595188622377350327L; private static final long serialVersionUID = 3595188622377350327L;
public void execute() { public void execute() {
AllZone.Stack.add(attach); AllZone.Stack.addSimultaneousStackEntry(attach);
} }
}; };
@@ -1548,7 +1549,8 @@ class CardFactory_Auras {
PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, card.getController()); PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, card.getController());
if(AllZone.GameAction.isCardInZone(c, play)) if(AllZone.GameAction.isCardInZone(c, play))
AllZone.Stack.add(detach); AllZone.Stack.addSimultaneousStackEntry(detach);
} }
}; };
// Do not remove SpellAbilities created by AbilityFactory or Keywords. // Do not remove SpellAbilities created by AbilityFactory or Keywords.
@@ -2242,7 +2244,9 @@ class CardFactory_Auras {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(card.getController()).append(" untaps up to 5 lands."); sb.append(card.getController()).append(" untaps up to 5 lands.");
untapAbility.setStackDescription(sb.toString()); untapAbility.setStackDescription(sb.toString());
AllZone.Stack.add(untapAbility);
AllZone.Stack.addSimultaneousStackEntry(untapAbility);
} }
}; };
if (optionUnTapLands) { if (optionUnTapLands) {

View File

@@ -189,7 +189,8 @@ public class CardFactory_Creatures {
private static final long serialVersionUID = 8485080996453793968L; private static final long serialVersionUID = 8485080996453793968L;
public void execute() { public void execute() {
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
};//Command };//Command
ability.setStackDescription("Caller of the Claw - Put a 2/2 green Bear creature token onto the battlefield for each nontoken creature put into your graveyard from play this turn."); ability.setStackDescription("Caller of the Claw - Put a 2/2 green Bear creature token onto the battlefield for each nontoken creature put into your graveyard from play this turn.");
@@ -456,7 +457,8 @@ public class CardFactory_Creatures {
private static final long serialVersionUID = 2856638426932227407L; private static final long serialVersionUID = 2856638426932227407L;
public void execute() { public void execute() {
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
@@ -507,8 +509,9 @@ public class CardFactory_Creatures {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(card.getName()).append(" - choose: 3/3, 2/2 flying, 1/6 defender"); sb.append(card.getName()).append(" - choose: 3/3, 2/2 flying, 1/6 defender");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
card.addComesIntoPlayCommand(intoPlay); card.addComesIntoPlayCommand(intoPlay);
@@ -529,8 +532,9 @@ public class CardFactory_Creatures {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(card.getName()).append(" - ").append(card.getOwner()).append(" creatures have Trample."); sb.append(card.getName()).append(" - ").append(card.getOwner()).append(" creatures have Trample.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
card.addDestroyCommand(destroy); card.addDestroyCommand(destroy);
@@ -552,8 +556,9 @@ public class CardFactory_Creatures {
sb.append(card.getName()).append(" - ").append(card.getOwner()); sb.append(card.getName()).append(" - ").append(card.getOwner());
sb.append(" creatures have Swampwalk."); sb.append(" creatures have Swampwalk.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
card.addDestroyCommand(destroy); card.addDestroyCommand(destroy);
@@ -688,8 +693,9 @@ public class CardFactory_Creatures {
sb.append(card.getName()).append(" - ").append(card.getOwner()); sb.append(card.getName()).append(" - ").append(card.getOwner());
sb.append(" creatures have Haste."); sb.append(" creatures have Haste.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
card.addDestroyCommand(destroy); card.addDestroyCommand(destroy);
@@ -711,8 +717,9 @@ public class CardFactory_Creatures {
sb.append(card.getName()).append(" - ").append(card.getOwner()); sb.append(card.getName()).append(" - ").append(card.getOwner());
sb.append(" creatures have First Strike."); sb.append(" creatures have First Strike.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
card.addDestroyCommand(destroy); card.addDestroyCommand(destroy);
@@ -734,8 +741,9 @@ public class CardFactory_Creatures {
sb.append(card.getName()).append(" - ").append(card.getOwner()); sb.append(card.getName()).append(" - ").append(card.getOwner());
sb.append(" creatures have Flying."); sb.append(" creatures have Flying.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
card.addDestroyCommand(destroy); card.addDestroyCommand(destroy);
@@ -828,8 +836,9 @@ public class CardFactory_Creatures {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(card.getController()).append(" sacrifices Drekavac unless he discards a noncreature card"); sb.append(card.getController()).append(" sacrifices Drekavac unless he discards a noncreature card");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
@@ -902,8 +911,9 @@ public class CardFactory_Creatures {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(card.getController()).append(" - discards at random or sacrifices ").append(cardName); sb.append(card.getController()).append(" - discards at random or sacrifices ").append(cardName);
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
card.addComesIntoPlayCommand(intoPlay); card.addComesIntoPlayCommand(intoPlay);
@@ -980,7 +990,8 @@ public class CardFactory_Creatures {
private static final long serialVersionUID = 4757054648163014149L; private static final long serialVersionUID = 4757054648163014149L;
public void execute() { public void execute() {
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@@ -1007,8 +1018,8 @@ public class CardFactory_Creatures {
private static final long serialVersionUID = -3934471871041458847L; private static final long serialVersionUID = -3934471871041458847L;
public void execute() { public void execute() {
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
}//execute() }//execute()
}; };
card.addComesIntoPlayCommand(intoPlay); card.addComesIntoPlayCommand(intoPlay);
@@ -1091,7 +1102,8 @@ public class CardFactory_Creatures {
if(o != null)//should never happen, but just in case if(o != null)//should never happen, but just in case
{ {
ability.setTargetCard((Card) o); ability.setTargetCard((Card) o);
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}//else }//else
}//execute() }//execute()
@@ -1165,8 +1177,9 @@ public class CardFactory_Creatures {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(card.getController()).append(" untaps up to 5 lands."); sb.append(card.getController()).append(" untaps up to 5 lands.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
card.addComesIntoPlayCommand(intoPlay); card.addComesIntoPlayCommand(intoPlay);
@@ -1227,8 +1240,9 @@ public class CardFactory_Creatures {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(card.getController()).append(" untaps up to 7 lands."); sb.append(card.getController()).append(" untaps up to 7 lands.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
card.addComesIntoPlayCommand(intoPlay); card.addComesIntoPlayCommand(intoPlay);
@@ -1289,8 +1303,9 @@ public class CardFactory_Creatures {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(card.getController()).append(" untaps up to 7 lands."); sb.append(card.getController()).append(" untaps up to 7 lands.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
card.addComesIntoPlayCommand(intoPlay); card.addComesIntoPlayCommand(intoPlay);
@@ -1371,8 +1386,9 @@ public class CardFactory_Creatures {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(card.getController()).append(" untaps up to 2 lands."); sb.append(card.getController()).append(" untaps up to 2 lands.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
card.addComesIntoPlayCommand(intoPlay); card.addComesIntoPlayCommand(intoPlay);
@@ -1407,8 +1423,9 @@ public class CardFactory_Creatures {
sb.append(card.getController()); sb.append(card.getController());
sb.append(" shuffles the cards from his hand into his library, then draws that many cards."); sb.append(" shuffles the cards from his hand into his library, then draws that many cards.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability );
} }
}; };
card.addComesIntoPlayCommand(intoPlay); card.addComesIntoPlayCommand(intoPlay);
@@ -1438,8 +1455,9 @@ public class CardFactory_Creatures {
sb.append(card.getController().getOpponent()); sb.append(card.getController().getOpponent());
sb.append(" gains control of all other permanents you control"); sb.append(" gains control of all other permanents you control");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
card.addComesIntoPlayCommand(intoPlay); card.addComesIntoPlayCommand(intoPlay);
@@ -1512,7 +1530,8 @@ public class CardFactory_Creatures {
if(computer.size() != 0) { if(computer.size() != 0) {
target = computer.get(0); target = computer.get(0);
abilityComes.setTargetCard(target); abilityComes.setTargetCard(target);
AllZone.Stack.add(abilityComes); AllZone.Stack.addSimultaneousStackEntry(abilityComes);
} }
else else
AllZone.GameAction.sacrifice(card); AllZone.GameAction.sacrifice(card);
@@ -1545,8 +1564,9 @@ public class CardFactory_Creatures {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(card.getName()).append(" - returning creature to the battlefield"); sb.append(card.getName()).append(" - returning creature to the battlefield");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
}//execute() }//execute()
};//Command };//Command
@@ -1663,7 +1683,8 @@ public class CardFactory_Creatures {
//computer chooses target in Command destroy //computer chooses target in Command destroy
if(con.equals(AllZone.ComputerPlayer)) ability.setTargetPlayer(AllZone.HumanPlayer); if(con.equals(AllZone.ComputerPlayer)) ability.setTargetPlayer(AllZone.HumanPlayer);
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
}//execute() }//execute()
}; };
card.addDestroyCommand(destroy); card.addDestroyCommand(destroy);
@@ -1707,8 +1728,9 @@ public class CardFactory_Creatures {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(card).append(" - ").append(opponent).append(" discards cards"); sb.append(card).append(" - ").append(opponent).append(" discards cards");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
}//execute() }//execute()
}; };
card.addDestroyCommand(destroy); card.addDestroyCommand(destroy);
@@ -1753,8 +1775,9 @@ public class CardFactory_Creatures {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(card).append(" - ").append(card.getController()).append(" draws cards"); sb.append(card).append(" - ").append(card.getController()).append(" draws cards");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
}//execute() }//execute()
}; };
@@ -1799,8 +1822,9 @@ public class CardFactory_Creatures {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(card).append(" - ").append(card.getController()).append(" gains life"); sb.append(card).append(" - ").append(card.getController()).append(" gains life");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
}//execute() }//execute()
}; };
@@ -1846,8 +1870,9 @@ public class CardFactory_Creatures {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(card).append(" - ").append(card.getController()).append(" puts tokens onto the battlefield"); sb.append(card).append(" - ").append(card.getController()).append(" puts tokens onto the battlefield");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
}//execute() }//execute()
}; };
card.addDestroyCommand(destroy); card.addDestroyCommand(destroy);
@@ -2447,7 +2472,8 @@ public class CardFactory_Creatures {
private static final long serialVersionUID = -2433442359225521472L; private static final long serialVersionUID = -2433442359225521472L;
public void execute() { public void execute() {
AllZone.Stack.add(new Ability(card, "0", "Adarkar Valkyrie - Return " + target[0] + " from graveyard to the battlefield") {
AllZone.Stack.addSimultaneousStackEntry(new Ability(card, "0", "Adarkar Valkyrie - Return " + target[0] + " from graveyard to the battlefield") {
@Override @Override
public void resolve() { public void resolve() {
PlayerZone grave = AllZone.getZone(target[0]); PlayerZone grave = AllZone.getZone(target[0]);
@@ -2887,7 +2913,8 @@ public class CardFactory_Creatures {
else if(ability.canPlayAI()) { else if(ability.canPlayAI()) {
ability.chooseTargetAI(); ability.chooseTargetAI();
//need to add this to the stack //need to add this to the stack
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}//execute() }//execute()
@@ -3078,7 +3105,8 @@ public class CardFactory_Creatures {
public void execute() { public void execute() {
AllZone.GameAction.sacrifice(card); AllZone.GameAction.sacrifice(card);
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
})); }));
}//*************** END ************ END ************************** }//*************** END ************ END **************************
@@ -3155,7 +3183,8 @@ public class CardFactory_Creatures {
private static final long serialVersionUID = 6667896040611028600L; private static final long serialVersionUID = 6667896040611028600L;
public void execute() { public void execute() {
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}); });
@@ -3399,7 +3428,8 @@ public class CardFactory_Creatures {
sb.append("Mystic Snake counters ").append(AllZone.Stack.peek().getSourceCard().getName()); sb.append("Mystic Snake counters ").append(AllZone.Stack.peek().getSourceCard().getName());
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
} }
}; };
@@ -4383,9 +4413,11 @@ public class CardFactory_Creatures {
if (card.getName().equals("Lost Auramancers") if (card.getName().equals("Lost Auramancers")
&& card.getCounters(Counters.TIME) <= 0) { && card.getCounters(Counters.TIME) <= 0) {
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} else if (card.getName().equals("Academy Rector")) { } else if (card.getName().equals("Academy Rector")) {
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}// execute() }// execute()
@@ -4459,7 +4491,8 @@ public class CardFactory_Creatures {
ButtonUtil.disableAll(); ButtonUtil.disableAll();
} else if(card.getController().equals(AllZone.ComputerPlayer)) { } else if(card.getController().equals(AllZone.ComputerPlayer)) {
ability.setTargetPlayer(AllZone.HumanPlayer); ability.setTargetPlayer(AllZone.HumanPlayer);
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}//execute() }//execute()
};//Command };//Command
@@ -4556,7 +4589,8 @@ public class CardFactory_Creatures {
else //computer else //computer
{ {
abilityComes.setTargetPlayer(AllZone.HumanPlayer); abilityComes.setTargetPlayer(AllZone.HumanPlayer);
AllZone.Stack.add(abilityComes); AllZone.Stack.addSimultaneousStackEntry(abilityComes);
}//else }//else
}//execute() }//execute()
};//CommandComes };//CommandComes
@@ -4578,8 +4612,9 @@ public class CardFactory_Creatures {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("Laquatus's Champion - ").append(abilityComes.getTargetPlayer()).append(" regains 6 life."); sb.append("Laquatus's Champion - ").append(abilityComes.getTargetPlayer()).append(" regains 6 life.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
}//execute() }//execute()
};//Command };//Command
@@ -4641,7 +4676,8 @@ public class CardFactory_Creatures {
private static final long serialVersionUID = 8485080996453793968L; private static final long serialVersionUID = 8485080996453793968L;
public void execute() { public void execute() {
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
};//Command };//Command
ability.setStackDescription("As Meddling Mage enters the battlefield, name a nonland card."); ability.setStackDescription("As Meddling Mage enters the battlefield, name a nonland card.");
@@ -4810,7 +4846,8 @@ public class CardFactory_Creatures {
} }
}; };
ability.setStackDescription(toString() + " - you may put a token that's a copy of " + getName() + " onto the battlefield."); ability.setStackDescription(toString() + " - you may put a token that's a copy of " + getName() + " onto the battlefield.");
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
for(Entry<Card, Integer> entry : m.entrySet()) { for(Entry<Card, Integer> entry : m.entrySet()) {
this.addDamage(entry.getValue(), entry.getKey()); this.addDamage(entry.getValue(), entry.getKey());
@@ -4904,7 +4941,8 @@ public class CardFactory_Creatures {
public void execute() { public void execute() {
ability.setStackDescription("Singe-Mind Ogre - target player reveals a card at random from " + ability.setStackDescription("Singe-Mind Ogre - target player reveals a card at random from " +
"his or her hand, then loses life equal to that card's converted mana cost."); "his or her hand, then loses life equal to that card's converted mana cost.");
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
card.addComesIntoPlayCommand(intoPlay); card.addComesIntoPlayCommand(intoPlay);
@@ -4987,7 +5025,8 @@ public class CardFactory_Creatures {
public void execute() { public void execute() {
ability.setStackDescription("Kinsbaile Borderguard enters the battlefield with a +1/+1 counter on it for each other Kithkin you control."); ability.setStackDescription("Kinsbaile Borderguard enters the battlefield with a +1/+1 counter on it for each other Kithkin you control.");
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
@@ -5011,7 +5050,8 @@ public class CardFactory_Creatures {
public void execute() { public void execute() {
ability2.setStackDescription("When Kinsbaile Borderguard is put into a graveyard from play, put a 1/1 white " + ability2.setStackDescription("When Kinsbaile Borderguard is put into a graveyard from play, put a 1/1 white " +
"Kithkin Soldier creature token onto the battlefield for each counter on it."); "Kithkin Soldier creature token onto the battlefield for each counter on it.");
AllZone.Stack.add(ability2); AllZone.Stack.addSimultaneousStackEntry(ability2);
} }
}; };
@@ -5038,8 +5078,9 @@ public class CardFactory_Creatures {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(card.getName()).append(" - gain 2 life for each age counter on it."); sb.append(card.getName()).append(" - gain 2 life for each age counter on it.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
};//command };//command
@@ -5093,7 +5134,8 @@ public class CardFactory_Creatures {
public void execute() { public void execute() {
if(card.isKicked()) { if(card.isKicked()) {
ability.setStackDescription("Kavu Titan gets 3 +1/+1 counters and gains trample."); ability.setStackDescription("Kavu Titan gets 3 +1/+1 counters and gains trample.");
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}//execute() }//execute()
};//CommandComes };//CommandComes
@@ -5161,7 +5203,8 @@ public class CardFactory_Creatures {
else //computer else //computer
{ {
ability.setStackDescription("Gatekeeper of Malakir - targeting Human"); ability.setStackDescription("Gatekeeper of Malakir - targeting Human");
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
}//else }//else
} }
}//execute() }//execute()
@@ -5192,7 +5235,8 @@ public class CardFactory_Creatures {
private static final long serialVersionUID = 4245563898487609274L; private static final long serialVersionUID = 4245563898487609274L;
public void execute() { public void execute() {
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
card.addComesIntoPlayCommand(comesIntoPlay); card.addComesIntoPlayCommand(comesIntoPlay);
@@ -5232,7 +5276,8 @@ public class CardFactory_Creatures {
sb.append(card.getName()).append(" - Add 2 Level counters to each creature you control with Level up."); sb.append(card.getName()).append(" - Add 2 Level counters to each creature you control with Level up.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
card.addComesIntoPlayCommand(addLevelCounters); card.addComesIntoPlayCommand(addLevelCounters);
@@ -5295,8 +5340,9 @@ public class CardFactory_Creatures {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(card.getName()).append(" - chosen type gets +2/+2 and Trample until EOT"); sb.append(card.getName()).append(" - chosen type gets +2/+2 and Trample until EOT");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
}//execute }//execute
};//command };//command
@@ -5326,7 +5372,8 @@ public class CardFactory_Creatures {
private static final long serialVersionUID = -3734151854295L; private static final long serialVersionUID = -3734151854295L;
public void execute() { public void execute() {
AllZone.Stack.add(intoPlay); AllZone.Stack.addSimultaneousStackEntry(intoPlay);
} }
}; };
@@ -5620,7 +5667,8 @@ public class CardFactory_Creatures {
private static final long serialVersionUID = 931101364538995898L; private static final long serialVersionUID = 931101364538995898L;
public void execute() { public void execute() {
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
@@ -5802,7 +5850,8 @@ public class CardFactory_Creatures {
private static final long serialVersionUID = -4300804642226899861L; private static final long serialVersionUID = -4300804642226899861L;
public void execute() { public void execute() {
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}; };
@@ -6002,7 +6051,8 @@ public class CardFactory_Creatures {
else if(list.size() != 0) { else if(list.size() != 0) {
Card target = CardFactoryUtil.AI_getBestCreature(list); Card target = CardFactoryUtil.AI_getBestCreature(list);
ability.setTargetCard(target); ability.setTargetCard(target);
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
} }
}//execute() }//execute()
}; };
@@ -6082,7 +6132,8 @@ public class CardFactory_Creatures {
public void execute() { public void execute() {
sacOrSac.setStackDescription("When "+cardName+" enters the battlefield, sacrifice it unless you sacrifice any number of creatures with total power 12 or greater."); sacOrSac.setStackDescription("When "+cardName+" enters the battlefield, sacrifice it unless you sacrifice any number of creatures with total power 12 or greater.");
AllZone.Stack.add(sacOrSac); AllZone.Stack.addSimultaneousStackEntry(sacOrSac);
} }
}; };
@@ -6119,7 +6170,8 @@ public class CardFactory_Creatures {
//Slight hack if the cloner copies a card with triggers //Slight hack if the cloner copies a card with triggers
AllZone.TriggerHandler.removeAllFromCard(cloned[0]); AllZone.TriggerHandler.removeAllFromCard(cloned[0]);
AllZone.Stack.add(copyBack); AllZone.Stack.addSimultaneousStackEntry(copyBack);
} }
}; };
@@ -6274,7 +6326,8 @@ public class CardFactory_Creatures {
private static final long serialVersionUID = 911163814565333484L; private static final long serialVersionUID = 911163814565333484L;
public void execute() { public void execute() {
AllZone.Stack.add(toPlay); AllZone.Stack.addSimultaneousStackEntry(toPlay);
} }
}; };

View File

@@ -244,7 +244,8 @@ class CardFactory_Lands {
if(card.getController() == AllZone.HumanPlayer) { if(card.getController() == AllZone.HumanPlayer) {
AllZone.InputControl.setInput(CardFactoryUtil.input_targetSpecific(a[0], creats, "Select target creature you control", false, false)); AllZone.InputControl.setInput(CardFactoryUtil.input_targetSpecific(a[0], creats, "Select target creature you control", false, false));
} else { } else {
AllZone.Stack.add(a[0]); AllZone.Stack.addSimultaneousStackEntry(a[0]);
} }
} }
}; };

View File

@@ -111,7 +111,7 @@ abstract public class Ability_Mana extends Ability_Activated implements java.io.
if (source.getName().equals("Forbidden Orchard")) { if (source.getName().equals("Forbidden Orchard")) {
this.undoable = false; this.undoable = false;
AllZone.Stack.add(CardFactoryUtil.getForbiddenOrchardAbility(source, getActivatingPlayer().getOpponent())); AllZone.Stack.addSimultaneousStackEntry(CardFactoryUtil.getForbiddenOrchardAbility(source, getActivatingPlayer().getOpponent()));
} }
if(source.getType().contains("Mountain") && AllZoneUtil.isCardInPlay("Gauntlet of Might")) { if(source.getType().contains("Mountain") && AllZoneUtil.isCardInPlay("Gauntlet of Might")) {
@@ -167,6 +167,8 @@ abstract public class Ability_Mana extends Ability_Activated implements java.io.
runParams.put("Ability_Mana", this); runParams.put("Ability_Mana", this);
runParams.put("Produced", produced); runParams.put("Produced", produced);
AllZone.TriggerHandler.runTrigger("TapsForMana", runParams); AllZone.TriggerHandler.runTrigger("TapsForMana", runParams);
}//end produceMana(String) }//end produceMana(String)

View File

@@ -40,6 +40,7 @@ public abstract class SpellAbility {
private boolean spell; private boolean spell;
private boolean trigger = false; private boolean trigger = false;
private boolean mandatory = false;
private boolean tapAbility; private boolean tapAbility;
private boolean untapAbility; private boolean untapAbility;
@@ -102,7 +103,7 @@ public abstract class SpellAbility {
public boolean canPlayAI() { public boolean canPlayAI() {
return true; return true;
} }
// This should be overridden by ALL AFs // This should be overridden by ALL AFs
public boolean doTrigger(boolean mandatory){ public boolean doTrigger(boolean mandatory){
return false; return false;
@@ -387,6 +388,8 @@ public abstract class SpellAbility {
public void setStackDescription(String s) { public void setStackDescription(String s) {
stackDescription = s; stackDescription = s;
if(description == "")
description = s;
} }
public String getStackDescription() { public String getStackDescription() {
@@ -432,6 +435,7 @@ public abstract class SpellAbility {
while(node != null){ while(node != null){
if (node != this) if (node != this)
sb.append(" "); sb.append(" ");
sb.append(node.getDescription().replace("CARDNAME", node.getSourceCard().getName())); sb.append(node.getDescription().replace("CARDNAME", node.getSourceCard().getName()));
node = node.getSubAbility(); node = node.getSubAbility();
@@ -589,4 +593,12 @@ public abstract class SpellAbility {
public boolean isTrigger() { public boolean isTrigger() {
return trigger; return trigger;
} }
public void setMandatory(boolean mand) {
this.mandatory = mand;
}
public boolean isMandatory() {
return mandatory;
}
} }

View File

@@ -79,7 +79,7 @@ public class Spell_Permanent extends Spell {
if(computer.size() != 0) { if(computer.size() != 0) {
target = computer.get(0); target = computer.get(0);
championAbilityComes.setTargetCard(target); championAbilityComes.setTargetCard(target);
AllZone.Stack.add(championAbilityComes); AllZone.Stack.addSimultaneousStackEntry(championAbilityComes);
if(getSourceCard().getName().equals("Mistbind Clique")) { if(getSourceCard().getName().equals("Mistbind Clique")) {
//TODO this needs to target //TODO this needs to target
CardList list = AllZoneUtil.getPlayerLandsInPlay(AllZone.HumanPlayer); CardList list = AllZoneUtil.getPlayerLandsInPlay(AllZone.HumanPlayer);
@@ -117,7 +117,7 @@ public class Spell_Permanent extends Spell {
sb.append(getSourceCard().getName()).append(" - returning card to battlefield."); sb.append(getSourceCard().getName()).append(" - returning card to battlefield.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
AllZone.Stack.add(ability); AllZone.Stack.addSimultaneousStackEntry(ability);
}//execute() }//execute()
};//championCommandLeavesPlay };//championCommandLeavesPlay

View File

@@ -283,7 +283,6 @@ public class TriggerHandler {
} }
} }
} }
} }
//Checks if the conditions are right for a single trigger to go off, and runs it if so. //Checks if the conditions are right for a single trigger to go off, and runs it if so.
@@ -948,7 +947,9 @@ public class TriggerHandler {
} }
}; };
wrapperAbility.setTrigger(true); wrapperAbility.setTrigger(true);
wrapperAbility.setMandatory(isMandatory);
wrapperAbility.setDescription(wrapperAbility.getStackDescription());
/*
if(host.getController().isHuman()) if(host.getController().isHuman())
{ {
AllZone.GameAction.playSpellAbility(wrapperAbility); AllZone.GameAction.playSpellAbility(wrapperAbility);
@@ -958,7 +959,8 @@ public class TriggerHandler {
wrapperAbility.doTrigger(isMandatory); wrapperAbility.doTrigger(isMandatory);
ComputerUtil.playStack(wrapperAbility); ComputerUtil.playStack(wrapperAbility);
} }
*/
AllZone.Stack.addSimultaneousStackEntry(wrapperAbility);
return true; return true;
} }