[PIP] Implement cards x4 (#12039)

* Elder Owyn Lyons

* Gunner Conscript

* Ian the Reckless

* Legate Lanius, Caesar's Ace

* Fix errors

* Review fixes
This commit is contained in:
ssk97 2024-04-04 19:16:08 -07:00 committed by GitHub
parent 2853c7cb4a
commit ac8722f707
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 326 additions and 0 deletions

View file

@ -0,0 +1,57 @@
package mage.cards.e;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldOrDiesSourceTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.WardAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.StaticFilters;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
/**
* @author notgreat
*/
public final class ElderOwynLyons extends CardImpl {
public ElderOwynLyons(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{U}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.KNIGHT);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Artifacts you control have ward {1}.
this.addAbility(new SimpleStaticAbility(
new GainAbilityControlledEffect(
new WardAbility(new GenericManaCost(1)), Duration.WhileOnBattlefield, StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACTS
)
));
// When Elder Owyn Lyons enters the battlefield or dies, return target artifact card from your graveyard to your hand.
Ability ability = new EntersBattlefieldOrDiesSourceTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect(), false);
ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_ARTIFACT_FROM_YOUR_GRAVEYARD));
this.addAbility(ability);
}
private ElderOwynLyons(final ElderOwynLyons card) {
super(card);
}
@Override
public ElderOwynLyons copy() {
return new ElderOwynLyons(this);
}
}

View file

@ -0,0 +1,101 @@
package mage.cards.g;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.dynamicvalue.AdditiveDynamicValue;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.AuraAttachedCount;
import mage.abilities.dynamicvalue.common.EquipmentAttachedCount;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
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.permanent.Permanent;
import mage.game.permanent.token.JunkToken;
import java.util.Objects;
import java.util.UUID;
/**
* @author notgreat
*/
public final class GunnerConscript extends CardImpl {
public GunnerConscript(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.MERCENARY);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Trample
this.addAbility(TrampleAbility.getInstance());
// Gunner Conscript gets +1/+1 for each Aura and Equipment attached to it.
DynamicValue totalAmount = new AdditiveDynamicValue(new AuraAttachedCount(), new EquipmentAttachedCount());
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new BoostSourceEffect(totalAmount, totalAmount, Duration.WhileOnBattlefield)
.setText("{this} gets +1/+1 for each Aura and Equipment attached to it")));
// When Gunner Conscript dies, if it was enchanted, create a Junk token.
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
new DiesSourceTriggeredAbility(new CreateTokenEffect(new JunkToken())), GunnerConscriptEnchantedCondition.instance,
"When Gunner Conscript dies, if it was enchanted, create a Junk token."));
// When Gunner Conscript dies, if it was equipped, create a Junk token.
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
new DiesSourceTriggeredAbility(new CreateTokenEffect(new JunkToken())), GunnerConscriptEquippedCondition.instance,
"When Gunner Conscript dies, if it was equipped, create a Junk token."));
}
private GunnerConscript(final GunnerConscript card) {
super(card);
}
@Override
public GunnerConscript copy() {
return new GunnerConscript(this);
}
}
// Derived from KollTheForgemaster
// Custom predicates call getPermanentOrLKIBattlefield (needed for the death trigger to work correctly)
enum GunnerConscriptEnchantedCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
Permanent sourcePermanent = source.getSourcePermanentOrLKI(game);
return sourcePermanent != null && sourcePermanent.getAttachments()
.stream()
.map(game::getPermanentOrLKIBattlefield)
.filter(Objects::nonNull)
.anyMatch(permanent -> permanent.isEnchantment(game));
}
}
enum GunnerConscriptEquippedCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
Permanent sourcePermanent = source.getSourcePermanentOrLKI(game);
return sourcePermanent != null && sourcePermanent.getAttachments()
.stream()
.map(game::getPermanentOrLKIBattlefield)
.filter(Objects::nonNull)
.anyMatch(attachment -> attachment.hasSubtype(SubType.EQUIPMENT, game));
}
}

View file

@ -0,0 +1,62 @@
package mage.cards.i;
import mage.MageInt;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.SourceMatchesFilterCondition;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.dynamicvalue.common.SourcePermanentPowerCount;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterPermanent;
import mage.filter.predicate.permanent.ModifiedPredicate;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
* @author notgreat
*/
public final class IanTheReckless extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent();
static {
filter.add(ModifiedPredicate.instance);
}
private static final Condition condition = new SourceMatchesFilterCondition(filter);
public IanTheReckless(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// Whenever Ian the Reckless attacks, if it's modified, you may have it deal damage equal to its power to you and any target.
TriggeredAbility ability = new AttacksTriggeredAbility(new DamageControllerEffect(
new SourcePermanentPowerCount()).setText("have it deal damage equal to its power to you"), true);
ability.addEffect(new DamageTargetEffect(new SourcePermanentPowerCount()).setText("and any target"));
ability.addTarget(new TargetAnyTarget());
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, condition,
"Whenever {this} attacks, if it's modified, you may have it deal damage equal to its power to you and any target."));
}
private IanTheReckless(final IanTheReckless card) {
super(card);
}
@Override
public IanTheReckless copy() {
return new IanTheReckless(this);
}
}

View file

@ -0,0 +1,102 @@
package mage.cards.l;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.SacrificeOpponentsEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
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.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetSacrifice;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
* @author notgreat
*/
public final class LegateLaniusCaesarsAce extends CardImpl {
public LegateLaniusCaesarsAce(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{R}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Decimate -- When Legate Lanius enters the battlefield, each opponent sacrifices a tenth of the creatures they control, rounded up.
this.addAbility(new EntersBattlefieldTriggeredAbility(new LegateLaniusCaesarsAceSacrificeEffect()).withFlavorWord("Decimate"));
// Whenever an opponent sacrifices a creature, put a +1/+1 counter on Legate Lanius.
this.addAbility(new SacrificePermanentTriggeredAbility(Zone.BATTLEFIELD,
new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
StaticFilters.FILTER_PERMANENT_A_CREATURE, TargetController.OPPONENT, SetTargetPointer.NONE, false
));
}
private LegateLaniusCaesarsAce(final LegateLaniusCaesarsAce card) {
super(card);
}
@Override
public LegateLaniusCaesarsAce copy() {
return new LegateLaniusCaesarsAce(this);
}
}
//Based on SacrificeAllEffect
class LegateLaniusCaesarsAceSacrificeEffect extends OneShotEffect {
LegateLaniusCaesarsAceSacrificeEffect() {
super(Outcome.Sacrifice);
this.staticText = "each opponent sacrifices a tenth of the creatures they control, rounded up.";
}
private LegateLaniusCaesarsAceSacrificeEffect(final LegateLaniusCaesarsAceSacrificeEffect effect) {
super(effect);
}
@Override
public LegateLaniusCaesarsAceSacrificeEffect copy() {
return new LegateLaniusCaesarsAceSacrificeEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Set<UUID> perms = new HashSet<>();
for (UUID playerId : game.getOpponents(source.getControllerId())) {
Player player = game.getPlayer(playerId);
if (player == null) {
continue;
}
// 1/10 rounded up
int num = (game.getBattlefield().count(StaticFilters.FILTER_PERMANENT_A_CREATURE,playerId,source, game)+9)/10;
int numTargets = Math.min(num, game.getBattlefield().count(TargetSacrifice.makeFilter(StaticFilters.FILTER_PERMANENT_A_CREATURE), player.getId(), source, game));
if (numTargets < 1) {
continue;
}
TargetSacrifice target = new TargetSacrifice(numTargets, StaticFilters.FILTER_PERMANENT_A_CREATURE);
while (!target.isChosen() && target.canChoose(playerId, source, game) && player.canRespond()) {
player.choose(Outcome.Sacrifice, target, source, game);
}
perms.addAll(target.getTargets());
}
for (UUID permID : perms) {
Permanent permanent = game.getPermanent(permID);
if (permanent != null) {
permanent.sacrifice(source, game);
}
}
return true;
}
}

View file

@ -99,6 +99,7 @@ public final class Fallout extends ExpansionSet {
cards.add(new SetCardInfo("Dr. Madison Li", 3, Rarity.MYTHIC, mage.cards.d.DrMadisonLi.class)); cards.add(new SetCardInfo("Dr. Madison Li", 3, Rarity.MYTHIC, mage.cards.d.DrMadisonLi.class));
cards.add(new SetCardInfo("Dragonskull Summit", 261, Rarity.RARE, mage.cards.d.DragonskullSummit.class)); cards.add(new SetCardInfo("Dragonskull Summit", 261, Rarity.RARE, mage.cards.d.DragonskullSummit.class));
cards.add(new SetCardInfo("Drowned Catacomb", 262, Rarity.RARE, mage.cards.d.DrownedCatacomb.class)); cards.add(new SetCardInfo("Drowned Catacomb", 262, Rarity.RARE, mage.cards.d.DrownedCatacomb.class));
cards.add(new SetCardInfo("Elder Owyn Lyons", 103, Rarity.UNCOMMON, mage.cards.e.ElderOwynLyons.class));
cards.add(new SetCardInfo("Electrosiphon", 104, Rarity.RARE, mage.cards.e.Electrosiphon.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Electrosiphon", 104, Rarity.RARE, mage.cards.e.Electrosiphon.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Electrosiphon", 414, Rarity.RARE, mage.cards.e.Electrosiphon.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Electrosiphon", 414, Rarity.RARE, mage.cards.e.Electrosiphon.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Electrosiphon", 632, Rarity.RARE, mage.cards.e.Electrosiphon.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Electrosiphon", 632, Rarity.RARE, mage.cards.e.Electrosiphon.class, NON_FULL_USE_VARIOUS));
@ -127,6 +128,7 @@ public final class Fallout extends ExpansionSet {
cards.add(new SetCardInfo("Glimmer of Genius", 176, Rarity.UNCOMMON, mage.cards.g.GlimmerOfGenius.class)); cards.add(new SetCardInfo("Glimmer of Genius", 176, Rarity.UNCOMMON, mage.cards.g.GlimmerOfGenius.class));
cards.add(new SetCardInfo("Grave Titan", 346, Rarity.MYTHIC, mage.cards.g.GraveTitan.class)); cards.add(new SetCardInfo("Grave Titan", 346, Rarity.MYTHIC, mage.cards.g.GraveTitan.class));
cards.add(new SetCardInfo("Guardian Project", 199, Rarity.RARE, mage.cards.g.GuardianProject.class)); cards.add(new SetCardInfo("Guardian Project", 199, Rarity.RARE, mage.cards.g.GuardianProject.class));
cards.add(new SetCardInfo("Gunner Conscript", 77, Rarity.UNCOMMON, mage.cards.g.GunnerConscript.class));
cards.add(new SetCardInfo("Hancock, Ghoulish Mayor", 45, Rarity.RARE, mage.cards.h.HancockGhoulishMayor.class)); cards.add(new SetCardInfo("Hancock, Ghoulish Mayor", 45, Rarity.RARE, mage.cards.h.HancockGhoulishMayor.class));
cards.add(new SetCardInfo("Hardened Scales", 200, Rarity.RARE, mage.cards.h.HardenedScales.class)); cards.add(new SetCardInfo("Hardened Scales", 200, Rarity.RARE, mage.cards.h.HardenedScales.class));
cards.add(new SetCardInfo("Harmonize", 201, Rarity.UNCOMMON, mage.cards.h.Harmonize.class)); cards.add(new SetCardInfo("Harmonize", 201, Rarity.UNCOMMON, mage.cards.h.Harmonize.class));
@ -136,6 +138,7 @@ public final class Fallout extends ExpansionSet {
cards.add(new SetCardInfo("Hornet Queen", 350, Rarity.RARE, mage.cards.h.HornetQueen.class)); cards.add(new SetCardInfo("Hornet Queen", 350, Rarity.RARE, mage.cards.h.HornetQueen.class));
cards.add(new SetCardInfo("Hour of Reckoning", 161, Rarity.RARE, mage.cards.h.HourOfReckoning.class)); cards.add(new SetCardInfo("Hour of Reckoning", 161, Rarity.RARE, mage.cards.h.HourOfReckoning.class));
cards.add(new SetCardInfo("Hullbreaker Horror", 344, Rarity.RARE, mage.cards.h.HullbreakerHorror.class)); cards.add(new SetCardInfo("Hullbreaker Horror", 344, Rarity.RARE, mage.cards.h.HullbreakerHorror.class));
cards.add(new SetCardInfo("Ian the Reckless", 59, Rarity.UNCOMMON, mage.cards.i.IanTheReckless.class));
cards.add(new SetCardInfo("Impassioned Orator", 162, Rarity.COMMON, mage.cards.i.ImpassionedOrator.class)); cards.add(new SetCardInfo("Impassioned Orator", 162, Rarity.COMMON, mage.cards.i.ImpassionedOrator.class));
cards.add(new SetCardInfo("Inexorable Tide", 177, Rarity.RARE, mage.cards.i.InexorableTide.class)); cards.add(new SetCardInfo("Inexorable Tide", 177, Rarity.RARE, mage.cards.i.InexorableTide.class));
cards.add(new SetCardInfo("Inspiring Call", 203, Rarity.UNCOMMON, mage.cards.i.InspiringCall.class)); cards.add(new SetCardInfo("Inspiring Call", 203, Rarity.UNCOMMON, mage.cards.i.InspiringCall.class));
@ -151,6 +154,7 @@ public final class Fallout extends ExpansionSet {
cards.add(new SetCardInfo("Kellogg, Dangerous Mind", 415, Rarity.RARE, mage.cards.k.KelloggDangerousMind.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kellogg, Dangerous Mind", 415, Rarity.RARE, mage.cards.k.KelloggDangerousMind.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Kellogg, Dangerous Mind", 634, Rarity.RARE, mage.cards.k.KelloggDangerousMind.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kellogg, Dangerous Mind", 634, Rarity.RARE, mage.cards.k.KelloggDangerousMind.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Kellogg, Dangerous Mind", 943, Rarity.RARE, mage.cards.k.KelloggDangerousMind.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kellogg, Dangerous Mind", 943, Rarity.RARE, mage.cards.k.KelloggDangerousMind.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Legate Lanius, Caesar's Ace", 107, Rarity.UNCOMMON, mage.cards.l.LegateLaniusCaesarsAce.class));
cards.add(new SetCardInfo("Lethal Scheme", 185, Rarity.RARE, mage.cards.l.LethalScheme.class)); cards.add(new SetCardInfo("Lethal Scheme", 185, Rarity.RARE, mage.cards.l.LethalScheme.class));
cards.add(new SetCardInfo("Liberty Prime, Recharged", 5, Rarity.MYTHIC, mage.cards.l.LibertyPrimeRecharged.class)); cards.add(new SetCardInfo("Liberty Prime, Recharged", 5, Rarity.MYTHIC, mage.cards.l.LibertyPrimeRecharged.class));
cards.add(new SetCardInfo("Lightning Greaves", 233, Rarity.UNCOMMON, mage.cards.l.LightningGreaves.class)); cards.add(new SetCardInfo("Lightning Greaves", 233, Rarity.UNCOMMON, mage.cards.l.LightningGreaves.class));