mirror of
https://github.com/correl/mage.git
synced 2024-11-15 03:00:16 +00:00
[J22] Implement Benevolent Hydra, Creeping Bloodsucker, Distinguished Conjurer, Instruments of War (#9910)
* [J22] Implement Benevolent Hydra * [J22] Implement Creeping Bloodsucker, correct author on Benevolent Hydra * [J22] Implement Distinguished Conjurer * [J22] Implement Instruments of War * Fix verify failure * Use overflow-safe increment in BenevolentHydra on principle. * Address code review
This commit is contained in:
parent
a0bd316f36
commit
40f1f57dc3
5 changed files with 308 additions and 0 deletions
108
Mage.Sets/src/mage/cards/b/BenevolentHydra.java
Normal file
108
Mage.Sets/src/mage/cards/b/BenevolentHydra.java
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
76
Mage.Sets/src/mage/cards/c/CreepingBloodsucker.java
Normal file
76
Mage.Sets/src/mage/cards/c/CreepingBloodsucker.java
Normal file
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
65
Mage.Sets/src/mage/cards/d/DistinguishedConjurer.java
Normal file
65
Mage.Sets/src/mage/cards/d/DistinguishedConjurer.java
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
55
Mage.Sets/src/mage/cards/i/InstrumentsOfWar.java
Normal file
55
Mage.Sets/src/mage/cards/i/InstrumentsOfWar.java
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
|
|
Loading…
Reference in a new issue