Merge pull request #5325 from magefree/master

merge
This commit is contained in:
theelk801 2018-09-22 15:41:41 -04:00 committed by GitHub
commit cf92f828fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
223 changed files with 7441 additions and 371 deletions

View file

@ -538,7 +538,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
// Always hide not hidden popup window or enlarged card view if a frame is set to active
try {
ActionCallback callback = Plugins.instance.getActionCallback();
if (callback != null && callback instanceof MageActionCallback) {
if (callback instanceof MageActionCallback) {
((MageActionCallback) callback).hideEnlargedCard();
}
Component container = MageFrame.getUI().getComponent(MageComponents.POPUP_CONTAINER);

View file

@ -319,7 +319,7 @@ public class DialogManager extends JComponent implements MouseListener,
if (e.getButton() == MouseEvent.BUTTON1) {
j = (JComponent) getComponentAt(e.getX(), e.getY());
if (j != null && j instanceof DialogContainer) {
if (j instanceof DialogContainer) {
rec = j.getBounds();
bDragged = true;
mx = e.getX();

View file

@ -530,7 +530,7 @@ public class MageBook extends JComponent {
Class<?> c = Class.forName(className);
Constructor<?> cons = c.getConstructor();
Object newToken = cons.newInstance();
if (newToken != null && newToken instanceof mage.game.permanent.token.Token) {
if (newToken instanceof Token) {
((Token) newToken).setExpansionSetCodeForImage(set);
((Token) newToken).setOriginalExpansionSetCode(set);
((Token) newToken).setTokenType(token.getType());
@ -580,7 +580,7 @@ public class MageBook extends JComponent {
Class<?> c = Class.forName(className);
Constructor<?> cons = c.getConstructor();
Object newEmblem = cons.newInstance();
if (newEmblem != null && newEmblem instanceof mage.game.command.Emblem) {
if (newEmblem instanceof Emblem) {
((Emblem) newEmblem).setExpansionSetCodeForImage(set);
emblems.add((Emblem) newEmblem);
@ -637,7 +637,7 @@ public class MageBook extends JComponent {
Class<?> c = Class.forName(className);
Constructor<?> cons = c.getConstructor();
Object newPlane = cons.newInstance();
if (newPlane != null && newPlane instanceof mage.game.command.Plane) {
if (newPlane instanceof Plane) {
((Plane) newPlane).setExpansionSetCodeForImage(set);
planes.add((Plane) newPlane);

View file

@ -369,7 +369,7 @@ public class TableModel extends AbstractTableModel implements ICardGrid {
if (!card.getId().equals(bigCard.getCardId())) {
if (!MageFrame.isLite()) {
Image image = Plugins.instance.getOriginalImage(card);
if (image != null && image instanceof BufferedImage) {
if (image instanceof BufferedImage) {
// XXX: scaled to fit width
bigCard.setCard(card.getId(), EnlargeMode.NORMAL, image, new ArrayList<>(), false);
} else {

View file

@ -617,7 +617,7 @@ public class MageActionCallback implements ActionCallback {
}
private void displayCardInfo(MageCard mageCard, Image image, BigCard bigCard) {
if (image != null && image instanceof BufferedImage) {
if (image instanceof BufferedImage) {
// XXX: scaled to fit width
bigCard.setCard(mageCard.getOriginal().getId(), enlargeMode, image, mageCard.getOriginal().getRules(), mageCard.getOriginal().isToRotate());
// if it's an ability, show only the ability text as overlay

View file

@ -47,7 +47,7 @@ public class CountryItemEditor extends BasicComboBoxEditor {
@Override
public void setItem(Object item) {
if (item == null || !(item instanceof String[])) {
if (!(item instanceof String[])) {
return;
}

View file

@ -800,7 +800,7 @@ public abstract class CardPanel extends MagePermanent implements MouseListener,
// this update removes the isChoosable mark from targetCardsInLibrary
// so only done for permanents because it's needed to redraw counters in different size, if window size was changed
// no perfect solution yet (maybe also other not wanted effects for PermanentView objects)
if (updateCard != null && (updateCard instanceof PermanentView)) {
if ((updateCard instanceof PermanentView)) {
update(updateCard);
}
}

View file

@ -225,7 +225,7 @@ public class Connection {
for (InterfaceAddress addr : iface.getInterfaceAddresses()) {
if (addr != null) {
InetAddress iaddr = addr.getAddress();
if (iaddr != null && iaddr instanceof Inet4Address) {
if (iaddr instanceof Inet4Address) {
return iaddr;
}
}

View file

@ -39,7 +39,7 @@ public final class CompressUtil {
* @return Decompressed object
*/
public static Object decompress(Object data) {
if (data == null || !(data instanceof ZippedObject)) {
if (!(data instanceof ZippedObject)) {
return data;
}
return ((ZippedObject) data).unzip();

View file

@ -76,8 +76,6 @@ public class AusHighlander extends Constructed {
pointMap.put("True-Name Nemesis", 1);
pointMap.put("Umezawas Jitte", 1);
pointMap.put("Wasteland", 1);
pointMap.put("Wheel of Fortune", 1);
pointMap.put("Worldly Tutor", 1);
pointMap.put("Yawgmoths Bargain", 1);
}

View file

@ -21,7 +21,7 @@ public class CanadianHighlander extends Constructed {
pointMap.put("Balance", 1);
pointMap.put("Birthing Pod", 3);
pointMap.put("Black Lotus", 7);
pointMap.put("Demonic Tutor", 4);
pointMap.put("Demonic Tutor", 3);
pointMap.put("Dig Through Time", 1);
pointMap.put("Enlightened Tutor", 1);
pointMap.put("Fastbond", 1);

View file

@ -27,7 +27,7 @@ public class LevelUpOptimizer extends BaseTreeOptimizer {
for (Ability ability : actions) {
if (ability instanceof LevelUpAbility) {
Permanent permanent = game.getPermanent(ability.getSourceId());
if (permanent != null && permanent instanceof PermanentCard) {
if (permanent instanceof PermanentCard) {
PermanentCard leveler = (PermanentCard) permanent;
// check already existing Level counters and compare to maximum that make sense
if (permanent.getCounters(game).getCount(CounterType.LEVEL) >= leveler.getMaxLevelCounters()) {

View file

@ -408,7 +408,7 @@ public final class SystemUtil {
Class<?> c = Class.forName("mage.game.permanent.token." + command.cardName);
Constructor<?> cons = c.getConstructor();
Object token = cons.newInstance();
if (token != null && token instanceof mage.game.permanent.token.Token) {
if (token instanceof mage.game.permanent.token.Token) {
((mage.game.permanent.token.Token) token).putOntoBattlefield(command.Amount, game, null, player.getId(), false, false);
continue;
}
@ -417,7 +417,7 @@ public final class SystemUtil {
Class<?> c = Class.forName("mage.game.command.emblems." + command.cardName);
Constructor<?> cons = c.getConstructor();
Object emblem = cons.newInstance();
if (emblem != null && emblem instanceof mage.game.command.Emblem) {
if (emblem instanceof mage.game.command.Emblem) {
((mage.game.command.Emblem) emblem).setControllerId(player.getId());
game.addEmblem((mage.game.command.Emblem) emblem, null, player.getId());
continue;
@ -427,7 +427,7 @@ public final class SystemUtil {
Class<?> c = Class.forName("mage.game.command.planes." + command.cardName);
Constructor<?> cons = c.getConstructor();
Object plane = cons.newInstance();
if (plane != null && plane instanceof mage.game.command.Plane) {
if (plane instanceof mage.game.command.Plane) {
((mage.game.command.Plane) plane).setControllerId(player.getId());
game.addPlane((mage.game.command.Plane) plane, null, player.getId());
continue;

View file

@ -48,8 +48,9 @@ public final class ArclightPhoenix extends CardImpl {
TargetController.YOU, true
), ArclightPhoenixCondition.instance,
"At the beginning of combat on your turn, "
+ "if you cast 3 or more instants and/or sorceries this turn, "
+ "you may return {this} from your graveyard to the battlefield."
+ "if you've cast three or more instant "
+ "and sorcery spells this turn, you may return {this} "
+ "from your graveyard to the battlefield."
), new ArclightPhoenixWatcher());
}

View file

@ -18,12 +18,12 @@ import mage.target.common.TargetCreaturePermanent;
*
* @author TheElk801
*/
public final class AssuranceAssociation extends SplitCard {
public final class AssureAssemble extends SplitCard {
public AssuranceAssociation(UUID ownerId, CardSetInfo setInfo) {
public AssureAssemble(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G/W}{G/W}", "{4}{G}{W}", SpellAbilityType.SPLIT);
// Assurance
// Assure
// Put a +1/+1 counter on target creature. It gains indestructible until end of turn.
this.getLeftHalfCard().getSpellAbility().addEffect(
new AddCountersTargetEffect(CounterType.P1P1.createInstance())
@ -38,19 +38,19 @@ public final class AssuranceAssociation extends SplitCard {
new TargetCreaturePermanent()
);
// Association
// Assemble
// Create three 2/2 green and white Elf Knight creature tokens with vigilance.
this.getRightHalfCard().getSpellAbility().addEffect(
new CreateTokenEffect(new ElfKnightToken(), 3)
);
}
public AssuranceAssociation(final AssuranceAssociation card) {
public AssureAssemble(final AssureAssemble card) {
super(card);
}
@Override
public AssuranceAssociation copy() {
return new AssuranceAssociation(this);
public AssureAssemble copy() {
return new AssureAssemble(this);
}
}

View file

@ -0,0 +1,44 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.keyword.SurveilEffect;
import mage.constants.SubType;
import mage.abilities.keyword.DefenderAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author TheElk801
*/
public final class BarrierOfBones extends CardImpl {
public BarrierOfBones(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}");
this.subtype.add(SubType.SKELETON);
this.subtype.add(SubType.WALL);
this.power = new MageInt(0);
this.toughness = new MageInt(3);
// Defender
this.addAbility(DefenderAbility.getInstance());
// When Barrier of Bones enters the battlefield, surveil 1.
this.addAbility(new EntersBattlefieldTriggeredAbility(
new SurveilEffect(1), false
));
}
public BarrierOfBones(final BarrierOfBones card) {
super(card);
}
@Override
public BarrierOfBones copy() {
return new BarrierOfBones(this);
}
}

View file

@ -0,0 +1,36 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.constants.SubType;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author TheElk801
*/
public final class BartizanBats extends CardImpl {
public BartizanBats(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
this.subtype.add(SubType.BAT);
this.power = new MageInt(3);
this.toughness = new MageInt(1);
// Flying
this.addAbility(FlyingAbility.getInstance());
}
public BartizanBats(final BartizanBats card) {
super(card);
}
@Override
public BartizanBats copy() {
return new BartizanBats(this);
}
}

View file

@ -0,0 +1,39 @@
package mage.cards.b;
import java.util.UUID;
import mage.abilities.dynamicvalue.common.InstantSorceryExileGraveyardCount;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.keyword.JumpStartAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author TheElk801
*/
public final class BeaconBolt extends CardImpl {
public BeaconBolt(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}{R}");
// Beacon Bolt deals damage to target creature equal to the total number of instant and sorcery cards you own in exile and in your graveyard.
this.getSpellAbility().addEffect(new DamageTargetEffect(
InstantSorceryExileGraveyardCount.instance
).setText("{this} deals damage to target creature equal to "
+ "the total number of instant and sorcery cards "
+ "you own in exile and in your graveyard"));
// Jump-start
this.addAbility(new JumpStartAbility(this));
}
public BeaconBolt(final BeaconBolt card) {
super(card);
}
@Override
public BeaconBolt copy() {
return new BeaconBolt(this);
}
}

View file

@ -0,0 +1,226 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.OneShotEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetPermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author TheElk801
*/
public final class BeamsplitterMage extends CardImpl {
public BeamsplitterMage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{R}");
this.subtype.add(SubType.VEDALKEN);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Whenever you cast an instant or sorcery spell that targets only Beamsplitter Mage, if you control one or more creatures that spell could target, choose one of those creatures. Copy that spell. The copy targets the chosen creature.
this.addAbility(new BeamsplitterMageTriggeredAbility());
}
public BeamsplitterMage(final BeamsplitterMage card) {
super(card);
}
@Override
public BeamsplitterMage copy() {
return new BeamsplitterMage(this);
}
}
class BeamsplitterMageTriggeredAbility extends TriggeredAbilityImpl {
public BeamsplitterMageTriggeredAbility() {
super(Zone.BATTLEFIELD, new BeamsplitterMageEffect(), false);
}
public BeamsplitterMageTriggeredAbility(final BeamsplitterMageTriggeredAbility ability) {
super(ability);
}
@Override
public BeamsplitterMageTriggeredAbility copy() {
return new BeamsplitterMageTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SPELL_CAST;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getPlayerId().equals(this.getControllerId())) {
Spell spell = game.getStack().getSpell(event.getTargetId());
if (!isControlledInstantOrSorcery(spell)) {
return false;
}
boolean targetsSource = false;
for (Ability ability : spell.getSpellAbilities()) {
for (UUID modeId : ability.getModes().getSelectedModes()) {
Mode mode = ability.getModes().get(modeId);
for (Target target : mode.getTargets()) {
if (!target.isNotTarget()) {
for (UUID targetId : target.getTargets()) {
if (targetId.equals(getSourceId())) {
targetsSource = true;
} else {
return false;
}
}
}
}
}
}
if (targetsSource) {
this.getEffects().get(0).setTargetPointer(new FixedTarget(spell.getId()));
return true;
}
}
return false;
}
private boolean isControlledInstantOrSorcery(Spell spell) {
return spell != null
&& (spell.isControlledBy(this.getControllerId()))
&& (spell.isInstant() || spell.isSorcery());
}
@Override
public String getRule() {
return "Whenever you cast an instant or sorcery spell that targets "
+ "only {this}, if you control one or more creatures "
+ "that spell could target, choose one of those creatures. "
+ "Copy that spell. The copy targets the chosen creature.";
}
}
class BeamsplitterMageEffect extends OneShotEffect {
public BeamsplitterMageEffect() {
super(Outcome.Detriment);
}
public BeamsplitterMageEffect(final BeamsplitterMageEffect effect) {
super(effect);
}
@Override
public BeamsplitterMageEffect copy() {
return new BeamsplitterMageEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Spell spell = game.getSpellOrLKIStack(this.getTargetPointer().getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId());
if (spell != null && controller != null) {
// search the target that targets source
Target usedTarget = null;
setUsedTarget:
for (Ability ability : spell.getSpellAbilities()) {
for (UUID modeId : ability.getModes().getSelectedModes()) {
Mode mode = ability.getModes().get(modeId);
for (Target target : mode.getTargets()) {
if (!target.isNotTarget() && target.getFirstTarget().equals(source.getSourceId())) {
usedTarget = target.copy();
usedTarget.clearChosen();
break setUsedTarget;
}
}
}
}
if (usedTarget == null) {
return false;
}
FilterPermanent filter = new BeamsplitterMageFilter(usedTarget, source.getSourceId());
Target target1 = new TargetPermanent(filter);
target1.setNotTarget(true);
if (controller.choose(outcome, target1, source.getSourceId(), game)) {
Permanent creature = game.getPermanent(target1.getFirstTarget());
if (creature == null) {
return false;
}
Spell copy = spell.copySpell(source.getControllerId());
game.getStack().push(copy);
setTarget:
for (UUID modeId : copy.getSpellAbility().getModes().getSelectedModes()) {
Mode mode = copy.getSpellAbility().getModes().get(modeId);
for (Target target : mode.getTargets()) {
if (target.getClass().equals(usedTarget.getClass())) {
target.clearChosen(); // For targets with Max > 1 we need to clear before the text is comapred
if (target.getMessage().equals(usedTarget.getMessage())) {
target.addTarget(creature.getId(), copy.getSpellAbility(), game, false);
break setTarget;
}
}
}
}
game.fireEvent(new GameEvent(GameEvent.EventType.COPIED_STACKOBJECT, copy.getId(), spell.getId(), source.getControllerId()));
String activateMessage = copy.getActivatedMessage(game);
if (activateMessage.startsWith(" casts ")) {
activateMessage = activateMessage.substring(6);
}
if (!game.isSimulation()) {
game.informPlayers(controller.getLogName() + activateMessage);
}
}
return true;
}
return false;
}
}
class BeamsplitterMageFilter extends FilterControlledPermanent {
private final Target target;
private final UUID notId;
public BeamsplitterMageFilter(Target target, UUID notId) {
super("creature this spell could target");
this.target = target;
this.notId = notId;
}
public BeamsplitterMageFilter(final BeamsplitterMageFilter filter) {
super(filter);
this.target = filter.target;
this.notId = filter.notId;
}
@Override
public BeamsplitterMageFilter copy() {
return new BeamsplitterMageFilter(this);
}
@Override
public boolean match(Permanent permanent, UUID sourceId, UUID playerId, Game game) {
return super.match(permanent, game)
&& permanent.isCreature()
&& !permanent.getId().equals(notId)
&& target.canTarget(permanent.getId(), game);
}
}

View file

@ -171,7 +171,7 @@ class BerserkDelayedDestroyEffect extends OneShotEffect {
Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source));
if (permanent != null) {
Watcher watcher = game.getState().getWatchers().get(AttackedThisTurnWatcher.class.getSimpleName());
if (watcher != null && watcher instanceof AttackedThisTurnWatcher) {
if (watcher instanceof AttackedThisTurnWatcher) {
if (((AttackedThisTurnWatcher) watcher).getAttackedThisTurnCreatures().contains(new MageObjectReference(permanent, game))) {
return permanent.destroy(source.getSourceId(), game, false);
}

View file

@ -0,0 +1,49 @@
package mage.cards.b;
import java.util.UUID;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.filter.common.FilterCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.SecondTargetPointer;
import mage.target.targetpointer.ThirdTargetPointer;
/**
*
* @author Ryan-Saklad
*/
public final class BountyOfMight extends CardImpl {
public BountyOfMight(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{G}{G}");
// Target creature gets +3/+3 until end of turn.
this.getSpellAbility().addEffect(new BoostTargetEffect(3, 3, Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature (1st)")));
// Target creature gets +3/+3 until end of turn.
Effect effect = new BoostTargetEffect(3, 3, Duration.EndOfTurn).setText("<br>Target creature gets +3/+3 until end of turn.");
effect.setTargetPointer(new SecondTargetPointer());
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature (2nd)")));
// Target creature gets +3/+3 until end of turn.
effect = new BoostTargetEffect(3, 3, Duration.EndOfTurn).setText("<br>Target creature gets +3/+3 until end of turn.");
effect.setTargetPointer(new ThirdTargetPointer());
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature (3rd)")));
}
public BountyOfMight(final BountyOfMight card) {
super(card);
}
@Override
public BountyOfMight copy() {
return new BountyOfMight(this);
}
}

View file

@ -0,0 +1,44 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.discard.DiscardEachPlayerEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetController;
/**
*
* @author TheElk801
*/
public final class BurglarRat extends CardImpl {
public BurglarRat(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
this.subtype.add(SubType.RAT);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// When Burglar Rat enters the battlefield, each opponent discards a card.
this.addAbility(new EntersBattlefieldTriggeredAbility(
new DiscardEachPlayerEffect(
new StaticValue(1), false,
TargetController.OPPONENT
)
));
}
public BurglarRat(final BurglarRat card) {
super(card);
}
@Override
public BurglarRat copy() {
return new BurglarRat(this);
}
}

View file

@ -136,7 +136,7 @@ class WhackCondition extends IntCompareCondition {
@Override
protected int getInputValue(Game game, Ability source) {
Object object = game.getState().getValue("whack" + source.getSourceId());
if (object != null && object instanceof Boolean && (Boolean) object) {
if (object instanceof Boolean && (Boolean) object) {
return 1;
}
return 0;
@ -157,7 +157,7 @@ class DoodleCondition extends IntCompareCondition {
@Override
protected int getInputValue(Game game, Ability source) {
Object object = game.getState().getValue("doodle" + source.getSourceId());
if (object != null && object instanceof Boolean && (Boolean) object) {
if (object instanceof Boolean && (Boolean) object) {
return 1;
}
return 0;
@ -178,7 +178,7 @@ class BuzzCondition extends IntCompareCondition {
@Override
protected int getInputValue(Game game, Ability source) {
Object object = game.getState().getValue("buzz" + source.getSourceId());
if (object != null && object instanceof Boolean && (Boolean) object) {
if (object instanceof Boolean && (Boolean) object) {
return 1;
}
return 0;

View file

@ -0,0 +1,72 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
/**
*
* @author TheElk801
*/
public final class Camaraderie extends CardImpl {
public Camaraderie(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{G}{W}");
// You gain X life and draw X cards, where X is the number of creatures you control. Creatures you control get +1/+1 until end of turn.
this.getSpellAbility().addEffect(new CamaraderieEffect());
}
public Camaraderie(final Camaraderie card) {
super(card);
}
@Override
public Camaraderie copy() {
return new Camaraderie(this);
}
}
class CamaraderieEffect extends OneShotEffect {
public CamaraderieEffect() {
super(Outcome.Benefit);
this.staticText = "You gain X life and draw X cards, "
+ "where X is the number of creatures you control. "
+ "Creatures you control get +1/+1 until end of turn.";
}
public CamaraderieEffect(final CamaraderieEffect effect) {
super(effect);
}
@Override
public CamaraderieEffect copy() {
return new CamaraderieEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getSourceId());
if (player == null) {
return false;
}
int xValue = game.getBattlefield().count(
StaticFilters.FILTER_CONTROLLED_CREATURE,
source.getSourceId(), source.getControllerId(), game
);
player.gainLife(xValue, game, source);
player.drawCards(xValue, game);
game.addEffect(new BoostControlledEffect(1, 1, Duration.EndOfTurn), source);
return true;
}
}

View file

@ -0,0 +1,59 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author Ryan-Saklad
*/
public final class CandlelightVigil extends CardImpl {
public CandlelightVigil(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}");
this.subtype.add(SubType.AURA);
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// Enchanted creature gets +3/+2 and has vigilance.
Effect effect = new BoostEnchantedEffect(3, 2, Duration.WhileOnBattlefield);
effect.setText("Enchanted creature gets +3/+2");
SimpleStaticAbility ability2 = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
effect = new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.AURA);
effect.setText("and has vigilance");
ability2.addEffect(effect);
this.addAbility(ability2);
}
public CandlelightVigil(final CandlelightVigil card) {
super(card);
}
@Override
public CandlelightVigil copy() {
return new CandlelightVigil(this);
}
}

View file

@ -0,0 +1,57 @@
package mage.cards.c;
import java.util.UUID;
import mage.constants.SubType;
import mage.abilities.keyword.FlashAbility;
import mage.target.common.TargetCreaturePermanent;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.DontUntapInControllersUntapStepEnchantedEffect;
import mage.abilities.effects.common.TapEnchantedEffect;
import mage.constants.Outcome;
import mage.target.TargetPermanent;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
/**
*
* @author TheElk801
*/
public final class CaptureSphere extends CardImpl {
public CaptureSphere(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}");
this.subtype.add(SubType.AURA);
// Flash
this.addAbility(FlashAbility.getInstance());
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// When Capture Sphere enters the battlefield, tap enchanted creature.
this.addAbility(new EntersBattlefieldTriggeredAbility(new TapEnchantedEffect()));
// Enchanted creature doesn't untap during its controller's untap step.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepEnchantedEffect()));
}
public CaptureSphere(final CaptureSphere card) {
super(card);
}
@Override
public CaptureSphere copy() {
return new CaptureSphere(this);
}
}

View file

@ -81,7 +81,7 @@ class ChainOfSilenceEffect extends OneShotEffect {
Spell spell = game.getStack().getSpell(source.getSourceId());
if (spell != null) {
StackObject newStackObject = spell.createCopyOnStack(game, source, player.getId(), true);
if (newStackObject != null && newStackObject instanceof Spell) {
if (newStackObject instanceof Spell) {
String activateMessage = ((Spell) newStackObject).getActivatedMessage(game);
if (activateMessage.startsWith(" casts ")) {
activateMessage = activateMessage.substring(6);

View file

@ -78,7 +78,7 @@ class ChainOfVaporEffect extends OneShotEffect {
Spell spell = game.getStack().getSpell(source.getSourceId());
if (spell != null) {
StackObject newStackObject = spell.createCopyOnStack(game, source, player.getId(), true);
if (newStackObject != null && newStackObject instanceof Spell) {
if (newStackObject instanceof Spell) {
String activateMessage = ((Spell) newStackObject).getActivatedMessage(game);
if (activateMessage.startsWith(" casts ")) {
activateMessage = activateMessage.substring(6);

View file

@ -80,7 +80,7 @@ class ChainStasisEffect extends OneShotEffect {
Spell spell = game.getStack().getSpell(source.getSourceId());
if (spell != null) {
StackObject newStackObject = spell.createCopyOnStack(game, source, player.getId(), true);
if (newStackObject != null && newStackObject instanceof Spell) {
if (newStackObject instanceof Spell) {
String activateMessage = ((Spell) newStackObject).getActivatedMessage(game);
if (activateMessage.startsWith(" casts ")) {
activateMessage = activateMessage.substring(6);

View file

@ -0,0 +1,132 @@
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.VariableCostImpl;
import mage.abilities.costs.common.RemoveCountersSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.ColorsOfManaSpentToCastCount;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.Counter;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetAnyTarget;
/**
*
* @author jmharmon
*/
public final class ChamberSentry extends CardImpl {
public ChamberSentry(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{X}");
this.subtype.add(SubType.CONSTRUCT);
this.power = new MageInt(0);
this.toughness = new MageInt(0);
// Chamber Sentry enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(), ColorsOfManaSpentToCastCount.getInstance(), true),
"with a +1/+1 counter on it for each color of mana spent to cast it"));
// {X}, {T}, Remove X +1/+1 counters from Chamber Sentry: It deals X damage to any target.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new ManacostVariableValue())
.setText("It deals X damage to any target"),
new ManaCostsImpl("{X}"));
ability.addCost(new TapSourceCost());
ability.addCost(new ChamberSentryRemoveVariableCountersSourceCost(CounterType.P1P1.createInstance()));
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
// {W}{U}{B}{R}{G}: Return Chamber Sentry from your graveyard to your hand.
this.addAbility(new SimpleActivatedAbility(Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), new ManaCostsImpl("{W}{U}{B}{R}{G}")));
}
public ChamberSentry(final ChamberSentry card) {
super(card);
}
@Override
public ChamberSentry copy() {
return new ChamberSentry(this);
}
}
class ChamberSentryRemoveVariableCountersSourceCost extends VariableCostImpl {
protected int minimalCountersToPay = 0;
private String counterName;
public ChamberSentryRemoveVariableCountersSourceCost(Counter counter) {
this(counter, 0);
}
public ChamberSentryRemoveVariableCountersSourceCost(Counter counter, String text) {
this(counter, 0, text);
}
public ChamberSentryRemoveVariableCountersSourceCost(Counter counter, int minimalCountersToPay) {
this(counter, minimalCountersToPay, "");
}
public ChamberSentryRemoveVariableCountersSourceCost(Counter counter, int minimalCountersToPay, String text) {
super(counter.getName() + " counters to remove");
this.minimalCountersToPay = minimalCountersToPay;
this.counterName = counter.getName();
if (text == null || text.isEmpty()) {
this.text = "Remove X " + counterName + " counters from {this}";
} else {
this.text = text;
}
}
public ChamberSentryRemoveVariableCountersSourceCost(final ChamberSentryRemoveVariableCountersSourceCost cost) {
super(cost);
this.minimalCountersToPay = cost.minimalCountersToPay;
this.counterName = cost.counterName;
}
@Override
public ChamberSentryRemoveVariableCountersSourceCost copy() {
return new ChamberSentryRemoveVariableCountersSourceCost(this);
}
@Override
public Cost getFixedCostsFromAnnouncedValue(int xValue) {
return new RemoveCountersSourceCost(new Counter(counterName, xValue));
}
@Override
public int getMinValue(Ability source, Game game) {
return minimalCountersToPay;
}
@Override
public int getMaxValue(Ability source, Game game) {
int maxValue = 0;
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
maxValue = permanent.getCounters(game).getCount(counterName);
}
return maxValue;
}
@Override
public int announceXValue(Ability source, Game game) {
return source.getManaCostsToPay().getX();
}
}

View file

@ -0,0 +1,36 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.common.turn.AddExtraTurnControllerEffect;
import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
/**
*
* @author TheElk801
*/
public final class ChanceForGlory extends CardImpl {
public ChanceForGlory(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}{W}");
// Creatures you control gain indestructible. Take an extra turn after this one. At the beginning of that turn's end step, you lose the game.
this.getSpellAbility().addEffect(new GainAbilityControlledEffect(
IndestructibleAbility.getInstance(), Duration.EndOfGame
).setText("Creatures you control gain indestructible"));
this.getSpellAbility().addEffect(new AddExtraTurnControllerEffect(true));
}
public ChanceForGlory(final ChanceForGlory card) {
super(card);
}
@Override
public ChanceForGlory copy() {
return new ChanceForGlory(this);
}
}

View file

@ -0,0 +1,76 @@
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.DiscardTargetCost;
import mage.abilities.costs.common.ExileFromGraveCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.SacrificeSourceEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.constants.SubType;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.target.common.TargetCardInHand;
import mage.target.common.TargetCardInYourGraveyard;
/**
*
* @author TheElk801
*/
public final class CharnelTroll extends CardImpl {
public CharnelTroll(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{G}");
this.subtype.add(SubType.TROLL);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// Trample
this.addAbility(TrampleAbility.getInstance());
// At the beginning of your upkeep, exile a creature card from your graveyard. If you do, put a +1/+1 counter on Morgue Troll. Otherwise sacrifice it.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
new DoIfCostPaid(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
new SacrificeSourceEffect(),
new ExileFromGraveCost(new TargetCardInYourGraveyard(
StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD
)), false
).setText("exile a creature card from your graveyard. "
+ "If you do, put a +1/+1 counter on {this}."
+ " Otherwise sacrifice it."),
TargetController.YOU, false
));
// {B}{G}, Discard a creature card: Put a +1/+1 counter on Morgue Troll.
Ability ability = new SimpleActivatedAbility(
Zone.BATTLEFIELD,
new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
new ManaCostsImpl("{B}{G}")
);
ability.addCost(new DiscardTargetCost(
new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE_A)
));
this.addAbility(ability);
}
public CharnelTroll(final CharnelTroll card) {
super(card);
}
@Override
public CharnelTroll copy() {
return new CharnelTroll(this);
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.c;
import java.util.UUID;
@ -46,6 +45,7 @@ public final class ChimeOfNight extends CardImpl {
// When Chime of Night is put into a graveyard from the battlefield, destroy target nonblack creature.
ability = new PutIntoGraveFromBattlefieldSourceTriggeredAbility(new DestroyTargetEffect(), false);
ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
}
public ChimeOfNight(final ChimeOfNight card) {

View file

@ -98,7 +98,7 @@ class ChorusOfTheConclaveReplacementEffect extends ReplacementEffectImpl {
// save the x value to be available for ETB replacement effect
Object object = game.getState().getValue("spellX" + source.getSourceId());
Map<String, Integer> spellX;
if (object != null && object instanceof Map) {
if (object instanceof Map) {
spellX = (Map<String, Integer>) object;
} else {
spellX = new HashMap<>();

View file

@ -1,4 +1,4 @@
package mage.cards.d;
package mage.cards.c;
import java.util.UUID;
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
@ -18,7 +18,7 @@ import mage.target.common.TargetCardInLibrary;
*
* @author TheElk801
*/
public final class Detour extends CardImpl {
public final class CircuitousRoute extends CardImpl {
private static final FilterCard filter
= new FilterCard("basic land cards and/or Gate cards");
@ -32,7 +32,7 @@ public final class Detour extends CardImpl {
));
}
public Detour(UUID ownerId, CardSetInfo setInfo) {
public CircuitousRoute(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}");
// Search your library for up to two basic lands and/or Gates and put them onto the battlefield tapped.
@ -41,12 +41,12 @@ public final class Detour extends CardImpl {
));
}
public Detour(final Detour card) {
public CircuitousRoute(final CircuitousRoute card) {
super(card);
}
@Override
public Detour copy() {
return new Detour(this);
public CircuitousRoute copy() {
return new CircuitousRoute(this);
}
}

View file

@ -0,0 +1,40 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.effects.common.DestroyAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.ToughnessPredicate;
/**
*
* @author TheElk801
*/
public final class CitywideBust extends CardImpl {
private static final FilterPermanent filter = new FilterCreaturePermanent("creatures with toughness 4 or greater");
static {
filter.add(new ToughnessPredicate(ComparisonType.MORE_THAN, 3));
}
public CitywideBust(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{W}{W}");
// Destroy all creatures with toughness 4 or greater.
this.getSpellAbility().addEffect(new DestroyAllEffect(filter));
}
public CitywideBust(final CitywideBust card) {
super(card);
}
@Override
public CitywideBust copy() {
return new CitywideBust(this);
}
}

View file

@ -0,0 +1,42 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.ToughnessPredicate;
import mage.target.common.TargetCreaturePermanent;
/**
* @author Ryan-Saklad
*/
public final class CollarTheCulprit extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with toughness 4 or greater");
static {
filter.add(new ToughnessPredicate(ComparisonType.MORE_THAN, 3));
}
public CollarTheCulprit(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{W}");
// Destroy target creature with toughness 4 or greater.
this.getSpellAbility().addEffect(new DestroyTargetEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
}
public CollarTheCulprit(final CollarTheCulprit card) {
super(card);
}
@Override
public CollarTheCulprit copy() {
return new CollarTheCulprit(this);
}
}

View file

@ -0,0 +1,45 @@
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.DiesTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.constants.SubType;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.game.permanent.token.ElfKnightToken;
/**
*
* @author TheElk801
*/
public final class ConclaveCavalier extends CardImpl {
public ConclaveCavalier(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{G}{W}{W}");
this.subtype.add(SubType.CENTAUR);
this.subtype.add(SubType.KNIGHT);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// When Conclave Cavalier dies, create two green and white 2/2 Elf Knight creature tokens with vigilance.
this.addAbility(new DiesTriggeredAbility(
new CreateTokenEffect(new ElfKnightToken(), 2)
));
}
public ConclaveCavalier(final ConclaveCavalier card) {
super(card);
}
@Override
public ConclaveCavalier copy() {
return new ConclaveCavalier(this);
}
}

View file

@ -0,0 +1,41 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.effects.common.DamageAllEffect;
import mage.abilities.effects.common.combat.CantBlockAllEffect;
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.common.FilterOpponentsCreaturePermanent;
/**
*
* @author TheElk801
*/
public final class CosmotronicWave extends CardImpl {
private static final FilterPermanent filter = new FilterOpponentsCreaturePermanent("creature your opponents control");
public CosmotronicWave(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}");
// Cosmotronic Wave deals 1 damage to each creature your opponents control. Creatures your opponents control can't block this turn.
this.getSpellAbility().addEffect(new DamageAllEffect(1, filter));
this.getSpellAbility().addEffect(new CantBlockAllEffect(
StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE,
Duration.EndOfTurn
));
}
public CosmotronicWave(final CosmotronicWave card) {
super(card);
}
@Override
public CosmotronicWave copy() {
return new CosmotronicWave(this);
}
}

View file

@ -6,6 +6,7 @@ import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.InstantSorceryExileGraveyardCount;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.SetPowerSourceEffect;
@ -40,7 +41,7 @@ public final class CracklingDrake extends CardImpl {
this.addAbility(new SimpleStaticAbility(
Zone.ALL,
new SetPowerSourceEffect(
new CracklingDrakeCount(), Duration.EndOfGame
InstantSorceryExileGraveyardCount.instance, Duration.EndOfGame
).setText("{this}'s power is equal to the total number "
+ "of instant and sorcery cards you own "
+ "in exile and in your graveyard.")

View file

@ -0,0 +1,45 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Mode;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetArtifactPermanent;
import mage.target.common.TargetEnchantmentPermanent;
/**
*
* @author Ryan-Saklad
*/
public final class CrushContraband extends CardImpl {
public CrushContraband(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{W}");
// Choose one or both - Destroy target artifact; or Destroy target land.
this.getSpellAbility().getModes().setMinModes(1);
this.getSpellAbility().getModes().setMaxModes(2);
this.getSpellAbility().addTarget(new TargetArtifactPermanent());
this.getSpellAbility().addEffect(new ExileTargetEffect());
Mode mode1 = new Mode();
mode1.getTargets().add(new TargetEnchantmentPermanent());
mode1.getEffects().add(new ExileTargetEffect());
this.getSpellAbility().addMode(mode1);
}
public CrushContraband(final CrushContraband card) {
super(card);
}
@Override
public CrushContraband copy() {
return new CrushContraband(this);
}
}

View file

@ -0,0 +1,49 @@
package mage.cards.d;
import java.util.UUID;
import mage.abilities.common.GainLifeControllerTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.game.permanent.token.SoldierLifelinkToken;
/**
*
* @author TheElk801
*/
public final class DawnOfHope extends CardImpl {
public DawnOfHope(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}");
// Whenever you gain life, you may pay {2}. If you do, draw a card.
this.addAbility(new GainLifeControllerTriggeredAbility(
new DoIfCostPaid(
new DrawCardSourceControllerEffect(1),
new GenericManaCost(2)), false
));
// {3}{W}: Create a 1/1 white Soldier creature token with lifelink.
this.addAbility(new SimpleActivatedAbility(
Zone.BATTLEFIELD,
new CreateTokenEffect(new SoldierLifelinkToken()),
new ManaCostsImpl("{3}{W}")
));
}
public DawnOfHope(final DawnOfHope card) {
super(card);
}
@Override
public DawnOfHope copy() {
return new DawnOfHope(this);
}
}

View file

@ -0,0 +1,37 @@
package mage.cards.d;
import java.util.UUID;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.keyword.SurveilEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author TheElk801
*/
public final class DazzlingLights extends CardImpl {
public DazzlingLights(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}");
// Target creature gets -3/-0 until end of turn.
this.getSpellAbility().addEffect(new BoostTargetEffect(-3, 0, Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Surveil 2.
this.getSpellAbility().addEffect(new SurveilEffect(2));
}
public DazzlingLights(final DazzlingLights card) {
super(card);
}
@Override
public DazzlingLights copy() {
return new DazzlingLights(this);
}
}

View file

@ -0,0 +1,51 @@
package mage.cards.d;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.combat.CantBlockActivateAttachedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.DefenderAbility;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author Ryan-Saklad
*/
public final class Demotion extends CardImpl {
public Demotion(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{W}");
this.subtype.add(SubType.AURA);
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// Enchanted creature can't block, and its activated abilities can't be activated.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBlockActivateAttachedEffect()));
}
public Demotion(final Demotion card) {
super(card);
}
@Override
public Demotion copy() {
return new Demotion(this);
}
}

View file

@ -0,0 +1,83 @@
package mage.cards.d;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CounterTargetWithReplacementEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetSpell;
import mage.target.common.TargetCardInYourGraveyard;
import mage.target.targetpointer.SecondTargetPointer;
/**
*
* @author TheElk801
*/
public final class DeviousCoverUp extends CardImpl {
public DeviousCoverUp(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}{U}");
// Counter target spell. If that spell is countered this way, exile it instead of putting it into its owner's graveyard.
this.getSpellAbility().addEffect(new CounterTargetWithReplacementEffect(Zone.EXILED));
this.getSpellAbility().addTarget(new TargetSpell());
// You may shuffle up to four target cards from your graveyard into your library.
this.getSpellAbility().addEffect(new DeviousCoverUpEffect().setTargetPointer(new SecondTargetPointer()));
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0, 4));
}
public DeviousCoverUp(final DeviousCoverUp card) {
super(card);
}
@Override
public DeviousCoverUp copy() {
return new DeviousCoverUp(this);
}
}
class DeviousCoverUpEffect extends OneShotEffect {
public DeviousCoverUpEffect() {
super(Outcome.Benefit);
this.staticText = "You may shuffle up to four target cards "
+ "from your graveyard into your library.";
}
public DeviousCoverUpEffect(final DeviousCoverUpEffect effect) {
super(effect);
}
@Override
public DeviousCoverUpEffect copy() {
return new DeviousCoverUpEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getFirstTarget());
if (player == null || !player.chooseUse(outcome, "Shuffle the targeted cards into your library?", source, game)) {
return false;
}
Cards cards = new CardsImpl();
for (UUID targetId : targetPointer.getTargets(game, source)) {
Card card = game.getCard(targetId);
if (card != null) {
cards.add(card);
}
}
player.getLibrary().addAll(cards.getCards(game), game);
player.shuffleLibrary(source, game);
return true;
}
}

View file

@ -0,0 +1,45 @@
package mage.cards.d;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Zone;
/**
*
* @author TheElk801
*/
public final class DevkarinDissident extends CardImpl {
public DevkarinDissident(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.subtype.add(SubType.ELF);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// {4}{G}: Devkarin Dissident gets +2/+2 until end of turn.
this.addAbility(new SimpleActivatedAbility(
Zone.BATTLEFIELD,
new BoostSourceEffect(2, 2, Duration.EndOfTurn),
new ManaCostsImpl("{4}{G}")
));
}
public DevkarinDissident(final DevkarinDissident card) {
super(card);
}
@Override
public DevkarinDissident copy() {
return new DevkarinDissident(this);
}
}

View file

@ -0,0 +1,126 @@
package mage.cards.d;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.ReturnToHandFromBattlefieldAllEffect;
import mage.abilities.effects.common.discard.DiscardEachPlayerEffect;
import mage.abilities.effects.keyword.SurveilEffect;
import mage.cards.CardSetInfo;
import mage.cards.SplitCard;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Outcome;
import mage.constants.SpellAbilityType;
import mage.constants.TargetController;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterNonlandPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.filter.predicate.permanent.PermanentIdPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetPermanent;
/**
*
* @author TheElk801
*/
public final class DiscoveryDispersal extends SplitCard {
public DiscoveryDispersal(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, new CardType[]{CardType.INSTANT}, "{1}{U/B}", "{3}{U}{B}", SpellAbilityType.SPLIT);
// Discovery
// Surveil 2, then draw a card.
this.getLeftHalfCard().getSpellAbility().addEffect(
new SurveilEffect(2).setText("Surveil 2,")
);
this.getLeftHalfCard().getSpellAbility().addEffect(
new DrawCardSourceControllerEffect(1
).setText("then draw a card. <i>(To surveil 2, "
+ "look at the top two cards of your library, "
+ "then put any number of them into your graveyard "
+ "and the rest on top of your library "
+ "in any order.)</i>")
);
// Dispersal
// Each opponent returns a nonland permanent they control with the highest converted mana cost among permanents they control to its owners hand, then discards a card.
this.getRightHalfCard().getSpellAbility().addEffect(new DispersalEffect());
}
public DiscoveryDispersal(final DiscoveryDispersal card) {
super(card);
}
@Override
public DiscoveryDispersal copy() {
return new DiscoveryDispersal(this);
}
}
class DispersalEffect extends OneShotEffect {
public DispersalEffect() {
super(Outcome.Benefit);
this.staticText = "Each opponent returns a nonland permanent "
+ "they control with the highest converted mana cost "
+ "among permanents they control to its owners hand, "
+ "then discards a card.";
}
public DispersalEffect(final DispersalEffect effect) {
super(effect);
}
@Override
public DispersalEffect copy() {
return new DispersalEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
Set<PermanentIdPredicate> permsToReturn = new HashSet();
for (UUID opponentId : game.getOpponents(player.getId())) {
Player opponent = game.getPlayer(opponentId);
if (opponent == null) {
continue;
}
int highestCMC = 0;
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(opponentId)) {
if (permanent != null && !permanent.isLand()) {
highestCMC = Math.max(highestCMC, permanent.getConvertedManaCost());
}
}
FilterPermanent filter = new FilterNonlandPermanent("permanent you control with converted mana cost " + highestCMC);
filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, highestCMC));
filter.add(new ControllerIdPredicate(opponentId));
Target target = new TargetPermanent(1, 1, filter, true);
if (opponent.choose(outcome, target, source.getSourceId(), game)) {
if (target.getFirstTarget() == null) {
continue;
}
permsToReturn.add(new PermanentIdPredicate(target.getFirstTarget()));
}
}
FilterPermanent filter = new FilterPermanent();
filter.add(Predicates.or(permsToReturn));
new ReturnToHandFromBattlefieldAllEffect(filter).apply(game, source);
new DiscardEachPlayerEffect(
new StaticValue(1), false, TargetController.OPPONENT
).apply(game, source);
return true;
}
}

View file

@ -0,0 +1,85 @@
package mage.cards.d;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.CopyEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.EntersTheBattlefieldEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentToken;
import mage.game.permanent.token.AngelVigilanceToken;
/**
*
* @author TheElk801
*/
public final class DivineVisitation extends CardImpl {
public DivineVisitation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}{W}");
// TODO: This implementation is not entirely correct, see https://twitter.com/EliShffrn/status/1042145606582591490
// If one or more creature tokens would be created under your control, that many 4/4 white Angel creature tokens with flying and vigilance are created instead.
this.addAbility(new SimpleStaticAbility(
Zone.BATTLEFIELD, new DivineVisitationEffect()
));
}
public DivineVisitation(final DivineVisitation card) {
super(card);
}
@Override
public DivineVisitation copy() {
return new DivineVisitation(this);
}
}
class DivineVisitationEffect extends ReplacementEffectImpl {
public DivineVisitationEffect() {
super(Duration.WhileOnBattlefield, Outcome.Copy, false);
staticText = "If one or more creature tokens would be created "
+ "under your control, that many 4/4 white Angel creature "
+ "tokens with flying and vigilance are created instead.";
}
public DivineVisitationEffect(DivineVisitationEffect effect) {
super(effect);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent perm = ((EntersTheBattlefieldEvent) event).getTarget();
return perm != null
&& perm.isCreature()
&& perm instanceof PermanentToken
&& perm.isControlledBy(source.getControllerId());
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
game.addEffect(new CopyEffect(Duration.Custom, new AngelVigilanceToken(), event.getTargetId()), source);
return false;
}
@Override
public DivineVisitationEffect copy() {
return new DivineVisitationEffect(this);
}
}

View file

@ -0,0 +1,32 @@
package mage.cards.d;
import java.util.UUID;
import mage.MageInt;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author TheElk801
*/
public final class DouserOfLights extends CardImpl {
public DouserOfLights(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}");
this.subtype.add(SubType.HORROR);
this.power = new MageInt(4);
this.toughness = new MageInt(5);
}
public DouserOfLights(final DouserOfLights card) {
super(card);
}
@Override
public DouserOfLights copy() {
return new DouserOfLights(this);
}
}

View file

@ -0,0 +1,46 @@
package mage.cards.d;
import java.util.UUID;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.PutLibraryIntoGraveTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.FilterSpell;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.target.TargetPlayer;
/**
*
* @author TheElk801
*/
public final class DrownedSecrets extends CardImpl {
private static final FilterSpell filter = new FilterSpell("a blue spell");
static {
filter.add(new ColorPredicate(ObjectColor.BLUE));
}
public DrownedSecrets(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}");
// Whenever you cast a blue spell, target player puts the top two cards if their library into their graveyard.
Ability ability = new SpellCastControllerTriggeredAbility(
new PutLibraryIntoGraveTargetEffect(2), filter, false
);
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
}
public DrownedSecrets(final DrownedSecrets card) {
super(card);
}
@Override
public DrownedSecrets copy() {
return new DrownedSecrets(this);
}
}

View file

@ -0,0 +1,46 @@
package mage.cards.e;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.DamagePlayersEffect;
import mage.constants.SubType;
import mage.abilities.keyword.DefenderAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetController;
import mage.filter.StaticFilters;
/**
*
* @author TheElk801
*/
public final class ElectrostaticField extends CardImpl {
public ElectrostaticField(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
this.subtype.add(SubType.WALL);
this.power = new MageInt(0);
this.toughness = new MageInt(4);
// Defender
this.addAbility(DefenderAbility.getInstance());
// When you cast an instant or sorcery spell, Electrostatic Field deals 1 damage to each opponent.
this.addAbility(new SpellCastControllerTriggeredAbility(
new DamagePlayersEffect(1, TargetController.OPPONENT),
StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false
));
}
public ElectrostaticField(final ElectrostaticField card) {
super(card);
}
@Override
public ElectrostaticField copy() {
return new ElectrostaticField(this);
}
}

View file

@ -70,7 +70,7 @@ class EngineeredExplosivesEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
MageObject engineeredExplosives = game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD);
if(engineeredExplosives != null && engineeredExplosives instanceof Permanent){
if(engineeredExplosives instanceof Permanent){
int count = ((Permanent)engineeredExplosives).getCounters(game).getCount(CounterType.CHARGE);
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if(permanent.getConvertedManaCost() == count){

View file

@ -4,12 +4,12 @@ import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.constants.SubType;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
@ -78,7 +78,7 @@ class ErraticCyclopsTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
return "Whenever you cast an instant or sorcery spell, "
+ "{this} gets +X/+X until end of turn, "
+ "{this} gets +X/+0 until end of turn, "
+ "where X is that spell's converted mana cost";
}

View file

@ -0,0 +1,58 @@
package mage.cards.e;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.LimitedTimesPerTurnActivatedAbility;
import mage.abilities.costs.common.DiscardTargetCost;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.target.common.TargetCardInHand;
/**
*
* @author TheElk801
*/
public final class ErstwhileTrooper extends CardImpl {
public ErstwhileTrooper(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{G}");
this.subtype.add(SubType.ZOMBIE);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Discard a creature card: Erstwhile Trooper gets +2/+2 and gains trample until end of turn. Activate this ability only once each turn.
Ability ability = new LimitedTimesPerTurnActivatedAbility(
Zone.BATTLEFIELD,
new BoostSourceEffect(
2, 2, Duration.EndOfTurn
).setText("{this} gets +2/+2"),
new DiscardTargetCost(new TargetCardInHand(
StaticFilters.FILTER_CARD_CREATURE_A
))
);
ability.addEffect(new GainAbilitySourceEffect(
TrampleAbility.getInstance(), Duration.EndOfTurn
).setText("and gains trample until end of turn"));
this.addAbility(ability);
}
public ErstwhileTrooper(final ErstwhileTrooper card) {
super(card);
}
@Override
public ErstwhileTrooper copy() {
return new ErstwhileTrooper(this);
}
}

View file

@ -77,7 +77,7 @@ class EssenceFluxEffect extends OneShotEffect {
cardsToBattlefield.add(targetId);
} else {
Card card = game.getCard(targetId);
if (card != null && card instanceof MeldCard) {
if (card instanceof MeldCard) {
MeldCard meldCard = (MeldCard) card;
Card topCard = meldCard.getTopHalfCard();
Card bottomCard = meldCard.getBottomHalfCard();

View file

@ -0,0 +1,151 @@
package mage.cards.e;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ShuffleIntoLibrarySourceEffect;
import mage.abilities.keyword.CantBeBlockedSourceAbility;
import mage.cards.Card;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.FilterCard;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.filter.predicate.permanent.CounterPredicate;
import mage.game.Game;
import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author TheElk801
*/
public final class EtrataTheSilencer extends CardImpl {
public EtrataTheSilencer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{B}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.VAMPIRE);
this.subtype.add(SubType.ASSASSIN);
this.power = new MageInt(3);
this.toughness = new MageInt(5);
// Etrata, the Silencer can't be blocked.
this.addAbility(new CantBeBlockedSourceAbility());
// Whenever Etrata deals combat damage to a player, exile target creature that player controls and put a hit counter on that card. That player loses the game if they own three or more exiled card with hit counters on them. Etrata's owner shuffles Etrata into their library.
this.addAbility(new EtrataTheSilencerTriggeredAbility());
}
public EtrataTheSilencer(final EtrataTheSilencer card) {
super(card);
}
@Override
public EtrataTheSilencer copy() {
return new EtrataTheSilencer(this);
}
}
class EtrataTheSilencerTriggeredAbility extends TriggeredAbilityImpl {
public EtrataTheSilencerTriggeredAbility() {
super(Zone.BATTLEFIELD, new EtrataTheSilencerEffect());
}
public EtrataTheSilencerTriggeredAbility(final EtrataTheSilencerTriggeredAbility ability) {
super(ability);
}
@Override
public EtrataTheSilencerTriggeredAbility copy() {
return new EtrataTheSilencerTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGED_PLAYER;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event;
if (damageEvent.isCombatDamage() && event.getSourceId().equals(this.getSourceId())) {
Player opponent = game.getPlayer(event.getPlayerId());
if (opponent != null) {
FilterCreaturePermanent filter = new FilterCreaturePermanent("creature " + opponent.getLogName() + " controls");
filter.add(new ControllerIdPredicate(opponent.getId()));
this.getTargets().clear();
this.addTarget(new TargetCreaturePermanent(filter));
return true;
}
}
return false;
}
@Override
public String getRule() {
return "Whenever {this} deals combat damage to a player, "
+ "exile target creature that player controls "
+ "and put a hit counter on that card. "
+ "That player loses the game if they own three or more "
+ "exiled cards with hit counters on them. "
+ "{this}'s owner shuffles {this} into their library.";
}
}
class EtrataTheSilencerEffect extends OneShotEffect {
private static final FilterCard filter = new FilterCard();
static {
filter.add(new CounterPredicate(CounterType.HIT));
}
public EtrataTheSilencerEffect() {
super(Outcome.Benefit);
}
public EtrataTheSilencerEffect(final EtrataTheSilencerEffect effect) {
super(effect);
}
@Override
public EtrataTheSilencerEffect copy() {
return new EtrataTheSilencerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent creature = game.getPermanent(source.getFirstTarget());
if (creature == null) {
return false;
}
Player controller = game.getPlayer(source.getControllerId());
Player player = game.getPlayer(creature.getControllerId());
if (controller == null || player == null) {
return false;
}
controller.moveCards(creature, Zone.EXILED, source, game);
Card card = game.getCard(source.getFirstTarget());
if (card != null) {
card.addCounters(CounterType.HIT.createInstance(), source, game);
}
if (game.getExile().getExileZone(player.getId()).count(filter, game) > 2) {
player.lost(game);
}
return new ShuffleIntoLibrarySourceEffect().apply(game, source);
}
}

View file

@ -40,7 +40,7 @@ public final class ExpansionExplosion extends SplitCard {
// Expansion
// Copy target instant or sorcery spell with converted mana cost 4 or less. You may choose new targets for the copy.
this.getLeftHalfCard().getSpellAbility().addEffect(new CopyTargetSpellEffect());
this.getSpellAbility().addTarget(new TargetSpell(filter));
this.getLeftHalfCard().getSpellAbility().addTarget(new TargetSpell(filter));
// Explosion
// Explosion deals X damage to any target. Target player draws X cards.

View file

@ -0,0 +1,133 @@
package mage.cards.e;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.common.DestroySourceEffect;
import mage.abilities.effects.common.continuous.PlayTheTopCardEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.players.Player;
/**
*
* @author TheElk801
*/
public final class ExperimentalFrenzy extends CardImpl {
public ExperimentalFrenzy(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}");
// You may look at the top card of your library any time.
this.addAbility(new SimpleStaticAbility(
Zone.BATTLEFIELD, new ExperimentalFrenzyTopCardEffect()
));
// You may play the top card of your library.
this.addAbility(new SimpleStaticAbility(
Zone.BATTLEFIELD, new PlayTheTopCardEffect()
));
// You can't play cards from your hand.
this.addAbility(new SimpleStaticAbility(
Zone.BATTLEFIELD, new ExperimentalFrenzyRestrictionEffect()
));
// {3}{R}: Destroy Experimental Frenzy.
this.addAbility(new SimpleActivatedAbility(
new DestroySourceEffect(), new ManaCostsImpl("{3}{R}")
));
}
public ExperimentalFrenzy(final ExperimentalFrenzy card) {
super(card);
}
@Override
public ExperimentalFrenzy copy() {
return new ExperimentalFrenzy(this);
}
}
class ExperimentalFrenzyTopCardEffect extends ContinuousEffectImpl {
public ExperimentalFrenzyTopCardEffect() {
super(Duration.WhileOnBattlefield, Layer.PlayerEffects, SubLayer.NA, Outcome.Benefit);
staticText = "You may look at the top card of your library any time.";
}
public ExperimentalFrenzyTopCardEffect(final ExperimentalFrenzyTopCardEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return true;
}
Card topCard = controller.getLibrary().getFromTop(game);
if (topCard == null) {
return true;
}
MageObject obj = source.getSourceObject(game);
if (obj == null) {
return true;
}
controller.lookAtCards("Top card of " + obj.getIdName() + " controller's library", topCard, game);
return true;
}
@Override
public ExperimentalFrenzyTopCardEffect copy() {
return new ExperimentalFrenzyTopCardEffect(this);
}
}
class ExperimentalFrenzyRestrictionEffect extends ContinuousRuleModifyingEffectImpl {
public ExperimentalFrenzyRestrictionEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment);
this.staticText = "You can't play cards from your hand";
}
public ExperimentalFrenzyRestrictionEffect(final ExperimentalFrenzyRestrictionEffect effect) {
super(effect);
}
@Override
public ExperimentalFrenzyRestrictionEffect copy() {
return new ExperimentalFrenzyRestrictionEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.PLAY_LAND
|| event.getType() == GameEvent.EventType.CAST_SPELL;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return event.getPlayerId().equals(source.getControllerId())
&& event.getZone() == Zone.HAND;
}
}

View file

@ -0,0 +1,33 @@
package mage.cards.f;
import java.util.UUID;
import mage.MageInt;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author TheElk801
*/
public final class FearlessHalberdier extends CardImpl {
public FearlessHalberdier(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(3);
this.toughness = new MageInt(2);
}
public FearlessHalberdier(final FearlessHalberdier card) {
super(card);
}
@Override
public FearlessHalberdier copy() {
return new FearlessHalberdier(this);
}
}

View file

@ -0,0 +1,46 @@
package mage.cards.f;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.constants.SubType;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.filter.StaticFilters;
/**
*
* @author TheElk801
*/
public final class FireUrchin extends CardImpl {
public FireUrchin(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
this.subtype.add(SubType.ELEMENTAL);
this.power = new MageInt(1);
this.toughness = new MageInt(3);
// Trample
this.addAbility(TrampleAbility.getInstance());
// Whenever you cast an instant or sorcery spell, Fire Urchin gets +1/+0 until end of turn.
this.addAbility(new SpellCastControllerTriggeredAbility(
new BoostSourceEffect(1, 0, Duration.EndOfTurn),
StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false
));
}
public FireUrchin(final FireUrchin card) {
super(card);
}
@Override
public FireUrchin copy() {
return new FireUrchin(this);
}
}

View file

@ -87,7 +87,7 @@ class FiresongAndSunspeakerTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
MageObject object = game.getObject(event.getSourceId());
if (object != null && object instanceof Spell) {
if (object instanceof Spell) {
if (event.getTargetId().equals(this.getControllerId())
&& object.getColor(game).contains(ObjectColor.WHITE)
&& (object.isInstant()

View file

@ -0,0 +1,41 @@
package mage.cards.f;
import java.util.UUID;
import mage.MageInt;
import mage.constants.SubType;
import mage.abilities.keyword.ConvokeAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author TheElk801
*/
public final class FlightOfEquenauts extends CardImpl {
public FlightOfEquenauts(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{7}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.KNIGHT);
this.power = new MageInt(4);
this.toughness = new MageInt(5);
// Convoke
this.addAbility(new ConvokeAbility());
// Flying
this.addAbility(FlyingAbility.getInstance());
}
public FlightOfEquenauts(final FlightOfEquenauts card) {
super(card);
}
@Override
public FlightOfEquenauts copy() {
return new FlightOfEquenauts(this);
}
}

View file

@ -0,0 +1,62 @@
package mage.cards.f;
import java.util.UUID;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.cards.CardSetInfo;
import mage.cards.SplitCard;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SpellAbilityType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.mageobject.SupertypePredicate;
import mage.target.common.TargetCardInLibrary;
/**
*
* @author TheElk801
*/
public final class FlowerFlourish extends SplitCard {
private static final FilterCard filter
= new FilterCard("basic Forest or Plains card");
static {
filter.add(new SupertypePredicate(SuperType.BASIC));
filter.add(Predicates.or(
new SubtypePredicate(SubType.FOREST),
new SubtypePredicate(SubType.PLAINS)
));
}
public FlowerFlourish(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{G/W}", "{4}{G}{W}", SpellAbilityType.SPLIT);
// Flower
// Search your library for a basic Forest or Plains card, reveal it, put it into your hand, then shuffle your library.
this.getLeftHalfCard().getSpellAbility().addEffect(
new SearchLibraryPutInHandEffect(
new TargetCardInLibrary(filter), true, true
)
);
// Flourish
// Creatures you control get +2/+2 until end of turn.
this.getRightHalfCard().getSpellAbility().addEffect(
new BoostControlledEffect(2, 2, Duration.EndOfTurn)
);
}
public FlowerFlourish(final FlowerFlourish card) {
super(card);
}
@Override
public FlowerFlourish copy() {
return new FlowerFlourish(this);
}
}

View file

@ -151,7 +151,7 @@ class ForbiddenCryptPutIntoYourGraveyardReplacementEffect extends ReplacementEff
Card card = game.getCard(event.getTargetId());
if (card != null && card.isOwnedBy(source.getControllerId())) {
Permanent permanent = ((ZoneChangeEvent) event).getTarget();
if (permanent == null || !(permanent instanceof PermanentToken)) {
if (!(permanent instanceof PermanentToken)) {
return true;
}
}

View file

@ -1,7 +1,6 @@
package mage.cards.f;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.BecomesTargetTriggeredAbility;
@ -15,13 +14,11 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterSpell;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
/**
@ -32,7 +29,6 @@ public final class ForceProjection extends CardImpl {
public ForceProjection(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}{U}");
// Create a token that is a copy of target creature you control except that it is an Illusion in addition to its other types and gains "When this creature becomes the target of a spell, sacrifice it."
this.getSpellAbility().addEffect(new ForceProjectionEffect());
@ -56,8 +52,8 @@ class ForceProjectionEffect extends OneShotEffect {
public ForceProjectionEffect() {
super(Outcome.Copy);
this.staticText = "Create a token that is a copy of target creature you control except that it is an Illusion " +
"in addition to its other types and gains \"When this creature becomes the target of a spell, sacrifice it.\"";
this.staticText = "Create a token that is a copy of target creature you control except that it is an Illusion "
+ "in addition to its other types and gains \"When this creature becomes the target of a spell, sacrifice it.\"";
}
public ForceProjectionEffect(final ForceProjectionEffect effect) {

View file

@ -73,7 +73,7 @@ class ForsakenWastesTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
MageObject eventSourceObject = game.getObject(event.getSourceId());
if (eventSourceObject != null && event.getTargetId().equals(this.getSourceId())&& eventSourceObject instanceof Spell ) {
if (event.getTargetId().equals(this.getSourceId()) && eventSourceObject instanceof Spell) {
getEffects().get(0).setTargetPointer(new FixedTarget(event.getPlayerId()));
return true;
}

View file

@ -150,7 +150,7 @@ class GoToJailUpkeepEffect extends OneShotEffect {
Permanent permanent = (Permanent) source.getSourceObjectIfItStillExists(game);
if (sourceObject != null && sourceObject instanceof Permanent && permanent != null) {
if (sourceObject instanceof Permanent && permanent != null) {
UUID opponentId = (UUID) game.getState().getValue(sourceObject.getId().toString() + ChooseOpponentEffect.VALUE_KEY);
Player opponent = game.getPlayer(opponentId);

View file

@ -0,0 +1,57 @@
package mage.cards.g;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.constants.SubType;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
/**
*
* @author TheElk801
*/
public final class GatekeeperGargoyle extends CardImpl {
private static final FilterPermanent filter = new FilterControlledPermanent();
static {
filter.add(new SubtypePredicate(SubType.GATE));
}
public GatekeeperGargoyle(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{6}");
this.subtype.add(SubType.GARGOYLE);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Gargoyle Guardian enters the battlefield with a +1/+1 counter on it for each Gate you control.
this.addAbility(new EntersBattlefieldAbility(
new AddCountersSourceEffect(
CounterType.P1P1.createInstance(),
new PermanentsOnBattlefieldCount(filter), true
), "with a +1/+1 counter on it for each Gate you control"
));
}
public GatekeeperGargoyle(final GatekeeperGargoyle card) {
super(card);
}
@Override
public GatekeeperGargoyle copy() {
return new GatekeeperGargoyle(this);
}
}

View file

@ -0,0 +1,39 @@
package mage.cards.g;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author TheElk801
*/
public final class GenerousStray extends CardImpl {
public GenerousStray(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}");
this.subtype.add(SubType.CAT);
this.power = new MageInt(1);
this.toughness = new MageInt(2);
// When Generous Stray enters the battlefield, draw a card.
this.addAbility(new EntersBattlefieldTriggeredAbility(
new DrawCardSourceControllerEffect(1)
));
}
public GenerousStray(final GenerousStray card) {
super(card);
}
@Override
public GenerousStray copy() {
return new GenerousStray(this);
}
}

View file

@ -71,7 +71,7 @@ class GenesisHydraPutOntoBattlefieldEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Object obj = getValue(CastSourceTriggeredAbility.SOURCE_CAST_SPELL_ABILITY);
if (controller != null && obj != null && obj instanceof SpellAbility) {
if (controller != null && obj instanceof SpellAbility) {
int count = ((SpellAbility) obj).getManaCostsToPay().getX();
if (count > 0) {
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, count));

View file

@ -0,0 +1,35 @@
package mage.cards.g;
import java.util.UUID;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.counters.CounterType;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author TheElk801
*/
public final class GirdForBattle extends CardImpl {
public GirdForBattle(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W}");
// Put a +1/+1 counter on each of up to two target creatures.
this.getSpellAbility().addEffect(new AddCountersTargetEffect(
CounterType.P1P1.createInstance()
).setText("Put a +1/+1 counter on each of up to two target creatures"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2));
}
public GirdForBattle(final GirdForBattle card) {
super(card);
}
@Override
public GirdForBattle copy() {
return new GirdForBattle(this);
}
}

View file

@ -10,11 +10,11 @@ import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.EquipAbility;
import mage.abilities.keyword.MenaceAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
@ -52,6 +52,7 @@ public final class GlaiveOfTheGuildpact extends CardImpl {
ability.addEffect(new GainAbilityAttachedEffect(
new MenaceAbility(), AttachmentType.EQUIPMENT
).setText("and menace"));
this.addAbility(ability);
// Equip {3}
this.addAbility(new EquipAbility(3));

View file

@ -8,11 +8,11 @@ import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveControllerEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.common.FilterLandCard;
import mage.game.Game;
import mage.players.Player;
@ -35,9 +35,11 @@ public final class GlowsporeShaman extends CardImpl {
this.toughness = new MageInt(1);
// When Glowspore Shaman enters the battlefield, put the top three cards of your library into your graveyard. You may put a land card from your graveyard on top of your library.
this.addAbility(new EntersBattlefieldTriggeredAbility(
Ability ability = new EntersBattlefieldTriggeredAbility(
new PutTopCardOfLibraryIntoGraveControllerEffect(3), false
));
);
ability.addEffect(new GlowsporeShamanEffect());
this.addAbility(ability);
}
public GlowsporeShaman(final GlowsporeShaman card) {

View file

@ -9,10 +9,10 @@ import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterNonlandPermanent;
import mage.filter.predicate.mageobject.ColorlessPredicate;
@ -40,7 +40,7 @@ public final class GoblinCratermaker extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// {1}, Sacrifice Goblin Cratermaker: Choose one
// {1}, Sacrifice Goblin Cratermaker: Choose one
// Goblin Cratermaker deals 2 damage to target creature.
Ability ability = new SimpleActivatedAbility(
new DamageTargetEffect(2), new GenericManaCost(1)
@ -51,7 +51,7 @@ public final class GoblinCratermaker extends CardImpl {
// Destroy target colorless nonland permanent.
Mode mode = new Mode();
mode.getEffects().add(new DestroyTargetEffect());
mode.getTargets().add(new TargetPermanent());
mode.getTargets().add(new TargetPermanent(filter));
ability.addMode(mode);
this.addAbility(ability);

View file

@ -0,0 +1,51 @@
package mage.cards.g;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.common.combat.CantBlockAllEffect;
import mage.abilities.keyword.DefenderAbility;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AbilityPredicate;
/**
*
* @author TheElk801
*/
public final class GoblinLocksmith extends CardImpl {
private static final FilterCreaturePermanent filter
= new FilterCreaturePermanent("creatures with defender");
static {
filter.add(new AbilityPredicate(DefenderAbility.class));
}
public GoblinLocksmith(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
this.subtype.add(SubType.GOBLIN);
this.subtype.add(SubType.ROGUE);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// Whenever Goblin Locksmith attacks, creatures with defender can't block this turn.
this.addAbility(new AttacksTriggeredAbility(
new CantBlockAllEffect(filter, Duration.EndOfTurn), false
));
}
public GoblinLocksmith(final GoblinLocksmith card) {
super(card);
}
@Override
public GoblinLocksmith copy() {
return new GoblinLocksmith(this);
}
}

View file

@ -0,0 +1,55 @@
package mage.cards.g;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.constants.SubType;
import mage.abilities.keyword.DefenderAbility;
import mage.abilities.keyword.IndestructibleAbility;
import mage.abilities.keyword.ReachAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Zone;
/**
*
* @author TheElk801
*/
public final class GrapplingSundew extends CardImpl {
public GrapplingSundew(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.subtype.add(SubType.PLANT);
this.power = new MageInt(0);
this.toughness = new MageInt(4);
// Defender
this.addAbility(DefenderAbility.getInstance());
// Reach
this.addAbility(ReachAbility.getInstance());
// {4}{G}: Grappling Sundew gains indestructible until end of turn.
this.addAbility(new SimpleActivatedAbility(
Zone.BATTLEFIELD,
new GainAbilitySourceEffect(
IndestructibleAbility.getInstance(),
Duration.EndOfTurn
), new ManaCostsImpl("{4}{G}")
));
}
public GrapplingSundew(final GrapplingSundew card) {
super(card);
}
@Override
public GrapplingSundew copy() {
return new GrapplingSundew(this);
}
}

View file

@ -0,0 +1,73 @@
package mage.cards.g;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.JumpStartAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPlayer;
import mage.target.common.TargetControlledCreaturePermanent;
/**
*
* @author TheElk801
*/
public final class GraviticPunch extends CardImpl {
public GraviticPunch(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}");
// Target creature you control deals damage equal to its power to target player.
this.getSpellAbility().addEffect(new GraviticPunchEffect());
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
this.getSpellAbility().addTarget(new TargetPlayer());
// Jump-start
this.addAbility(new JumpStartAbility(this));
}
public GraviticPunch(final GraviticPunch card) {
super(card);
}
@Override
public GraviticPunch copy() {
return new GraviticPunch(this);
}
}
class GraviticPunchEffect extends OneShotEffect {
public GraviticPunchEffect() {
super(Outcome.Benefit);
this.staticText = "Target creature you control deals damage "
+ "equal to its power to target player.";
}
public GraviticPunchEffect(final GraviticPunchEffect effect) {
super(effect);
}
@Override
public GraviticPunchEffect copy() {
return new GraviticPunchEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent controlledCreature = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source));
Player player = game.getPlayer(source.getTargets().get(1).getFirstTarget());
if (player == null || controlledCreature == null) {
return false;
}
player.damage(controlledCreature.getPower().getValue(), controlledCreature.getId(), game, false, true);
return true;
}
}

View file

@ -0,0 +1,109 @@
package mage.cards.g;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.Target;
import mage.target.common.TargetCardInYourGraveyard;
/**
*
* @author TheElk801
*/
public final class GruesomeMenagerie extends CardImpl {
public GruesomeMenagerie(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}{B}");
// Choose a creature card with converted mana cost 1 in your graveyard, then do the same for creature cards with converted mana costs 2 and 3. Return those cards to the battlefield.
this.getSpellAbility().addEffect(new GruesomeMenagerieEffect());
}
public GruesomeMenagerie(final GruesomeMenagerie card) {
super(card);
}
@Override
public GruesomeMenagerie copy() {
return new GruesomeMenagerie(this);
}
}
class GruesomeMenagerieEffect extends OneShotEffect {
private static final FilterCard filter1
= new FilterCreatureCard("creature card with converted mana cost 1");
private static final FilterCard filter2
= new FilterCreatureCard("creature card with converted mana cost 2");
private static final FilterCard filter3
= new FilterCreatureCard("creature card with converted mana cost 3");
static {
filter1.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, 1));
filter2.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, 2));
filter3.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, 3));
}
public GruesomeMenagerieEffect() {
super(Outcome.Benefit);
this.staticText = "Choose a creature card with converted mana cost 1 "
+ "in your graveyard, then do the same for creature cards "
+ "with converted mana costs 2 and 3. "
+ "Return those cards to the battlefield.";
}
public GruesomeMenagerieEffect(final GruesomeMenagerieEffect effect) {
super(effect);
}
@Override
public GruesomeMenagerieEffect copy() {
return new GruesomeMenagerieEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
Cards cards = new CardsImpl();
Target target;
target = new TargetCardInYourGraveyard(filter1);
if (player.choose(outcome, target, source.getSourceId(), game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
cards.add(card);
}
}
target = new TargetCardInYourGraveyard(filter2);
if (player.choose(outcome, target, source.getSourceId(), game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
cards.add(card);
}
}
target = new TargetCardInYourGraveyard(filter3);
if (player.choose(outcome, target, source.getSourceId(), game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
cards.add(card);
}
}
return player.moveCards(cards, Zone.BATTLEFIELD, source, game);
}
}

View file

@ -0,0 +1,142 @@
package mage.cards.g;
import java.util.UUID;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.mana.AnyColorManaAbility;
import mage.abilities.mana.ColorlessManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.WatcherScope;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.events.EntersTheBattlefieldEvent;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.watchers.Watcher;
/**
*
* @author LevelX2
*/
public final class GuildmagesForum extends CardImpl {
public GuildmagesForum(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
// {T}: Add {C}.
this.addAbility(new ColorlessManaAbility());
// {1}, {T}: Add one mana of any color. If that mana is spent on a multicolored creature spell, that creature enters the battlefield with an additional +1/+1 counter on it.
Ability ability = new AnyColorManaAbility(new GenericManaCost(1), true);
ability.getEffects().get(0).setText("Add one mana of any color. If that mana is spent on a multicolored creature spell, that creature enters the battlefield with an additional +1/+1 counter on it");
ability.addCost(new TapSourceCost());
this.addAbility(ability, new GuildmagesForumWatcher(ability));
}
public GuildmagesForum(final GuildmagesForum card) {
super(card);
}
@Override
public GuildmagesForum copy() {
return new GuildmagesForum(this);
}
}
class GuildmagesForumWatcher extends Watcher {
private final Ability source;
GuildmagesForumWatcher(Ability source) {
super("GuildmagesForumWatcher", WatcherScope.CARD);
this.source = source;
}
GuildmagesForumWatcher(final GuildmagesForumWatcher watcher) {
super(watcher);
this.source = watcher.source;
}
@Override
public GuildmagesForumWatcher copy() {
return new GuildmagesForumWatcher(this);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == EventType.MANA_PAID) {
MageObject target = game.getObject(event.getTargetId());
if (event.getSourceId() != null
&& event.getSourceId().equals(this.getSourceId())
&& target != null && target.isCreature() && target.getColor(game).isMulticolored()
&& event.getFlag()) {
if (target instanceof Spell) {
game.getState().addEffect(new GuildmagesForumEntersBattlefieldEffect(
new MageObjectReference(((Spell) target).getSourceId(), target.getZoneChangeCounter(game), game)), source);
}
}
}
}
@Override
public void reset() {
super.reset();
}
}
class GuildmagesForumEntersBattlefieldEffect extends ReplacementEffectImpl {
private final MageObjectReference mor;
public GuildmagesForumEntersBattlefieldEffect(MageObjectReference mor) {
super(Duration.EndOfTurn, Outcome.BoostCreature);
this.staticText = "If that mana is spent on a multicolored creature spell, that creature enters the battlefield with an additional +1/+1 counter on it";
this.mor = mor;
}
public GuildmagesForumEntersBattlefieldEffect(GuildmagesForumEntersBattlefieldEffect effect) {
super(effect);
this.mor = effect.mor;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget();
return permanent != null && mor.refersTo(permanent, game);
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Permanent target = ((EntersTheBattlefieldEvent) event).getTarget();
if (target != null) {
target.addCounters(CounterType.P1P1.createInstance(), source, game, event.getAppliedEffects());
}
return false;
}
@Override
public GuildmagesForumEntersBattlefieldEffect copy() {
return new GuildmagesForumEntersBattlefieldEffect(this);
}
}

View file

@ -0,0 +1,75 @@
package mage.cards.h;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.token.SoldierLifelinkToken;
/**
*
* @author TheElk801
*/
public final class HaazdaMarshal extends CardImpl {
public HaazdaMarshal(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Whenever Haazda Marshal and at least two other creatures attack, create a 1/1 white Solider creature token with lifelink.
this.addAbility(new HaazdaMarshalTriggeredAbility());
}
public HaazdaMarshal(final HaazdaMarshal card) {
super(card);
}
@Override
public HaazdaMarshal copy() {
return new HaazdaMarshal(this);
}
}
class HaazdaMarshalTriggeredAbility extends TriggeredAbilityImpl {
public HaazdaMarshalTriggeredAbility() {
super(Zone.BATTLEFIELD, new CreateTokenEffect(new SoldierLifelinkToken()));
}
public HaazdaMarshalTriggeredAbility(final HaazdaMarshalTriggeredAbility ability) {
super(ability);
}
@Override
public HaazdaMarshalTriggeredAbility copy() {
return new HaazdaMarshalTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DECLARED_ATTACKERS;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return game.getCombat().getAttackers().size() >= 3
&& game.getCombat().getAttackers().contains(this.sourceId);
}
@Override
public String getRule() {
return "Whenever {this} and at least two other creatures attack, "
+ "create a 1/1 white Solider creature token with lifelink.";
}
}

View file

@ -0,0 +1,121 @@
package mage.cards.h;
import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CastSourceTriggeredAbility;
import mage.constants.SubType;
import mage.abilities.keyword.ReachAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.common.FilterPermanentCard;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCardInLibrary;
/**
*
* @author TheElk801
*/
public final class HatcherySpider extends CardImpl {
public HatcherySpider(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{G}");
this.subtype.add(SubType.SPIDER);
this.power = new MageInt(5);
this.toughness = new MageInt(7);
// Reach
this.addAbility(ReachAbility.getInstance());
// Undergrowth When you cast this spell, reveal the top X cards of your library, where X is the number of creature cards in your graveyard. You may put a green permanent card with converted mana cost X or less from among them onto the battlefield. Put the rest on the bottom of your library in a random order.
this.addAbility(new CastSourceTriggeredAbility(
new HatcherySpiderEffect(), false,
"<i>Undergrowth</i> &mdash; "
));
}
public HatcherySpider(final HatcherySpider card) {
super(card);
}
@Override
public HatcherySpider copy() {
return new HatcherySpider(this);
}
}
class HatcherySpiderEffect extends OneShotEffect {
public HatcherySpiderEffect() {
super(Outcome.Benefit);
this.staticText = "reveal the top X cards of your library, "
+ "where X is the number of creature cards in your graveyard. "
+ "You may put a green permanent card with converted mana cost "
+ "X or less from among them onto the battlefield. "
+ "Put the rest on the bottom of your library "
+ "in a random order.";
}
public HatcherySpiderEffect(final HatcherySpiderEffect effect) {
super(effect);
}
@Override
public HatcherySpiderEffect copy() {
return new HatcherySpiderEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getFirstTarget());
if (player == null) {
return false;
}
int xValue = new CardsInControllerGraveyardCount(
StaticFilters.FILTER_CARD_CREATURE
).calculate(game, source, this);
FilterCard filter = new FilterPermanentCard(
"green permanent card with converted mana cost "
+ xValue + " or less"
);
filter.add(new ColorPredicate(ObjectColor.GREEN));
filter.add(new ConvertedManaCostPredicate(
ComparisonType.FEWER_THAN, xValue + 1
));
TargetCard target = new TargetCardInLibrary(filter);
Cards cards = new CardsImpl(
player.getLibrary().getTopCards(game, xValue)
);
if (player.chooseUse(outcome, "Put a card onto the battlefield?", source, game)
&& player.choose(outcome, cards, target, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null
&& player.moveCards(card, Zone.BATTLEFIELD, source, game)) {
cards.remove(card);
}
}
while (!cards.isEmpty()) {
Card card = cards.getRandom(game);
player.getLibrary().putOnBottom(card, game);
cards.remove(card);
}
return true;
}
}

View file

@ -0,0 +1,57 @@
package mage.cards.h;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.constants.SubType;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.permanent.DefendingPlayerControlsPredicate;
import mage.target.TargetPermanent;
/**
*
* @author TheElk801
*/
public final class HellkiteWhelp extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("creature defending player controls");
static {
filter.add(new CardTypePredicate(CardType.CREATURE));
filter.add(new DefendingPlayerControlsPredicate());
}
public HellkiteWhelp(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}");
this.subtype.add(SubType.DRAGON);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever Hellkite Whelp attacks, it deals 1 damage to target creature defending player controls.
Ability ability = new AttacksTriggeredAbility(
new DamageTargetEffect(1, "it"), false
);
ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
}
public HellkiteWhelp(final HellkiteWhelp card) {
super(card);
}
@Override
public HellkiteWhelp copy() {
return new HellkiteWhelp(this);
}
}

View file

@ -0,0 +1,37 @@
package mage.cards.h;
import java.util.UUID;
import mage.MageInt;
import mage.constants.SubType;
import mage.abilities.keyword.DeathtouchAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author TheElk801
*/
public final class HiredPoisoner extends CardImpl {
public HiredPoisoner(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ASSASSIN);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Deathtouch
this.addAbility(DeathtouchAbility.getInstance());
}
public HiredPoisoner(final HiredPoisoner card) {
super(card);
}
@Override
public HiredPoisoner copy() {
return new HiredPoisoner(this);
}
}

View file

@ -184,7 +184,7 @@ class HopeOfGhirapurCombatDamageWatcher extends Watcher {
public boolean playerGotCombatDamage(UUID objectId, UUID playerId, Game game) {
StackObject stackObject = game.getState().getStack().getStackObject(objectId);
MageObjectReference mor;
if (stackObject != null && stackObject instanceof StackAbility) {
if (stackObject instanceof StackAbility) {
// This is neccessary because the source object was sacrificed as cost and the correct zone change counter for target calid check can only be get from stack
mor = new MageObjectReference(objectId, ((StackAbility) stackObject).getSourceObjectZoneChangeCounter(), game);
} else {

View file

@ -265,7 +265,7 @@ class IceCauldronManaCondition implements Condition {
public boolean apply(Game game, Ability source) {
if (source instanceof SpellAbility) {
Card card = game.getCard(source.getSourceId());
if (card != null && exiledCard != null && card.equals(exiledCard)) {
if (card != null && card.equals(exiledCard)) {
return true;
}
}

View file

@ -17,8 +17,8 @@ public final class InescapableBlaze extends CardImpl {
public InescapableBlaze(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{R}{R}");
// This spell can't be countered.
this.addAbility(new CantBeCounteredAbility());
// This spell can't be countered.
this.addAbility(new CantBeCounteredAbility().setRuleAtTheTop(true));
// Inescapable Flame deals 6 damage to any target.
this.getSpellAbility().addEffect(new DamageTargetEffect(6));

View file

@ -0,0 +1,40 @@
package mage.cards.i;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
/**
*
* @author TheElk801
*/
public final class InspiringUnicorn extends CardImpl {
public InspiringUnicorn(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}");
this.subtype.add(SubType.UNICORN);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Whenever Inspiring Unicorn attacks, creatures you control get +1/+1 until end of turn.
this.addAbility(new AttacksTriggeredAbility(
new BoostControlledEffect(1, 1, Duration.EndOfTurn), false
));
}
public InspiringUnicorn(final InspiringUnicorn card) {
super(card);
}
@Override
public InspiringUnicorn copy() {
return new InspiringUnicorn(this);
}
}

View file

@ -33,7 +33,7 @@ public final class IntegrityIntervention extends SplitCard {
// Intervention
// Intervention deals 3 damage to any target and you gain 3 life.
this.getRightHalfCard().getSpellAbility().addEffect(
new DamageTargetEffect(3)
new DamageTargetEffect(3).setText("Intervention deals 3 damage to any target")
);
this.getRightHalfCard().getSpellAbility().addEffect(
new GainLifeEffect(3).setText("and you gain 3 life")

View file

@ -0,0 +1,45 @@
package mage.cards.i;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.TapTargetEffect;
import mage.constants.SubType;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetOpponentsCreaturePermanent;
/**
*
* @author TheElk801
*/
public final class IntrusivePackbeast extends CardImpl {
public IntrusivePackbeast(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}");
this.subtype.add(SubType.BEAST);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// When Intrusive Packbeast enters the battlefield, tap up to two target creatures your opponents control.
Ability ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect());
ability.addTarget(new TargetOpponentsCreaturePermanent(0, 2));
this.addAbility(ability);
}
public IntrusivePackbeast(final IntrusivePackbeast card) {
super(card);
}
@Override
public IntrusivePackbeast copy() {
return new IntrusivePackbeast(this);
}
}

View file

@ -9,7 +9,9 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.target.TargetSpell;
/**
*
@ -21,6 +23,7 @@ public final class Ionize extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}{R}");
// Counter target spell. Ionize deals 2 damage to that spell's controller.
this.getSpellAbility().addTarget(new TargetSpell());
this.getSpellAbility().addEffect(new IonizeEffect());
}
@ -53,11 +56,16 @@ class IonizeEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(game.getControllerId(source.getSourceId()));
new CounterTargetEffect().apply(game, source);
if (player == null) {
return false;
boolean result = false;
Spell spell = game.getStack().getSpell(source.getFirstTarget());
if (spell != null) {
Player spellController = game.getPlayer(spell.getControllerId());
result = game.getStack().counter(source.getFirstTarget(), source.getSourceId(), game);
if (spellController != null) {
spellController.damage(2, source.getSourceId(), game, false, true);
}
}
return player.damage(2, source.getSourceId(), game, false, true) > 0;
return result;
}
}

View file

@ -0,0 +1,45 @@
package mage.cards.j;
import java.util.UUID;
import mage.abilities.effects.common.UntapAllEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.HexproofAbility;
import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.filter.StaticFilters;
/**
*
* @author TheElk801
*/
public final class JoinShields extends CardImpl {
public JoinShields(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{G}{W}");
// Untap all creatures you control. They gain hexproof and indestructible until end of turn.
this.getSpellAbility().addEffect(new UntapAllEffect(
StaticFilters.FILTER_CONTROLLED_CREATURES
));
this.getSpellAbility().addEffect(new GainAbilityControlledEffect(
HexproofAbility.getInstance(), Duration.EndOfTurn,
StaticFilters.FILTER_CONTROLLED_CREATURES
).setText("They gain hexproof"));
this.getSpellAbility().addEffect(new GainAbilityControlledEffect(
IndestructibleAbility.getInstance(), Duration.EndOfTurn,
StaticFilters.FILTER_CONTROLLED_CREATURES
).setText("and indestructible until end of turn"));
}
public JoinShields(final JoinShields card) {
super(card);
}
@Override
public JoinShields copy() {
return new JoinShields(this);
}
}

View file

@ -0,0 +1,62 @@
package mage.cards.j;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author TheElk801
*/
public final class JusticeStrike extends CardImpl {
public JusticeStrike(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}{W}");
// Target creature deals damage to itself equal to its power.
this.getSpellAbility().addEffect(new JusticeStrikeEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
public JusticeStrike(final JusticeStrike card) {
super(card);
}
@Override
public JusticeStrike copy() {
return new JusticeStrike(this);
}
}
class JusticeStrikeEffect extends OneShotEffect {
public JusticeStrikeEffect() {
super(Outcome.Benefit);
this.staticText = "Target creature deals damage to itself equal to its power.";
}
public JusticeStrikeEffect(final JusticeStrikeEffect effect) {
super(effect);
}
@Override
public JusticeStrikeEffect copy() {
return new JusticeStrikeEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (permanent == null) {
return false;
}
return permanent.damage(permanent.getPower().getValue(), permanent.getId(), game, false, true) > 0;
}
}

View file

@ -0,0 +1,43 @@
package mage.cards.k;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount;
import mage.abilities.effects.common.GainLifeEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.common.FilterCreatureCard;
/**
*
* @author TheElk801
*/
public final class KraulForagers extends CardImpl {
public KraulForagers(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}");
this.subtype.add(SubType.INSECT);
this.subtype.add(SubType.SCOUT);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// Undergrowth When Kraul Foragers enters the battlefield, you gain 1 life for each creature card in your graveyard.
this.addAbility(new EntersBattlefieldTriggeredAbility(
new GainLifeEffect(new CardsInControllerGraveyardCount(new FilterCreatureCard())),
false, "<i>Undergrowth</i> &mdash; "
));
}
public KraulForagers(final KraulForagers card) {
super(card);
}
@Override
public KraulForagers copy() {
return new KraulForagers(this);
}
}

View file

@ -0,0 +1,105 @@
package mage.cards.k;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.constants.SubType;
import mage.abilities.keyword.ReachAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
/**
*
* @author TheElk801
*/
public final class KraulHarpooner extends CardImpl {
private static final FilterPermanent filter = new FilterCreaturePermanent("creature with flying you don't control");
static {
filter.add(new ControllerPredicate(TargetController.NOT_YOU));
filter.add(new AbilityPredicate(FlyingAbility.class));
}
public KraulHarpooner(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.subtype.add(SubType.INSECT);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// Reach
this.addAbility(ReachAbility.getInstance());
// Undergrowth When Kraul Harpooner enters the battlefield, choose up to one target creature with flying you don't control. Kraul Harpooner gets +X/+0 until end of turn, where X is the number of creature cards in your graveyard, then you may have Kraul Harpooner fight that creature.
Ability ability = new EntersBattlefieldTriggeredAbility(
new KraulHarpoonerEffect(), false,
"<i>Undergrowth</i> &mdash; "
);
ability.addTarget(new TargetPermanent(0, 1, filter, false));
this.addAbility(ability);
}
public KraulHarpooner(final KraulHarpooner card) {
super(card);
}
@Override
public KraulHarpooner copy() {
return new KraulHarpooner(this);
}
}
class KraulHarpoonerEffect extends OneShotEffect {
public KraulHarpoonerEffect() {
super(Outcome.Benefit);
this.staticText = "choose up to one target creature with flying "
+ "you don't control. {this} gets +X/+0 until end of turn, "
+ "where X is the number of creature cards in your graveyard, "
+ "then you may have {this} fight that creature.";
}
public KraulHarpoonerEffect(final KraulHarpoonerEffect effect) {
super(effect);
}
@Override
public KraulHarpoonerEffect copy() {
return new KraulHarpoonerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent sourcePerm = game.getPermanent(source.getSourceId());
Player player = game.getPlayer(source.getControllerId());
if (sourcePerm == null || player == null) {
return false;
}
int xValue = player.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, game);
game.addEffect(new BoostSourceEffect(xValue, 0, Duration.EndOfTurn), source);
Permanent creature = game.getPermanent(source.getFirstTarget());
if (creature == null || !player.chooseUse(outcome, "Have " + sourcePerm.getLogName() + " fight " + creature.getLogName() + "?", source, game)) {
return true;
}
return creature.fight(sourcePerm, source, game);
}
}

View file

@ -0,0 +1,37 @@
package mage.cards.k;
import java.util.UUID;
import mage.MageInt;
import mage.constants.SubType;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author TheElk801
*/
public final class KraulRaider extends CardImpl {
public KraulRaider(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
this.subtype.add(SubType.INSECT);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Menace
this.addAbility(new MenaceAbility());
}
public KraulRaider(final KraulRaider card) {
super(card);
}
@Override
public KraulRaider copy() {
return new KraulRaider(this);
}
}

View file

@ -0,0 +1,56 @@
package mage.cards.k;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.DiscardTargetCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect;
import mage.constants.SubType;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.target.common.TargetCardInHand;
/**
*
* @author TheElk801
*/
public final class KraulSwarm extends CardImpl {
public KraulSwarm(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}");
this.subtype.add(SubType.INSECT);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(4);
this.toughness = new MageInt(1);
// Flying
this.addAbility(FlyingAbility.getInstance());
// {2}{B}, Discard a creature card: Return Kraul Swarm from your graveyard to your hand.
Ability ability = new SimpleActivatedAbility(
Zone.GRAVEYARD,
new ReturnSourceFromGraveyardToHandEffect(),
new ManaCostsImpl("{2}{B}")
);
ability.addCost(new DiscardTargetCost(
new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE_A)
));
this.addAbility(ability);
}
public KraulSwarm(final KraulSwarm card) {
super(card);
}
@Override
public KraulSwarm copy() {
return new KraulSwarm(this);
}
}

View file

@ -74,7 +74,7 @@ class LabyrinthGuardianTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
MageObject eventSourceObject = game.getObject(event.getSourceId());
if (eventSourceObject != null && event.getTargetId().equals(this.getSourceId()) && eventSourceObject instanceof Spell) {
if (event.getTargetId().equals(this.getSourceId()) && eventSourceObject instanceof Spell) {
getEffects().get(0).setTargetPointer(new FixedTarget(event.getPlayerId()));
return true;
}

View file

@ -0,0 +1,83 @@
package mage.cards.l;
import java.util.List;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.stack.Spell;
import mage.watchers.common.SpellsCastWatcher;
/**
*
* @author TheElk801
*/
public final class Leapfrog extends CardImpl {
public Leapfrog(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}");
this.subtype.add(SubType.FROG);
this.power = new MageInt(3);
this.toughness = new MageInt(1);
// Leapfrog has flying as long as you've cast an instant or sorcery spell this turn.
this.addAbility(new SimpleStaticAbility(
Zone.BATTLEFIELD,
new ConditionalContinuousEffect(
new GainAbilitySourceEffect(
FlyingAbility.getInstance(),
Duration.WhileOnBattlefield
), LeapfrogCondition.instance,
"{this} has flying as long as you've cast "
+ "an instant or sorcery spell this turn."
)
), new SpellsCastWatcher());
}
public Leapfrog(final Leapfrog card) {
super(card);
}
@Override
public Leapfrog copy() {
return new Leapfrog(this);
}
}
enum LeapfrogCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
SpellsCastWatcher watcher
= (SpellsCastWatcher) game.getState().getWatchers().get(
SpellsCastWatcher.class.getSimpleName()
);
if (watcher == null) {
return false;
}
List<Spell> spells = watcher.getSpellsCastThisTurn(source.getControllerId());
if (spells == null) {
return false;
}
for (Spell spell : spells) {
if (!spell.getSourceId().equals(source.getSourceId())
&& spell.isInstantOrSorcery()) {
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,109 @@
package mage.cards.l;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
import mage.game.permanent.token.SoldierLifelinkToken;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author TheElk801
*/
public final class LedevChampion extends CardImpl {
public LedevChampion(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{W}");
this.subtype.add(SubType.ELF);
this.subtype.add(SubType.KNIGHT);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Whenever Ledev Champion attacks, you may tap any number of untapped creatures you control. Ledev Champion gets +1/+1 until end of turn for each creature tapped this way.
this.addAbility(new AttacksTriggeredAbility(
new LedevChampionEffect(), false
));
// {3}{G}{W}: Create a 1/1 white soldier creature token with lifelink.
this.addAbility(new SimpleActivatedAbility(
Zone.BATTLEFIELD,
new CreateTokenEffect(new SoldierLifelinkToken()),
new ManaCostsImpl("{3}{G}{W}")
));
}
public LedevChampion(final LedevChampion card) {
super(card);
}
@Override
public LedevChampion copy() {
return new LedevChampion(this);
}
}
class LedevChampionEffect extends OneShotEffect {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("untapped creatures you control");
static {
filter.add(new ControllerPredicate(TargetController.YOU));
filter.add(Predicates.not(new TappedPredicate()));
}
public LedevChampionEffect() {
super(Outcome.GainLife);
staticText = "you may tap any number of untapped creatures you control. "
+ "{this} gets +1/+1 until end of turn for each creature tapped this way.";
}
public LedevChampionEffect(LedevChampionEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
int tappedAmount = 0;
TargetCreaturePermanent target = new TargetCreaturePermanent(0, Integer.MAX_VALUE, filter, true);
if (target.canChoose(source.getControllerId(), game)
&& target.choose(Outcome.Tap, source.getControllerId(), source.getSourceId(), game)) {
for (UUID creature : target.getTargets()) {
if (creature != null) {
game.getPermanent(creature).tap(game);
tappedAmount++;
}
}
}
if (tappedAmount > 0) {
game.addEffect(new BoostSourceEffect(tappedAmount, tappedAmount, Duration.EndOfTurn), source);
return true;
}
return false;
}
@Override
public LedevChampionEffect copy() {
return new LedevChampionEffect(this);
}
}

View file

@ -0,0 +1,58 @@
package mage.cards.l;
import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.common.DiesTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersAllEffect;
import mage.constants.SubType;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.MentorAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.mageobject.ColorPredicate;
/**
*
* @author TheElk801
*/
public final class LightOfTheLegion extends CardImpl {
private static final FilterPermanent filter = new FilterControlledCreaturePermanent("white creature you control");
static {
filter.add(new ColorPredicate(ObjectColor.WHITE));
}
public LightOfTheLegion(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{W}");
this.subtype.add(SubType.ANGEL);
this.power = new MageInt(5);
this.toughness = new MageInt(5);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Mentor
this.addAbility(new MentorAbility());
// When Light of the Legion dies, put a +1/+1 counter on each white creature you control.
this.addAbility(new DiesTriggeredAbility(new AddCountersAllEffect(
CounterType.P1P1.createInstance(), filter
)));
}
public LightOfTheLegion(final LightOfTheLegion card) {
super(card);
}
@Override
public LightOfTheLegion copy() {
return new LightOfTheLegion(this);
}
}

Some files were not shown because too many files have changed in this diff Show more