diff --git a/Mage.Common/src/mage/view/CardView.java b/Mage.Common/src/mage/view/CardView.java
index 5be823cbe31..885d75593fe 100644
--- a/Mage.Common/src/mage/view/CardView.java
+++ b/Mage.Common/src/mage/view/CardView.java
@@ -186,16 +186,14 @@ public class CardView extends SimpleCardView {
this.rules.add("You may cast this card as a 2/2 face-down creature, with no text,"
+ " no name, no subtypes, and no mana cost by paying {3} rather than paying its mana cost.");
return;
+ } else if (card instanceof Permanent) {
+ this.power = Integer.toString(card.getPower().getValue());
+ this.toughness = Integer.toString(card.getToughness().getValue());
+ this.cardTypes = card.getCardType();
+ this.faceDown = ((Permanent) card).isFaceDown(game);
} else {
- if (card instanceof Permanent) {
- this.power = Integer.toString(card.getPower().getValue());
- this.toughness = Integer.toString(card.getToughness().getValue());
- this.cardTypes = card.getCardType();
- this.faceDown = ((Permanent) card).isFaceDown(game);
- } else {
- // this.hideInfo = true;
- return;
- }
+ // this.hideInfo = true;
+ return;
}
}
@@ -203,18 +201,16 @@ public class CardView extends SimpleCardView {
if (card.isSplitCard()) {
splitCard = (SplitCard) card;
rotate = true;
- } else {
- if (card instanceof Spell) {
- switch (((Spell) card).getSpellAbility().getSpellAbilityType()) {
- case SPLIT_FUSED:
- splitCard = (SplitCard) ((Spell) card).getCard();
- rotate = true;
- break;
- case SPLIT_LEFT:
- case SPLIT_RIGHT:
- rotate = true;
- break;
- }
+ } else if (card instanceof Spell) {
+ switch (((Spell) card).getSpellAbility().getSpellAbilityType()) {
+ case SPLIT_FUSED:
+ splitCard = (SplitCard) ((Spell) card).getCard();
+ rotate = true;
+ break;
+ case SPLIT_LEFT:
+ case SPLIT_RIGHT:
+ rotate = true;
+ break;
}
}
if (splitCard != null) {
@@ -241,7 +237,7 @@ public class CardView extends SimpleCardView {
this.mageObjectType = MageObjectType.PERMANENT;
Permanent permanent = (Permanent) card;
this.loyalty = Integer.toString(permanent.getCounters().getCount(CounterType.LOYALTY));
- this.pairedCard = permanent.getPairedCard();
+ this.pairedCard = permanent.getPairedCard() != null ? permanent.getPairedCard().getSourceId() : null;
if (!permanent.getControllerId().equals(permanent.getOwnerId())) {
controlledByOwner = false;
}
@@ -421,12 +417,10 @@ public class CardView extends SimpleCardView {
if (card != null) {
if (card instanceof Permanent) {
this.mageObjectType = MageObjectType.PERMANENT;
+ } else if (card.isCopy()) {
+ this.mageObjectType = MageObjectType.COPY_CARD;
} else {
- if (card.isCopy()) {
- this.mageObjectType = MageObjectType.COPY_CARD;
- } else {
- this.mageObjectType = MageObjectType.CARD;
- }
+ this.mageObjectType = MageObjectType.CARD;
}
if (card instanceof PermanentToken) {
this.mageObjectType = MageObjectType.TOKEN;
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/DeadeyeNavigator.java b/Mage.Sets/src/mage/sets/avacynrestored/DeadeyeNavigator.java
index 88addcc3e72..f5b882ffb0c 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/DeadeyeNavigator.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/DeadeyeNavigator.java
@@ -58,7 +58,7 @@ public class DeadeyeNavigator extends CardImpl {
this.toughness = new MageInt(5);
// Soulbond
- this.addAbility(SoulbondAbility.getInstance());
+ this.addAbility(new SoulbondAbility());
// As long as Deadeye Navigator is paired with another creature, each of those creatures has "{1}{U}: Exile this creature, then return it to the battlefield under your control."
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileSourceEffect(true), new ManaCostsImpl("{1}{U}"));
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/DiregrafEscort.java b/Mage.Sets/src/mage/sets/avacynrestored/DiregrafEscort.java
index 8f3f2a08be5..15e7377ee4b 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/DiregrafEscort.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/DiregrafEscort.java
@@ -64,7 +64,7 @@ public class DiregrafEscort extends CardImpl {
this.toughness = new MageInt(1);
// Soulbond
- this.addAbility(SoulbondAbility.getInstance());
+ this.addAbility(new SoulbondAbility());
// As long as Diregraf Escort is paired with another creature, both creatures have protection from Zombies.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityPairedEffect(new ProtectionAbility(filter), ruleText)));
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/DruidsFamiliar.java b/Mage.Sets/src/mage/sets/avacynrestored/DruidsFamiliar.java
index 026de8d4fbc..1e1588e616f 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/DruidsFamiliar.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/DruidsFamiliar.java
@@ -55,7 +55,7 @@ public class DruidsFamiliar extends CardImpl {
this.toughness = new MageInt(2);
// Soulbond
- this.addAbility(SoulbondAbility.getInstance());
+ this.addAbility(new SoulbondAbility());
// As long as Druid's Familiar is paired with another creature, each of those creatures gets +2/+2.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostPairedEffect(2, 2, ruleText)));
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/ElgaudShieldmate.java b/Mage.Sets/src/mage/sets/avacynrestored/ElgaudShieldmate.java
index 65af29ca5c7..3ec6a556266 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/ElgaudShieldmate.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/ElgaudShieldmate.java
@@ -55,7 +55,7 @@ public class ElgaudShieldmate extends CardImpl {
this.toughness = new MageInt(3);
// Soulbond
- this.addAbility(SoulbondAbility.getInstance());
+ this.addAbility(new SoulbondAbility());
// As long as Elgaud Shieldmate is paired with another creature, both creatures have hexproof.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityPairedEffect(HexproofAbility.getInstance(), ruleText)));
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/FloweringLumberknot.java b/Mage.Sets/src/mage/sets/avacynrestored/FloweringLumberknot.java
index 397163a3caf..2a6a99d2d61 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/FloweringLumberknot.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/FloweringLumberknot.java
@@ -27,21 +27,20 @@
*/
package mage.sets.avacynrestored;
-import mage.constants.CardType;
-import mage.constants.Rarity;
+import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.RestrictionEffect;
import mage.abilities.keyword.SoulbondAbility;
import mage.cards.CardImpl;
+import mage.constants.CardType;
import mage.constants.Duration;
+import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
-import java.util.UUID;
-
/**
* @author noxx
*/
@@ -83,17 +82,26 @@ class FloweringLumberknotEffect extends RestrictionEffect {
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
if (permanent.getId().equals(source.getSourceId())) {
- if (permanent.getPairedCard() == null) {
- return true; // not paired => can't attack or block
+ if (permanent.getPairedCard() != null) {
+ Permanent paired = permanent.getPairedCard().getPermanent(game);
+ if (paired != null) {
+ boolean found = false;
+ for (Ability ability : paired.getAbilities(game)) {
+ if (ability instanceof SoulbondAbility) {
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ return false;// paired => can attack or block
+ }
+ }
}
- Permanent paired = game.getPermanent(permanent.getPairedCard());
- if (paired != null && paired.getAbilities().contains(SoulbondAbility.getInstance())) {
- return false; // paired => can attack or block
- }
- // can't attack or block otherwise
+ // can't attack or block
return true;
}
return false;
+
}
@Override
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/GalvanicAlchemist.java b/Mage.Sets/src/mage/sets/avacynrestored/GalvanicAlchemist.java
index d29e9b8226d..5155169cc51 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/GalvanicAlchemist.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/GalvanicAlchemist.java
@@ -58,7 +58,7 @@ public class GalvanicAlchemist extends CardImpl {
this.toughness = new MageInt(4);
// Soulbond
- this.addAbility(SoulbondAbility.getInstance());
+ this.addAbility(new SoulbondAbility());
// As long as Galvanic Alchemist is paired with another creature, each of those creatures has "{2}{U}: Untap this creature."
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new UntapSourceEffect(), new ManaCostsImpl("{2}{U}"));
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/GeistTrappers.java b/Mage.Sets/src/mage/sets/avacynrestored/GeistTrappers.java
index b9548a39b42..03643b1748e 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/GeistTrappers.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/GeistTrappers.java
@@ -55,7 +55,7 @@ public class GeistTrappers extends CardImpl {
this.toughness = new MageInt(5);
// Soulbond
- this.addAbility(SoulbondAbility.getInstance());
+ this.addAbility(new SoulbondAbility());
// As long as Geist Trappers is paired with another creature, both creatures have reach.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityPairedEffect(ReachAbility.getInstance(), ruleText)));
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/HanweirLancer.java b/Mage.Sets/src/mage/sets/avacynrestored/HanweirLancer.java
index 6afd6a9aba1..d7c41a478bf 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/HanweirLancer.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/HanweirLancer.java
@@ -55,7 +55,7 @@ public class HanweirLancer extends CardImpl {
this.toughness = new MageInt(2);
// Soulbond
- this.addAbility(SoulbondAbility.getInstance());
+ this.addAbility(new SoulbondAbility());
// As long as Hanweir Lancer is paired with another creature, both creatures have first strike.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityPairedEffect(FirstStrikeAbility.getInstance(), ruleText)));
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/JointAssault.java b/Mage.Sets/src/mage/sets/avacynrestored/JointAssault.java
index c625f1f5f24..701cb39e7ff 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/JointAssault.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/JointAssault.java
@@ -27,21 +27,21 @@
*/
package mage.sets.avacynrestored;
-import mage.constants.CardType;
-import mage.constants.Rarity;
+import java.util.UUID;
+import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.CardImpl;
+import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
+import mage.constants.Rarity;
import mage.constants.SubLayer;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
-import java.util.UUID;
-
/**
* @author noxx
*/
@@ -51,7 +51,6 @@ public class JointAssault extends CardImpl {
super(ownerId, 183, "Joint Assault", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{G}");
this.expansionSetCode = "AVR";
-
// Target creature gets +2/+2 until end of turn. If it's paired with a creature, that creature also gets +2/+2 until end of turn.
this.getSpellAbility().addEffect(new JointAssaultBoostTargetEffect(2, 2, Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
@@ -69,9 +68,9 @@ public class JointAssault extends CardImpl {
class JointAssaultBoostTargetEffect extends ContinuousEffectImpl {
- private int power;
- private int toughness;
- private UUID paired;
+ private final int power;
+ private final int toughness;
+ private MageObjectReference paired;
public JointAssaultBoostTargetEffect(int power, int toughness, Duration duration) {
super(duration, Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, Outcome.BoostCreature);
@@ -116,10 +115,10 @@ class JointAssaultBoostTargetEffect extends ContinuousEffectImpl {
}
if (this.paired != null) {
- Permanent paired = game.getPermanent(this.paired);
- if (paired != null) {
- paired.addPower(power);
- paired.addToughness(toughness);
+ Permanent pairedPermanent = this.paired.getPermanent(game);
+ if (pairedPermanent != null) {
+ pairedPermanent.addPower(power);
+ pairedPermanent.addToughness(toughness);
affectedTargets++;
}
}
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/LightningMauler.java b/Mage.Sets/src/mage/sets/avacynrestored/LightningMauler.java
index 4cd01414af0..470d291dabe 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/LightningMauler.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/LightningMauler.java
@@ -57,7 +57,7 @@ public class LightningMauler extends CardImpl {
this.toughness = new MageInt(1);
// Soulbond
- this.addAbility(SoulbondAbility.getInstance());
+ this.addAbility(new SoulbondAbility());
// As long as Lightning Mauler is paired with another creature, both creatures have haste.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityPairedEffect(HasteAbility.getInstance(), ruleText)));
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/NearheathPilgrim.java b/Mage.Sets/src/mage/sets/avacynrestored/NearheathPilgrim.java
index 05f5c75bd02..cb2461a1011 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/NearheathPilgrim.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/NearheathPilgrim.java
@@ -55,7 +55,7 @@ public class NearheathPilgrim extends CardImpl {
this.toughness = new MageInt(1);
// Soulbond
- this.addAbility(SoulbondAbility.getInstance());
+ this.addAbility(new SoulbondAbility());
// As long as Nearheath Pilgrim is paired with another creature, both creatures have lifelink.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityPairedEffect(LifelinkAbility.getInstance(), ruleText)));
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/NightshadePeddler.java b/Mage.Sets/src/mage/sets/avacynrestored/NightshadePeddler.java
index 92b146acf25..9209cf8bf91 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/NightshadePeddler.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/NightshadePeddler.java
@@ -55,7 +55,7 @@ public class NightshadePeddler extends CardImpl {
this.toughness = new MageInt(1);
// Soulbond
- this.addAbility(SoulbondAbility.getInstance());
+ this.addAbility(new SoulbondAbility());
// As long as Nightshade Peddler is paired with another creature, both creatures have deathtouch.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityPairedEffect(DeathtouchAbility.getInstance(), ruleText)));
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/PathbreakerWurm.java b/Mage.Sets/src/mage/sets/avacynrestored/PathbreakerWurm.java
index 9efa9431ae5..5a6c1b5c9cb 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/PathbreakerWurm.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/PathbreakerWurm.java
@@ -54,7 +54,7 @@ public class PathbreakerWurm extends CardImpl {
this.toughness = new MageInt(4);
// Soulbond
- this.addAbility(SoulbondAbility.getInstance());
+ this.addAbility(new SoulbondAbility());
// As long as Pathbreaker Wurm is paired with another creature, both creatures have trample.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityPairedEffect(TrampleAbility.getInstance(), ruleText)));
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/SilverbladePaladin.java b/Mage.Sets/src/mage/sets/avacynrestored/SilverbladePaladin.java
index e37cfe7e501..0a3e36f8652 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/SilverbladePaladin.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/SilverbladePaladin.java
@@ -55,7 +55,7 @@ public class SilverbladePaladin extends CardImpl {
this.toughness = new MageInt(2);
// Soulbond
- this.addAbility(SoulbondAbility.getInstance());
+ this.addAbility(new SoulbondAbility());
// As long as Silverblade Paladin is paired with another creature, both creatures have double strike.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityPairedEffect(DoubleStrikeAbility.getInstance(), ruleText)));
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/SpectralGateguards.java b/Mage.Sets/src/mage/sets/avacynrestored/SpectralGateguards.java
index 77efc0a7e49..e1b0e2d1eb4 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/SpectralGateguards.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/SpectralGateguards.java
@@ -55,7 +55,7 @@ public class SpectralGateguards extends CardImpl {
this.toughness = new MageInt(5);
// Soulbond
- this.addAbility(SoulbondAbility.getInstance());
+ this.addAbility(new SoulbondAbility());
// As long as Spectral Gateguards is paired with another creature, both creatures have vigilance.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityPairedEffect(VigilanceAbility.getInstance(), ruleText)));
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/SternMentor.java b/Mage.Sets/src/mage/sets/avacynrestored/SternMentor.java
index feb58ede09a..4e1006f01de 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/SternMentor.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/SternMentor.java
@@ -59,7 +59,7 @@ public class SternMentor extends CardImpl {
this.toughness = new MageInt(2);
// Soulbond
- this.addAbility(SoulbondAbility.getInstance());
+ this.addAbility(new SoulbondAbility());
// As long as Stern Mentor is paired with another creature, each of those creatures has "{T}: Target player puts the top two cards of his or her library into his or her graveyard."
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutLibraryIntoGraveTargetEffect(2), new TapSourceCost());
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/Stonewright.java b/Mage.Sets/src/mage/sets/avacynrestored/Stonewright.java
index cfb262d43fc..ab0116c728e 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/Stonewright.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/Stonewright.java
@@ -59,7 +59,7 @@ public class Stonewright extends CardImpl {
this.toughness = new MageInt(1);
// Soulbond
- this.addAbility(SoulbondAbility.getInstance());
+ this.addAbility(new SoulbondAbility());
// As long as Stonewright is paired with another creature, each of those creatures has "{R}: This creature gets +1/+0 until end of turn."
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 0, Duration.EndOfTurn), new ManaCostsImpl("{R}"));
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/TandemLookout.java b/Mage.Sets/src/mage/sets/avacynrestored/TandemLookout.java
index a2cec673f68..4d9f26a803f 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/TandemLookout.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/TandemLookout.java
@@ -57,7 +57,7 @@ public class TandemLookout extends CardImpl {
this.toughness = new MageInt(1);
// Soulbond
- this.addAbility(SoulbondAbility.getInstance());
+ this.addAbility(new SoulbondAbility());
// As long as Tandem Lookout is paired with another creature, each of those creatures has "Whenever this creature deals damage to an opponent, draw a card."
Ability ability = new DealsDamageToOpponentTriggeredAbility(new DrawCardSourceControllerEffect(1));
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/TrustedForcemage.java b/Mage.Sets/src/mage/sets/avacynrestored/TrustedForcemage.java
index d7f87bea1bd..fb67db8533f 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/TrustedForcemage.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/TrustedForcemage.java
@@ -54,7 +54,7 @@ public class TrustedForcemage extends CardImpl {
this.toughness = new MageInt(2);
// Soulbond
- this.addAbility(SoulbondAbility.getInstance());
+ this.addAbility(new SoulbondAbility());
// As long as Trusted Forcemage is paired with another creature, each of those creatures gets +1/+1.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostPairedEffect(1, 1, ruleText)));
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/Wingcrafter.java b/Mage.Sets/src/mage/sets/avacynrestored/Wingcrafter.java
index 35cba6a297b..11104a704dc 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/Wingcrafter.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/Wingcrafter.java
@@ -57,7 +57,7 @@ public class Wingcrafter extends CardImpl {
this.toughness = new MageInt(1);
// Soulbond
- this.addAbility(SoulbondAbility.getInstance());
+ this.addAbility(new SoulbondAbility());
// As long as Wingcrafter is paired with another creature, both creatures have flying.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityPairedEffect(FlyingAbility.getInstance(), ruleText)));
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/WolfirSilverheart.java b/Mage.Sets/src/mage/sets/avacynrestored/WolfirSilverheart.java
index 76e751edc66..63f706ce094 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/WolfirSilverheart.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/WolfirSilverheart.java
@@ -54,7 +54,7 @@ public class WolfirSilverheart extends CardImpl {
this.toughness = new MageInt(4);
// Soulbond
- this.addAbility(SoulbondAbility.getInstance());
+ this.addAbility(new SoulbondAbility());
// As long as Wolfir Silverheart is paired with another creature, each of those creatures gets +4/+4.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostPairedEffect(4, 4, ruleText)));
diff --git a/Mage.Sets/src/mage/sets/magic2012/PhantasmalBear.java b/Mage.Sets/src/mage/sets/magic2012/PhantasmalBear.java
index d8b971a44f0..d26375c8063 100644
--- a/Mage.Sets/src/mage/sets/magic2012/PhantasmalBear.java
+++ b/Mage.Sets/src/mage/sets/magic2012/PhantasmalBear.java
@@ -28,12 +28,12 @@
package mage.sets.magic2012;
import java.util.UUID;
-import mage.constants.CardType;
-import mage.constants.Rarity;
import mage.MageInt;
import mage.abilities.common.BecomesTargetTriggeredAbility;
import mage.abilities.effects.common.SacrificeSourceEffect;
import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Rarity;
/**
*
@@ -50,6 +50,7 @@ public class PhantasmalBear extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(2);
+ // When Phantasmal Bear becomes the target of a spell or ability, sacrifice it.
this.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()));
}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SoulbondKeywordTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SoulbondKeywordTest.java
index 94afd71874a..f1f1d9c0717 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SoulbondKeywordTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SoulbondKeywordTest.java
@@ -9,7 +9,6 @@ import mage.constants.Zone;
import mage.filter.Filter;
import mage.game.permanent.Permanent;
import org.junit.Assert;
-import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
@@ -318,9 +317,12 @@ public class SoulbondKeywordTest extends CardTestPlayerBase {
*/
@Test
public void testRebondOnNextCreature() {
- addCard(Zone.BATTLEFIELD, playerA, "Elite Vanguard");
+ // When Phantasmal Bear becomes the target of a spell or ability, sacrifice it.
addCard(Zone.HAND, playerA, "Phantasmal Bear");
+ // Soulbond
+ // As long as Trusted Forcemage is paired with another creature, each of those creatures gets +1/+1.
addCard(Zone.HAND, playerA, "Trusted Forcemage");
+ addCard(Zone.BATTLEFIELD, playerA, "Elite Vanguard"); // 2/1
addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
@@ -329,10 +331,10 @@ public class SoulbondKeywordTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Lightning Bolt", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Trusted Forcemage");
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Elite Vanguard");
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phantasmal Bear");
+ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", "Elite Vanguard");
+ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Phantasmal Bear");
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ setStopAt(1, PhaseStep.END_TURN);
execute();
assertPermanentCount(playerA, "Elite Vanguard", 0);
@@ -347,7 +349,9 @@ public class SoulbondKeywordTest extends CardTestPlayerBase {
*/
@Test
public void testGrantingAbility() {
- addCard(Zone.BATTLEFIELD, playerA, "Elite Vanguard");
+ addCard(Zone.BATTLEFIELD, playerA, "Elite Vanguard"); // 2/1
+ // Soulbond
+ // As long as Nearheath Pilgrim is paired with another creature, both creatures have lifelink.
addCard(Zone.HAND, playerA, "Nearheath Pilgrim");
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
@@ -391,42 +395,39 @@ public class SoulbondKeywordTest extends CardTestPlayerBase {
Assert.assertEquals(trustedForcemange.getPairedCard(), null);
Assert.assertEquals(eliteVanguard.getPairedCard(), null);
}
-
+
/*
* Reported bug: Soulbond should use the stack, but unable to use instant speed removal since no trigger occurs
- */
+ */
@Test
- @Ignore
// Soulbond does not currently use the stack, so this test will fail until then
public void testRespondToSoulboundWithRemoval() {
-
+
// When Palinchron enters the battlefield, untap up to seven lands.
// {2}{U}{U}: Return Palinchron to its owner's hand.
addCard(Zone.BATTLEFIELD, playerA, "Palinchron"); // 4/5 flying
-
+
// Soulbond
// As long as Deadeye Navigator is paired with another creature, each of those creatures has "{1}{U}: Exile this creature, then return it to the battlefield under your control."
addCard(Zone.HAND, playerA, "Deadeye Navigator"); // 5/5
addCard(Zone.BATTLEFIELD, playerA, "Island", 8);
- addCard(Zone.BATTLEFIELD, playerB, "Doom Blade", 1); // {1}{B} instant: Destroy target non-black creature
+ addCard(Zone.HAND, playerB, "Doom Blade", 1); // {1}{B} instant: Destroy target non-black creature
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
-
+
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Deadeye Navigator");
setChoice(playerA, "Yes");
- addTarget(playerA, "Palinchron");
+ setChoice(playerA, "Palinchron");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Doom Blade", "Deadeye Navigator");
-
- // Deadeye's ability should not be usable since was Destroyed before Soulbond trigger resolved
+
+ // Deadeye's ability should not be usable since was destroyed before Soulbond trigger resolved
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{U}:");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
-
+
Permanent palinchron = getPermanent("Palinchron", playerA);
- Permanent deadeye = getPermanent("Deadeye Navigator", playerA);
Assert.assertEquals(null, palinchron.getPairedCard()); // should not be paired
- Assert.assertEquals(null, deadeye.getPairedCard()); // should not be paired
- assertGraveyardCount(playerA, "Deadeye Navigator", 1);
- assertGraveyardCount(playerB, "Doom Blade", 1);
+ assertGraveyardCount(playerA, "Deadeye Navigator", 1);
+ assertGraveyardCount(playerB, "Doom Blade", 1);
assertPermanentCount(playerA, "Palinchron", 1);
}
}
diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostPairedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostPairedEffect.java
index b9651c6e985..8cad96f84c7 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostPairedEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostPairedEffect.java
@@ -24,16 +24,15 @@
* 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.continuous;
+import mage.abilities.Ability;
+import mage.abilities.effects.ContinuousEffectImpl;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
-import mage.abilities.Ability;
-import mage.abilities.effects.ContinuousEffectImpl;
import mage.game.Game;
import mage.game.permanent.Permanent;
@@ -68,7 +67,7 @@ public class BoostPairedEffect extends ContinuousEffectImpl {
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null && permanent.getPairedCard() != null) {
- Permanent paired = game.getPermanent(permanent.getPairedCard());
+ Permanent paired = permanent.getPairedCard().getPermanent(game);
if (paired != null) {
permanent.addPower(power);
permanent.addToughness(toughness);
diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityPairedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityPairedEffect.java
index 686b7f0a525..ff651cb4138 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityPairedEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityPairedEffect.java
@@ -1,16 +1,16 @@
/*
* 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
@@ -20,20 +20,20 @@
* 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.continuous;
+import mage.MageObjectReference;
+import mage.abilities.Ability;
+import mage.abilities.effects.ContinuousEffectImpl;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
-import mage.abilities.Ability;
-import mage.abilities.effects.ContinuousEffectImpl;
import mage.game.Game;
import mage.game.permanent.Permanent;
@@ -66,11 +66,15 @@ public class GainAbilityPairedEffect extends ContinuousEffectImpl {
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null && permanent.getPairedCard() != null) {
- Permanent paired = game.getPermanent(permanent.getPairedCard());
- if (paired != null) {
- permanent.addAbility(ability, game);
+ Permanent paired = permanent.getPairedCard().getPermanent(game);
+ if (paired != null && paired.getPairedCard() != null && paired.getPairedCard().equals(new MageObjectReference(permanent, game))) {
+ permanent.addAbility(ability, source.getSourceId(), game);
paired.addAbility(ability, source.getSourceId(), game, false);
return true;
+
+ } else {
+ // No longer the same cards as orininally paired.
+ permanent.setPairedCard(null);
}
}
return false;
diff --git a/Mage/src/main/java/mage/abilities/keyword/SoulbondAbility.java b/Mage/src/main/java/mage/abilities/keyword/SoulbondAbility.java
index f8150ded958..1029ffc903a 100644
--- a/Mage/src/main/java/mage/abilities/keyword/SoulbondAbility.java
+++ b/Mage/src/main/java/mage/abilities/keyword/SoulbondAbility.java
@@ -24,32 +24,71 @@
* 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 java.io.ObjectStreamException;
-import mage.abilities.MageSingleton;
-import mage.abilities.StaticAbility;
+import mage.MageObjectReference;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SetTargetPointer;
+import mage.constants.TargetController;
import mage.constants.Zone;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicate;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.filter.predicate.permanent.ControllerPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.common.TargetControlledPermanent;
/**
- * @author noxx
+ * 702.94. Soulbond
+ *
+ * 702.94a Soulbond is a keyword that represents two triggered abilities.
+ * “Soulbond” means “When this creature enters the battlefield, if you control
+ * both this creature and another creature and both are unpaired, you may pair
+ * this creature with another unpaired creature you control for as long as both
+ * remain creatures on the battlefield under your control” and “Whenever another
+ * creature enters the battlefield under your control, if you control both that
+ * creature and this one and both are unpaired, you may pair that creature with
+ * this creature for as long as both remain creatures on the battlefield under
+ * your control.”
+ *
+ * 702.94b A creature becomes “paired” with another as the result of a soulbond
+ * ability. Abilities may refer to a paired creature, the creature another
+ * creature is paired with, or whether a creature is paired. An “unpaired”
+ * creature is one that is not paired.
+ *
+ * 702.94c When the soulbond ability resolves, if either object that would be
+ * paired is no longer a creature, no longer on the battlefield, or no longer
+ * under the control of the player who controls the soulbond ability, neither
+ * object becomes paired.
+ *
+ * 702.94d A creature can be paired with only one other creature.
+ *
+ * 702.94e A paired creature becomes unpaired if any of the following occur:
+ * another player gains control of it or the creature it’s paired with; it or
+ * the creature it’s paired with stops being a creature; or it or the creature
+ * it’s paired with leaves the battlefield.
+ *
+ * @author LevelX2
*/
-public class SoulbondAbility extends StaticAbility implements MageSingleton {
+public class SoulbondAbility extends EntersBattlefieldTriggeredAbility {
- private static final SoulbondAbility fINSTANCE = new SoulbondAbility();
-
- private Object readResolve() throws ObjectStreamException {
- return fINSTANCE;
+ public SoulbondAbility() {
+ super(new SoulboundEntersSelfEffect(), true);
+ this.addSubAbility(new SoulbondEntersOtherAbility());
}
- public static SoulbondAbility getInstance() {
- return fINSTANCE;
- }
-
- private SoulbondAbility() {
- super(Zone.BATTLEFIELD, null);
+ public SoulbondAbility(SoulbondAbility ability) {
+ super(ability);
}
@Override
@@ -57,9 +96,200 @@ public class SoulbondAbility extends StaticAbility implements MageSingleton {
return "Soulbond (You may pair this creature with another unpaired creature when either enters the battlefield. They remain paired for as long as you control both of them.)";
}
+ @Override
+ public boolean checkInterveningIfClause(Game game) {
+ // if you control both this creature and another creature and both are unpaired
+ boolean self = false;
+ boolean other = false;
+ for (Permanent permanent : game.getBattlefield().getAllActivePermanents(getControllerId())) {
+ if (permanent.getCardType().contains(CardType.CREATURE)) {
+ if (permanent.getId().equals(getSourceId())) {
+ if (permanent.getControllerId().equals(getControllerId())) {
+ self = true;
+ if (other) {
+ return true;
+ }
+ } else {
+ return false;
+ }
+ } else if (permanent.getPairedCard() == null) {
+ other = true;
+ if (self) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
@Override
public SoulbondAbility copy() {
- return fINSTANCE;
+ return new SoulbondAbility(this);
+
+ }
+
+}
+// When this creature enters the battlefield, if you control both this creature and another creature and both are unpaired, you may pair
+// this creature with another unpaired creature you control for as long as both remain creatures on the battlefield under your control
+
+class SoulboundEntersSelfEffect extends OneShotEffect {
+
+ private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("another not paired creature you control");
+
+ static {
+ filter.add(new AnotherPredicate());
+ filter.add(Predicates.not(new PairedPredicate()));
+ }
+
+ public SoulboundEntersSelfEffect() {
+ super(Outcome.Benefit);
+ }
+
+ public SoulboundEntersSelfEffect(final SoulboundEntersSelfEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public SoulboundEntersSelfEffect copy() {
+ return new SoulboundEntersSelfEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent permanent = game.getPermanent(source.getSourceId());
+ if (permanent != null && permanent.getCardType().contains(CardType.CREATURE)) {
+ Player controller = game.getPlayer(permanent.getControllerId());
+ if (controller != null) {
+ TargetControlledPermanent target = new TargetControlledPermanent(filter);
+ target.setNotTarget(true);
+ if (target.canChoose(permanent.getId(), controller.getId(), game)) {
+ if (controller.choose(Outcome.Benefit, target, permanent.getId(), game)) {
+ Permanent chosen = game.getPermanent(target.getFirstTarget());
+ if (chosen != null) {
+ chosen.setPairedCard(new MageObjectReference(permanent, game));
+ permanent.setPairedCard(new MageObjectReference(chosen, game));
+ if (!game.isSimulation()) {
+ game.informPlayers(controller.getLogName() + " soulbonds " + permanent.getLogName() + " with " + chosen.getLogName());
+ }
+ }
+ }
+ }
+
+ }
+ return true;
+ }
+ return false;
+ }
+}
+
+/**
+ * “Whenever another creature enters the battlefield under your control, if you
+ * control both that creature and this one and both are unpaired, you may pair
+ * that creature with this creature for as long as both remain creatures on the
+ * battlefield under your control.”
+ *
+ */
+class SoulbondEntersOtherAbility extends EntersBattlefieldAllTriggeredAbility {
+
+ private final static FilterCreaturePermanent soulbondFilter = new FilterCreaturePermanent();
+
+ static {
+ soulbondFilter.add(Predicates.not(new PairedPredicate()));
+ soulbondFilter.add(new ControllerPredicate(TargetController.YOU));
+ soulbondFilter.add(new AnotherPredicate());
+ }
+
+ public SoulbondEntersOtherAbility() {
+ super(Zone.BATTLEFIELD, new SoulboundEntersOtherEffect(), soulbondFilter, true, SetTargetPointer.PERMANENT, "");
+ setRuleVisible(false);
+ }
+
+ public SoulbondEntersOtherAbility(SoulbondEntersOtherAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public String getRule() {
+ return "Soulbond (You may pair this creature with another unpaired creature when either enters the battlefield. They remain paired for as long as you control both of them.)";
+ }
+
+ @Override
+ public boolean checkInterveningIfClause(Game game) {
+ // if you control both this creature and another creature and both are unpaired
+ if (game.getBattlefield().countAll(filter, getControllerId(), game) > 0) {
+ Permanent sourcePermanent = game.getPermanent(getSourceId());
+ if (sourcePermanent != null && sourcePermanent.getControllerId().equals(getControllerId()) && sourcePermanent.getPairedCard() == null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public SoulbondEntersOtherAbility copy() {
+ return new SoulbondEntersOtherAbility(this);
+ }
+
+}
+
+class SoulboundEntersOtherEffect extends OneShotEffect {
+
+ private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("another not paired creature you control");
+
+ static {
+ filter.add(new AnotherPredicate());
+ filter.add(Predicates.not(new PairedPredicate()));
+ }
+
+ public SoulboundEntersOtherEffect() {
+ super(Outcome.Benefit);
+ }
+
+ public SoulboundEntersOtherEffect(final SoulboundEntersOtherEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public SoulboundEntersOtherEffect copy() {
+ return new SoulboundEntersOtherEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent permanent = game.getPermanent(source.getSourceId());
+ if (permanent != null && permanent.getPairedCard() == null
+ && permanent.getCardType().contains(CardType.CREATURE)) {
+ Player controller = game.getPlayer(permanent.getControllerId());
+ if (controller != null) {
+ Permanent enteringPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
+ if (enteringPermanent != null && enteringPermanent.getCardType().contains(CardType.CREATURE) && enteringPermanent.getPairedCard() == null) {
+ enteringPermanent.setPairedCard(new MageObjectReference(permanent, game));
+ permanent.setPairedCard(new MageObjectReference(enteringPermanent, game));
+ if (!game.isSimulation()) {
+ game.informPlayers(controller.getLogName() + " soulbonds " + permanent.getLogName() + " with " + enteringPermanent.getLogName());
+ }
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+}
+
+class PairedPredicate implements Predicate {
+
+ @Override
+ public boolean apply(Permanent input, Game game) {
+ return input.getPairedCard() != null;
+ }
+
+ @Override
+ public String toString() {
+ return "Paired";
}
}
diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java
index defd8d18293..4ba9f91b1e8 100644
--- a/Mage/src/main/java/mage/game/GameImpl.java
+++ b/Mage/src/main/java/mage/game/GameImpl.java
@@ -131,7 +131,6 @@ import mage.watchers.common.DamageDoneWatcher;
import mage.watchers.common.MorbidWatcher;
import mage.watchers.common.PlayerDamagedBySourceWatcher;
import mage.watchers.common.PlayerLostLifeWatcher;
-import mage.watchers.common.SoulbondWatcher;
import org.apache.log4j.Logger;
public abstract class GameImpl implements Game, Serializable {
@@ -1007,7 +1006,6 @@ public abstract class GameImpl implements Game, Serializable {
}
watchers.add(new MorbidWatcher());
watchers.add(new CastSpellLastTurnWatcher());
- watchers.add(new SoulbondWatcher());
watchers.add(new PlayerLostLifeWatcher());
watchers.add(new BlockedAttackerWatcher());
watchers.add(new DamageDoneWatcher());
@@ -1687,7 +1685,7 @@ public abstract class GameImpl implements Game, Serializable {
if (perm.getPairedCard() != null) {
//702.93e.: ...another player gains control
// ...or the creature it's paired with leaves the battlefield.
- Permanent paired = getPermanent(perm.getPairedCard());
+ Permanent paired = perm.getPairedCard().getPermanent(this);
if (paired == null || !perm.getControllerId().equals(paired.getControllerId()) || paired.getPairedCard() == null) {
perm.setPairedCard(null);
if (paired != null) {
@@ -1698,7 +1696,7 @@ public abstract class GameImpl implements Game, Serializable {
}
} else if (perm.getPairedCard() != null) {
//702.93e.: ...stops being a creature
- Permanent paired = getPermanent(perm.getPairedCard());
+ Permanent paired = perm.getPairedCard().getPermanent(this);
perm.setPairedCard(null);
if (paired != null) {
paired.setPairedCard(null);
diff --git a/Mage/src/main/java/mage/game/permanent/Permanent.java b/Mage/src/main/java/mage/game/permanent/Permanent.java
index 3e0429d6acf..a7497bb4c57 100644
--- a/Mage/src/main/java/mage/game/permanent/Permanent.java
+++ b/Mage/src/main/java/mage/game/permanent/Permanent.java
@@ -327,14 +327,14 @@ public interface Permanent extends Card, Controllable {
*
* @param pairedCard
*/
- void setPairedCard(UUID pairedCard);
+ void setPairedCard(MageObjectReference pairedCard);
/**
* Gets paired card. Can return null.
*
* @return
*/
- UUID getPairedCard();
+ MageObjectReference getPairedCard();
/**
* Makes permanent paired with no other permanent.
diff --git a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java
index 7e5de9d2bc5..16a1726137c 100644
--- a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java
+++ b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java
@@ -116,7 +116,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
protected HashSet dealtDamageByThisTurn;
protected UUID attachedTo;
protected int attachedToZoneChangeCounter;
- protected UUID pairedCard;
+ protected MageObjectReference pairedPermanent;
protected Counters counters;
protected List markedDamage;
protected int timesLoyaltyUsed = 0;
@@ -179,7 +179,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
this.transformed = permanent.transformed;
this.monstrous = permanent.monstrous;
this.renowned = permanent.renowned;
- this.pairedCard = permanent.pairedCard;
+ this.pairedPermanent = permanent.pairedPermanent;
this.timesLoyaltyUsed = permanent.timesLoyaltyUsed;
this.morphed = permanent.morphed;
@@ -1318,18 +1318,18 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
}
@Override
- public void setPairedCard(UUID pairedCard) {
- this.pairedCard = pairedCard;
+ public void setPairedCard(MageObjectReference pairedCard) {
+ this.pairedPermanent = pairedCard;
}
@Override
- public UUID getPairedCard() {
- return pairedCard;
+ public MageObjectReference getPairedCard() {
+ return pairedPermanent;
}
@Override
public void clearPairedCard() {
- this.pairedCard = null;
+ this.pairedPermanent = null;
}
@Override
diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java
index dccd865a1a1..69d7ec91c29 100644
--- a/Mage/src/main/java/mage/players/PlayerImpl.java
+++ b/Mage/src/main/java/mage/players/PlayerImpl.java
@@ -839,7 +839,7 @@ public abstract class PlayerImpl implements Player, Serializable {
}
if (permanent.getPairedCard() != null) {
- Permanent pairedCard = game.getPermanent(permanent.getPairedCard());
+ Permanent pairedCard = permanent.getPairedCard().getPermanent(game);
if (pairedCard != null) {
pairedCard.clearPairedCard();
}
diff --git a/Mage/src/main/java/mage/watchers/common/SoulbondWatcher.java b/Mage/src/main/java/mage/watchers/common/SoulbondWatcher.java
deleted file mode 100644
index ffe63d93f6b..00000000000
--- a/Mage/src/main/java/mage/watchers/common/SoulbondWatcher.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * 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.watchers.common;
-
-import mage.abilities.keyword.SoulbondAbility;
-import mage.cards.Cards;
-import mage.cards.CardsImpl;
-import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.WatcherScope;
-import mage.filter.common.FilterControlledCreaturePermanent;
-import mage.filter.predicate.Predicate;
-import mage.filter.predicate.Predicates;
-import mage.filter.predicate.permanent.AnotherPredicate;
-import mage.game.Game;
-import mage.game.events.GameEvent;
-import mage.game.permanent.Permanent;
-import mage.players.Player;
-import mage.target.common.TargetControlledPermanent;
-import mage.watchers.Watcher;
-
-/**
- * Reacts on various events to pair or unpair creatures on the battlefield.
- *
- * @author noxx
- */
-public class SoulbondWatcher extends Watcher {
-
- private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("another not paired creature you control");
-
- static {
- filter.add(new AnotherPredicate());
- filter.add(Predicates.not(new PairedPredicate()));
- }
-
- public SoulbondWatcher() {
- super("SoulbondWatcher", WatcherScope.GAME);
- }
-
- public SoulbondWatcher(final SoulbondWatcher watcher) {
- super(watcher);
- }
-
- @Override
- public void watch(GameEvent event, Game game) {
- if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) {
- Permanent permanent = game.getPermanent(event.getTargetId());
- if (permanent != null && permanent.getCardType().contains(CardType.CREATURE)) {
- if (permanent.getAbilities().contains(SoulbondAbility.getInstance())) {
- Player controller = game.getPlayer(permanent.getControllerId());
- if (controller != null) {
- Cards cards = new CardsImpl();
- cards.add(permanent);
- controller.lookAtCards("Soulbond", cards, game);
- if (controller.chooseUse(Outcome.Benefit, "Use Soulbond?", null, game)) {
- TargetControlledPermanent target = new TargetControlledPermanent(filter);
- target.setNotTarget(true);
- if (target.canChoose(permanent.getId(), controller.getId(), game)) {
- if (controller.choose(Outcome.Benefit, target, permanent.getId(), game)) {
- Permanent chosen = game.getPermanent(target.getFirstTarget());
- if (chosen != null) {
- chosen.setPairedCard(permanent.getId());
- permanent.setPairedCard(chosen.getId());
- if (!game.isSimulation()) {
- game.informPlayers(new StringBuilder(controller.getLogName()).append(" souldbonds ").append(permanent.getLogName()).append(" with ").append(chosen.getName()).toString());
- }
- }
- }
- }
- }
- }
- }
-
- // if still unpaired
- if (permanent.getPairedCard() == null) {
- // try to find creature with Soulbond and unpaired
- Player controller = null;
- for (Permanent chosen : game.getBattlefield().getActivePermanents(filter, permanent.getControllerId(), permanent.getId(), game)) {
- if (!chosen.getId().equals(permanent.getId()) && chosen.getAbilities().contains(SoulbondAbility.getInstance()) && chosen.getPairedCard() == null) {
- if (controller == null) {
- controller = game.getPlayer(permanent.getControllerId());
- }
- if (controller != null) {
- Cards cards = new CardsImpl();
- cards.add(chosen);
- controller.lookAtCards("Soulbond", cards, game);
- if (controller.chooseUse(Outcome.Benefit, "Use Soulbond for recent " + permanent.getLogName() + "?", SoulbondAbility.getInstance(), game)) {
- chosen.setPairedCard(permanent.getId());
- permanent.setPairedCard(chosen.getId());
- if (!game.isSimulation()) {
- game.informPlayers(new StringBuilder(controller.getLogName()).append(" souldbonds ").append(permanent.getLogName()).append(" with ").append(chosen.getName()).toString());
- }
- break;
- }
- }
- }
- }
- }
- }
- }
- }
-
- @Override
- public SoulbondWatcher copy() {
- return new SoulbondWatcher(this);
- }
-}
-
-class PairedPredicate implements Predicate {
-
- @Override
- public boolean apply(Permanent input, Game game) {
- return input.getPairedCard() != null;
- }
-
- @Override
- public String toString() {
- return "Paired";
- }
-}