mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
Merge branch 'svarsOriginalCardState' into 'master'
CardTraitBase: store the CardState where it was generated from Closes #1738 See merge request core-developers/forge!4019
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
package forge.game;
|
||||
|
||||
import forge.card.CardStateName;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.mana.ManaAtom;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.card.CardState;
|
||||
import forge.game.card.CardUtil;
|
||||
import forge.game.card.CardView;
|
||||
import forge.game.card.IHasCardView;
|
||||
@@ -29,8 +31,7 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView,
|
||||
|
||||
/** The host card. */
|
||||
protected Card hostCard;
|
||||
|
||||
private Card grantorCard = null; // card which grants the ability (equipment or owner of static ability that gave this one)
|
||||
protected CardState cardState = null;
|
||||
|
||||
/** The map params. */
|
||||
protected Map<String, String> originalMapParams = Maps.newHashMap(),
|
||||
@@ -468,9 +469,8 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView,
|
||||
}
|
||||
|
||||
protected IHasSVars getSVarFallback() {
|
||||
if (getOriginalHost() != null) {
|
||||
return getOriginalHost();
|
||||
}
|
||||
if (getCardState() != null)
|
||||
return getCardState();
|
||||
return getHostCard();
|
||||
}
|
||||
|
||||
@@ -520,11 +520,30 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView,
|
||||
sVars.remove(var);
|
||||
}
|
||||
|
||||
public Card getOriginalHost() {
|
||||
return grantorCard;
|
||||
public CardState getCardState() {
|
||||
return cardState;
|
||||
}
|
||||
public void setOriginalHost(final Card c) {
|
||||
grantorCard = c;
|
||||
public void setCardState(CardState state) {
|
||||
this.cardState = state;
|
||||
}
|
||||
public CardStateName getCardStateName() {
|
||||
if (this.getCardState() == null) {
|
||||
return null;
|
||||
}
|
||||
return getCardState().getView().getState();
|
||||
}
|
||||
|
||||
public Card getOriginalHost() {
|
||||
if (getCardState() != null)
|
||||
return getCardState().getCard();
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isCopiedTrait() {
|
||||
if (this.getCardState() == null) {
|
||||
return false;
|
||||
}
|
||||
return !getHostCard().equals(getCardState().getCard());
|
||||
}
|
||||
|
||||
public Map<String, String> getChangedTextColors() {
|
||||
@@ -580,6 +599,7 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView,
|
||||
copy.originalMapParams = Maps.newHashMap(originalMapParams);
|
||||
copy.mapParams = Maps.newHashMap(originalMapParams);
|
||||
copy.setSVars(sVars);
|
||||
copy.setCardState(cardState);
|
||||
// dont use setHostCard to not trigger the not copied parts yet
|
||||
copy.hostCard = host;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardState;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.zone.Zone;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -27,15 +28,13 @@ public abstract class TriggerReplacementBase extends CardTraitBase implements II
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOriginalHost(Card c) {
|
||||
super.setOriginalHost(c);
|
||||
public void setCardState(CardState state) {
|
||||
super.setCardState(state);
|
||||
if (overridingAbility != null) {
|
||||
overridingAbility.setOriginalHost(c);
|
||||
overridingAbility.setCardState(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Set<ZoneType> getActiveZone() {
|
||||
return validHostZones;
|
||||
}
|
||||
|
||||
@@ -226,6 +226,7 @@ public final class AbilityFactory {
|
||||
msg.append(". Looking for API: ").append(api);
|
||||
throw new RuntimeException(msg.toString());
|
||||
}
|
||||
spellAbility.setCardState(state);
|
||||
|
||||
if (mapParams.containsKey("Forecast")) {
|
||||
spellAbility.putParam("ActivationZone", "Hand");
|
||||
|
||||
@@ -1614,7 +1614,7 @@ public class AbilityUtils {
|
||||
|
||||
// If the chosen creature has X in its mana cost, that X is considered to be 0.
|
||||
// The value of X in Altered Ego’s last ability will be whatever value was chosen for X while casting Altered Ego.
|
||||
if (sa.getOriginalHost() != null || !sa.getHostCard().equals(c)) {
|
||||
if (sa.isCopiedTrait() || !sa.getHostCard().equals(c)) {
|
||||
return CardFactoryUtil.doXMath(0, expr, c);
|
||||
}
|
||||
|
||||
@@ -2063,7 +2063,6 @@ public class AbilityUtils {
|
||||
|
||||
subAbility.setActivatingPlayer(sa.getActivatingPlayer());
|
||||
subAbility.setHostCard(sa.getHostCard());
|
||||
subAbility.setOriginalHost(c);
|
||||
|
||||
//add the spliced ability to the end of the chain
|
||||
sa.appendSubAbility(subAbility);
|
||||
|
||||
@@ -431,7 +431,7 @@ public abstract class SpellAbilityEffect {
|
||||
+ " exile it instead of putting it anywhere else.";
|
||||
String effect = "DB$ ChangeZone | Defined$ ReplacedCard | Origin$ Battlefield | Destination$ " + zone;
|
||||
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, eff, true, null);
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, eff, true);
|
||||
re.setLayer(ReplacementLayer.Other);
|
||||
|
||||
re.setOverridingAbility(AbilityFactory.getAbility(effect, eff));
|
||||
|
||||
@@ -152,7 +152,6 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
||||
final List<SpellAbility> addedAbilities = Lists.newArrayList();
|
||||
for (final String s : abilities) {
|
||||
SpellAbility sSA = AbilityFactory.getAbility(c, s, sa);
|
||||
sSA.setOriginalHost(source);
|
||||
addedAbilities.add(sSA);
|
||||
}
|
||||
|
||||
@@ -160,7 +159,6 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
||||
final List<Trigger> addedTriggers = Lists.newArrayList();
|
||||
for (final String s : triggers) {
|
||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(AbilityUtils.getSVar(sa, s), c, false, sa);
|
||||
parsedTrigger.setOriginalHost(source);
|
||||
addedTriggers.add(parsedTrigger);
|
||||
}
|
||||
|
||||
@@ -174,7 +172,7 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
||||
// itself a static ability)
|
||||
final List<StaticAbility> addedStaticAbilities = Lists.newArrayList();
|
||||
for (final String s : stAbs) {
|
||||
addedStaticAbilities.add(new StaticAbility(AbilityUtils.getSVar(sa, s), c));
|
||||
addedStaticAbilities.add(new StaticAbility(AbilityUtils.getSVar(sa, s), c, sa.getCardState()));
|
||||
}
|
||||
|
||||
final GameCommand unanimate = new GameCommand() {
|
||||
|
||||
@@ -251,7 +251,7 @@ public class PlayEffect extends SpellAbilityEffect {
|
||||
tgtSA = sa.getActivatingPlayer().getController().getAbilityToPlay(tgtCard, sas);
|
||||
} else {
|
||||
// For Illusionary Mask effect
|
||||
tgtSA = CardFactoryUtil.abilityMorphDown(tgtCard);
|
||||
tgtSA = CardFactoryUtil.abilityMorphDown(tgtCard.getCurrentState());
|
||||
}
|
||||
// in case player canceled from choice dialog
|
||||
if (tgtSA == null) {
|
||||
|
||||
@@ -2227,7 +2227,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
String sAbility = formatSpellAbility(sa);
|
||||
|
||||
// add Adventure to AbilityText
|
||||
if (sa.isAdventure() && state.getView().getState().equals(CardStateName.Original)) {
|
||||
if (sa.isAdventure() && state.getStateName().equals(CardStateName.Original)) {
|
||||
CardState advState = getState(CardStateName.Adventure);
|
||||
StringBuilder sbSA = new StringBuilder();
|
||||
sbSA.append(Localizer.getInstance().getMessage("lblAdventure"));
|
||||
@@ -4388,7 +4388,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
}
|
||||
public final StaticAbility addStaticAbility(final String s) {
|
||||
if (!s.trim().isEmpty()) {
|
||||
final StaticAbility stAb = new StaticAbility(s, this);
|
||||
final StaticAbility stAb = new StaticAbility(s, this, currentState);
|
||||
stAb.setIntrinsic(true);
|
||||
currentState.addStaticAbility(stAb);
|
||||
return stAb;
|
||||
@@ -6326,11 +6326,14 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
}
|
||||
|
||||
public void setSplitStateToPlayAbility(final SpellAbility sa) {
|
||||
if (isFaceDown()) {
|
||||
return;
|
||||
}
|
||||
if (sa.isBestow()) {
|
||||
animateBestow();
|
||||
}
|
||||
CardStateName stateName = sa.getCardState();
|
||||
if (hasState(stateName)) {
|
||||
CardStateName stateName = sa.getCardStateName();
|
||||
if (stateName != null && hasState(stateName) && this.getCurrentStateName() != stateName) {
|
||||
setState(stateName, true);
|
||||
// need to set backSide value according to the SplitType
|
||||
if (hasBackSide()) {
|
||||
@@ -6356,6 +6359,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
}
|
||||
|
||||
public List<SpellAbility> getAllPossibleAbilities(final Player player, final boolean removeUnplayable) {
|
||||
CardState oState = getState(CardStateName.Original);
|
||||
// this can only be called by the Human
|
||||
final List<SpellAbility> abilities = Lists.newArrayList();
|
||||
for (SpellAbility sa : getSpellAbilities()) {
|
||||
@@ -6382,7 +6386,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
}
|
||||
|
||||
if (isInPlay() && isFaceDown() && isManifested()) {
|
||||
CardState oState = getState(CardStateName.Original);
|
||||
ManaCost cost = oState.getManaCost();
|
||||
if (oState.getType().isCreature()) {
|
||||
abilities.add(CardFactoryUtil.abilityManifestFaceUp(this, cost));
|
||||
@@ -6409,6 +6412,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
}
|
||||
if (getState(CardStateName.Original).getType().isLand()) {
|
||||
LandAbility la = new LandAbility(this, player, null);
|
||||
la.setCardState(oState);
|
||||
if (la.canPlay()) {
|
||||
abilities.add(la);
|
||||
}
|
||||
@@ -6433,6 +6437,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
// extra for MayPlay
|
||||
for (CardPlayOption o : source.mayPlay(player)) {
|
||||
la = new LandAbility(this, player, o.getAbility());
|
||||
la.setCardState(oState);
|
||||
if (la.canPlay()) {
|
||||
abilities.add(la);
|
||||
}
|
||||
@@ -6449,9 +6454,10 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
}
|
||||
|
||||
if (isModal() && hasState(CardStateName.Modal)) {
|
||||
if (getState(CardStateName.Modal).getType().isLand()) {
|
||||
CardState modal = getState(CardStateName.Modal);
|
||||
if (modal.getType().isLand()) {
|
||||
LandAbility la = new LandAbility(this, player, null);
|
||||
la.setCardState(CardStateName.Modal);
|
||||
la.setCardState(modal);
|
||||
|
||||
Card source = CardUtil.getLKICopy(this);
|
||||
boolean lkicheck = true;
|
||||
@@ -6483,7 +6489,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
// extra for MayPlay
|
||||
for (CardPlayOption o : source.mayPlay(player)) {
|
||||
la = new LandAbility(this, player, o.getAbility());
|
||||
la.setCardState(CardStateName.Modal);
|
||||
la.setCardState(modal);
|
||||
if (la.canPlay(source)) {
|
||||
abilities.add(la);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import forge.game.Game;
|
||||
import forge.game.ability.AbilityFactory;
|
||||
import forge.game.cost.Cost;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.replacement.ReplacementEffect;
|
||||
import forge.game.replacement.ReplacementHandler;
|
||||
import forge.game.spellability.*;
|
||||
import forge.game.staticability.StaticAbility;
|
||||
@@ -258,7 +257,7 @@ public class CardFactory {
|
||||
// ************** Link to different CardFactories *******************
|
||||
if (state == CardStateName.LeftSplit || state == CardStateName.RightSplit) {
|
||||
for (final SpellAbility sa : card.getSpellAbilities()) {
|
||||
sa.setCardState(state);
|
||||
sa.setCardState(card.getState(state));
|
||||
}
|
||||
CardFactoryUtil.setupKeywordedAbilities(card);
|
||||
final CardState original = card.getState(CardStateName.Original);
|
||||
@@ -366,9 +365,9 @@ public class CardFactory {
|
||||
|
||||
for (Entry<String, String> v : face.getVariables()) c.setSVar(v.getKey(), v.getValue());
|
||||
|
||||
for (String r : face.getReplacements()) c.addReplacementEffect(ReplacementHandler.parseReplacement(r, c, true));
|
||||
for (String r : face.getReplacements()) c.addReplacementEffect(ReplacementHandler.parseReplacement(r, c, true, c.getCurrentState()));
|
||||
for (String s : face.getStaticAbilities()) c.addStaticAbility(s);
|
||||
for (String t : face.getTriggers()) c.addTrigger(TriggerHandler.parseTrigger(t, c, true));
|
||||
for (String t : face.getTriggers()) c.addTrigger(TriggerHandler.parseTrigger(t, c, true, c.getCurrentState()));
|
||||
|
||||
// keywords not before variables
|
||||
c.addIntrinsicKeywords(face.getKeywords(), false);
|
||||
@@ -401,9 +400,9 @@ public class CardFactory {
|
||||
SpellAbility sa = new SpellPermanent(c);
|
||||
|
||||
// Currently only for Modal, might react different when state is always set
|
||||
if (c.getCurrentStateName() == CardStateName.Modal) {
|
||||
sa.setCardState(c.getCurrentStateName());
|
||||
}
|
||||
//if (c.getCurrentStateName() == CardStateName.Modal) {
|
||||
sa.setCardState(c.getCurrentState());
|
||||
//}
|
||||
c.addSpellAbility(sa);
|
||||
}
|
||||
// TODO add LandAbility there when refactor MayPlay
|
||||
@@ -678,7 +677,6 @@ public class CardFactory {
|
||||
if (origSVars.containsKey(s)) {
|
||||
final String actualTrigger = origSVars.get(s);
|
||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, out, true);
|
||||
parsedTrigger.setOriginalHost(host);
|
||||
state.addTrigger(parsedTrigger);
|
||||
}
|
||||
}
|
||||
@@ -702,7 +700,6 @@ public class CardFactory {
|
||||
if (origSVars.containsKey(s)) {
|
||||
final String actualAbility = origSVars.get(s);
|
||||
final SpellAbility grantedAbility = AbilityFactory.getAbility(actualAbility, out);
|
||||
grantedAbility.setOriginalHost(host);
|
||||
grantedAbility.setIntrinsic(true);
|
||||
state.addSpellAbility(grantedAbility);
|
||||
}
|
||||
@@ -715,8 +712,7 @@ public class CardFactory {
|
||||
for (final String s : str.split(",")) {
|
||||
if (origSVars.containsKey(s)) {
|
||||
final String actualStatic = origSVars.get(s);
|
||||
final StaticAbility grantedStatic = new StaticAbility(actualStatic, out);
|
||||
grantedStatic.setOriginalHost(host);
|
||||
final StaticAbility grantedStatic = new StaticAbility(actualStatic, out, sa.getCardState());
|
||||
grantedStatic.setIntrinsic(true);
|
||||
state.addStaticAbility(grantedStatic);
|
||||
}
|
||||
@@ -765,26 +761,6 @@ public class CardFactory {
|
||||
|
||||
// set the host card for copied replacement effects
|
||||
// needed for copied xPaid ETB effects (for the copy, xPaid = 0)
|
||||
for (final ReplacementEffect rep : state.getReplacementEffects()) {
|
||||
final SpellAbility newSa = rep.getOverridingAbility();
|
||||
if (newSa != null && newSa.getOriginalHost() == null) {
|
||||
newSa.setOriginalHost(in);
|
||||
}
|
||||
}
|
||||
|
||||
// set the host card for copied spellabilities, if they are not set yet
|
||||
for (final SpellAbility newSa : state.getSpellAbilities()) {
|
||||
if (newSa.getOriginalHost() == null) {
|
||||
newSa.setOriginalHost(in);
|
||||
}
|
||||
}
|
||||
|
||||
for (final Trigger trigger : state.getTriggers()) {
|
||||
final SpellAbility newSa = trigger.getOverridingAbility();
|
||||
if (newSa != null && newSa.getOriginalHost() == null) {
|
||||
newSa.setOriginalHost(in);
|
||||
}
|
||||
}
|
||||
|
||||
if (sa.hasParam("GainTextOf") && originalState != null) {
|
||||
state.setSetCode(originalState.getSetCode());
|
||||
|
||||
@@ -94,8 +94,8 @@ public class CardFactoryUtil {
|
||||
* a {@link forge.game.card.Card} object.
|
||||
* @return a {@link forge.game.spellability.SpellAbility} object.
|
||||
*/
|
||||
public static SpellAbility abilityMorphDown(final Card sourceCard) {
|
||||
final Spell morphDown = new Spell(sourceCard, new Cost(ManaCost.THREE, false)) {
|
||||
public static SpellAbility abilityMorphDown(final CardState cardState) {
|
||||
final Spell morphDown = new Spell(cardState.getCard(), new Cost(ManaCost.THREE, false)) {
|
||||
private static final long serialVersionUID = -1438810964807867610L;
|
||||
|
||||
@Override
|
||||
@@ -119,6 +119,8 @@ public class CardFactoryUtil {
|
||||
}
|
||||
};
|
||||
|
||||
morphDown.setCardState(cardState);
|
||||
|
||||
morphDown.setDescription("(You may cast this card face down as a 2/2 creature for {3}.)");
|
||||
morphDown.setStackDescription("Morph - Creature 2/2");
|
||||
morphDown.setCastFaceDown(true);
|
||||
@@ -136,7 +138,7 @@ public class CardFactoryUtil {
|
||||
* a {@link forge.game.card.Card} object.
|
||||
* @return a {@link forge.game.spellability.AbilityActivated} object.
|
||||
*/
|
||||
public static SpellAbility abilityMorphUp(final Card sourceCard, final String costStr, final boolean mega) {
|
||||
public static SpellAbility abilityMorphUp(final CardState cardState, final String costStr, final boolean mega) {
|
||||
Cost cost = new Cost(costStr, true);
|
||||
String costDesc = cost.toString();
|
||||
StringBuilder sbCost = new StringBuilder(mega ? "Megamorph" : "Morph");
|
||||
@@ -156,15 +158,15 @@ public class CardFactoryUtil {
|
||||
|
||||
sb.append(" | Mode$ TurnFace | SpellDescription$ (Turn this face up any time for its morph cost.)");
|
||||
|
||||
final SpellAbility morphUp = AbilityFactory.getAbility(sb.toString(), sourceCard);
|
||||
final SpellAbility morphUp = AbilityFactory.getAbility(sb.toString(), cardState);
|
||||
|
||||
// if Cost has X in cost, need to check source for an SVar for this
|
||||
if (cost.hasXInAnyCostPart() && sourceCard.hasSVar("X")) {
|
||||
morphUp.setSVar("X", sourceCard.getSVar("X"));
|
||||
if (cost.hasXInAnyCostPart() && cardState.hasSVar("X")) {
|
||||
morphUp.setSVar("X", cardState.getSVar("X"));
|
||||
}
|
||||
|
||||
final StringBuilder sbStack = new StringBuilder();
|
||||
sbStack.append(sourceCard.getName()).append(" - turn this card face up.");
|
||||
sbStack.append(cardState.getName()).append(" - turn this card face up.");
|
||||
morphUp.setStackDescription(sbStack.toString());
|
||||
|
||||
return morphUp;
|
||||
@@ -2098,6 +2100,7 @@ public class CardFactoryUtil {
|
||||
final SpellAbility intrinsicAbility = AbilityFactory.getAbility(rawAbility, card);
|
||||
card.addSpellAbility(intrinsicAbility);
|
||||
intrinsicAbility.setIntrinsic(true);
|
||||
intrinsicAbility.setCardState(card.getCurrentState());
|
||||
} catch (Exception e) {
|
||||
String msg = "CardFactoryUtil:addAbilityFactoryAbilities: crash in raw Ability";
|
||||
Sentry.getContext().recordBreadcrumb(
|
||||
@@ -2139,16 +2142,17 @@ public class CardFactoryUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private static ReplacementEffect createETBReplacement(final Card card, ReplacementLayer layer,
|
||||
private static ReplacementEffect createETBReplacement(final CardState card, ReplacementLayer layer,
|
||||
final String effect, final boolean optional, final boolean secondary,
|
||||
final boolean intrinsic, final String valid, final String zone) {
|
||||
SpellAbility repAb = AbilityFactory.getAbility(effect, card);
|
||||
return createETBReplacement(card, layer, repAb, optional, secondary, intrinsic, valid, zone);
|
||||
}
|
||||
|
||||
private static ReplacementEffect createETBReplacement(final Card card, ReplacementLayer layer,
|
||||
private static ReplacementEffect createETBReplacement(final CardState card, ReplacementLayer layer,
|
||||
final SpellAbility repAb, final boolean optional, final boolean secondary,
|
||||
final boolean intrinsic, final String valid, final String zone) {
|
||||
Card host = card.getCard();
|
||||
String desc = repAb.getDescription();
|
||||
setupETBReplacementAbility(repAb);
|
||||
if (!intrinsic) {
|
||||
@@ -2169,14 +2173,14 @@ public class CardFactoryUtil {
|
||||
repEffsb.append(" | ActiveZones$ ").append(zone);
|
||||
}
|
||||
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repEffsb.toString(), card, intrinsic);
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repEffsb.toString(), host, intrinsic, card);
|
||||
re.setLayer(layer);
|
||||
re.setOverridingAbility(repAb);
|
||||
|
||||
return re;
|
||||
}
|
||||
|
||||
public static ReplacementEffect makeEtbCounter(final String kw, final Card card, final boolean intrinsic)
|
||||
public static ReplacementEffect makeEtbCounter(final String kw, final CardState card, final boolean intrinsic)
|
||||
{
|
||||
String parse = kw;
|
||||
|
||||
@@ -2212,7 +2216,7 @@ public class CardFactoryUtil {
|
||||
String repeffstr = "Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield "
|
||||
+ "| Secondary$ True | Description$ " + desc + (!extraparams.equals("") ? " | " + extraparams : "");
|
||||
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, card, intrinsic);
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, card.getCard(), intrinsic, card);
|
||||
|
||||
re.setOverridingAbility(sa);
|
||||
|
||||
@@ -3342,10 +3346,11 @@ public class CardFactoryUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void addReplacementEffect(final KeywordInterface inst, final Card card, final boolean intrinsic) {
|
||||
public static void addReplacementEffect(final KeywordInterface inst, final CardState card, final boolean intrinsic) {
|
||||
Card host = card.getCard();
|
||||
|
||||
String keyword = inst.getOriginal();
|
||||
if (keyword.equals("Aftermath") && card.getCurrentStateName().equals(CardStateName.RightSplit)) {
|
||||
if (keyword.equals("Aftermath") && card.getStateName().equals(CardStateName.RightSplit)) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Event$ Moved | ValidCard$ Card.Self | Origin$ Stack | ExcludeDestination$ Exile ");
|
||||
sb.append("| ValidStackSa$ Spell.Aftermath | Description$ Aftermath");
|
||||
@@ -3362,7 +3367,7 @@ public class CardFactoryUtil {
|
||||
|
||||
saExile.setIntrinsic(intrinsic);
|
||||
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, card, intrinsic);
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, host, intrinsic, card);
|
||||
|
||||
re.setOverridingAbility(saExile);
|
||||
|
||||
@@ -3408,7 +3413,7 @@ public class CardFactoryUtil {
|
||||
|
||||
saReveal.setIntrinsic(intrinsic);
|
||||
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(actualRep, card, intrinsic);
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(actualRep, host, intrinsic, card);
|
||||
|
||||
re.setOverridingAbility(saReveal);
|
||||
|
||||
@@ -3460,7 +3465,7 @@ public class CardFactoryUtil {
|
||||
|
||||
saReturn.setIntrinsic(intrinsic);
|
||||
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, card, intrinsic);
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, host, intrinsic, card);
|
||||
|
||||
re.setOverridingAbility(saReturn);
|
||||
|
||||
@@ -3483,7 +3488,7 @@ public class CardFactoryUtil {
|
||||
|
||||
saMill.setIntrinsic(intrinsic);
|
||||
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(actualRep, card, intrinsic);
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(actualRep, host, intrinsic, card);
|
||||
re.setOverridingAbility(saMill);
|
||||
|
||||
re.setSVar("DredgeCheckLib", "Count$ValidLibrary Card.YouOwn");
|
||||
@@ -3513,7 +3518,7 @@ public class CardFactoryUtil {
|
||||
|
||||
String repeffstr = "Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | Secondary$ True | Description$ Devour " + magnitude + " ("+ inst.getReminderText() + ")";
|
||||
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, card, intrinsic);
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, host, intrinsic, card);
|
||||
|
||||
setupETBReplacementAbility(cleanupSA);
|
||||
re.setOverridingAbility(sacrificeSA);
|
||||
@@ -3563,7 +3568,7 @@ public class CardFactoryUtil {
|
||||
saExile.setIntrinsic(false);
|
||||
}
|
||||
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, card, intrinsic);
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, host, intrinsic, card);
|
||||
|
||||
re.setOverridingAbility(saExile);
|
||||
|
||||
@@ -3598,7 +3603,7 @@ public class CardFactoryUtil {
|
||||
saExile.setIntrinsic(false);
|
||||
}
|
||||
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, card, intrinsic);
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, host, intrinsic, card);
|
||||
|
||||
re.setOverridingAbility(saExile);
|
||||
|
||||
@@ -3607,7 +3612,7 @@ public class CardFactoryUtil {
|
||||
// Set Madness Replacement effects
|
||||
String repeffstr = "Event$ Discard | ActiveZones$ Hand | ValidCard$ Card.Self | Secondary$ True "
|
||||
+ " | Description$ Madness: If you discard this card, discard it into exile.";
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, card, intrinsic);
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, host, intrinsic, card);
|
||||
String sVarMadness = "DB$ Discard | Defined$ ReplacedPlayer | Mode$ Defined | DefinedCards$ ReplacedCard | Madness$ True";
|
||||
|
||||
re.setOverridingAbility(AbilityFactory.getAbility(sVarMadness, card));
|
||||
@@ -3657,7 +3662,7 @@ public class CardFactoryUtil {
|
||||
saExile.setIntrinsic(false);
|
||||
}
|
||||
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, card, intrinsic);
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, host, intrinsic, card);
|
||||
|
||||
re.setOverridingAbility(saExile);
|
||||
|
||||
@@ -3704,7 +3709,7 @@ public class CardFactoryUtil {
|
||||
} else if (keyword.equals("Sunburst")) {
|
||||
// Rule 702.43a If this object is entering the battlefield as a creature,
|
||||
// ignoring any type-changing effects that would affect it
|
||||
CounterType t = CounterType.get(card.isCreature() ? CounterEnumType.P1P1 : CounterEnumType.CHARGE);
|
||||
CounterType t = CounterType.get(host.isCreature() ? CounterEnumType.P1P1 : CounterEnumType.CHARGE);
|
||||
|
||||
StringBuilder sb = new StringBuilder("etbCounter:");
|
||||
sb.append(t).append(":Sunburst:no Condition:");
|
||||
@@ -3732,7 +3737,7 @@ public class CardFactoryUtil {
|
||||
sa.setIntrinsic(false);
|
||||
}
|
||||
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, card, intrinsic);
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, host, intrinsic, card);
|
||||
|
||||
re.setOverridingAbility(sa);
|
||||
|
||||
@@ -3773,7 +3778,7 @@ public class CardFactoryUtil {
|
||||
String repeffstr = "Event$ Destroy | ActiveZones$ Battlefield | ValidCard$ Card.Self"
|
||||
+ " | Secondary$ True | Regeneration$ True | Description$ " + keyword;
|
||||
String effect = "DB$ Regeneration | Defined$ ReplacedCard";
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, card, intrinsic);
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, host, intrinsic, card);
|
||||
SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||
re.setOverridingAbility(sa);
|
||||
|
||||
@@ -3810,13 +3815,13 @@ public class CardFactoryUtil {
|
||||
|
||||
if (from) {
|
||||
String fromRep = rep + " | ValidSource$ Card.Self";
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(fromRep, card, intrinsic);
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(fromRep, host, intrinsic, card);
|
||||
|
||||
inst.addReplacement(re);
|
||||
}
|
||||
if (to) {
|
||||
String toRep = rep + " | ValidTarget$ Card.Self";
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(toRep, card, intrinsic);
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(toRep, host, intrinsic, card);
|
||||
|
||||
inst.addReplacement(re);
|
||||
}
|
||||
@@ -3828,7 +3833,7 @@ public class CardFactoryUtil {
|
||||
StringBuilder sb = new StringBuilder("Event$ Moved | Destination$ Graveyard | ValidCard$ Card.Self ");
|
||||
|
||||
// to show it on Nexus
|
||||
if (card.isPermanent()) {
|
||||
if (host.isPermanent()) {
|
||||
sb.append("| Secondary$ True");
|
||||
}
|
||||
sb.append("| Description$ ").append(keyword);
|
||||
@@ -3841,7 +3846,7 @@ public class CardFactoryUtil {
|
||||
sa.setIntrinsic(false);
|
||||
}
|
||||
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(sb.toString(), card, intrinsic);
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(sb.toString(), host, intrinsic, card);
|
||||
|
||||
re.setOverridingAbility(sa);
|
||||
|
||||
@@ -3878,16 +3883,17 @@ public class CardFactoryUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void addSpellAbility(final KeywordInterface inst, final Card card, final boolean intrinsic) {
|
||||
public static void addSpellAbility(final KeywordInterface inst, final CardState card, final boolean intrinsic) {
|
||||
String keyword = inst.getOriginal();
|
||||
if (keyword.startsWith("Alternative Cost") && !card.isLand()) {
|
||||
Card host = card.getCard();
|
||||
if (keyword.startsWith("Alternative Cost") && !host.isLand()) {
|
||||
final String[] kw = keyword.split(":");
|
||||
String costStr = kw[1];
|
||||
for (SpellAbility sa: card.getBasicSpells()) {
|
||||
for (SpellAbility sa: host.getBasicSpells()) {
|
||||
final SpellAbility newSA = sa.copy();
|
||||
newSA.setBasicSpell(false);
|
||||
if (costStr.equals("ConvertedManaCost")) {
|
||||
costStr = Integer.toString(card.getCMC());
|
||||
costStr = Integer.toString(host.getCMC());
|
||||
}
|
||||
final Cost cost = new Cost(costStr, false).add(sa.getPayCosts().copyWithNoMana());
|
||||
newSA.putParam("Secondary", "True");
|
||||
@@ -3925,7 +3931,7 @@ public class CardFactoryUtil {
|
||||
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||
sa.setIntrinsic(intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
} else if (keyword.equals("Aftermath") && card.getCurrentStateName().equals(CardStateName.RightSplit)) {
|
||||
} else if (keyword.equals("Aftermath") && card.getStateName().equals(CardStateName.RightSplit)) {
|
||||
// Aftermath does modify existing SA, and does not add new one
|
||||
|
||||
// only target RightSplit of it
|
||||
@@ -4135,7 +4141,7 @@ public class CardFactoryUtil {
|
||||
inst.addSpellAbility(newSA);
|
||||
} else if (keyword.startsWith("Foretell")) {
|
||||
|
||||
final SpellAbility foretell = new AbilityStatic(card, new Cost(ManaCost.TWO, false), null) {
|
||||
final SpellAbility foretell = new AbilityStatic(card.getCard(), new Cost(ManaCost.TWO, false), null) {
|
||||
@Override
|
||||
public boolean canPlay() {
|
||||
if (!getRestrictions().canPlay(getHostCard(), this)) {
|
||||
@@ -4183,6 +4189,8 @@ public class CardFactoryUtil {
|
||||
foretell.setDescription(sbDesc.toString());
|
||||
foretell.putParam("Secondary", "True");
|
||||
|
||||
foretell.setCardState(card);
|
||||
|
||||
foretell.getRestrictions().setZone(ZoneType.Hand);
|
||||
foretell.setIntrinsic(intrinsic);
|
||||
inst.addSpellAbility(foretell);
|
||||
@@ -4207,12 +4215,12 @@ public class CardFactoryUtil {
|
||||
// instantiate attach ability
|
||||
final SpellAbility sa = AbilityFactory.getAbility(abilityStr.toString(), card);
|
||||
inst.addSpellAbility(sa);
|
||||
} else if (keyword.startsWith("Fuse") && card.getCurrentStateName().equals(CardStateName.Original)) {
|
||||
final SpellAbility sa = AbilityFactory.buildFusedAbility(card);
|
||||
} else if (keyword.startsWith("Fuse") && card.getStateName().equals(CardStateName.Original)) {
|
||||
final SpellAbility sa = AbilityFactory.buildFusedAbility(card.getCard());
|
||||
card.addSpellAbility(sa);
|
||||
inst.addSpellAbility(sa);
|
||||
} else if (keyword.startsWith("Haunt")) {
|
||||
if (!card.isCreature() && intrinsic) {
|
||||
if (!host.isCreature() && intrinsic) {
|
||||
final String[] k = keyword.split(":");
|
||||
final String hauntSVarName = k[1];
|
||||
|
||||
@@ -4377,7 +4385,7 @@ public class CardFactoryUtil {
|
||||
final Cost prowlCost = new Cost(k[1], false);
|
||||
final SpellAbility newSA = card.getFirstSpellAbility().copyWithDefinedCost(prowlCost);
|
||||
|
||||
if (card.isInstant() || card.isSorcery()) {
|
||||
if (host.isInstant() || host.isSorcery()) {
|
||||
newSA.putParam("Secondary", "True");
|
||||
}
|
||||
newSA.putParam("PrecostDesc", "Prowl");
|
||||
@@ -4509,7 +4517,7 @@ public class CardFactoryUtil {
|
||||
|
||||
// be careful with Suspend ability, it will not hit the stack
|
||||
Cost cost = new Cost(k[2], true);
|
||||
final SpellAbility suspend = new AbilityStatic(card, cost, null) {
|
||||
final SpellAbility suspend = new AbilityStatic(host, cost, null) {
|
||||
@Override
|
||||
public boolean canPlay() {
|
||||
if (!(this.getRestrictions().canPlay(this.getHostCard(), this))) {
|
||||
@@ -4525,7 +4533,7 @@ public class CardFactoryUtil {
|
||||
|
||||
@Override
|
||||
public void resolve() {
|
||||
final Game game = card.getGame();
|
||||
final Game game = this.getHostCard().getGame();
|
||||
final Card c = game.getAction().exile(this.getHostCard(), this);
|
||||
|
||||
int counters = AbilityUtils.calculateAmount(c, k[1], this);
|
||||
@@ -4546,6 +4554,7 @@ public class CardFactoryUtil {
|
||||
|
||||
String svar = "X"; // emulate "References X" here
|
||||
suspend.setSVar(svar, card.getSVar(svar));
|
||||
suspend.setCardState(card);
|
||||
|
||||
final StringBuilder sbStack = new StringBuilder();
|
||||
sbStack.append(card.getName()).append(" suspending for ");
|
||||
@@ -4673,7 +4682,7 @@ public class CardFactoryUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void addStaticAbility(final KeywordInterface inst, final Card card, final boolean intrinsic) {
|
||||
public static void addStaticAbility(final KeywordInterface inst, final CardState state, final boolean intrinsic) {
|
||||
String keyword = inst.getOriginal();
|
||||
String effect = null;
|
||||
Map<String, String> svars = Maps.newHashMap();
|
||||
@@ -4716,7 +4725,7 @@ public class CardFactoryUtil {
|
||||
sb.append("Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ PlayEncoded");
|
||||
sb.append(" | CombatDamage$ True | OptionalDecider$ You | TriggerDescription$ ");
|
||||
sb.append("Whenever CARDNAME deals combat damage to a player, its controller may cast a copy of ");
|
||||
sb.append(card.getName()).append(" without paying its mana cost.");
|
||||
sb.append(state.getName()).append(" without paying its mana cost.");
|
||||
|
||||
String trig = sb.toString();
|
||||
|
||||
@@ -4786,7 +4795,7 @@ public class CardFactoryUtil {
|
||||
}
|
||||
|
||||
if (effect != null) {
|
||||
StaticAbility st = new StaticAbility(effect, card);
|
||||
StaticAbility st = new StaticAbility(effect, state.getCard(), state);
|
||||
st.setIntrinsic(intrinsic);
|
||||
for (Map.Entry<String, String> e : svars.entrySet()) {
|
||||
st.setSVar(e.getKey(), e.getValue());
|
||||
@@ -4964,7 +4973,7 @@ public class CardFactoryUtil {
|
||||
if (sa == null) {
|
||||
return;
|
||||
}
|
||||
sa.setCardState(CardStateName.Adventure);
|
||||
sa.setCardState(card.getCurrentState());
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Event$ Moved | ValidCard$ Card.Self | Origin$ Stack | ExcludeDestination$ Exile ");
|
||||
|
||||
@@ -104,6 +104,10 @@ public class CardState extends GameObject implements IHasSVars {
|
||||
view.updateName(this);
|
||||
}
|
||||
|
||||
public CardStateName getStateName() {
|
||||
return this.getView().getState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + " (" + view.getState() + ")";
|
||||
@@ -303,6 +307,11 @@ public class CardState extends GameObject implements IHasSVars {
|
||||
return Iterables.filter(getSpellAbilities(), SpellAbilityPredicates.isIntrinsic());
|
||||
}
|
||||
|
||||
|
||||
public final SpellAbility getFirstSpellAbility() {
|
||||
return Iterables.getFirst(getNonManaAbilities(), null);
|
||||
}
|
||||
|
||||
public final boolean hasSpellAbility(final SpellAbility sa) {
|
||||
return getSpellAbilities().contains(sa);
|
||||
}
|
||||
@@ -431,7 +440,7 @@ public class CardState extends GameObject implements IHasSVars {
|
||||
|
||||
if (getTypeWithChanges().isPlaneswalker()) {
|
||||
if (loyaltyRep == null) {
|
||||
loyaltyRep = CardFactoryUtil.makeEtbCounter("etbCounter:LOYALTY:" + this.baseLoyalty, card, true);
|
||||
loyaltyRep = CardFactoryUtil.makeEtbCounter("etbCounter:LOYALTY:" + this.baseLoyalty, this, true);
|
||||
}
|
||||
result.add(loyaltyRep);
|
||||
}
|
||||
|
||||
@@ -109,9 +109,9 @@ public abstract class KeywordInstance<T extends KeywordInstance<?>> implements K
|
||||
Sentry.getContext().addExtra("Keyword", this.original);
|
||||
|
||||
CardFactoryUtil.addTriggerAbility(this, host, intrinsic);
|
||||
CardFactoryUtil.addReplacementEffect(this, host, intrinsic);
|
||||
CardFactoryUtil.addSpellAbility(this, host, intrinsic);
|
||||
CardFactoryUtil.addStaticAbility(this, host, intrinsic);
|
||||
CardFactoryUtil.addReplacementEffect(this, host.getCurrentState(), intrinsic);
|
||||
CardFactoryUtil.addSpellAbility(this, host.getCurrentState(), intrinsic);
|
||||
CardFactoryUtil.addStaticAbility(this, host.getCurrentState(), intrinsic);
|
||||
} catch (Exception e) {
|
||||
String msg = "KeywordInstance:createTraits: failed Traits for Keyword";
|
||||
Sentry.getContext().recordBreadcrumb(
|
||||
|
||||
@@ -29,7 +29,7 @@ public class PlayerFactoryUtil {
|
||||
}
|
||||
if (effect != null) {
|
||||
final Card card = player.getKeywordCard();
|
||||
StaticAbility st = new StaticAbility(effect, card);
|
||||
StaticAbility st = new StaticAbility(effect, card, card.getCurrentState());
|
||||
st.setIntrinsic(false);
|
||||
inst.addStaticAbility(st);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package forge.game.replacement;
|
||||
|
||||
import forge.game.CardTraitBase;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameLogEntryType;
|
||||
import forge.game.IHasSVars;
|
||||
@@ -25,6 +26,7 @@ import forge.game.ability.AbilityKey;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardState;
|
||||
import forge.game.card.CardTraitChanges;
|
||||
import forge.game.card.CardUtil;
|
||||
import forge.game.keyword.KeywordInterface;
|
||||
@@ -405,6 +407,11 @@ public class ReplacementHandler {
|
||||
ret.setOverridingAbility(AbilityFactory.getAbility(host, mapParams.get("ReplaceWith"), sVarHolder));
|
||||
}
|
||||
|
||||
if (sVarHolder instanceof CardState) {
|
||||
ret.setCardState((CardState)sVarHolder);
|
||||
} else if (sVarHolder instanceof CardTraitBase) {
|
||||
ret.setCardState(((CardTraitBase)sVarHolder).getCardState());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,11 +49,11 @@ public class LandAbility extends Ability {
|
||||
Card land = this.getHostCard();
|
||||
final Player p = this.getActivatingPlayer();
|
||||
|
||||
if (this.getCardState() != null) {
|
||||
if (this.getCardState() != null && land.getCurrentStateName() != this.getCardStateName()) {
|
||||
if (!land.isLKI()) {
|
||||
land = CardUtil.getLKICopy(land);
|
||||
}
|
||||
CardStateName stateName = getCardState();
|
||||
CardStateName stateName = getCardStateName();
|
||||
if (!land.hasState(stateName)) {
|
||||
land.addAlternateState(stateName, false);
|
||||
land.getState(stateName).copyFrom(getHostCard().getState(stateName), true);
|
||||
@@ -87,7 +87,7 @@ public class LandAbility extends Ability {
|
||||
StringBuilder sb = new StringBuilder("Play land");
|
||||
|
||||
if (getHostCard().isModal()) {
|
||||
sb.append(" (").append(getHostCard().getName(ObjectUtils.defaultIfNull(getCardState(), CardStateName.Original))).append(")");
|
||||
sb.append(" (").append(getHostCard().getName(ObjectUtils.firstNonNull(getCardStateName(), CardStateName.Original))).append(")");
|
||||
}
|
||||
|
||||
StaticAbility sta = getMayPlay();
|
||||
|
||||
@@ -175,11 +175,11 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
|
||||
}
|
||||
source.turnFaceDownNoUpdate();
|
||||
lkicheck = true;
|
||||
} else if (getCardState() != null) {
|
||||
} else if (getCardState() != null && source.getCurrentStateName() != getCardStateName()) {
|
||||
if (!source.isLKI()) {
|
||||
source = CardUtil.getLKICopy(source);
|
||||
}
|
||||
CardStateName stateName = getCardState();
|
||||
CardStateName stateName = getCardState().getStateName();
|
||||
if (!source.hasState(stateName)) {
|
||||
source.addAlternateState(stateName, false);
|
||||
source.getState(stateName).copyFrom(getHostCard().getState(stateName), true);
|
||||
|
||||
@@ -115,8 +115,6 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
private boolean blessing = false;
|
||||
private Integer chapter = null;
|
||||
|
||||
private CardStateName stateName = null;
|
||||
|
||||
/** The pay costs. */
|
||||
private Cost payCosts;
|
||||
private SpellAbilityRestriction restrictions = new SpellAbilityRestriction();
|
||||
@@ -466,21 +464,6 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
return this.hasParam("Boast");
|
||||
}
|
||||
|
||||
public void setOriginalHost(final Card c) {
|
||||
super.setOriginalHost(c);
|
||||
if (subAbility != null) {
|
||||
subAbility.setOriginalHost(c);
|
||||
}
|
||||
for (AbilitySub sa : additionalAbilities.values()) {
|
||||
sa.setOriginalHost(c);
|
||||
}
|
||||
for (List<AbilitySub> list : additionalAbilityLists.values()) {
|
||||
for (AbilitySub sa : list) {
|
||||
sa.setOriginalHost(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If this is not null, then ability was made in a factory
|
||||
public ApiType getApi() {
|
||||
return api;
|
||||
@@ -960,15 +943,8 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
mayPlay = sta;
|
||||
}
|
||||
|
||||
public CardStateName getCardState() {
|
||||
return stateName;
|
||||
}
|
||||
public void setCardState(CardStateName stateName0) {
|
||||
this.stateName = stateName0;
|
||||
}
|
||||
|
||||
public boolean isAdventure() {
|
||||
return this.stateName == CardStateName.Adventure;
|
||||
return this.getCardStateName() == CardStateName.Adventure;
|
||||
}
|
||||
|
||||
public SpellAbility copy() {
|
||||
|
||||
@@ -31,6 +31,7 @@ import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardCollectionView;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.card.CardState;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.cost.Cost;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
@@ -236,8 +237,8 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
|
||||
* @param host
|
||||
* the host
|
||||
*/
|
||||
public StaticAbility(final String params, final Card host) {
|
||||
this(parseParams(params, host), host);
|
||||
public StaticAbility(final String params, final Card host, CardState state) {
|
||||
this(parseParams(params, host), host, state);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -248,13 +249,14 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
|
||||
* @param host
|
||||
* the host
|
||||
*/
|
||||
private StaticAbility(final Map<String, String> params, final Card host) {
|
||||
private StaticAbility(final Map<String, String> params, final Card host, CardState state) {
|
||||
this.id = nextId();
|
||||
this.originalMapParams.putAll(params);
|
||||
this.mapParams.putAll(params);
|
||||
this.layers = this.generateLayer();
|
||||
this.hostCard = host;
|
||||
buildCommonAttributes(host);
|
||||
this.setCardState(state);
|
||||
}
|
||||
|
||||
public final CardCollectionView applyContinuousAbilityBefore(final StaticAbilityLayer layer, final CardCollectionView preList) {
|
||||
|
||||
@@ -736,7 +736,6 @@ public final class StaticAbilityContinuous {
|
||||
if (abilty.startsWith("AB") || abilty.startsWith("ST")) { // grant the ability
|
||||
final SpellAbility sa = AbilityFactory.getAbility(abilty, affectedCard, stAb);
|
||||
sa.setIntrinsic(false);
|
||||
sa.setOriginalHost(hostCard);
|
||||
addedAbilities.add(sa);
|
||||
}
|
||||
}
|
||||
@@ -766,9 +765,6 @@ public final class StaticAbilityContinuous {
|
||||
newSA.setRestrictions(sa.getRestrictions());
|
||||
newSA.getRestrictions().setLimitToCheck(params.get("GainsAbilitiesLimitPerTurn"));
|
||||
}
|
||||
if (newSA.getOriginalHost() == null) {
|
||||
newSA.setOriginalHost(c);
|
||||
}
|
||||
newSA.setOriginalAbility(sa); // need to be set to get the Once Per turn Clause correct
|
||||
newSA.setGrantorStatic(stAb);
|
||||
newSA.setIntrinsic(false);
|
||||
@@ -794,7 +790,6 @@ public final class StaticAbilityContinuous {
|
||||
// turn them into SpellAbility object before adding to card
|
||||
// with that the TargetedCard does not need the Svars added to them anymore
|
||||
// but only do it if the trigger doesn't already have a overriding ability
|
||||
actualTrigger.setOriginalHost(hostCard);
|
||||
addedTrigger.add(actualTrigger);
|
||||
}
|
||||
}
|
||||
@@ -807,9 +802,8 @@ public final class StaticAbilityContinuous {
|
||||
s = TextUtil.fastReplace(s, "ConvertedManaCost", costcmc);
|
||||
}
|
||||
|
||||
StaticAbility stat = new StaticAbility(s, affectedCard);
|
||||
StaticAbility stat = new StaticAbility(s, affectedCard, stAb.getCardState());
|
||||
stat.setIntrinsic(false);
|
||||
stat.setOriginalHost(hostCard);
|
||||
addedStaticAbility.add(stat);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package forge.game.trigger;
|
||||
|
||||
import forge.game.CardTraitBase;
|
||||
import forge.game.Game;
|
||||
import forge.game.GlobalRuleChange;
|
||||
import forge.game.IHasSVars;
|
||||
@@ -29,6 +30,7 @@ import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.card.CardPredicates;
|
||||
import forge.game.card.CardState;
|
||||
import forge.game.card.CardZoneTable;
|
||||
import forge.game.keyword.KeywordInterface;
|
||||
import forge.game.player.Player;
|
||||
@@ -151,6 +153,12 @@ public class TriggerHandler {
|
||||
ret = type.createTrigger(mapParams, host, intrinsic);
|
||||
if (sVarHolder != null) {
|
||||
ret.ensureAbility(sVarHolder);
|
||||
|
||||
if (sVarHolder instanceof CardState) {
|
||||
ret.setCardState((CardState)sVarHolder);
|
||||
} else if (sVarHolder instanceof CardTraitBase) {
|
||||
ret.setCardState(((CardTraitBase)sVarHolder).getCardState());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String msg = "TriggerHandler:parseTrigger failed to parse";
|
||||
|
||||
@@ -6,6 +6,7 @@ import forge.game.ability.AbilityKey;
|
||||
import forge.game.ability.ApiType;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardState;
|
||||
import forge.game.cost.Cost;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.*;
|
||||
@@ -515,10 +516,11 @@ public class WrappedAbility extends Ability {
|
||||
sa.setXManaCostPaid(n);
|
||||
}
|
||||
|
||||
public Card getOriginalHost() {
|
||||
return sa.getOriginalHost();
|
||||
|
||||
public CardState getCardState() {
|
||||
return sa.getCardState();
|
||||
}
|
||||
public void setOriginalHost(final Card c) {
|
||||
sa.setOriginalHost(c);
|
||||
public void setCardState(CardState state) {
|
||||
sa.setCardState(state);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user