diff --git a/.gitattributes b/.gitattributes index 8d49fda1d9c..763fe994db7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8365,6 +8365,7 @@ res/cardsfolder/p/puffer_extract.txt svneol=native#text/plain res/cardsfolder/p/pull_from_eternity.txt -text res/cardsfolder/p/pull_under.txt svneol=native#text/plain res/cardsfolder/p/pulling_teeth.txt svneol=native#text/plain +res/cardsfolder/p/pulmonic_sliver.txt -text res/cardsfolder/p/pulsating_illusion.txt svneol=native#text/plain res/cardsfolder/p/pulse_of_the_dross.txt -text res/cardsfolder/p/pulse_of_the_fields.txt svneol=native#text/plain diff --git a/res/cardsfolder/p/pulmonic_sliver.txt b/res/cardsfolder/p/pulmonic_sliver.txt new file mode 100644 index 00000000000..ba4b0894099 --- /dev/null +++ b/res/cardsfolder/p/pulmonic_sliver.txt @@ -0,0 +1,11 @@ +Name:Pulmonic Sliver +ManaCost:3 W W +Types:Creature Sliver +PT:3/3 +S:Mode$ Continuous | Affected$ Creature.Sliver | AddKeyword$ Flying | Description$ All Sliver creatures have flying. +S:Mode$ Continuous | Affected$ Card.Sliver | AddReplacementEffects$ PulmonicMoveToLibrary | AddSVar$ PulmonicSliverRep | Description$ All Slivers have "If this permanent would be put into a graveyard, you may put it on top of its owner's library instead." +SVar:PulmonicMoveToLibrary:Event$ Moved | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | ReplaceWith$ PulmonicSliverRep | Optional$ True | Description$ If CARDNAME would die, you may put it on the top of its owner's library instead. +SVar:PulmonicSliverRep:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Library | LibraryPosition$ 0 | Defined$ ReplacedCard +SVar:PlayMain1:TRUE +SVar:Picture:http://www.wizards.com/global/images/magic/general/pulmonic_sliver.jpg +Oracle:All Sliver creatures have flying.\nAll Slivers have "If this permanent would be put into a graveyard, you may put it on top of its owner's library instead." diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index 73d445b358a..95746868d96 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -8203,10 +8203,11 @@ public class Card extends GameEntity implements Comparable { * @param replacementEffect * the rE */ - public void addReplacementEffect(final ReplacementEffect replacementEffect) { + public ReplacementEffect addReplacementEffect(final ReplacementEffect replacementEffect) { final ReplacementEffect replacementEffectCopy = replacementEffect.getCopy(); // doubtful - every caller provides a newly parsed instance, why copy? replacementEffectCopy.setHostCard(this); this.getCharacteristics().getReplacementEffects().add(replacementEffectCopy); + return replacementEffectCopy; } /** diff --git a/src/main/java/forge/card/replacement/ReplacementEffect.java b/src/main/java/forge/card/replacement/ReplacementEffect.java index 08c31a06226..cae9e649c21 100644 --- a/src/main/java/forge/card/replacement/ReplacementEffect.java +++ b/src/main/java/forge/card/replacement/ReplacementEffect.java @@ -247,4 +247,27 @@ public abstract class ReplacementEffect extends TriggerReplacementBase { return ""; } } + + + /** The temporary. */ + private boolean temporary = false; + + /** + * Sets the temporary. + * + * @param temp + * the new temporary + */ + public final void setTemporary(final boolean temp) { + this.temporary = temp; + } + + /** + * Checks if is temporary. + * + * @return true, if is temporary + */ + public final boolean isTemporary() { + return this.temporary; + } } diff --git a/src/main/java/forge/card/replacement/ReplacementHandler.java b/src/main/java/forge/card/replacement/ReplacementHandler.java index f9c00d41275..46947c61926 100644 --- a/src/main/java/forge/card/replacement/ReplacementHandler.java +++ b/src/main/java/forge/card/replacement/ReplacementHandler.java @@ -43,6 +43,14 @@ import forge.util.FileSection; * */ public class ReplacementHandler { + private final Game game; + /** + * ReplacementHandler. + * @param gameState + */ + public ReplacementHandler(Game gameState) { + game = gameState; + } //private final List tmpEffects = new ArrayList(); @@ -281,4 +289,24 @@ public class ReplacementHandler { return ret; } + + /** + * TODO: Write javadoc for this method. + */ + public void cleanUpTemporaryReplacements() { + final List absolutelyAllCards = game.getCardsInGame(); + for (final Card c : absolutelyAllCards) { + for (int i = 0; i < c.getReplacementEffects().size(); i++) { + if (c.getReplacementEffects().get(i).isTemporary()) { + c.getReplacementEffects().remove(i); + i--; + } + } + } + for (final Card c : absolutelyAllCards) { + for (int i = 0; i < c.getReplacementEffects().size(); i++) { + c.getReplacementEffects().get(i).setTemporarilySuppressed(false); + } + } + } } diff --git a/src/main/java/forge/card/staticability/StaticAbility.java b/src/main/java/forge/card/staticability/StaticAbility.java index a2c0edbf0b0..4c85e88e7c2 100644 --- a/src/main/java/forge/card/staticability/StaticAbility.java +++ b/src/main/java/forge/card/staticability/StaticAbility.java @@ -157,7 +157,7 @@ public class StaticAbility { if (this.params.containsKey("AddKeyword") || this.params.containsKey("AddAbility") || this.params.containsKey("AddTrigger") || this.params.containsKey("RemoveTriggers") - || this.params.containsKey("RemoveKeyword")) { + || this.params.containsKey("RemoveKeyword") || this.params.containsKey("AddReplacementEffects")) { return 7; // Layer 6 (dependent) } diff --git a/src/main/java/forge/card/staticability/StaticAbilityContinuous.java b/src/main/java/forge/card/staticability/StaticAbilityContinuous.java index a3ecefc9f03..4c143271fb9 100644 --- a/src/main/java/forge/card/staticability/StaticAbilityContinuous.java +++ b/src/main/java/forge/card/staticability/StaticAbilityContinuous.java @@ -34,6 +34,8 @@ import forge.card.TriggerReplacementBase; import forge.card.ability.AbilityFactory; import forge.card.ability.AbilityUtils; import forge.card.cardfactory.CardFactoryUtil; +import forge.card.replacement.ReplacementEffect; +import forge.card.replacement.ReplacementHandler; import forge.card.spellability.AbilityActivated; import forge.card.spellability.SpellAbility; import forge.card.trigger.Trigger; @@ -86,6 +88,7 @@ public class StaticAbilityContinuous { String[] addHiddenKeywords = null; String[] removeKeywords = null; String[] addAbilities = null; + String[] addReplacements = null; String[] addSVars = null; String[] addTypes = null; String[] removeTypes = null; @@ -186,6 +189,14 @@ public class StaticAbilityContinuous { addAbilities = sVars; } + if (params.containsKey("AddReplacementEffects")) { + final String[] sVars = params.get("AddReplacementEffects").split(" & "); + for (int i = 0; i < sVars.length; i++) { + sVars[i] = hostCard.getSVar(sVars[i]); + } + addReplacements = sVars; + } + if (params.containsKey("AddSVar")) { addSVars = params.get("AddSVar").split(" & "); } @@ -417,6 +428,14 @@ public class StaticAbilityContinuous { } } + // add Replacement effects + if (addReplacements != null) { + for (String rep : addReplacements) { + final ReplacementEffect actualRep = ReplacementHandler.parseReplacement(rep, affectedCard); + affectedCard.addReplacementEffect(actualRep).setTemporary(true);; + } + } + // add Types if ((addTypes != null) || (removeTypes != null)) { affectedCard.addChangedCardTypes(addTypes, removeTypes, removeSuperTypes, removeCardTypes, diff --git a/src/main/java/forge/game/Game.java b/src/main/java/forge/game/Game.java index b517113e1ba..9520ae270cd 100644 --- a/src/main/java/forge/game/Game.java +++ b/src/main/java/forge/game/Game.java @@ -70,7 +70,7 @@ public class Game { public final MagicStack stack; private final StaticEffects staticEffects = new StaticEffects(); private final TriggerHandler triggerHandler = new TriggerHandler(this); - private final ReplacementHandler replacementHandler = new ReplacementHandler(); + private final ReplacementHandler replacementHandler = new ReplacementHandler(this); private Combat combat = new Combat(); private final EventBus events = new EventBus(); private final GameLog gameLog = new GameLog(); diff --git a/src/main/java/forge/game/GameAction.java b/src/main/java/forge/game/GameAction.java index 6f13b27e4eb..d750cf5868b 100644 --- a/src/main/java/forge/game/GameAction.java +++ b/src/main/java/forge/game/GameAction.java @@ -797,6 +797,7 @@ public class GameAction { // remove old effects game.getStaticEffects().clearStaticEffects(); game.getTriggerHandler().cleanUpTemporaryTriggers(); + game.getReplacementHandler().cleanUpTemporaryReplacements(); // search for cards with static abilities final List allCards = game.getCardsInGame(); diff --git a/src/main/java/forge/game/limited/BoosterDraft.java b/src/main/java/forge/game/limited/BoosterDraft.java index 37fec4c0789..d6b1180bb35 100644 --- a/src/main/java/forge/game/limited/BoosterDraft.java +++ b/src/main/java/forge/game/limited/BoosterDraft.java @@ -32,13 +32,10 @@ import javax.swing.JOptionPane; import org.apache.commons.lang.ArrayUtils; import com.google.common.base.Supplier; -import com.google.common.collect.Iterables; - import forge.Card; import forge.Constant.Preferences; import forge.Singletons; import forge.card.CardBlock; -import forge.card.CardDb; import forge.card.CardEdition; import forge.card.IUnOpenedProduct; import forge.card.SealedProductTemplate; @@ -50,7 +47,6 @@ import forge.item.IPaperCard; import forge.item.ItemPool; import forge.item.ItemPoolView; import forge.properties.NewConstants; -import forge.util.Aggregates; import forge.util.FileUtil; import forge.util.HttpUtil; import forge.util.storage.IStorageView;