mirror of
https://github.com/magefree/mage.git
synced 2026-01-25 20:59:14 -08:00
[C21] Implemented Fractal Harness
This commit is contained in:
parent
2e5619e268
commit
1fad23b9fb
7 changed files with 152 additions and 131 deletions
116
Mage.Sets/src/mage/cards/f/FractalHarness.java
Normal file
116
Mage.Sets/src/mage/cards/f/FractalHarness.java
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
package mage.cards.f;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.AttacksAttachedTriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.keyword.EquipAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AttachmentType;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.QuandrixToken;
|
||||
import mage.game.permanent.token.Token;
|
||||
import mage.watchers.common.ManaSpentToCastWatcher;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class FractalHarness extends CardImpl {
|
||||
|
||||
public FractalHarness(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{X}{2}{G}");
|
||||
|
||||
this.subtype.add(SubType.EQUIPMENT);
|
||||
|
||||
// When Fractal Harness enters the battlefield, create a 0/0 green and blue Fractal creature token. Put X +1/+1 counters on it and attach Fractal Harness to it.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new FractalHarnessTokenEffect()), new ManaSpentToCastWatcher());
|
||||
|
||||
// Whenever equipped creature attacks, double the number of +1/+1 counters on it.
|
||||
this.addAbility(new AttacksAttachedTriggeredAbility(
|
||||
new FractalHarnessDoubleEffect(), AttachmentType.EQUIPMENT, false
|
||||
));
|
||||
|
||||
// Equip {2}
|
||||
this.addAbility(new EquipAbility(2));
|
||||
}
|
||||
|
||||
private FractalHarness(final FractalHarness card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FractalHarness copy() {
|
||||
return new FractalHarness(this);
|
||||
}
|
||||
}
|
||||
|
||||
class FractalHarnessTokenEffect extends OneShotEffect {
|
||||
|
||||
FractalHarnessTokenEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "create a 0/0 green and blue Fractal creature token. " +
|
||||
"Put X +1/+1 counters on it and attach {this} to it";
|
||||
}
|
||||
|
||||
private FractalHarnessTokenEffect(final FractalHarnessTokenEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FractalHarnessTokenEffect copy() {
|
||||
return new FractalHarnessTokenEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Token token = new QuandrixToken();
|
||||
token.putOntoBattlefield(1, game, source, source.getControllerId());
|
||||
int xValue = ManacostVariableValue.instance.calculate(game, source, this);
|
||||
boolean flag = true;
|
||||
for (UUID tokenId : token.getLastAddedTokenIds()) {
|
||||
Permanent permanent = game.getPermanent(tokenId);
|
||||
if (permanent == null) {
|
||||
continue;
|
||||
}
|
||||
if (flag && permanent.addAttachment(tokenId, source, game)) {
|
||||
flag = false;
|
||||
}
|
||||
permanent.addCounters(CounterType.P1P1.createInstance(xValue), source.getControllerId(), source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class FractalHarnessDoubleEffect extends OneShotEffect {
|
||||
|
||||
FractalHarnessDoubleEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "double the number of +1/+1 counters on it";
|
||||
}
|
||||
|
||||
private FractalHarnessDoubleEffect(final FractalHarnessDoubleEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FractalHarnessDoubleEffect copy() {
|
||||
return new FractalHarnessDoubleEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = (Permanent) getValue("attachedPermanent");
|
||||
return permanent != null && permanent.addCounters(CounterType.P1P1.createInstance(
|
||||
permanent.getCounters(game).getCount(CounterType.P1P1)
|
||||
), source.getControllerId(), source, game);
|
||||
}
|
||||
}
|
||||
|
|
@ -5,22 +5,21 @@ import mage.ObjectColor;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SpellCastControllerTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.effects.common.TapTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.TargetController;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.FilterSpell;
|
||||
import mage.filter.common.FilterNonlandPermanent;
|
||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.watchers.Watcher;
|
||||
import mage.watchers.common.ManaSpentToCastWatcher;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -50,8 +49,8 @@ public final class GadwickTheWizened extends CardImpl {
|
|||
|
||||
// When Gadwick, the Wizened enters the battlefield, draw X cards.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(
|
||||
new DrawCardSourceControllerEffect(GadwickTheWizenedValue.instance)
|
||||
), new GadwickTheWizenedWatcher());
|
||||
new DrawCardSourceControllerEffect(ManacostVariableValue.instance)
|
||||
), new ManaSpentToCastWatcher());
|
||||
|
||||
// Whenever you cast a blue spell, tap target nonland permanent an opponent controls.
|
||||
Ability ability = new SpellCastControllerTriggeredAbility(new TapTargetEffect(), filter, false);
|
||||
|
|
@ -68,60 +67,3 @@ public final class GadwickTheWizened extends CardImpl {
|
|||
return new GadwickTheWizened(this);
|
||||
}
|
||||
}
|
||||
|
||||
enum GadwickTheWizenedValue implements DynamicValue {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
// watcher in card's scope
|
||||
GadwickTheWizenedWatcher watcher = game.getState().getWatcher(GadwickTheWizenedWatcher.class, sourceAbility.getSourceId());
|
||||
if (watcher == null) {
|
||||
return 0;
|
||||
}
|
||||
if (game.getState().getValue(sourceAbility.getSourceId().toString()
|
||||
+ "cardsToDraw") == null) {
|
||||
return 0;
|
||||
}
|
||||
return (Integer) game.getState().getValue(sourceAbility.getSourceId().toString()
|
||||
+ "cardsToDraw");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "X";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
class GadwickTheWizenedWatcher extends Watcher {
|
||||
|
||||
GadwickTheWizenedWatcher() {
|
||||
super(WatcherScope.CARD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
if (event.getType() != GameEvent.EventType.SPELL_CAST) {
|
||||
return;
|
||||
}
|
||||
Spell spell = game.getSpellOrLKIStack(event.getTargetId());
|
||||
if (spell == null) {
|
||||
return;
|
||||
}
|
||||
if (spell.getSourceId() != super.getSourceId()) {
|
||||
return; // the spell is not Gadwick, the Wizened
|
||||
}
|
||||
game.getState().setValue(spell.getSourceId().toString()
|
||||
+ "cardsToDraw", spell.getSpellAbility().getManaCostsToPay().getX());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
|
|||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.MultipliedValue;
|
||||
import mage.abilities.dynamicvalue.common.CardsDrawnThisTurnDynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
|
|
@ -16,18 +17,20 @@ import mage.abilities.effects.common.ReturnToHandTargetEffect;
|
|||
import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.permanent.TappedPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.token.ShardToken;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
import mage.watchers.Watcher;
|
||||
import mage.watchers.common.CardsDrawnThisTurnWatcher;
|
||||
import mage.watchers.common.ManaSpentToCastWatcher;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
|
@ -54,8 +57,8 @@ public final class NikoAris extends CardImpl {
|
|||
|
||||
// When Niko Aris enters the battlefield, create X Shard tokens.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(
|
||||
new CreateTokenEffect(new ShardToken(), NikoArisValue.instance)
|
||||
), new NikoArisWatcher());
|
||||
new CreateTokenEffect(new ShardToken(), ManacostVariableValue.instance)
|
||||
), new ManaSpentToCastWatcher());
|
||||
|
||||
// +1: Up to one target creature you control can't be blocked this turn. Whenever that creature deals damage this turn, return it to its owner's hand.
|
||||
Ability ability = new LoyaltyAbility(new CantBeBlockedTargetEffect(Duration.EndOfTurn), 1);
|
||||
|
|
@ -84,59 +87,6 @@ public final class NikoAris extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
enum NikoArisValue implements DynamicValue {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
NikoArisWatcher watcher = game.getState().getWatcher(NikoArisWatcher.class, sourceAbility.getSourceId());
|
||||
if (watcher == null) {
|
||||
return 0;
|
||||
}
|
||||
if (game.getState().getValue(sourceAbility.getSourceId().toString() + "xValue") == null) {
|
||||
return 0;
|
||||
}
|
||||
return (Integer) game.getState().getValue(sourceAbility.getSourceId().toString() + "xValue");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "X";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
class NikoArisWatcher extends Watcher {
|
||||
|
||||
NikoArisWatcher() {
|
||||
super(WatcherScope.CARD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
if (event.getType() != GameEvent.EventType.SPELL_CAST) {
|
||||
return;
|
||||
}
|
||||
Spell spell = game.getSpellOrLKIStack(event.getTargetId());
|
||||
if (spell == null || spell.getSourceId() != super.getSourceId()) {
|
||||
return;
|
||||
}
|
||||
game.getState().setValue(
|
||||
spell.getSourceId().toString() + "xValue",
|
||||
spell.getSpellAbility().getManaCostsToPay().getX()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NikoArisDamageTriggeredAbility extends DelayedTriggeredAbility {
|
||||
|
||||
NikoArisDamageTriggeredAbility() {
|
||||
|
|
@ -176,4 +126,4 @@ class NikoArisDamageTriggeredAbility extends DelayedTriggeredAbility {
|
|||
public String getRule() {
|
||||
return "Whenever that creature deals damage this turn, return it to its owner's hand.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ public final class Commander2021Edition extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Fiery Fall", 170, Rarity.COMMON, mage.cards.f.FieryFall.class));
|
||||
cards.add(new SetCardInfo("Forgotten Ancient", 189, Rarity.RARE, mage.cards.f.ForgottenAncient.class));
|
||||
cards.add(new SetCardInfo("Forgotten Cave", 289, Rarity.COMMON, mage.cards.f.ForgottenCave.class));
|
||||
cards.add(new SetCardInfo("Fractal Harness", 61, Rarity.RARE, mage.cards.f.FractalHarness.class));
|
||||
cards.add(new SetCardInfo("Garruk, Primal Hunter", 190, Rarity.MYTHIC, mage.cards.g.GarrukPrimalHunter.class));
|
||||
cards.add(new SetCardInfo("Gaze of Granite", 217, Rarity.RARE, mage.cards.g.GazeOfGranite.class));
|
||||
cards.add(new SetCardInfo("Geometric Nexus", 77, Rarity.RARE, mage.cards.g.GeometricNexus.class));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue