From 7e5b67764723d308c10c13b7e617a58ffd211343 Mon Sep 17 00:00:00 2001 From: North Date: Fri, 7 Sep 2012 00:38:24 +0300 Subject: [PATCH] Added UnblockableSourceEffect; Unblockable isn't Singleton anymore --- .../src/mage/player/ai/ma/MagicAbility.java | 2 +- .../mage/sets/alarareborn/GlassdustHulk.java | 13 +- .../mage/sets/avacynrestored/LatchSeeker.java | 2 +- .../src/mage/sets/conflux/VectisAgents.java | 13 +- .../src/mage/sets/darksteel/Spincrusher.java | 13 +- .../mage/sets/innistrad/InvisibleStalker.java | 2 +- .../mage/sets/magic2010/PhantomWarrior.java | 2 +- .../mage/sets/magic2012/TormentedSoul.java | 2 +- .../src/mage/sets/magic2013/HarborBandit.java | 11 +- .../src/mage/sets/mirrodin/NeurokSpy.java | 16 +-- .../mage/sets/newphyrexia/BlightedAgent.java | 2 +- .../newphyrexia/TrespassingSouleater.java | 6 +- .../mage/sets/ravnika/DimirInfiltrator.java | 2 +- .../src/mage/sets/ravnika/HuntedPhantasm.java | 2 +- .../sets/riseoftheeldrazi/HadaSpyPatrol.java | 4 +- .../scarsofmirrodin/NeurokInvisimancer.java | 2 +- .../scarsofmirrodin/ScrapdiverSerpent.java | 16 +-- .../sets/shadowmoor/InkfathomInfiltrator.java | 2 +- .../shardsofalara/JhessianInfiltrator.java | 2 +- .../sets/urzasdestiny/BubblingBeebles.java | 10 +- .../sets/urzaslegacy/BouncingBeebles.java | 13 +- .../mage/sets/worldwake/CreepingTarPit.java | 2 +- .../src/mage/sets/zendikar/AetherFigment.java | 2 +- .../common/UnblockableSourceEffect.java | 71 +++++++++++ .../abilities/keyword/UnblockableAbility.java | 116 +++++------------- Mage/src/mage/util/trace/TraceUtil.java | 1 - 26 files changed, 178 insertions(+), 151 deletions(-) create mode 100644 Mage/src/mage/abilities/effects/common/UnblockableSourceEffect.java diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ma/MagicAbility.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ma/MagicAbility.java index d89062cfe9c..4ba58bf34fb 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ma/MagicAbility.java +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ma/MagicAbility.java @@ -32,7 +32,7 @@ public class MagicAbility { put(ShroudAbility.getInstance().getRule(), 60); put(new SwampwalkAbility().getRule(), 10); put(TrampleAbility.getInstance().getRule(), 30); - put(UnblockableAbility.getInstance().getRule(), 100); + put(new UnblockableAbility().getRule(), 100); put(VigilanceAbility.getInstance().getRule(), 20); put(WitherAbility.getInstance().getRule(), 30); }}; diff --git a/Mage.Sets/src/mage/sets/alarareborn/GlassdustHulk.java b/Mage.Sets/src/mage/sets/alarareborn/GlassdustHulk.java index 2d986155c39..a06b3d4c208 100644 --- a/Mage.Sets/src/mage/sets/alarareborn/GlassdustHulk.java +++ b/Mage.Sets/src/mage/sets/alarareborn/GlassdustHulk.java @@ -28,17 +28,16 @@ package mage.sets.alarareborn; import java.util.UUID; - -import mage.Constants; import mage.Constants.CardType; +import mage.Constants.Duration; import mage.Constants.Rarity; +import mage.Constants.Zone; import mage.MageInt; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.UnblockableSourceEffect; import mage.abilities.effects.common.continious.BoostSourceEffect; -import mage.abilities.effects.common.continious.GainAbilitySourceEffect; import mage.abilities.keyword.CyclingAbility; -import mage.abilities.keyword.UnblockableAbility; import mage.cards.CardImpl; import mage.game.Game; import mage.game.events.GameEvent; @@ -78,8 +77,8 @@ public class GlassdustHulk extends CardImpl { class GlassdustHulkTriggeredAbility extends TriggeredAbilityImpl { GlassdustHulkTriggeredAbility() { - super(Constants.Zone.BATTLEFIELD, new BoostSourceEffect(1, 1, Constants.Duration.EndOfTurn)); - this.addEffect(new GainAbilitySourceEffect(UnblockableAbility.getInstance(), Constants.Duration.EndOfTurn)); + super(Zone.BATTLEFIELD, new BoostSourceEffect(1, 1, Duration.EndOfTurn)); + this.addEffect(new UnblockableSourceEffect(Duration.EndOfTurn)); } GlassdustHulkTriggeredAbility(final GlassdustHulkTriggeredAbility ability) { @@ -95,7 +94,7 @@ class GlassdustHulkTriggeredAbility extends TriggeredAbilityImpl { this.toughness = new MageInt(1); // Latch Seeker is unblockable. - this.addAbility(UnblockableAbility.getInstance()); + this.addAbility(new UnblockableAbility()); } public LatchSeeker(final LatchSeeker card) { diff --git a/Mage.Sets/src/mage/sets/conflux/VectisAgents.java b/Mage.Sets/src/mage/sets/conflux/VectisAgents.java index 2c71d2dd5a1..7b935df4273 100644 --- a/Mage.Sets/src/mage/sets/conflux/VectisAgents.java +++ b/Mage.Sets/src/mage/sets/conflux/VectisAgents.java @@ -37,9 +37,8 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.UnblockableSourceEffect; import mage.abilities.effects.common.continious.BoostSourceEffect; -import mage.abilities.effects.common.continious.GainAbilitySourceEffect; -import mage.abilities.keyword.UnblockableAbility; import mage.cards.CardImpl; /** @@ -56,9 +55,13 @@ public class VectisAgents extends CardImpl { this.subtype.add("Human"); this.subtype.add("Rogue"); this.power = new MageInt(4); - this.toughness = new MageInt(3); - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(-2, -0, Duration.EndOfTurn), new ManaCostsImpl("{U}{B}")); - ability.addEffect(new GainAbilitySourceEffect(UnblockableAbility.getInstance(), Duration.EndOfTurn)); + this.toughness = new MageInt(3); + + // {U}{B}: Vectis Agents gets -2/-0 until end of turn and is unblockable this turn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new BoostSourceEffect(-2, -0, Duration.EndOfTurn), + new ManaCostsImpl("{U}{B}")); + ability.addEffect(new UnblockableSourceEffect(Duration.EndOfTurn)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/darksteel/Spincrusher.java b/Mage.Sets/src/mage/sets/darksteel/Spincrusher.java index 6e4de1bd8f4..1eb240b9002 100644 --- a/Mage.Sets/src/mage/sets/darksteel/Spincrusher.java +++ b/Mage.Sets/src/mage/sets/darksteel/Spincrusher.java @@ -30,16 +30,16 @@ package mage.sets.darksteel; import java.util.UUID; -import mage.Constants; import mage.Constants.CardType; +import mage.Constants.Duration; import mage.Constants.Rarity; +import mage.Constants.Zone; import mage.MageInt; import mage.abilities.common.BlocksTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.RemoveCountersSourceCost; -import mage.abilities.effects.common.continious.GainAbilitySourceEffect; +import mage.abilities.effects.common.UnblockableSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.keyword.UnblockableAbility; import mage.cards.CardImpl; import mage.counters.CounterType; @@ -54,8 +54,13 @@ public class Spincrusher extends CardImpl { this.subtype.add("Construct"); this.power = new MageInt(0); this.toughness = new MageInt(2); + + // Whenever Spincrusher blocks, put a +1/+1 counter on it. this.addAbility(new BlocksTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false)); - this.addAbility(new SimpleActivatedAbility(Constants.Zone.BATTLEFIELD, new GainAbilitySourceEffect(UnblockableAbility.getInstance(), Constants.Duration.EndOfTurn), new RemoveCountersSourceCost(CounterType.P1P1.createInstance(1)))); + // Remove a +1/+1 counter from Spincrusher: Spincrusher is unblockable this turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, + new UnblockableSourceEffect(Duration.EndOfTurn), + new RemoveCountersSourceCost(CounterType.P1P1.createInstance(1)))); } public Spincrusher(final Spincrusher card) { diff --git a/Mage.Sets/src/mage/sets/innistrad/InvisibleStalker.java b/Mage.Sets/src/mage/sets/innistrad/InvisibleStalker.java index 689e081979d..64e3530642f 100644 --- a/Mage.Sets/src/mage/sets/innistrad/InvisibleStalker.java +++ b/Mage.Sets/src/mage/sets/innistrad/InvisibleStalker.java @@ -53,7 +53,7 @@ public class InvisibleStalker extends CardImpl { this.addAbility(HexproofAbility.getInstance()); // Invisible Stalker is unblockable. - this.addAbility(UnblockableAbility.getInstance()); + this.addAbility(new UnblockableAbility()); } public InvisibleStalker(final InvisibleStalker card) { diff --git a/Mage.Sets/src/mage/sets/magic2010/PhantomWarrior.java b/Mage.Sets/src/mage/sets/magic2010/PhantomWarrior.java index d22fa9fff6c..aa518c29b2b 100644 --- a/Mage.Sets/src/mage/sets/magic2010/PhantomWarrior.java +++ b/Mage.Sets/src/mage/sets/magic2010/PhantomWarrior.java @@ -48,7 +48,7 @@ public class PhantomWarrior extends CardImpl { this.color.setBlue(true); this.power = new MageInt(2); this.toughness = new MageInt(2); - this.addAbility(UnblockableAbility.getInstance()); + this.addAbility(new UnblockableAbility()); } public PhantomWarrior(final PhantomWarrior card) { diff --git a/Mage.Sets/src/mage/sets/magic2012/TormentedSoul.java b/Mage.Sets/src/mage/sets/magic2012/TormentedSoul.java index e170bc76e8f..6d07df56b10 100644 --- a/Mage.Sets/src/mage/sets/magic2012/TormentedSoul.java +++ b/Mage.Sets/src/mage/sets/magic2012/TormentedSoul.java @@ -50,7 +50,7 @@ public class TormentedSoul extends CardImpl { this.power = new MageInt(1); this.toughness = new MageInt(1); this.addAbility(CantBlockAbility.getInstance()); - this.addAbility(UnblockableAbility.getInstance()); + this.addAbility(new UnblockableAbility()); } public TormentedSoul(final TormentedSoul card) { diff --git a/Mage.Sets/src/mage/sets/magic2013/HarborBandit.java b/Mage.Sets/src/mage/sets/magic2013/HarborBandit.java index 65823851b9a..b8aea47c6e2 100644 --- a/Mage.Sets/src/mage/sets/magic2013/HarborBandit.java +++ b/Mage.Sets/src/mage/sets/magic2013/HarborBandit.java @@ -28,19 +28,18 @@ package mage.sets.magic2013; import java.util.UUID; -import mage.Constants; import mage.Constants.CardType; import mage.Constants.Duration; import mage.Constants.Rarity; +import mage.Constants.Zone; import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.ControlsPermanentCondition; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalContinousEffect; +import mage.abilities.effects.common.UnblockableSourceEffect; import mage.abilities.effects.common.continious.BoostSourceEffect; -import mage.abilities.effects.common.continious.GainAbilitySourceEffect; -import mage.abilities.keyword.UnblockableAbility; import mage.cards.CardImpl; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.SubtypePredicate; @@ -70,10 +69,12 @@ public class HarborBandit extends CardImpl { // Harbor Bandit gets +1/+1 as long as you control an Island. ConditionalContinousEffect effect = new ConditionalContinousEffect(new BoostSourceEffect(1, 1, Duration.WhileOnBattlefield), new ControlsPermanentCondition(filter), rule); - this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, effect)); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); // {1}{U}: Harbor Bandit is unblockable this turn. - this.addAbility(new SimpleActivatedAbility(Constants.Zone.BATTLEFIELD, new GainAbilitySourceEffect(UnblockableAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl("{1}{U}"))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, + new UnblockableSourceEffect(Duration.EndOfTurn), + new ManaCostsImpl("{1}{U}"))); } public HarborBandit(final HarborBandit card) { diff --git a/Mage.Sets/src/mage/sets/mirrodin/NeurokSpy.java b/Mage.Sets/src/mage/sets/mirrodin/NeurokSpy.java index 9ff9344e279..0d222cc4133 100644 --- a/Mage.Sets/src/mage/sets/mirrodin/NeurokSpy.java +++ b/Mage.Sets/src/mage/sets/mirrodin/NeurokSpy.java @@ -28,21 +28,21 @@ package mage.sets.mirrodin; import java.util.UUID; - import mage.Constants; + import mage.Constants.CardType; import mage.Constants.Rarity; +import mage.Constants.Zone; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.Condition; import mage.abilities.decorator.ConditionalContinousEffect; -import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.continious.GainAbilitySourceEffect; -import mage.abilities.keyword.UnblockableAbility; +import mage.abilities.effects.common.UnblockableSourceEffect; import mage.cards.CardImpl; import mage.filter.FilterPermanent; +import mage.filter.common.FilterArtifactPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.game.Game; @@ -52,7 +52,6 @@ import mage.game.Game; */ public class NeurokSpy extends CardImpl { - private static final String text = "Neurok Spy is unblockable as long as defending player controls an artifact"; private static final FilterPermanent filter = new FilterPermanent(); static { @@ -81,9 +80,10 @@ public class NeurokSpy extends CardImpl { this.toughness = new MageInt(2); //Neurok Spy is unblockable as long as defending player controls an artifact. - ContinuousEffect gainAbility = new GainAbilitySourceEffect(UnblockableAbility.getInstance(), Constants.Duration.WhileOnBattlefield); - Effect effect = new ConditionalContinousEffect(gainAbility, new DefendingPlayerControlsArtifact(), text); - this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, effect)); + Effect effect = new ConditionalContinousEffect(new UnblockableSourceEffect(), + new DefendingPlayerControlsArtifact(), + "Neurok Spy is unblockable as long as defending player controls an artifact"); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); } public NeurokSpy(final NeurokSpy card) { diff --git a/Mage.Sets/src/mage/sets/newphyrexia/BlightedAgent.java b/Mage.Sets/src/mage/sets/newphyrexia/BlightedAgent.java index 4d9b6f441fe..c85409e01d3 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/BlightedAgent.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/BlightedAgent.java @@ -52,7 +52,7 @@ public class BlightedAgent extends CardImpl { this.toughness = new MageInt(1); this.addAbility(InfectAbility.getInstance()); - this.addAbility(UnblockableAbility.getInstance()); + this.addAbility(new UnblockableAbility()); } public BlightedAgent(final BlightedAgent card) { diff --git a/Mage.Sets/src/mage/sets/newphyrexia/TrespassingSouleater.java b/Mage.Sets/src/mage/sets/newphyrexia/TrespassingSouleater.java index a9d594223c4..ea6905ba553 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/TrespassingSouleater.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/TrespassingSouleater.java @@ -36,8 +36,7 @@ import mage.Constants.Zone; import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.PhyrexianManaCost; -import mage.abilities.effects.common.continious.GainAbilitySourceEffect; -import mage.abilities.keyword.UnblockableAbility; +import mage.abilities.effects.common.UnblockableSourceEffect; import mage.cards.CardImpl; /** @@ -54,8 +53,9 @@ public class TrespassingSouleater extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(2); + // {UP}: Trespassing Souleater is unblockable this turn. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, - new GainAbilitySourceEffect(UnblockableAbility.getInstance(), Duration.EndOfTurn), + new UnblockableSourceEffect(Duration.EndOfTurn), new PhyrexianManaCost(ColoredManaSymbol.U))); } diff --git a/Mage.Sets/src/mage/sets/ravnika/DimirInfiltrator.java b/Mage.Sets/src/mage/sets/ravnika/DimirInfiltrator.java index 4a353f7fd75..17b3765bc69 100644 --- a/Mage.Sets/src/mage/sets/ravnika/DimirInfiltrator.java +++ b/Mage.Sets/src/mage/sets/ravnika/DimirInfiltrator.java @@ -52,7 +52,7 @@ public class DimirInfiltrator extends CardImpl { this.toughness = new MageInt(3); // Dimir Infiltrator is unblockable. - this.addAbility(UnblockableAbility.getInstance()); + this.addAbility(new UnblockableAbility()); // Transmute {1}{U}{B} this.addAbility(new TransmuteAbility("{1}{U}{B}")); } diff --git a/Mage.Sets/src/mage/sets/ravnika/HuntedPhantasm.java b/Mage.Sets/src/mage/sets/ravnika/HuntedPhantasm.java index 110a12112d8..db666226acd 100644 --- a/Mage.Sets/src/mage/sets/ravnika/HuntedPhantasm.java +++ b/Mage.Sets/src/mage/sets/ravnika/HuntedPhantasm.java @@ -56,7 +56,7 @@ public class HuntedPhantasm extends CardImpl { this.toughness = new MageInt(6); // Hunted Phantasm is unblockable. - this.addAbility(UnblockableAbility.getInstance()); + this.addAbility(new UnblockableAbility()); // When Hunted Phantasm enters the battlefield, put five 1/1 red Goblin creature tokens onto the battlefield under target opponent's control. Ability ability = new EntersBattlefieldTriggeredAbility(new CreateTokenTargetEffect(new GoblinToken(), 5), false); Target target = new TargetOpponent(); diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/HadaSpyPatrol.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/HadaSpyPatrol.java index 8f09f15f7d4..b20e70a8526 100644 --- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/HadaSpyPatrol.java +++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/HadaSpyPatrol.java @@ -61,10 +61,10 @@ public class HadaSpyPatrol extends LevelerCard { this.addAbility(new LevelUpAbility(new ManaCostsImpl("{2}{U}"))); Abilities abilities1 = new AbilitiesImpl(); - abilities1.add(UnblockableAbility.getInstance()); + abilities1.add(new UnblockableAbility()); Abilities abilities2 = new AbilitiesImpl(); - abilities2.add(UnblockableAbility.getInstance()); + abilities2.add(new UnblockableAbility()); abilities2.add(ShroudAbility.getInstance()); LevelerCardBuilder.construct(this, diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/NeurokInvisimancer.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/NeurokInvisimancer.java index d5e41b82aa7..e5e4b97ebd0 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/NeurokInvisimancer.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/NeurokInvisimancer.java @@ -55,7 +55,7 @@ public class NeurokInvisimancer extends CardImpl { this.toughness = new MageInt(1); // Neurok Invisimancer is unblockable. - this.addAbility(UnblockableAbility.getInstance()); + this.addAbility(new UnblockableAbility()); // When Neurok Invisimancer enters the battlefield, target creature is unblockable this turn. Ability ability = new EntersBattlefieldTriggeredAbility(new UnblockableTargetEffect()); ability.addTarget(new TargetCreaturePermanent()); diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/ScrapdiverSerpent.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/ScrapdiverSerpent.java index ae285bacf81..73447b1d596 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/ScrapdiverSerpent.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/ScrapdiverSerpent.java @@ -32,7 +32,9 @@ import java.util.UUID; import mage.Constants; import mage.Constants.CardType; +import mage.Constants.Duration; import mage.Constants.Rarity; +import mage.Constants.Zone; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; @@ -40,8 +42,7 @@ import mage.abilities.condition.Condition; import mage.abilities.decorator.ConditionalContinousEffect; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.continious.GainAbilitySourceEffect; -import mage.abilities.keyword.UnblockableAbility; +import mage.abilities.effects.common.UnblockableSourceEffect; import mage.cards.CardImpl; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -53,8 +54,6 @@ import mage.game.Game; */ public class ScrapdiverSerpent extends CardImpl { - private static final String rule = "Scrapdiver Serpent is unblockable as long as defending player controls an artifact"; - private static final FilterPermanent filter = new FilterPermanent(); static { @@ -79,9 +78,12 @@ public class ScrapdiverSerpent extends CardImpl { this.color.setBlue(true); this.power = new MageInt(5); this.toughness = new MageInt(5); - ContinuousEffect gainAbility = new GainAbilitySourceEffect(UnblockableAbility.getInstance(), Constants.Duration.WhileOnBattlefield); - Effect effect = new ConditionalContinousEffect(gainAbility, new DefendingPlayerControlsArtifact(), rule); - this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, effect)); + + // Scrapdiver Serpent is unblockable as long as defending player controls an artifact + Effect effect = new ConditionalContinousEffect(new UnblockableSourceEffect(Duration.WhileOnBattlefield), + new DefendingPlayerControlsArtifact(), + "{this} is unblockable as long as defending player controls an artifact"); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); } public ScrapdiverSerpent (final ScrapdiverSerpent card) { diff --git a/Mage.Sets/src/mage/sets/shadowmoor/InkfathomInfiltrator.java b/Mage.Sets/src/mage/sets/shadowmoor/InkfathomInfiltrator.java index a818fc8b16d..ad2ccbe2ea1 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/InkfathomInfiltrator.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/InkfathomInfiltrator.java @@ -53,7 +53,7 @@ public class InkfathomInfiltrator extends CardImpl { this.toughness = new MageInt(1); this.addAbility(CantBlockAbility.getInstance()); - this.addAbility(UnblockableAbility.getInstance()); + this.addAbility(new UnblockableAbility()); } public InkfathomInfiltrator(final InkfathomInfiltrator card) { diff --git a/Mage.Sets/src/mage/sets/shardsofalara/JhessianInfiltrator.java b/Mage.Sets/src/mage/sets/shardsofalara/JhessianInfiltrator.java index e4736c2eddc..2032f050f98 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/JhessianInfiltrator.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/JhessianInfiltrator.java @@ -50,7 +50,7 @@ public class JhessianInfiltrator extends CardImpl { this.color.setBlue(true); this.power = new MageInt(2); this.toughness = new MageInt(2); - this.addAbility(UnblockableAbility.getInstance()); + this.addAbility(new UnblockableAbility()); } public JhessianInfiltrator (final JhessianInfiltrator card) { diff --git a/Mage.Sets/src/mage/sets/urzasdestiny/BubblingBeebles.java b/Mage.Sets/src/mage/sets/urzasdestiny/BubblingBeebles.java index fd7df83b45b..53b9e058ebf 100644 --- a/Mage.Sets/src/mage/sets/urzasdestiny/BubblingBeebles.java +++ b/Mage.Sets/src/mage/sets/urzasdestiny/BubblingBeebles.java @@ -36,10 +36,8 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.Condition; import mage.abilities.decorator.ConditionalContinousEffect; -import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.continious.GainAbilitySourceEffect; -import mage.abilities.keyword.UnblockableAbility; +import mage.abilities.effects.common.UnblockableSourceEffect; import mage.cards.CardImpl; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -51,7 +49,6 @@ import mage.game.Game; */ public class BubblingBeebles extends CardImpl { - private static final String rule = "{this} is unblockable as long as defending player controls an enchantment"; private static final FilterPermanent filter = new FilterPermanent(); static { @@ -79,8 +76,9 @@ public class BubblingBeebles extends CardImpl { this.toughness = new MageInt(3); // Bubbling Beebles is unblockable as long as defending player controls an enchantment. - ContinuousEffect gainAbility = new GainAbilitySourceEffect(UnblockableAbility.getInstance(), Constants.Duration.WhileOnBattlefield); - Effect effect = new ConditionalContinousEffect(gainAbility, new DefendingPlayerControlsEnchantment(), rule); + Effect effect = new ConditionalContinousEffect(new UnblockableSourceEffect(Constants.Duration.WhileOnBattlefield), + new DefendingPlayerControlsEnchantment(), + "{this} is unblockable as long as defending player controls an enchantment"); this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, effect)); } diff --git a/Mage.Sets/src/mage/sets/urzaslegacy/BouncingBeebles.java b/Mage.Sets/src/mage/sets/urzaslegacy/BouncingBeebles.java index 5db60ff9427..eecd5f25c5e 100644 --- a/Mage.Sets/src/mage/sets/urzaslegacy/BouncingBeebles.java +++ b/Mage.Sets/src/mage/sets/urzaslegacy/BouncingBeebles.java @@ -32,15 +32,14 @@ import java.util.UUID; import mage.Constants; import mage.Constants.CardType; import mage.Constants.Rarity; +import mage.Constants.Zone; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.Condition; import mage.abilities.decorator.ConditionalContinousEffect; -import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.continious.GainAbilitySourceEffect; -import mage.abilities.keyword.UnblockableAbility; +import mage.abilities.effects.common.UnblockableSourceEffect; import mage.cards.CardImpl; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -52,7 +51,6 @@ import mage.game.Game; */ public class BouncingBeebles extends CardImpl { - private static final String rule = "Bouncing Beebles is unblockable as long as defending player controls an artifact"; private static final FilterPermanent filter = new FilterPermanent(); static { @@ -80,9 +78,10 @@ public class BouncingBeebles extends CardImpl { this.toughness = new MageInt(2); //Bouncing Beebles is unblockable as long as defending player controls an artifact. - ContinuousEffect gainAbility = new GainAbilitySourceEffect(UnblockableAbility.getInstance(), Constants.Duration.WhileOnBattlefield); - Effect effect = new ConditionalContinousEffect(gainAbility, new DefendingPlayerControlsArtifact(), rule); - this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, effect)); + Effect effect = new ConditionalContinousEffect(new UnblockableSourceEffect(), + new DefendingPlayerControlsArtifact(), + "Neurok Spy is unblockable as long as defending player controls an artifact"); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); } public BouncingBeebles(final BouncingBeebles card) { diff --git a/Mage.Sets/src/mage/sets/worldwake/CreepingTarPit.java b/Mage.Sets/src/mage/sets/worldwake/CreepingTarPit.java index 22e7b0bdd04..472d11a1173 100644 --- a/Mage.Sets/src/mage/sets/worldwake/CreepingTarPit.java +++ b/Mage.Sets/src/mage/sets/worldwake/CreepingTarPit.java @@ -79,6 +79,6 @@ class CreepingTarPitToken extends Token { color.setBlack(true); power = new MageInt(3); toughness = new MageInt(2); - this.addAbility(UnblockableAbility.getInstance()); + this.addAbility(new UnblockableAbility()); } } diff --git a/Mage.Sets/src/mage/sets/zendikar/AetherFigment.java b/Mage.Sets/src/mage/sets/zendikar/AetherFigment.java index 3afc7086f77..12e8ac55696 100644 --- a/Mage.Sets/src/mage/sets/zendikar/AetherFigment.java +++ b/Mage.Sets/src/mage/sets/zendikar/AetherFigment.java @@ -59,7 +59,7 @@ public class AetherFigment extends CardImpl { this.toughness = new MageInt(1); // AEther Figment is unblockable. - this.addAbility(UnblockableAbility.getInstance()); + this.addAbility(new UnblockableAbility()); // Kicker {3} this.getSpellAbility().addOptionalCost(new KickerManaCost("{3}")); diff --git a/Mage/src/mage/abilities/effects/common/UnblockableSourceEffect.java b/Mage/src/mage/abilities/effects/common/UnblockableSourceEffect.java new file mode 100644 index 00000000000..51ce92e1fbf --- /dev/null +++ b/Mage/src/mage/abilities/effects/common/UnblockableSourceEffect.java @@ -0,0 +1,71 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.abilities.effects.common; + +import mage.Constants.Duration; +import mage.abilities.Ability; +import mage.abilities.effects.RestrictionEffect; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author North + */ +public class UnblockableSourceEffect extends RestrictionEffect { + + public UnblockableSourceEffect() { + this(Duration.WhileOnBattlefield); + } + public UnblockableSourceEffect(Duration duration) { + super(duration); + this.staticText = "{this} is unblockable"; + if (Duration.EndOfTurn.equals(this.duration)) { + this.staticText += " this turn"; + } + } + + public UnblockableSourceEffect(UnblockableSourceEffect effect) { + super(effect); + } + + @Override + public UnblockableSourceEffect copy() { + return new UnblockableSourceEffect(this); + } + + @Override + public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game) { + return false; + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + return permanent.getId().equals(source.getSourceId()); + } +} diff --git a/Mage/src/mage/abilities/keyword/UnblockableAbility.java b/Mage/src/mage/abilities/keyword/UnblockableAbility.java index 79c82ba5b4a..e52360c0b4d 100644 --- a/Mage/src/mage/abilities/keyword/UnblockableAbility.java +++ b/Mage/src/mage/abilities/keyword/UnblockableAbility.java @@ -1,100 +1,50 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.abilities.keyword; -import mage.Constants.Duration; -import mage.abilities.Ability; import mage.abilities.EvasionAbility; -import mage.abilities.MageSingleton; -import mage.abilities.effects.RestrictionEffect; -import mage.game.Game; -import mage.game.permanent.Permanent; - -import java.io.ObjectStreamException; +import mage.abilities.effects.common.UnblockableSourceEffect; /** * @author BetaSteward_at_googlemail.com */ -public class UnblockableAbility extends EvasionAbility implements MageSingleton { +public class UnblockableAbility extends EvasionAbility { - private static final UnblockableAbility fINSTANCE = new UnblockableAbility(); - - private Object readResolve() throws ObjectStreamException { - return fINSTANCE; + public UnblockableAbility() { + this.addEffect(new UnblockableSourceEffect()); } - public static UnblockableAbility getInstance() { - return fINSTANCE; - } - - private UnblockableAbility() { - this.addEffect(new UnblockableEffect()); - } - - @Override - public String getRule() { - return "Unblockable"; + private UnblockableAbility(UnblockableAbility ability) { + super(ability); } @Override public UnblockableAbility copy() { - return fINSTANCE; + return new UnblockableAbility(this); } - } - -class UnblockableEffect extends RestrictionEffect implements MageSingleton { - - public UnblockableEffect() { - super(Duration.EndOfGame); - } - - public UnblockableEffect(final UnblockableEffect effect) { - super(effect); - } - - @Override - public boolean applies(Permanent permanent, Ability source, Game game) { - if (permanent.getAbilities().containsKey(UnblockableAbility.getInstance().getId())) { - return true; - } - return false; - } - - @Override - public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game) { - return false; - } - - @Override - public UnblockableEffect copy() { - return new UnblockableEffect(this); - } - -} \ No newline at end of file diff --git a/Mage/src/mage/util/trace/TraceUtil.java b/Mage/src/mage/util/trace/TraceUtil.java index 22287e11445..681861c4186 100644 --- a/Mage/src/mage/util/trace/TraceUtil.java +++ b/Mage/src/mage/util/trace/TraceUtil.java @@ -107,7 +107,6 @@ public class TraceUtil { log.error(uuid); log.error(uuid+"Flying ability id: " + FlyingAbility.getInstance().getId()); log.error(uuid+"Reach ability id: " + ReachAbility.getInstance().getId()); - log.error(uuid+"Unblockable ability id: " + UnblockableAbility.getInstance().getId()); log.error(uuid); log.error(uuid+"Restriction effects:");