diff --git a/Mage.Sets/src/mage/cards/b/BenevolentHydra.java b/Mage.Sets/src/mage/cards/b/BenevolentHydra.java new file mode 100644 index 0000000000..8422a3c948 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BenevolentHydra.java @@ -0,0 +1,108 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.EntersBattlefieldWithXCountersEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * + * @author Grath + */ +public final class BenevolentHydra extends CardImpl { + + public BenevolentHydra(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{X}{G}{G}"); + + this.subtype.add(SubType.HYDRA); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Hungering Hydra enters the battlefield with X +1/+1 counters on it. + this.addAbility(new EntersBattlefieldAbility( + new EntersBattlefieldWithXCountersEffect(CounterType.P1P1.createInstance()) + )); + + // If one or more +1/+1 counters would be put on another creature you control, that many plus one +1/+1 counters are put on it instead. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BenevolentHydraEffect())); + + // {T}, Remove a +1/+1 counter from Benevolent Hydra: Put a +1/+1 counter on another target creature you control. + Ability ability = new SimpleActivatedAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()).setText("Put a +1/+1 counter on another target creature you control"), new TapSourceCost()); + ability.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance())); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); + this.addAbility(ability); + } + + private BenevolentHydra(final BenevolentHydra card) { + super(card); + } + + @Override + public BenevolentHydra copy() { + return new BenevolentHydra(this); + } +} + +class BenevolentHydraEffect extends ReplacementEffectImpl { + + BenevolentHydraEffect() { + super(Duration.WhileOnBattlefield, Outcome.BoostCreature, false); + staticText = "If one or more +1/+1 counters would be put on another creature you control, that many plus one +1/+1 counters are put on it instead"; + } + + BenevolentHydraEffect(final BenevolentHydraEffect effect) { + super(effect); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + event.setAmountForCounters(CardUtil.overflowInc(event.getAmount(), 1), true); + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ADD_COUNTERS; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getData().equals(CounterType.P1P1.getName()) && event.getAmount() > 0) { + Permanent permanent = game.getPermanent(event.getTargetId()); + if (permanent == null) { + permanent = game.getPermanentEntering(event.getTargetId()); + } + return permanent != null && permanent.isControlledBy(source.getControllerId()) + && permanent.isCreature(game) && !event.getTargetId().equals(source.getSourceId()); + } + return false; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public BenevolentHydraEffect copy() { + return new BenevolentHydraEffect(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/c/CreepingBloodsucker.java b/Mage.Sets/src/mage/cards/c/CreepingBloodsucker.java new file mode 100644 index 0000000000..fbc5b5c69d --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CreepingBloodsucker.java @@ -0,0 +1,76 @@ + +package mage.cards.c; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.game.Game; +import mage.players.Player; + +import java.util.UUID; + +/** + * + * @author Grath + */ +public final class CreepingBloodsucker extends CardImpl { + + public CreepingBloodsucker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}"); + this.subtype.add(SubType.VAMPIRE); + + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // At the beginning of your upkeep, Creeping Bloodsucker deals 1 damage to each opponent. You gain life equal to the damage dealt this way. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new CreepingBloodsuckerEffect(), TargetController.YOU, false)); + } + + private CreepingBloodsucker(final CreepingBloodsucker card) { + super(card); + } + + @Override + public CreepingBloodsucker copy() { + return new CreepingBloodsucker(this); + } +} + +class CreepingBloodsuckerEffect extends OneShotEffect { + public CreepingBloodsuckerEffect() { + super(Outcome.Damage); + staticText = "{this} deals 1 damage to each opponent. You gain life equal to the damage dealt this way"; + } + + public CreepingBloodsuckerEffect(final CreepingBloodsuckerEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + int damageDealt = 0; + Player player = game.getPlayer(source.getControllerId()); + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { + if (player.hasOpponent(playerId, game)) { + damageDealt += game.getPlayer(playerId).damage(1, source.getSourceId(), source, game); + } + } + if (damageDealt > 0) { + game.getPlayer(source.getControllerId()).gainLife(damageDealt, game, source); + } + return true; + } + + @Override + public CreepingBloodsuckerEffect copy() { + return new CreepingBloodsuckerEffect(this); + } + +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/d/DistinguishedConjurer.java b/Mage.Sets/src/mage/cards/d/DistinguishedConjurer.java new file mode 100644 index 0000000000..68ec7d14c4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DistinguishedConjurer.java @@ -0,0 +1,65 @@ +package mage.cards.d; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.ExileTargetForSourceEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.target.common.TargetControlledCreaturePermanent; + +import java.util.UUID; + +/** + * @author Grath + */ +public final class DistinguishedConjurer extends CardImpl { + + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("another creature"); + private static final FilterControlledCreaturePermanent filter2 + = new FilterControlledCreaturePermanent("another target creature you control"); + + static { + filter.add(AnotherPredicate.instance); + filter2.add(AnotherPredicate.instance); + } + + public DistinguishedConjurer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Whenever another creature enters the battlefield under your control, you gain 1 life. + this.addAbility(new EntersBattlefieldControlledTriggeredAbility(new GainLifeEffect(1), filter)); + + // {4}{W}, {T}: Exile another target creature you control, then return it to the battlefield under its owner’s control. + Ability ability = new SimpleActivatedAbility(new ExileTargetForSourceEffect(), new ManaCostsImpl<>("{4}{W}")); + ability.addCost(new TapSourceCost()); + ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false).concatBy(", then")); + ability.addTarget(new TargetControlledCreaturePermanent(filter2)); + this.addAbility(ability); + } + + private DistinguishedConjurer(final DistinguishedConjurer card) { + super(card); + } + + @Override + public DistinguishedConjurer copy() { + return new DistinguishedConjurer(this); + } +} diff --git a/Mage.Sets/src/mage/cards/i/InstrumentsOfWar.java b/Mage.Sets/src/mage/cards/i/InstrumentsOfWar.java new file mode 100644 index 0000000000..5a841c23c5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/InstrumentsOfWar.java @@ -0,0 +1,55 @@ +package mage.cards.i; + +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.ChooseCreatureTypeEffect; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.keyword.FlashAbility; +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.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ChosenSubtypePredicate; + +import java.util.UUID; + +/** + * @author Grath + */ +public final class InstrumentsOfWar extends CardImpl { + + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("creatures you control of the chosen type"); + + static { + filter.add(ChosenSubtypePredicate.TRUE); + filter.add(TargetController.YOU.getControllerPredicate()); + } + + public InstrumentsOfWar(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // As Instruments of War enters the battlefield, choose a creature type. + this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.BoostCreature))); + + // Creatures you control of the chosen type get +1/+1. + this.addAbility(new SimpleStaticAbility(new BoostAllEffect( + 1, 1, Duration.WhileOnBattlefield, filter, false + ))); + } + + private InstrumentsOfWar(final InstrumentsOfWar card) { + super(card); + } + + @Override + public InstrumentsOfWar copy() { + return new InstrumentsOfWar(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Jumpstart2022.java b/Mage.Sets/src/mage/sets/Jumpstart2022.java index 562486a658..613ce3a68a 100644 --- a/Mage.Sets/src/mage/sets/Jumpstart2022.java +++ b/Mage.Sets/src/mage/sets/Jumpstart2022.java @@ -74,6 +74,7 @@ public final class Jumpstart2022 extends ExpansionSet { cards.add(new SetCardInfo("Basri's Acolyte", 154, Rarity.COMMON, mage.cards.b.BasrisAcolyte.class)); cards.add(new SetCardInfo("Battle Squadron", 497, Rarity.UNCOMMON, mage.cards.b.BattleSquadron.class)); cards.add(new SetCardInfo("Benalish Honor Guard", 155, Rarity.COMMON, mage.cards.b.BenalishHonorGuard.class)); + cards.add(new SetCardInfo("Benevolent Hydra", 38, Rarity.RARE, mage.cards.b.BenevolentHydra.class)); cards.add(new SetCardInfo("Berg Strider", 277, Rarity.COMMON, mage.cards.b.BergStrider.class)); cards.add(new SetCardInfo("Biblioplex Kraken", 10, Rarity.UNCOMMON, mage.cards.b.BiblioplexKraken.class)); cards.add(new SetCardInfo("Big Score", 498, Rarity.COMMON, mage.cards.b.BigScore.class)); @@ -152,6 +153,7 @@ public final class Jumpstart2022 extends ExpansionSet { cards.add(new SetCardInfo("Crashing Tide", 283, Rarity.COMMON, mage.cards.c.CrashingTide.class)); cards.add(new SetCardInfo("Crawling Sensation", 642, Rarity.UNCOMMON, mage.cards.c.CrawlingSensation.class)); cards.add(new SetCardInfo("Creeperhulk", 643, Rarity.RARE, mage.cards.c.Creeperhulk.class)); + cards.add(new SetCardInfo("Creeping Bloodsucker", 21, Rarity.COMMON, mage.cards.c.CreepingBloodsucker.class)); cards.add(new SetCardInfo("Crippling Chill", 284, Rarity.COMMON, mage.cards.c.CripplingChill.class)); cards.add(new SetCardInfo("Crow of Dark Tidings", 390, Rarity.COMMON, mage.cards.c.CrowOfDarkTidings.class)); cards.add(new SetCardInfo("Cruel Sadist", 391, Rarity.RARE, mage.cards.c.CruelSadist.class)); @@ -186,6 +188,7 @@ public final class Jumpstart2022 extends ExpansionSet { cards.add(new SetCardInfo("Devouring Swarm", 401, Rarity.COMMON, mage.cards.d.DevouringSwarm.class)); cards.add(new SetCardInfo("Diabolic Edict", 67, Rarity.COMMON, mage.cards.d.DiabolicEdict.class)); cards.add(new SetCardInfo("Dismiss", 286, Rarity.UNCOMMON, mage.cards.d.Dismiss.class)); + cards.add(new SetCardInfo("Distinguished Conjurer", 4, Rarity.UNCOMMON, mage.cards.d.DistinguishedConjurer.class)); cards.add(new SetCardInfo("Divine Arrow", 176, Rarity.COMMON, mage.cards.d.DivineArrow.class)); cards.add(new SetCardInfo("Divine Verdict", 177, Rarity.COMMON, mage.cards.d.DivineVerdict.class)); cards.add(new SetCardInfo("Djinn of Wishes", 287, Rarity.RARE, mage.cards.d.DjinnOfWishes.class)); @@ -366,6 +369,7 @@ public final class Jumpstart2022 extends ExpansionSet { cards.add(new SetCardInfo("Inner Demon", 428, Rarity.UNCOMMON, mage.cards.i.InnerDemon.class)); cards.add(new SetCardInfo("Inspiring Cleric", 199, Rarity.UNCOMMON, mage.cards.i.InspiringCleric.class)); cards.add(new SetCardInfo("Inspiring Overseer", 200, Rarity.COMMON, mage.cards.i.InspiringOverseer.class)); + cards.add(new SetCardInfo("Instruments of War", 50, Rarity.UNCOMMON, mage.cards.i.InstrumentsOfWar.class)); cards.add(new SetCardInfo("Interpret the Signs", 309, Rarity.UNCOMMON, mage.cards.i.InterpretTheSigns.class)); cards.add(new SetCardInfo("Irencrag Pyromancer", 559, Rarity.RARE, mage.cards.i.IrencragPyromancer.class)); cards.add(new SetCardInfo("Iridescent Hornbeetle", 678, Rarity.UNCOMMON, mage.cards.i.IridescentHornbeetle.class));