mirror of
https://github.com/correl/mage.git
synced 2024-12-26 19:16:54 +00:00
Implemented Crystalline Resonance
This commit is contained in:
parent
357d1873db
commit
2d11f69d0e
6 changed files with 186 additions and 88 deletions
76
Mage.Sets/src/mage/cards/c/CrystallineResonance.java
Normal file
76
Mage.Sets/src/mage/cards/c/CrystallineResonance.java
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
package mage.cards.c;
|
||||||
|
|
||||||
|
import mage.MageObject;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.CycleControllerTriggeredAbility;
|
||||||
|
import mage.abilities.effects.common.CopyPermanentEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.filter.FilterPermanent;
|
||||||
|
import mage.filter.StaticFilters;
|
||||||
|
import mage.filter.predicate.permanent.AnotherPredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.target.TargetPermanent;
|
||||||
|
import mage.util.functions.ApplyToPermanent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class CrystallineResonance extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterPermanent filter = new FilterPermanent("another permanent");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(AnotherPredicate.instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CrystallineResonance(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
|
||||||
|
|
||||||
|
// Whenever you cycle a card, you may have Crystalline Resonance become a copy of another target permanent until your next turn, except it has this ability.
|
||||||
|
this.addAbility(this.createAbility());
|
||||||
|
}
|
||||||
|
|
||||||
|
private CrystallineResonance(final CrystallineResonance card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CrystallineResonance copy() {
|
||||||
|
return new CrystallineResonance(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Ability createAbility() {
|
||||||
|
Ability ability = new CycleControllerTriggeredAbility(
|
||||||
|
new CopyPermanentEffect(
|
||||||
|
StaticFilters.FILTER_PERMANENT_CREATURE,
|
||||||
|
new CrystallineResonanceApplier(), true
|
||||||
|
).setDuration(Duration.UntilYourNextTurn).setText(
|
||||||
|
"have {this} become a copy of another target permanent until your next turn, " +
|
||||||
|
"except it has this ability"
|
||||||
|
), true
|
||||||
|
);
|
||||||
|
ability.addTarget(new TargetPermanent(filter));
|
||||||
|
return ability;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CrystallineResonanceApplier extends ApplyToPermanent {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) {
|
||||||
|
permanent.getAbilities().add(CrystallineResonance.createAbility());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
|
||||||
|
mageObject.getAbilities().add(CrystallineResonance.createAbility());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,7 +28,7 @@ public final class DrannithStinger extends CardImpl {
|
||||||
|
|
||||||
// Whenever you cycle another card, Drannith Stinger deals 1 damage to each opponent.
|
// Whenever you cycle another card, Drannith Stinger deals 1 damage to each opponent.
|
||||||
this.addAbility(new CycleControllerTriggeredAbility(
|
this.addAbility(new CycleControllerTriggeredAbility(
|
||||||
new DamagePlayersEffect(1, TargetController.OPPONENT)
|
new DamagePlayersEffect(1, TargetController.OPPONENT), false, true
|
||||||
));
|
));
|
||||||
|
|
||||||
// Cycling {1}
|
// Cycling {1}
|
||||||
|
|
|
@ -27,7 +27,7 @@ public final class FlourishingFox extends CardImpl {
|
||||||
|
|
||||||
// Whenever you cycle another card, put a +1/+1 counter on Flourishing Fox.
|
// Whenever you cycle another card, put a +1/+1 counter on Flourishing Fox.
|
||||||
this.addAbility(new CycleControllerTriggeredAbility(
|
this.addAbility(new CycleControllerTriggeredAbility(
|
||||||
new AddCountersSourceEffect(CounterType.P1P1.createInstance())
|
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false, true
|
||||||
));
|
));
|
||||||
|
|
||||||
// Cycling {1}
|
// Cycling {1}
|
||||||
|
|
|
@ -71,6 +71,7 @@ public final class Commander2020Edition extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Commander's Sphere", 240, Rarity.COMMON, mage.cards.c.CommandersSphere.class));
|
cards.add(new SetCardInfo("Commander's Sphere", 240, Rarity.COMMON, mage.cards.c.CommandersSphere.class));
|
||||||
cards.add(new SetCardInfo("Crop Rotation", 169, Rarity.COMMON, mage.cards.c.CropRotation.class));
|
cards.add(new SetCardInfo("Crop Rotation", 169, Rarity.COMMON, mage.cards.c.CropRotation.class));
|
||||||
cards.add(new SetCardInfo("Cryptic Trilobite", 21, Rarity.RARE, mage.cards.c.CrypticTrilobite.class));
|
cards.add(new SetCardInfo("Cryptic Trilobite", 21, Rarity.RARE, mage.cards.c.CrypticTrilobite.class));
|
||||||
|
cards.add(new SetCardInfo("Crystalline Resonance", 31, Rarity.RARE, mage.cards.c.CrystallineResonance.class));
|
||||||
cards.add(new SetCardInfo("Curious Herd", 59, Rarity.RARE, mage.cards.c.CuriousHerd.class));
|
cards.add(new SetCardInfo("Curious Herd", 59, Rarity.RARE, mage.cards.c.CuriousHerd.class));
|
||||||
cards.add(new SetCardInfo("Daring Fiendbonder", 41, Rarity.RARE, mage.cards.d.DaringFiendbonder.class));
|
cards.add(new SetCardInfo("Daring Fiendbonder", 41, Rarity.RARE, mage.cards.d.DaringFiendbonder.class));
|
||||||
cards.add(new SetCardInfo("Deadly Tempest", 131, Rarity.RARE, mage.cards.d.DeadlyTempest.class));
|
cards.add(new SetCardInfo("Deadly Tempest", 131, Rarity.RARE, mage.cards.d.DeadlyTempest.class));
|
||||||
|
|
|
@ -14,16 +14,24 @@ import mage.game.stack.StackObject;
|
||||||
*/
|
*/
|
||||||
public class CycleControllerTriggeredAbility extends TriggeredAbilityImpl {
|
public class CycleControllerTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
|
private final boolean excludeSource;
|
||||||
|
|
||||||
public CycleControllerTriggeredAbility(Effect effect) {
|
public CycleControllerTriggeredAbility(Effect effect) {
|
||||||
this(effect, false);
|
this(effect, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CycleControllerTriggeredAbility(Effect effect, boolean optional) {
|
public CycleControllerTriggeredAbility(Effect effect, boolean optional) {
|
||||||
|
this(effect, optional, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CycleControllerTriggeredAbility(Effect effect, boolean optional, boolean excludeSource) {
|
||||||
super(Zone.BATTLEFIELD, effect, optional);
|
super(Zone.BATTLEFIELD, effect, optional);
|
||||||
|
this.excludeSource = excludeSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CycleControllerTriggeredAbility(final CycleControllerTriggeredAbility ability) {
|
private CycleControllerTriggeredAbility(final CycleControllerTriggeredAbility ability) {
|
||||||
super(ability);
|
super(ability);
|
||||||
|
this.excludeSource = ability.excludeSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -35,7 +43,7 @@ public class CycleControllerTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
if (game.getState().getStack().isEmpty()
|
if (game.getState().getStack().isEmpty()
|
||||||
|| !event.getPlayerId().equals(this.getControllerId())
|
|| !event.getPlayerId().equals(this.getControllerId())
|
||||||
|| event.getSourceId().equals(this.getSourceId())) {
|
|| (event.getSourceId().equals(this.getSourceId()) && excludeSource)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
StackObject item = game.getState().getStack().getFirst();
|
StackObject item = game.getState().getStack().getFirst();
|
||||||
|
@ -45,7 +53,7 @@ public class CycleControllerTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return "Whenever you cycle another card, " + super.getRule();
|
return "Whenever you cycle " + (excludeSource ? "another" : "a") + " card, " + super.getRule();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -6,11 +6,11 @@ import mage.abilities.SpellAbility;
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.keyword.EnchantAbility;
|
import mage.abilities.keyword.EnchantAbility;
|
||||||
|
import mage.constants.Duration;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.filter.FilterPermanent;
|
import mage.filter.FilterPermanent;
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
@ -26,13 +26,14 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public class CopyPermanentEffect extends OneShotEffect {
|
public class CopyPermanentEffect extends OneShotEffect {
|
||||||
|
|
||||||
private FilterPermanent filter;
|
private final FilterPermanent filter;
|
||||||
private ApplyToPermanent applier;
|
private final ApplyToPermanent applier;
|
||||||
|
private final boolean useTargetOfAbility;
|
||||||
private Permanent bluePrintPermanent;
|
private Permanent bluePrintPermanent;
|
||||||
private boolean useTargetOfAbility;
|
private Duration duration = Duration.Custom;
|
||||||
|
|
||||||
public CopyPermanentEffect() {
|
public CopyPermanentEffect() {
|
||||||
this(new FilterCreaturePermanent());
|
this(StaticFilters.FILTER_PERMANENT_CREATURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CopyPermanentEffect(ApplyToPermanent applier) {
|
public CopyPermanentEffect(ApplyToPermanent applier) {
|
||||||
|
@ -72,7 +73,9 @@ public class CopyPermanentEffect extends OneShotEffect {
|
||||||
if (sourcePermanent == null) {
|
if (sourcePermanent == null) {
|
||||||
sourcePermanent = game.getObject(source.getSourceId());
|
sourcePermanent = game.getObject(source.getSourceId());
|
||||||
}
|
}
|
||||||
if (controller != null && sourcePermanent != null) {
|
if (controller == null || sourcePermanent == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Permanent copyFromPermanent = null;
|
Permanent copyFromPermanent = null;
|
||||||
if (useTargetOfAbility) {
|
if (useTargetOfAbility) {
|
||||||
copyFromPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
copyFromPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||||
|
@ -84,14 +87,18 @@ public class CopyPermanentEffect extends OneShotEffect {
|
||||||
copyFromPermanent = game.getPermanent(target.getFirstTarget());
|
copyFromPermanent = game.getPermanent(target.getFirstTarget());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (copyFromPermanent != null) {
|
if (copyFromPermanent == null) {
|
||||||
bluePrintPermanent = game.copyPermanent(copyFromPermanent, sourcePermanent.getId(), source, applier);
|
return true;
|
||||||
|
}
|
||||||
|
bluePrintPermanent = game.copyPermanent(duration, copyFromPermanent, sourcePermanent.getId(), source, applier);
|
||||||
if (bluePrintPermanent == null) {
|
if (bluePrintPermanent == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if object is a copy of an aura, it needs to attach again for new target
|
// if object is a copy of an aura, it needs to attach again for new target
|
||||||
if (bluePrintPermanent.hasSubtype(SubType.AURA, game)) {
|
if (!bluePrintPermanent.hasSubtype(SubType.AURA, game)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
//copied from mage.cards.c.CopyEnchantment.java
|
//copied from mage.cards.c.CopyEnchantment.java
|
||||||
|
|
||||||
// permanent can be attached (Estrid's Mask) or enchant (Utopia Sprawl)
|
// permanent can be attached (Estrid's Mask) or enchant (Utopia Sprawl)
|
||||||
|
@ -101,34 +108,39 @@ public class CopyPermanentEffect extends OneShotEffect {
|
||||||
|
|
||||||
// attach - search effect in spell ability (example: cast Utopia Sprawl, cast Estrid's Invocation on it)
|
// attach - search effect in spell ability (example: cast Utopia Sprawl, cast Estrid's Invocation on it)
|
||||||
for (Ability ability : bluePrintPermanent.getAbilities()) {
|
for (Ability ability : bluePrintPermanent.getAbilities()) {
|
||||||
if (ability instanceof SpellAbility) {
|
if (!(ability instanceof SpellAbility)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
auraOutcome = ability.getEffects().getOutcome(ability);
|
auraOutcome = ability.getEffects().getOutcome(ability);
|
||||||
for (Effect effect : ability.getEffects()) {
|
for (Effect effect : ability.getEffects()) {
|
||||||
if (effect instanceof AttachEffect) {
|
if (!(effect instanceof AttachEffect)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (bluePrintPermanent.getSpellAbility().getTargets().size() > 0) {
|
if (bluePrintPermanent.getSpellAbility().getTargets().size() > 0) {
|
||||||
auraTarget = bluePrintPermanent.getSpellAbility().getTargets().get(0);
|
auraTarget = bluePrintPermanent.getSpellAbility().getTargets().get(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// enchant - search in all abilities (example: cast Estrid's Invocation on enchanted creature by Estrid, the Masked second ability, cast Estrid's Invocation on it)
|
// enchant - search in all abilities (example: cast Estrid's Invocation on enchanted creature by Estrid, the Masked second ability, cast Estrid's Invocation on it)
|
||||||
if (auraTarget == null) {
|
if (auraTarget == null) {
|
||||||
for (Ability ability : bluePrintPermanent.getAbilities()) {
|
for (Ability ability : bluePrintPermanent.getAbilities()) {
|
||||||
if (ability instanceof EnchantAbility) {
|
if (!(ability instanceof EnchantAbility)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
auraOutcome = ability.getEffects().getOutcome(ability);
|
auraOutcome = ability.getEffects().getOutcome(ability);
|
||||||
if (ability.getTargets().size() > 0) { // Animate Dead don't have targets
|
if (ability.getTargets().size() > 0) { // Animate Dead don't have targets
|
||||||
auraTarget = ability.getTargets().get(0);
|
auraTarget = ability.getTargets().get(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* if this is a copy of a copy, the copy's target has been
|
/* if this is a copy of a copy, the copy's target has been
|
||||||
* copied and needs to be cleared
|
* copied and needs to be cleared
|
||||||
*/
|
*/
|
||||||
if (auraTarget != null) {
|
if (auraTarget == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
// clear selected target
|
// clear selected target
|
||||||
if (auraTarget.getFirstTarget() != null) {
|
if (auraTarget.getFirstTarget() != null) {
|
||||||
auraTarget.remove(auraTarget.getFirstTarget());
|
auraTarget.remove(auraTarget.getFirstTarget());
|
||||||
|
@ -136,7 +148,9 @@ public class CopyPermanentEffect extends OneShotEffect {
|
||||||
|
|
||||||
// select new target
|
// select new target
|
||||||
auraTarget.setNotTarget(true);
|
auraTarget.setNotTarget(true);
|
||||||
if (controller.choose(auraOutcome, auraTarget, source.getSourceId(), game)) {
|
if (!controller.choose(auraOutcome, auraTarget, source.getSourceId(), game)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
UUID targetId = auraTarget.getFirstTarget();
|
UUID targetId = auraTarget.getFirstTarget();
|
||||||
Permanent targetPermanent = game.getPermanent(targetId);
|
Permanent targetPermanent = game.getPermanent(targetId);
|
||||||
Player targetPlayer = game.getPlayer(targetId);
|
Player targetPlayer = game.getPlayer(targetId);
|
||||||
|
@ -147,14 +161,8 @@ public class CopyPermanentEffect extends OneShotEffect {
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Permanent getBluePrintPermanent() {
|
public Permanent getBluePrintPermanent() {
|
||||||
return bluePrintPermanent;
|
return bluePrintPermanent;
|
||||||
|
@ -164,4 +172,9 @@ public class CopyPermanentEffect extends OneShotEffect {
|
||||||
public CopyPermanentEffect copy() {
|
public CopyPermanentEffect copy() {
|
||||||
return new CopyPermanentEffect(this);
|
return new CopyPermanentEffect(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CopyPermanentEffect setDuration(Duration duration) {
|
||||||
|
this.duration = duration;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue