*Changed Characteristics-handling from an array to a Map.

*Renamed AF_ChangeState to AF_SetState. SetState can be used with a Transform,Flip or NewState parameter.
*Rewrote Clones to use Characteristics.
*Rewrote Morph to use Characteristics.
*Added
	Ixidron
	Sakashima, the Impostor
This commit is contained in:
Hellfish
2011-11-15 17:14:53 +00:00
parent d4fe16cc7a
commit cbf36eeef0
55 changed files with 501 additions and 383 deletions

View File

@@ -4,10 +4,12 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import com.esotericsoftware.minlog.Log;
@@ -41,46 +43,97 @@ public class Card extends GameEntity implements Comparable<Card> {
private int uniqueNumber = nextUniqueNumber++;
private long value;
private Map<String, CardCharacteristics> characteristicsMap = new HashMap<String,CardCharacteristics>();
private String curCharacteristics = "Original";
private String preTFDCharacteristic = "Original";
private CardCharacteristics[] characteristics = new CardCharacteristics[] { new CardCharacteristics(), null };
private int currentCharacteristic = 0;
private boolean isDoubleFaced = false;
private boolean isFlip = false;
public Card() {
characteristicsMap.put("Original", new CardCharacteristics());
characteristicsMap.put("FaceDown", CardUtil.getFaceDownCharacteristic());
}
public boolean setState(String state) {
if(state.equals("FaceDown") && isDoubleFaced) {
return false; //Doublefaced cards can't be turned face-down.
}
if(!characteristicsMap.containsKey(state)) {
System.out.println(getName() + " tried to switch to non-existant state \"" + state + "\"!");
return false; //Nonexistant state.
}
if(state.equals(curCharacteristics)) {
return false;
}
curCharacteristics = state;
return true;
}
public Set<String> getStates() {
return characteristicsMap.keySet();
}
public String getCurState() {
return curCharacteristics;
}
public void switchStates(String from,String to)
{
CardCharacteristics tmp = characteristicsMap.get(from);
characteristicsMap.put(from, characteristicsMap.get(to));
characteristicsMap.put(to, tmp);
}
public void clearStates(String state) {
characteristicsMap.remove(state);
}
public void turnFaceDown() {
if(!isDoubleFaced) {
preTFDCharacteristic = curCharacteristics;
curCharacteristics = "FaceDown";
}
}
public void turnFaceUp() {
if(curCharacteristics.equals("FaceDown")) {
curCharacteristics = preTFDCharacteristic;
}
}
public boolean isCloned() {
for(String state : characteristicsMap.keySet()) {
if(state.equals("Cloner")) {
return true;
}
}
return false;
}
public CardCharacteristics getState(String state) {
return characteristicsMap.get(state);
}
/**
* Gets the characteristics.
*
* @return the characteristics
*/
public CardCharacteristics getCharacteristics() {
return characteristics[currentCharacteristic];
return characteristicsMap.get(curCharacteristics);
}
/**
*
* addAlternateState.
*/
public final void addAlternateState() {
characteristics[1] = new CardCharacteristics();
}
/**
*
* clearAlternateState.
*/
public final void clearAlternateState() {
if (currentCharacteristic == 1) {
changeState();
}
characteristics[1] = null;
}
/**
*
* clearOtherState.
*/
public final void clearOtherState() {
characteristics[1 - currentCharacteristic] = null;
public final void addAlternateState(String state) {
characteristicsMap.put(state,new CardCharacteristics());
}
/*
@@ -110,7 +163,7 @@ public class Card extends GameEntity implements Comparable<Card> {
* @return boolean
*/
public final boolean isInAlternateState() {
return currentCharacteristic == 1;
return !(curCharacteristics.equals("Original") || curCharacteristics.equals("Cloned"));
}
/**
@@ -120,23 +173,7 @@ public class Card extends GameEntity implements Comparable<Card> {
* @return boolean
*/
public final boolean hasAlternateState() {
return characteristics[1] != null;
}
/**
*
* changeState.
*
* @return boolean
*/
public final boolean changeState() {
if (characteristics[1 - currentCharacteristic] != null) {
currentCharacteristic = 1 - currentCharacteristic;
return true;
}
return false;
return characteristicsMap.keySet().size() > 2;
}
/**
@@ -231,7 +268,6 @@ public class Card extends GameEntity implements Comparable<Card> {
private ArrayList<Card> mustBlockCards = new ArrayList<Card>();
private boolean canMorph = false;
private boolean faceDown = false;
private boolean kicked = false;
private boolean evoked = false;
@@ -2735,12 +2771,15 @@ public class Card extends GameEntity implements Comparable<Card> {
* @return ArrayList<SpellAbility>
*/
public final ArrayList<SpellAbility> getAllSpellAbilities() {
ArrayList<SpellAbility> res = new ArrayList<SpellAbility>(getSpellAbilities());
if (hasAlternateState()) {
changeState();
ArrayList<SpellAbility> res = new ArrayList<SpellAbility>();
String curState = curCharacteristics;
for(String key : characteristicsMap.keySet()) {
setState(key);
res.addAll(getSpellAbilities());
changeState();
}
setState(curState);
return res;
}
@@ -3064,18 +3103,6 @@ public class Card extends GameEntity implements Comparable<Card> {
return spellCopyingCard;
}
/**
* <p>
* setIsFaceDown.
* </p>
*
* @param b
* a boolean.
*/
public final void setIsFaceDown(final boolean b) {
faceDown = b;
}
/**
* <p>
* isFaceDown.
@@ -3084,7 +3111,7 @@ public class Card extends GameEntity implements Comparable<Card> {
* @return a boolean.
*/
public final boolean isFaceDown() {
return faceDown;
return curCharacteristics.equals("FaceDown");
}
/**

View File

@@ -456,8 +456,15 @@ public class CardReader implements Runnable {
card.addSet(new SetInfo(value)); // NOPMD by Braids on
// 8/18/11 11:08 PM
} else if (line.equals("ALTERNATE")) {
card.addAlternateState();
card.changeState();
String mode;
if(card.isFlip()) {
mode = "Flipped";
}
else {
mode = "Transformed";
}
card.addAlternateState(mode);
card.setState(mode);
} else if (line.startsWith("AlternateMode:")) {
final String value = line.substring("AlternateMode:".length());
if (value.equalsIgnoreCase("Flip")) {
@@ -494,10 +501,9 @@ public class CardReader implements Runnable {
}
if (card.isInAlternateState()) {
card.changeState();
card.setState("Original");
}
listRulesToFill.add(rulesReader.getCard());
mapToFill.put(card.getName(), card);
return card;

View File

@@ -13,6 +13,7 @@ import net.slightlymagic.maxmtg.Predicate;
import org.apache.commons.lang3.StringUtils;
import forge.card.CardCharacteristics;
import forge.card.mana.ManaCost;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityList;
@@ -960,5 +961,22 @@ public final class CardUtil {
return usableColors;
}
public static CardCharacteristics getFaceDownCharacteristic() {
ArrayList<String> types = new ArrayList<String>();
types.add("Creature");
CardCharacteristics ret = new CardCharacteristics();
ret.setBaseAttack(2);
ret.setBaseDefense(2);
ret.setName("");
ret.setType(types);
ret.setImageFilename("morph.jpg");
return ret;
}
} // end class CardUtil

View File

@@ -70,16 +70,9 @@ public class GameAction {
// Reset Activations per Turn
for (final Card card : all) {
for (final SpellAbility sa : card.getSpellAbility()) {
for (final SpellAbility sa : card.getAllSpellAbilities()) {
sa.getRestrictions().resetTurnActivations();
}
if (card.hasAlternateState()) {
card.changeState();
for (final SpellAbility sa : card.getSpellAbility()) {
sa.getRestrictions().resetTurnActivations();
}
card.changeState();
}
}
}
@@ -121,8 +114,13 @@ public class GameAction {
copied = c;
} else {
if (c.isInAlternateState()) {
c.changeState();
c.setState("Original");
}
if (c.isCloned()) {
c.switchStates("Cloner", "Original");
c.setState("Original");
}
copied = AllZone.getCardFactory().copyCard(c);
lastKnownInfo = CardUtil.getLKICopy(c);
@@ -545,7 +543,7 @@ public class GameAction {
if(c.isInAlternateState())
{
c.changeState();
c.setState("Original");
}
if ((p != null) && p.is(Constant.Zone.Battlefield)) {
@@ -1344,9 +1342,16 @@ public class GameAction {
AllZone.getHumanPlayer().getZone(Zone.Library).add(card);
if (card.hasAlternateState()) {
card.changeState();
if(card.isDoubleFaced()) {
card.setState("Transformed");
}
if(card.isFlip()) {
card.setState("Flipped");
}
card.setImageFilename(CardUtil.buildFilename(card));
card.changeState();
card.setState("Original");
}
}
}
@@ -1380,9 +1385,16 @@ public class GameAction {
}
if (card.hasAlternateState()) {
card.changeState();
if(card.isDoubleFaced()) {
card.setState("Transformed");
}
if(card.isFlip()) {
card.setState("Flipped");
}
card.setImageFilename(CardUtil.buildFilename(card));
card.changeState();
card.setState("Original");
}
}
}

View File

@@ -1486,24 +1486,8 @@ public final class GuiDisplayUtil {
}
} else if (info.equalsIgnoreCase("SummonSick:True")) {
c.setSickness(true);
} else if (info.equalsIgnoreCase("Morphed:True")) {
if (!c.getCanMorph()) {
System.out.println("Setup game state - Can't morph a card without the morph keyword!");
continue;
}
c.setIsFaceDown(true);
c.setManaCost("");
c.setColor(new ArrayList<CardColor>()); // remove all
// colors
c.addColor("0");
c.setBaseAttack(2);
c.setBaseDefense(2);
c.comesIntoPlay();
c.setIntrinsicKeyword(new ArrayList<String>()); // remove
// all
// keywords
c.setType(new ArrayList<String>()); // remove all types
c.addType("Creature");
} else if (info.equalsIgnoreCase("FaceDown:True")) {
c.setState("FaceDown");
}
}

View File

@@ -48,10 +48,15 @@ public class GuiDownloadPicturesLQ extends GuiDownloader {
String base = ForgeProps.getFile(NewConstants.IMAGE_BASE).getPath();
for (Card c : AllZone.getCardFactory()) {
cList.addAll(createDLObjects(c, base));
if (c.hasAlternateState()) {
c.changeState();
if (c.isFlip()) {
c.setState("Flip");
cList.addAll(createDLObjects(c, base));
}
if(c.isDoubleFaced()) {
c.setState("Transformed");
cList.addAll(createDLObjects(c, base));
}
c.setState("Original");
}
ArrayList<DownloadObject> list = new ArrayList<DownloadObject>();

View File

@@ -2482,26 +2482,16 @@ public class Upkeep implements java.io.Serializable {
* add new to play
*/
final Card newCopy = AllZone.getCardFactory().getCard(newTarget[0].getName(), player);
final Card newCopy = AllZone.getCardFactory().getCard(newTarget[0].getState("Original").getName(), player);
newCopy.setCurSetCode(newTarget[0].getCurSetCode());
newCopy.setImageFilename(newTarget[0].getImageFilename());
// need to add the leaves play command (2)
newCopy.addLeavesPlayCommand(c.getCloneLeavesPlayCommand());
c.removeTrigger(c.getCloneLeavesPlayCommand(), ZCTrigger.LEAVEFIELD);
newCopy.setCloneLeavesPlayCommand(c.getCloneLeavesPlayCommand());
newCopy.addExtrinsicKeyword(keyword);
newCopy.addColor("U", newCopy, false, true);
newCopy.setCloneOrigin(c.getCloneOrigin());
newCopy.getCloneOrigin().setCurrentlyCloningCard(newCopy);
c.setCloneOrigin(null);
// 5
final PlayerZone play = AllZone.getZoneOf(c);
play.remove(c);
play.add(newCopy);
newCopy.setState(newTarget[0].getCurState());
CardFactoryUtil.copyCharacteristics(newCopy, c);
c.addColor("U");
c.addExtrinsicKeyword(keyword);
}
}
};

View File

@@ -1146,23 +1146,23 @@ public class AbilityFactory {
}
}
else if (this.api.equals("ChangeState")) {
else if (this.api.equals("SetState")) {
if (this.isAb) {
spellAbility = AbilityFactoryChangeState.getChangeStateAbility(this);
spellAbility = AbilityFactorySetState.getSetStateAbility(this);
} else if (this.isSp) {
spellAbility = AbilityFactoryChangeState.getChangeStateSpell(this);
spellAbility = AbilityFactorySetState.getSetStateSpell(this);
} else if (this.isDb) {
spellAbility = AbilityFactoryChangeState.getChangeStateDrawback(this);
spellAbility = AbilityFactorySetState.getSetStateDrawback(this);
}
}
else if (this.api.equals("ChangeStateAll")) {
else if (this.api.equals("SetStateAll")) {
if (this.isAb) {
spellAbility = AbilityFactoryChangeState.getChangeStateAllAbility(this);
spellAbility = AbilityFactorySetState.getSetStateAllAbility(this);
} else if (this.isSp) {
spellAbility = AbilityFactoryChangeState.getChangeStateAllSpell(this);
spellAbility = AbilityFactorySetState.getSetStateAllSpell(this);
} else if (this.isDb) {
spellAbility = AbilityFactoryChangeState.getChangeStateAllDrawback(this);
spellAbility = AbilityFactorySetState.getSetStateAllDrawback(this);
}
}

View File

@@ -843,7 +843,7 @@ public final class AbilityFactoryChangeZone {
} else {
movedCard = AllZone.getGameAction().moveTo(destZone, c);
if (params.containsKey("ExileFaceDown")) {
movedCard.setIsFaceDown(true);
movedCard.setState("FaceDown");
}
}
@@ -1007,7 +1007,7 @@ public final class AbilityFactoryChangeZone {
} else {
newCard = AllZone.getGameAction().moveTo(destZone, c);
if (params.containsKey("ExileFaceDown")) {
newCard.setIsFaceDown(true);
newCard.setState("FaceDown");
}
}
@@ -1793,7 +1793,7 @@ public final class AbilityFactoryChangeZone {
} else {
movedCard = AllZone.getGameAction().moveTo(pl.getZone(destination), tgtC);
if (params.containsKey("ExileFaceDown")) {
movedCard.setIsFaceDown(true);
movedCard.setState("FaceDown");
}
}
}
@@ -2199,7 +2199,7 @@ public final class AbilityFactoryChangeZone {
} else {
final Card movedCard = AllZone.getGameAction().moveTo(destination, c, libraryPos);
if (params.containsKey("ExileFaceDown")) {
movedCard.setIsFaceDown(true);
movedCard.setState("FaceDown");
}
}

View File

@@ -347,7 +347,7 @@ public final class AbilityFactoryCopy {
boolean wasInAlt = false;
if (c.isInAlternateState()) {
wasInAlt = true;
c.changeState();
c.setState("Original");
}
// start copied Kiki code
@@ -395,35 +395,22 @@ public final class AbilityFactoryCopy {
if (c.isDoubleFaced()) { // Cloned DFC's can't transform
if (wasInAlt) {
copy.changeState();
c.changeState();
copy.setState("Transformed");
}
copy.clearOtherState();
}
if (c.isFlip()) { // Cloned Flips CAN flip.
copy.changeState();
c.changeState();
copy.setState("Original");
c.setState("Original");
copy.setImageFilename(c.getImageFilename());
if (!c.isInAlternateState()) {
copy.changeState();
copy.setState("Flipped");
}
c.changeState();
c.setState("Flipped");
}
if (c.isFaceDown()) {
copy.setIsFaceDown(true);
copy.setManaCost("");
copy.setBaseAttack(2);
copy.setBaseDefense(2);
//remove all keywords
copy.setIntrinsicKeyword(new ArrayList<String>());
//remove all types
copy.setType(new ArrayList<String>());
copy.addType("Creature");
copy.clearSpellAbility(); // disallow "morph_up"
copy.setCurSetCode("");
copy.setImageFilename("morph.jpg");
c.setState("FaceDown");
}
copy = AllZone.getGameAction().moveToPlay(copy);

View File

@@ -20,7 +20,7 @@ import forge.card.spellability.Target;
* AbilityFactory for abilities that cause cards to change states.
*
*/
public class AbilityFactoryChangeState {
public class AbilityFactorySetState {
/**
* Gets the change state ability.
@@ -29,19 +29,19 @@ public class AbilityFactoryChangeState {
* the aF
* @return the change state ability
*/
public static SpellAbility getChangeStateAbility(final AbilityFactory abilityFactory) {
public static SpellAbility getSetStateAbility(final AbilityFactory abilityFactory) {
final SpellAbility ret = new AbilityActivated(abilityFactory.getHostCard(), abilityFactory.getAbCost(),
abilityFactory.getAbTgt()) {
private static final long serialVersionUID = -1083427558368639457L;
@Override
public String getStackDescription() {
return AbilityFactoryChangeState.changeStateStackDescription(abilityFactory, this);
return AbilityFactorySetState.setStateStackDescription(abilityFactory, this);
}
@Override
public void resolve() {
AbilityFactoryChangeState.changeStateResolve(abilityFactory, this);
AbilityFactorySetState.setStateResolve(abilityFactory, this);
}
};
@@ -55,18 +55,18 @@ public class AbilityFactoryChangeState {
* the aF
* @return the change state spell
*/
public static SpellAbility getChangeStateSpell(final AbilityFactory abilityFactory) {
public static SpellAbility getSetStateSpell(final AbilityFactory abilityFactory) {
final SpellAbility ret = new Spell(abilityFactory.getHostCard()) {
private static final long serialVersionUID = -7506856902233086859L;
@Override
public String getStackDescription() {
return AbilityFactoryChangeState.changeStateStackDescription(abilityFactory, this);
return AbilityFactorySetState.setStateStackDescription(abilityFactory, this);
}
@Override
public void resolve() {
AbilityFactoryChangeState.changeStateResolve(abilityFactory, this);
AbilityFactorySetState.setStateResolve(abilityFactory, this);
}
};
@@ -80,14 +80,14 @@ public class AbilityFactoryChangeState {
* the aF
* @return the change state drawback
*/
public static SpellAbility getChangeStateDrawback(final AbilityFactory abilityFactory) {
public static SpellAbility getSetStateDrawback(final AbilityFactory abilityFactory) {
final AbilitySub ret = new AbilitySub(abilityFactory.getHostCard(), abilityFactory.getAbTgt()) {
private static final long serialVersionUID = -3793247725721587468L;
@Override
public String getStackDescription() {
return AbilityFactoryChangeState.changeStateStackDescription(abilityFactory, this);
return AbilityFactorySetState.setStateStackDescription(abilityFactory, this);
}
@Override
@@ -113,7 +113,7 @@ public class AbilityFactoryChangeState {
@Override
public void resolve() {
AbilityFactoryChangeState.changeStateResolve(abilityFactory, this);
AbilityFactorySetState.setStateResolve(abilityFactory, this);
}
};
@@ -121,7 +121,7 @@ public class AbilityFactoryChangeState {
return ret;
}
private static String changeStateStackDescription(final AbilityFactory abilityFactory, final SpellAbility sa) {
private static String setStateStackDescription(final AbilityFactory abilityFactory, final SpellAbility sa) {
final Map<String, String> params = abilityFactory.getMapParams();
final StringBuilder sb = new StringBuilder();
@@ -176,7 +176,7 @@ public class AbilityFactoryChangeState {
return sb.toString();
}
private static void changeStateResolve(final AbilityFactory abilityFactory, final SpellAbility sa) {
private static void setStateResolve(final AbilityFactory abilityFactory, final SpellAbility sa) {
ArrayList<Card> tgtCards;
@@ -193,7 +193,32 @@ public class AbilityFactoryChangeState {
continue;
}
}
tgt.changeState();
if(abilityFactory.getMapParams().containsKey("Transform"))
{
if(tgt.getCurState().equals("Transformed")) {
tgt.setState("Original");
}
else if(tgt.hasAlternateState() && tgt.getCurState().equals("Original")) {
if(tgt.isDoubleFaced()) {
tgt.setState("Transformed");
}
}
}
else if(abilityFactory.getMapParams().containsKey("Flip"))
{
if(tgt.getCurState().equals("Flipped")) {
tgt.setState("Original");
}
else if(tgt.hasAlternateState()) {
if(tgt.isFlip() && tgt.getCurState().equals("Original")) {
tgt.setState("Flipped");
}
}
}
else
{
tgt.setState(abilityFactory.getMapParams().get("NewState"));
}
}
}
@@ -209,7 +234,7 @@ public class AbilityFactoryChangeState {
* the aF
* @return the change state all ability
*/
public static SpellAbility getChangeStateAllAbility(final AbilityFactory abilityFactory) {
public static SpellAbility getSetStateAllAbility(final AbilityFactory abilityFactory) {
final SpellAbility ret = new AbilityActivated(abilityFactory.getHostCard(), abilityFactory.getAbCost(),
abilityFactory.getAbTgt()) {
@@ -217,12 +242,12 @@ public class AbilityFactoryChangeState {
@Override
public String getStackDescription() {
return AbilityFactoryChangeState.changeStateAllStackDescription(abilityFactory, this);
return AbilityFactorySetState.setStateAllStackDescription(abilityFactory, this);
}
@Override
public void resolve() {
AbilityFactoryChangeState.changeStateAllResolve(abilityFactory, this);
AbilityFactorySetState.setStateAllResolve(abilityFactory, this);
}
};
@@ -237,19 +262,19 @@ public class AbilityFactoryChangeState {
* the aF
* @return the change state all spell
*/
public static SpellAbility getChangeStateAllSpell(final AbilityFactory abilityFactory) {
public static SpellAbility getSetStateAllSpell(final AbilityFactory abilityFactory) {
final SpellAbility ret = new Spell(abilityFactory.getHostCard()) {
private static final long serialVersionUID = 4217632586060204603L;
@Override
public String getStackDescription() {
return AbilityFactoryChangeState.changeStateAllStackDescription(abilityFactory, this);
return AbilityFactorySetState.setStateAllStackDescription(abilityFactory, this);
}
@Override
public void resolve() {
AbilityFactoryChangeState.changeStateAllResolve(abilityFactory, this);
AbilityFactorySetState.setStateAllResolve(abilityFactory, this);
}
};
@@ -263,14 +288,14 @@ public class AbilityFactoryChangeState {
* the aF
* @return the change state all drawback
*/
public static SpellAbility getChangeStateAllDrawback(final AbilityFactory abilityFactory) {
public static SpellAbility getSetStateAllDrawback(final AbilityFactory abilityFactory) {
final AbilitySub ret = new AbilitySub(abilityFactory.getHostCard(), abilityFactory.getAbTgt()) {
private static final long serialVersionUID = 4047514893482113436L;
@Override
public String getStackDescription() {
return AbilityFactoryChangeState.changeStateAllStackDescription(abilityFactory, this);
return AbilityFactorySetState.setStateAllStackDescription(abilityFactory, this);
}
@Override
@@ -292,7 +317,7 @@ public class AbilityFactoryChangeState {
@Override
public void resolve() {
AbilityFactoryChangeState.changeStateAllResolve(abilityFactory, this);
AbilityFactorySetState.setStateAllResolve(abilityFactory, this);
}
};
@@ -300,7 +325,7 @@ public class AbilityFactoryChangeState {
return ret;
}
private static void changeStateAllResolve(final AbilityFactory abilityFactory, final SpellAbility sa) {
private static void setStateAllResolve(final AbilityFactory abilityFactory, final SpellAbility sa) {
final HashMap<String, String> params = abilityFactory.getMapParams();
final Card card = sa.getSourceCard();
@@ -338,13 +363,43 @@ public class AbilityFactoryChangeState {
}
for (int i = 0; i < list.size(); i++) {
if (list.get(i).changeState()) {
card.addRemembered(list.get(i));
String mode = list.get(i).getCurState();
if(list.get(i).isDoubleFaced()) {
if(list.get(i).getCurState().equals("Original"))
{
mode = "Transformed";
}
else {
mode = "Original";
}
if(list.get(i).setState(mode) && remChanged) {
card.addRemembered(list.get(i));
}
}
else if(list.get(i).isFlip()) {
if(list.get(i).getCurState().equals("Original"))
{
mode = "Flipped";
}
else if(list.get(i).getCurState().equals("Flipped")){
mode = "Original";
}
if(list.get(i).setState(mode) && remChanged) {
card.addRemembered(list.get(i));
}
}
else {
if(list.get(i).setState(abilityFactory.getMapParams().get("NewState")) && remChanged) {
card.addRemembered(list.get(i));
}
}
}
}
private static String changeStateAllStackDescription(final AbilityFactory abilityFactory, final SpellAbility sa) {
private static String setStateAllStackDescription(final AbilityFactory abilityFactory, final SpellAbility sa) {
final Card host = abilityFactory.getHostCard();
final Map<String, String> params = abilityFactory.getMapParams();

View File

@@ -171,11 +171,14 @@ public abstract class AbstractCardFactory implements CardFactoryInterface {
CardFactoryUtil.copyCharacteristics(in, out);
if (in.hasAlternateState()) {
in.changeState();
out.changeState();
CardFactoryUtil.copyCharacteristics(in, out);
in.changeState();
out.changeState();
String curState = in.getCurState();
for(String state : in.getStates()) {
in.setState(state);
out.setState(state);
CardFactoryUtil.copyCharacteristics(in, out);
}
in.setState(curState);
out.setState(curState);
}
// I'm not sure if we really should be copying enchant/equip stuff over.
@@ -480,7 +483,7 @@ public abstract class AbstractCardFactory implements CardFactoryInterface {
card.addColor(card.getManaCost());
}
// may have to change the spell
// this is so permanents like creatures and artifacts have a "default"
// spell
if (card.isPermanent() && !card.isLand() && !card.isAura()) {
@@ -500,15 +503,18 @@ public abstract class AbstractCardFactory implements CardFactoryInterface {
}
if (card.hasAlternateState()) {
card.changeState();
this.addAbilityFactoryAbilities(card);
stAbs = card.getStaticAbilityStrings();
if (stAbs.size() > 0) {
for (int i = 0; i < stAbs.size(); i++) {
card.addStaticAbility(stAbs.get(i));
for(String state : card.getStates()) {
card.setState(state);
this.addAbilityFactoryAbilities(card);
stAbs = card.getStaticAbilityStrings();
if (stAbs.size() > 0) {
for (int i = 0; i < stAbs.size(); i++) {
card.addStaticAbility(stAbs.get(i));
}
}
}
card.changeState();
card.setState("Original");
}
// ******************************************************************

View File

@@ -2225,24 +2225,10 @@ public class CardFactoryCreatures {
else if (cardName.equals("Clone") || cardName.equals("Vesuvan Doppelganger")
|| cardName.equals("Quicksilver Gargantuan") || cardName.equals("Jwari Shapeshifter")
|| cardName.equals("Phyrexian Metamorph") || cardName.equals("Phantasmal Image")
|| cardName.equals("Body Double") || cardName.equals("Evil Twin")) {
|| cardName.equals("Body Double") || cardName.equals("Evil Twin")
|| cardName.equals("Sakashima the Impostor")) {
final CardFactoryInterface cfact = cf;
final Card[] copyTarget = new Card[1];
final Card[] cloned = new Card[1];
final Command leaves = new Command() {
private static final long serialVersionUID = 8590474793502538215L;
@Override
public void execute() {
final Card orig = cfact.getCard(card.getName(), card.getController());
final PlayerZone dest = AllZone.getZoneOf(card.getCurrentlyCloningCard());
AllZone.getGameAction().moveTo(dest, orig);
dest.remove(card.getCurrentlyCloningCard());
}
};
final SpellAbility copy = new Spell(card) {
private static final long serialVersionUID = 4496978456522751302L;
@@ -2257,107 +2243,80 @@ public class CardFactoryCreatures {
}
if (copyTarget[0] != null) {
final boolean wasInAlt = copyTarget[0].isInAlternateState();
/*
* This cannot just be copyStats with an addSpellAbility
* loop from copyTarget[0]. Unless we get a
* copySpellAbility. Adding the SpellAbility from the
* source card causes many weird and Bad Things to
* happen.
*/
try {
if (wasInAlt) {
copyTarget[0].changeState();
}
cloned[0] = cfact.getCard(copyTarget[0].getName(), card.getController());
if (wasInAlt) {
cloned[0].setImageFilename(copyTarget[0].getImageFilename());
copyTarget[0].changeState();
}
} catch (final RuntimeException re) {
// the copyTarget was not found in CardFactory
cloned[0] = CardFactoryUtil.copyStats(copyTarget[0]);
Card cloned;
cloned = cfact.getCard(copyTarget[0].getState("Original").getName(), card.getOwner());
card.addAlternateState("Cloner");
card.switchStates("Original", "Cloner");
card.setState("Original");
if(copyTarget[0].getCurState().equals("Transformed") && copyTarget[0].isDoubleFaced()) {
cloned.setState("Transformed");
}
cloned[0].setOwner(card.getController());
cloned[0].addController(card.getController());
if (cardName.equals("Phyrexian Metamorph")) {
cloned[0].addType("Artifact");
}
if (cardName.equals("Phantasmal Image")) {
cloned[0].addType("Illusion");
}
cloned[0].setCloneOrigin(card);
cloned[0].addLeavesPlayCommand(leaves);
cloned[0].setCloneLeavesPlayCommand(leaves);
cloned[0].setCurSetCode(copyTarget[0].getCurSetCode());
CardFactoryUtil.copyCharacteristics(cloned,card);
this.grantExtras();
if (copyTarget[0].isDoubleFaced()) { // Cloned DFC's
// can't transform
if (wasInAlt) {
cloned[0].changeState();
}
cloned[0].clearOtherState();
//If target is a flipped card, also copy the flipped state.
if(copyTarget[0].isFlip()) {
cloned.setState("Flipped");
cloned.setImageFilename(CardUtil.buildFilename(cloned));
card.addAlternateState("Flipped");
card.setState("Flipped");
CardFactoryUtil.copyCharacteristics(cloned,card);
this.grantExtras();
card.setFlip(true);
card.setState("Original");
}
if (copyTarget[0].isFlip()) { // Cloned Flips CAN flip.
cloned[0].changeState();
copyTarget[0].changeState();
cloned[0].setImageFilename(copyTarget[0].getImageFilename());
if (!copyTarget[0].isInAlternateState()) {
cloned[0].changeState();
}
copyTarget[0].changeState();
else {
card.setFlip(false);
}
if (cardName.equals("Vesuvan Doppelganger")) {
final StringBuilder sb = new StringBuilder();
sb.append("At the beginning of your upkeep, you may have ");
sb.append("this creature become a copy of target creature ");
sb.append("except it doesn't copy that creature's color. ");
sb.append("If you do, this creature gains this ability.");
cloned[0].addExtrinsicKeyword(sb.toString());
cloned[0].addColor("U", cloned[0], false, true);
} else if (cardName.equals("Quicksilver Gargantuan")) {
cloned[0].setBaseDefense(7);
cloned[0].setBaseAttack(7);
} else if (cardName.equals("Phantasmal Image")) {
final StringBuilder trigScript = new StringBuilder();
trigScript.append("Mode$ BecomesTarget | ValidTarget$ Card.Self | ");
trigScript.append("TriggerZones$ Battlefield | Execute$ ");
final StringBuilder svarName = new StringBuilder("TrigSac");
// Couple of hoops to jump through to make sure no
// svar is overwritten.
int iter = 0;
while (cloned[0].getSVar(svarName.toString()) != "") {
iter++;
if (svarName.length() == 7) {
svarName.append(iter);
} else {
svarName.delete(8, svarName.length());
svarName.append(iter);
}
}
trigScript.append(svarName.toString());
trigScript.append(" | TriggerDescription$ When this creature ");
trigScript.append("becomes the target of a spell or ability, sacrifice it.");
cloned[0].addTrigger(forge.card.trigger.TriggerHandler.parseTrigger(trigScript.toString(),
card, true));
cloned[0].setSVar(svarName.toString(), "AB$Sacrifice | Cost$ 0 | Defined$ Self");
}
if (cardName.equals("Evil Twin")) {
final AbilityFactory abilityFactory = new AbilityFactory();
final StringBuilder sbET = new StringBuilder();
sbET.append("AB$Destroy | Cost$ U B T | ValidTgts$ Creature.sameName | ");
sbET.append("TgtPrompt$ Select target creature with the same name. | ");
sbET.append("SpellDescription$ Destroy target creature with the same name as this creature.");
final SpellAbility destroySameName = abilityFactory.getAbility(sbET.toString(), cloned[0]);
cloned[0].addSpellAbility(destroySameName);
}
AllZone.getGameAction().moveToPlayFromHand(cloned[0]);
card.setCurrentlyCloningCard(cloned[0]);
}
AllZone.getGameAction().moveToPlay(card);
}
private void grantExtras() {
//Grant stuff from specific cloners
if(cardName.equals("Vesuvan Doppelganger")) {
final String keyword = "At the beginning of your upkeep, you may have this "
+ "creature become a copy of target creature except it doesn't copy that "
+ "creature's color. If you do, this creature gains this ability.";
card.addIntrinsicKeyword(keyword);
card.addColor("U");
}
else if(cardName.equals("Quicksilver Gargantuan")) {
card.setBaseAttack(7);
card.setBaseDefense(7);
}
else if(cardName.equals("Phyrexian Metamorph")) {
card.addType("Artifact");
}
else if(cardName.equals("Phantasmal Image")) {
Trigger t = forge.card.trigger.TriggerHandler.parseTrigger("Mode$ BecomesTarget | ValidTarget$ Card.Self | Execute$ TrigSac | TriggerDescription$ When this creature becomes the target of a spell or ability, sacrifice it.", card, true);
card.addTrigger(t);
card.setSVar("TrigSac", "AB$Sacrifice | Cost$ 0 | Defined$ Self");
}
else if(cardName.equals("Evil Twin")) {
AbilityFactory af = new AbilityFactory();
SpellAbility ab = af.getAbility("AB$Destroy | Cost$ U B T | ValidTgts$ Creature.sameName | TgtPrompt$ Select target creature with the same name. | SpellDescription$ Destroy target creature with the same name as this creature.", card);
card.addSpellAbility(ab);
}
else if(cardName.equals("Sakashima the Impostor")) {
AbilityFactory af = new AbilityFactory();
SpellAbility ab = af.getAbility("AB$DelayedTrigger | Cost$ 2 U U | Mode$ Phase | Phase$ End of Turn | Execute$ TrigReturnSak | TriggerDescription$ Return CARDNAME to it's owners hand at the beginning of the next end step.",card);
card.addSpellAbility(ab);
card.setSVar("TrigReturnSak","AB$ChangeZone | Cost$ 0 | Defined$ Self | Origin$ Battlefield | Destination$ Hand");
card.setName("Sakashima the Impostor");
card.addType("Legendary");
}
}
}; // SpellAbility
@@ -2735,6 +2694,35 @@ public class CardFactoryCreatures {
ability.setStackDescription(sbStack.toString());
} // *************** END ************ END **************************
// *************** START *********** START **************************
else if (cardName.equals("Ixidron")) {
Trigger tfdTrigger = forge.card.trigger.TriggerHandler.parseTrigger("Mode$ ChangesZone | Destination$ Battlefield | ValidCard$ Card.Self | Static$ True | TriggerDescription$ As CARDNAME enters the battlefield, turn all other nontoken creatures face down. (They're 2/2 creatures.)", card, true);
final SpellAbility triggeredAbility = new Ability(card, "0") {
@Override
public void resolve() {
CardList creatsInPlay = AllZoneUtil.getCreaturesInPlay();
creatsInPlay = creatsInPlay.filter(new CardListFilter() {
@Override
public boolean addCard(Card c) {
return !c.isToken() && !c.equals(card);
}
});
for(Card c : creatsInPlay) {
c.turnFaceDown();
}
}
};
tfdTrigger.setOverridingAbility(triggeredAbility);
card.addTrigger(tfdTrigger);
} // *************** END ************ END **************************
// ***************************************************
// end of card specific code
// ***************************************************

View File

@@ -918,20 +918,9 @@ public class CardFactoryUtil {
@Override
public void resolve() {
// card.setName("Morph");
sourceCard.setIsFaceDown(true);
sourceCard.setManaCost("");
sourceCard.setColor(new ArrayList<CardColor>()); // remove all
// colors
sourceCard.addColor("0");
sourceCard.setBaseAttack(2);
sourceCard.setBaseDefense(2);
sourceCard.turnFaceDown();
sourceCard.comesIntoPlay();
sourceCard.setIntrinsicKeyword(new ArrayList<String>()); // remove
// all
// keywords
sourceCard.setType(new ArrayList<String>()); // remove all types
sourceCard.addType("Creature");
AllZone.getGameAction().moveToPlay(sourceCard);
}
@@ -979,15 +968,8 @@ public class CardFactoryUtil {
@Override
public void resolve() {
// card.setName("Morph");
sourceCard.setIsFaceDown(false);
sourceCard.setManaCost(origManaCost);
sourceCard.addColor(origManaCost);
sourceCard.setBaseAttack(attack);
sourceCard.setBaseDefense(defense);
sourceCard.setIntrinsicKeyword(sourceCard.getPrevIntrinsicKeyword());
sourceCard.setType(sourceCard.getPrevType());
sourceCard.turnFaceUp();
// Run triggers
final Map<String, Object> runParams = new TreeMap<String, Object>();
runParams.put("Card", sourceCard);
@@ -998,6 +980,7 @@ public class CardFactoryUtil {
public boolean canPlay() {
// unMorphing a card is a Special Action, and not affected by
// Linvala
Card c = sourceCard;
return sourceCard.getController().equals(this.getActivatingPlayer()) && sourceCard.isFaceDown()
&& AllZoneUtil.isCardInPlay(sourceCard);
}
@@ -4235,12 +4218,16 @@ public class CardFactoryUtil {
CardFactoryUtil.copyCharacteristics(sim, c);
if (sim.hasAlternateState()) {
c.addAlternateState();
c.changeState();
sim.changeState();
CardFactoryUtil.copyCharacteristics(sim, c);
c.changeState();
sim.changeState();
String origState = sim.getCurState();
for(String state : sim.getStates()) {
c.addAlternateState(state);
c.setState(state);
sim.setState(state);
CardFactoryUtil.copyCharacteristics(sim, c);
}
sim.setState(origState);
c.setState(origState);
}
c.setFlip(sim.isFlip());
@@ -4278,7 +4265,7 @@ public class CardFactoryUtil {
to.setImageFilename(from.getImageFilename());
to.setTriggers(from.getTriggers());
to.setStaticAbilityStrings(from.getStaticAbilityStrings());
}
/**
@@ -5124,8 +5111,13 @@ public class CardFactoryUtil {
final String orgManaCost = card.getManaCost();
card.addSpellAbility(CardFactoryUtil.abilityMorphUp(card, cost, orgManaCost, attack, defense));
card.addSpellAbility(CardFactoryUtil.abilityMorphDown(card));
card.turnFaceDown();
card.addSpellAbility(CardFactoryUtil.abilityMorphUp(card, cost, orgManaCost, attack, defense));
card.turnFaceUp();
}
} // Morph

View File

@@ -122,7 +122,7 @@ public class CardPanelHeavy extends CardPanelBase {
public final void setCard(final Card c) {
if (this.picture.getCard() != null) {
if (this.picture.getCard().isInAlternateState()) {
this.picture.getCard().changeState();
this.picture.getCard().setState("Original");
}
}
this.picture.setCard(c);
@@ -149,7 +149,17 @@ public class CardPanelHeavy extends CardPanelBase {
*/
final void changeStateButtonActionPerformed(final ActionEvent e) {
final Card cur = this.picture.getCard();
cur.changeState();
if(cur.isInAlternateState()) {
cur.setState("Original");
}
else {
if(cur.isFlip()) {
cur.setState("Flipped");
}
if(cur.isDoubleFaced()) {
cur.setState("Transformed");
}
}
this.picture.setCard(cur);
this.detail.setCard(cur);

View File

@@ -110,7 +110,15 @@ public class CardPanelLite extends CardPanelBase {
private void bChangeStateActionPerformed(final ActionEvent e) {
final Card cur = this.detail.getCard();
if (cur != null) {
cur.changeState();
if(cur.isDoubleFaced()) {
if(cur.getCurState().equals("Transformed"))
{
cur.setState("Original");
}
else {
cur.setState("Transformed");
}
}
this.setCard(cur);
}

View File

@@ -267,10 +267,15 @@ public final class CardPrinted implements Comparable<CardPrinted>, InventoryItem
c.setCurSetCode(this.getSet());
c.setRandomPicture(this.artIndex + 1);
c.setImageFilename(this.getImageFilename());
if (c.hasAlternateState()) {
c.changeState();
if (c.isFlip()) {
c.setState("Flipped");
c.setImageFilename(CardUtil.buildFilename(c));
c.changeState();
c.setState("Original");
}
if (c.isDoubleFaced()) {
c.setState("Transformed");
c.setImageFilename(CardUtil.buildFilename(c));
c.setState("Original");
}
}
// else throw "Unsupported card";