diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index e7f2d603de7..9f8bd28db45 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -499,9 +499,6 @@ public class Card extends GameEntity implements Comparable, IHasSVars, ITr if (state == CardStateName.FaceDown) { return getFaceDownState(); } - if (state == CardStateName.EmptyRoom) { - return getEmptyRoomState(); - } CardCloneStates clStates = getLastClonedState(); if (clStates == null) { return getOriginalState(state); @@ -560,7 +557,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars, ITr boolean needsTransformAnimation = transform || rollback; // faceDown has higher priority over clone states // while text change states doesn't apply while the card is faceDown - if (state != CardStateName.FaceDown && state != CardStateName.EmptyRoom) { + if (state != CardStateName.FaceDown) { CardCloneStates cloneStates = getLastClonedState(); if (cloneStates != null) { if (!cloneStates.containsKey(state)) { diff --git a/forge-game/src/main/java/forge/game/card/CardCloneStates.java b/forge-game/src/main/java/forge/game/card/CardCloneStates.java index 4cb5b0c51c9..152f8ff5235 100644 --- a/forge-game/src/main/java/forge/game/card/CardCloneStates.java +++ b/forge-game/src/main/java/forge/game/card/CardCloneStates.java @@ -49,6 +49,10 @@ public class CardCloneStates extends ForwardingMap { return result; } + public void add(CardState state) { + put(state.getStateName(), state); + } + public CardCloneStates copy(final Card host, final boolean lki) { CardCloneStates result = new CardCloneStates(origin, ctb); for (Map.Entry e : dataMap.entrySet()) { diff --git a/forge-game/src/main/java/forge/game/card/CardFactory.java b/forge-game/src/main/java/forge/game/card/CardFactory.java index efda56fa831..7ae219899ce 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -477,6 +477,7 @@ public class CardFactory { final CardCloneStates result = new CardCloneStates(in, cause); final String newName = cause.getParam("NewName"); + ManaCost manaCost = null; ColorSet colors = null; if (cause.hasParam("AddTypes")) { @@ -508,11 +509,10 @@ public class CardFactory { colors = ColorSet.fromNames(cause.getParam("SetColor").split(",")); } - if (cause.hasParam("SetColorByManaCost")) { - if (cause.hasParam("SetManaCost")) { - colors = ColorSet.fromManaCost(new ManaCost(new ManaCostParser(cause.getParam("SetManaCost")))); - } else { - colors = ColorSet.fromManaCost(host.getManaCost()); + if (cause.hasParam("SetManaCost")) { + manaCost = new ManaCost(new ManaCostParser(cause.getParam("SetManaCost"))); + if (cause.hasParam("SetColorByManaCost")) { + colors = ColorSet.fromManaCost(manaCost); } } @@ -521,57 +521,34 @@ public class CardFactory { if (in.isFaceDown()) { // if something is cloning a facedown card, it only clones the // facedown state into original - final CardState ret = new CardState(out, CardStateName.Original); - ret.copyFrom(in.getFaceDownState(), false, cause); - result.put(CardStateName.Original, ret); + result.add(in.getFaceDownState().copy(out, CardStateName.Original, cause)); } else if (in.isFlipCard()) { // if something is cloning a flip card, copy both original and // flipped state - final CardState ret1 = new CardState(out, CardStateName.Original); - ret1.copyFrom(in.getState(CardStateName.Original), false, cause); - result.put(CardStateName.Original, ret1); - - final CardState ret2 = new CardState(out, CardStateName.Flipped); - ret2.copyFrom(in.getState(CardStateName.Flipped), false, cause); - result.put(CardStateName.Flipped, ret2); + result.add(in.getState(CardStateName.Original).copy(out, cause)); + result.add(in.getState(CardStateName.Flipped).copy(out, cause)); } else if (in.hasState(CardStateName.Secondary)) { - final CardState ret1 = new CardState(out, CardStateName.Original); - ret1.copyFrom(in.getState(CardStateName.Original), false, cause); - result.put(CardStateName.Original, ret1); - - final CardState ret2 = new CardState(out, CardStateName.Secondary); - ret2.copyFrom(in.getState(CardStateName.Secondary), false, cause); - result.put(CardStateName.Secondary, ret2); + result.add(in.getState(CardStateName.Original).copy(out, cause)); + result.add(in.getState(CardStateName.Secondary).copy(out, cause)); } else if (in.isTransformable() && cause instanceof SpellAbility sa && ( ApiType.CopyPermanent.equals(sa.getApi()) || ApiType.CopySpellAbility.equals(sa.getApi()) || ApiType.ReplaceToken.equals(sa.getApi()))) { // CopyPermanent can copy token - final CardState ret1 = new CardState(out, CardStateName.Original); - ret1.copyFrom(in.getState(CardStateName.Original), false, cause); - result.put(CardStateName.Original, ret1); - - final CardState ret2 = new CardState(out, CardStateName.Backside); - ret2.copyFrom(in.getState(CardStateName.Backside), false, cause); - result.put(CardStateName.Backside, ret2); + result.add(in.getState(CardStateName.Original).copy(out, cause)); + result.add(in.getState(CardStateName.Backside).copy(out, cause)); } else if (in.isSplitCard()) { // for split cards, copy all three states - final CardState ret1 = new CardState(out, CardStateName.Original); - ret1.copyFrom(in.getState(CardStateName.Original), false, cause); - result.put(CardStateName.Original, ret1); - final CardState ret2 = new CardState(out, CardStateName.LeftSplit); - ret2.copyFrom(in.getState(CardStateName.LeftSplit), false, cause); - result.put(CardStateName.LeftSplit, ret2); - - final CardState ret3 = new CardState(out, CardStateName.RightSplit); - ret3.copyFrom(in.getState(CardStateName.RightSplit), false, cause); - result.put(CardStateName.RightSplit, ret3); + result.add(in.getState(CardStateName.Original).copy(out, cause)); + result.add(in.getState(CardStateName.LeftSplit).copy(out, cause)); + result.add(in.getState(CardStateName.RightSplit).copy(out, cause)); + if (in.isPermanent()) { + result.add(in.getState(CardStateName.EmptyRoom).copy(out, cause)); + } } else { // in all other cases just copy the current state to original - final CardState ret = new CardState(out, CardStateName.Original); - ret.copyFrom(in.getState(in.getCurrentStateName()), false, cause); - result.put(CardStateName.Original, ret); + result.add(in.getState(in.getCurrentStateName()).copy(out, CardStateName.Original, cause)); } // update all states, both for flip cards @@ -614,21 +591,9 @@ public class CardFactory { state.setCreatureTypes(creatureTypes); } - List finalizedKWs = KWifNew ? Lists.newArrayList() : keywords; + List finalizedKWs = keywords; if (KWifNew) { - for (String k : keywords) { - Keyword toAdd = Keyword.getInstance(k).getKeyword(); - boolean match = false; - for (KeywordInterface kw : state.getIntrinsicKeywords()) { - if (kw.getKeyword().equals(toAdd)) { - match = true; - break; - } - } - if (!match) { - finalizedKWs.add(k); - } - } + finalizedKWs = keywords.stream().filter(k -> !state.hasIntrinsicKeyword(Keyword.getInstance(k).getKeyword())).collect(Collectors.toList()); } state.addIntrinsicKeywords(finalizedKWs); for (String kw : removeKeywords) { @@ -656,7 +621,7 @@ public class CardFactory { } if (cause.hasParam("SetManaCost")) { - state.setManaCost(new ManaCost(new ManaCostParser(cause.getParam("SetManaCost")))); + state.setManaCost(manaCost); } // SVars to add to clone @@ -793,11 +758,11 @@ public class CardFactory { public static CardCloneStates getMutatedCloneStates(final Card card, final CardTraitBase sa) { final Card top = card.getTopMergedCard(); final CardStateName state = top.getCurrentStateName(); - final CardState ret = new CardState(card, state); + CardState ret; if (top.isCloned()) { - ret.copyFrom(top.getState(state), false, sa); + ret = top.getState(state).copy(card, sa); } else { - ret.copyFrom(top.getOriginalState(state), false, sa); + ret = top.getOriginalState(state).copy(card, sa); } boolean first = true; @@ -814,9 +779,7 @@ public class CardFactory { // For face down, flipped, transformed, melded or MDFC card, also copy the original state to avoid crash if (state != CardStateName.Original) { - final CardState ret1 = new CardState(card, CardStateName.Original); - ret1.copyFrom(top.getState(CardStateName.Original), false, sa); - result.put(CardStateName.Original, ret1); + result.add(top.getState(CardStateName.Original).copy(card, sa)); } return result; diff --git a/forge-game/src/main/java/forge/game/card/CardState.java b/forge-game/src/main/java/forge/game/card/CardState.java index 54624699f6b..8080402c16d 100644 --- a/forge-game/src/main/java/forge/game/card/CardState.java +++ b/forge-game/src/main/java/forge/game/card/CardState.java @@ -309,6 +309,9 @@ public class CardState implements GameObject, IHasSVars, ITranslatable { public final boolean hasIntrinsicKeyword(String k) { return intrinsicKeywords.contains(k); } + public final boolean hasIntrinsicKeyword(Keyword k) { + return intrinsicKeywords.contains(k); + } public final void setIntrinsicKeywords(final Iterable intrinsicKeyword0, final boolean lki) { intrinsicKeywords.clear(); for (KeywordInterface k : intrinsicKeyword0) { @@ -841,8 +844,17 @@ public class CardState implements GameObject, IHasSVars, ITranslatable { } public CardState copy(final Card host, CardStateName name, final boolean lki) { + return copy(host, name, lki, null); + } + public CardState copy(final Card host, final CardTraitBase ctb) { + return copy(host, this.getStateName(), false, ctb); + } + public CardState copy(final Card host, CardStateName name, final CardTraitBase ctb) { + return copy(host, name, false, ctb); + } + public CardState copy(final Card host, CardStateName name, final boolean lki, final CardTraitBase ctb) { CardState result = new CardState(host, name); - result.copyFrom(this, lki); + result.copyFrom(this, lki, ctb); return result; }