Merge branch 'morphRework' into 'master'

Morph and Manifest are not to facedown anymore

See merge request core-developers/forge!1252
This commit is contained in:
Hans Mackowiak
2018-12-29 19:18:35 +00:00
5 changed files with 49 additions and 54 deletions

View File

@@ -310,7 +310,8 @@ public class GameCopier {
newCard.setManifested(true);
// TODO: Should be able to copy other abilities...
if (isCreature && hasManaCost) {
newCard.addSpellAbility(CardFactoryUtil.abilityManifestFaceUp(newCard, newCard.getManaCost()));
newCard.getState(CardStateName.Original).addSpellAbility(
CardFactoryUtil.abilityManifestFaceUp(newCard, newCard.getManaCost()));
}
}
}

View File

@@ -528,30 +528,30 @@ public class Card extends GameEntity implements Comparable<Card> {
public Card manifest(Player p, SpellAbility sa) {
// Turn Face Down (even if it's DFC).
CardState originalCard = this.getState(CardStateName.Original);
ManaCost cost = originalCard.getManaCost();
ManaCost cost = getState(CardStateName.Original).getManaCost();
boolean isCreature = this.isCreature();
boolean isCreature = isCreature();
// Sometimes cards are manifested while already being face down
if (!turnFaceDown(true) && currentStateName != CardStateName.FaceDown) {
return null;
}
// Sometimes cards are manifested while already being face down
if (!turnFaceDown(true) && !isFaceDown()) {
return null;
}
// Move to p's battlefield
Game game = p.getGame();
// Just in case you aren't the controller, now you are!
this.setController(p, game.getNextTimestamp());
// Just in case you aren't the controller, now you are!
setController(p, game.getNextTimestamp());
// Mark this card as "manifested"
this.setPreFaceDownState(CardStateName.Original);
this.setManifested(true);
setPreFaceDownState(CardStateName.Original);
setManifested(true);
Card c = game.getAction().moveToPlay(this, p, sa);
// Add manifest demorph static ability for creatures
if (isCreature && !cost.isNoCost()) {
c.addSpellAbility(CardFactoryUtil.abilityManifestFaceUp(c, cost));
// Add Manifest to original State
c.getState(CardStateName.Original).addSpellAbility(CardFactoryUtil.abilityManifestFaceUp(c, cost));
c.updateStateForView();
}
@@ -2233,6 +2233,16 @@ public class Card extends GameEntity implements Comparable<Card> {
updateBasicLandAbilities(list, state);
}
// add Facedown abilities from Original state but only if this state is face down
// need CardStateView#getState or might crash in StackOverflow
if ((mana == null || mana == false) && isFaceDown() && state.getView().getState() == CardStateName.FaceDown) {
for (SpellAbility sa : getState(CardStateName.Original).getNonManaAbilities()) {
if (sa.isManifestUp() || sa.isMorphUp()) {
list.add(sa);
}
}
}
for (KeywordInterface kw : getUnhiddenKeywords(state)) {
for (SpellAbility sa : kw.getAbilities()) {
if (mana == null || mana == sa.isManaAbility()) {

View File

@@ -136,27 +136,27 @@ public class CardFactoryUtil {
public static SpellAbility abilityMorphUp(final Card sourceCard, final String costStr, final boolean mega) {
Cost cost = new Cost(costStr, true);
String costDesc = cost.toString();
// get rid of the ": " at the end
costDesc = costDesc.substring(0, costDesc.length() - 2);
StringBuilder sbCost = new StringBuilder(mega ? "Megamorph" : "Morph");
sbCost.append(" ");
if (!cost.isOnlyManaCost()) {
costDesc = "" + costDesc;
sbCost.append(" ");
}
// get rid of the ": " at the end
sbCost.append(costDesc.substring(0, costDesc.length() - 2));
String ab = "ST$ SetState | Cost$ " + costStr + " | CostDesc$ Morph" + costDesc
+ " | MorphUp$ True"
+ " | ConditionDefined$ Self | ConditionPresent$ Card.faceDown"
+ " | Mode$ TurnFace | SpellDescription$ (Turn this face up any time for its morph cost.)";
StringBuilder sb = new StringBuilder();
sb.append("ST$ SetState | Cost$ ").append(costStr).append(" | CostDesc$ ").append(sbCost);
sb.append(" | MorphUp$ True | Secondary$ True | IsPresent$ Card.Self+faceDown");
if (mega) {
ab += " | Mega$ True";
sb.append(" | Mega$ True");
}
sb.append(" | Mode$ TurnFace | SpellDescription$ (Turn this face up any time for its morph cost.)");
final SpellAbility morphUp = AbilityFactory.getAbility(ab, sourceCard);
final SpellAbility morphUp = AbilityFactory.getAbility(sb.toString(), sourceCard);
final StringBuilder sbStack = new StringBuilder();
sbStack.append(sourceCard.getName()).append(" - turn this card face up.");
morphUp.setStackDescription(sbStack.toString());
morphUp.setIsMorphUp(true);
return morphUp;
}
@@ -166,18 +166,17 @@ public class CardFactoryUtil {
String costDesc = manaCost.toString();
// Cost need to be set later
String ab = "ST$ SetState | Cost$ 0 | CostDesc$ Unmanifest " + costDesc
+ " | ManifestUp$ True"
+ " | ConditionDefined$ Self | ConditionPresent$ Card.faceDown+manifested"
+ " | Mode$ TurnFace | SpellDescription$ (Turn this face up any time for its mana cost.)";
StringBuilder sb = new StringBuilder();
sb.append("ST$ SetState | Cost$ 0 | CostDesc$ Unmanifest ").append(costDesc);
sb.append(" | ManifestUp$ True | Secondary$ True | IsPresent$ Card.Self+faceDown+manifested");
sb.append(" | Mode$ TurnFace | SpellDescription$ (Turn this face up any time for its mana cost.)");
final SpellAbility manifestUp = AbilityFactory.getAbility(ab, sourceCard);
final SpellAbility manifestUp = AbilityFactory.getAbility(sb.toString(), sourceCard);
manifestUp.setPayCosts(new Cost(manaCost, true));
final StringBuilder sbStack = new StringBuilder();
sbStack.append(sourceCard.getName()).append(" - turn this card face up.");
manifestUp.setStackDescription(sbStack.toString());
manifestUp.setIsManifestUp(true);
return manifestUp;
}
@@ -4037,22 +4036,12 @@ public class CardFactoryUtil {
final String[] k = keyword.split(":");
inst.addSpellAbility(abilityMorphDown(card));
CardState state = card.getState(CardStateName.FaceDown);
state.setSVars(card.getSVars());
KeywordInterface facedownKeyword = Keyword.getInstance("");
facedownKeyword.addSpellAbility(abilityMorphUp(card, k[1], false));
state.addIntrinsicKeywords(Lists.newArrayList(facedownKeyword));
inst.addSpellAbility(abilityMorphUp(card, k[1], false));
} else if (keyword.startsWith("Megamorph")){
final String[] k = keyword.split(":");
inst.addSpellAbility(abilityMorphDown(card));
CardState state = card.getState(CardStateName.FaceDown);
state.setSVars(card.getSVars());
KeywordInterface facedownKeyword = Keyword.getInstance("");
facedownKeyword.addSpellAbility(abilityMorphUp(card, k[1], true));
state.addIntrinsicKeywords(Lists.newArrayList(facedownKeyword));
inst.addSpellAbility(abilityMorphUp(card, k[1], true));
} else if (keyword.startsWith("Multikicker")) {
final String[] n = keyword.split(":");
final SpellAbility sa = card.getFirstSpellAbility();

View File

@@ -69,6 +69,10 @@ public class CardState extends GameObject {
private final CardStateView view;
private final Card card;
public CardState(Card card, CardStateName name) {
this(card.getView().createAlternateState(name), card);
}
public CardState(CardStateView view0, Card card0) {
view = view0;
card = card0;

View File

@@ -107,8 +107,6 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
private boolean spectacle = false;
private boolean offering = false;
private boolean emerge = false;
private boolean morphup = false;
private boolean manifestUp = false;
private boolean cumulativeupkeep = false;
private boolean outlast = false;
private boolean blessing = false;
@@ -372,22 +370,15 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
public boolean isAbility() { return true; }
public boolean isMorphUp() {
return morphup;
return this.hasParam("MorphUp");
}
public boolean isCastFaceDown() {
return false;
}
public final void setIsMorphUp(final boolean b) {
morphup = b;
}
public boolean isManifestUp() {
return manifestUp;
}
public final void setIsManifestUp(final boolean b) {
manifestUp = b;
return hasParam("ManifestUp");
}
public boolean isCycling() {