diff --git a/Mage.Sets/src/mage/cards/a/AcesBaseballBat.java b/Mage.Sets/src/mage/cards/a/AcesBaseballBat.java index 75383b17811..d03992b2eb0 100644 --- a/Mage.Sets/src/mage/cards/a/AcesBaseballBat.java +++ b/Mage.Sets/src/mage/cards/a/AcesBaseballBat.java @@ -2,7 +2,7 @@ package mage.cards.a; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.Condition; +import mage.abilities.condition.common.AttachedAttackingCondition; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneAttachedEffect; @@ -14,8 +14,6 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.common.FilterControlledCreaturePermanent; -import mage.game.Game; -import mage.game.permanent.Permanent; import mage.target.common.TargetControlledCreaturePermanent; import java.util.UUID; @@ -27,12 +25,14 @@ public final class AcesBaseballBat extends CardImpl { private static final FilterControlledCreaturePermanent filterLegendary = new FilterControlledCreaturePermanent("legendary creature"); + static { filterLegendary.add(SuperType.LEGENDARY.getPredicate()); } private static final FilterControlledCreaturePermanent filterDalek = new FilterControlledCreaturePermanent("a Dalek"); + static { filterDalek.add(SubType.DALEK.getPredicate()); } @@ -48,12 +48,19 @@ public final class AcesBaseballBat extends CardImpl { // As long as equipped creature is attacking, it has first strike and must be blocked by a Dalek if able. Ability ability = new SimpleStaticAbility(new ConditionalContinuousEffect( new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), AttachmentType.EQUIPMENT), - AttachedToAttackingCondition.instance, "As long as equipped creature is attacking, it has first strike")); - ability.addEffect(new MustBeBlockedByAtLeastOneAttachedEffect(filterDalek).concatBy("and")); + AttachedAttackingCondition.instance, "as long as equipped creature is attacking, it has first strike" + )); + ability.addEffect(new ConditionalContinuousEffect( + new MustBeBlockedByAtLeastOneAttachedEffect(filterDalek), + AttachedAttackingCondition.instance, "and must be blocked by a Dalek if able" + )); this.addAbility(ability); // Equip legendary creature (1) - this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(1), new TargetControlledCreaturePermanent(filterLegendary), false)); + this.addAbility(new EquipAbility( + Outcome.AddAbility, new GenericManaCost(1), + new TargetControlledCreaturePermanent(filterLegendary), false + )); // Equip {3} this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(3), false)); @@ -68,19 +75,3 @@ public final class AcesBaseballBat extends CardImpl { return new AcesBaseballBat(this); } } -enum AttachedToAttackingCondition implements Condition { - instance; - - @Override - public boolean apply(Game game, Ability source) { - Permanent attachment = game.getPermanent(source.getSourceId()); - if (attachment == null || attachment.getAttachedTo() == null) { - return false; - } - Permanent attachedTo = game.getPermanent(attachment.getAttachedTo()); - if (attachedTo == null) { - return false; - } - return attachedTo.isAttacking(); - } -} diff --git a/Mage.Sets/src/mage/cards/t/TheMasamune.java b/Mage.Sets/src/mage/cards/t/TheMasamune.java new file mode 100644 index 00000000000..ecc00cdaead --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TheMasamune.java @@ -0,0 +1,118 @@ +package mage.cards.t; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.AttachedAttackingCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneAttachedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.game.command.Emblem; +import mage.game.events.GameEvent; +import mage.game.events.NumberOfTriggersEvent; +import mage.game.events.ZoneChangeEvent; +import mage.util.CardUtil; + +import java.util.Optional; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TheMasamune extends CardImpl { + + public TheMasamune(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.EQUIPMENT); + + // As long as equipped creature is attacking, it has first strike and must be blocked if able. + Ability ability = new SimpleStaticAbility(new ConditionalContinuousEffect( + new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), AttachmentType.EQUIPMENT), + AttachedAttackingCondition.instance, "as long as equipped creature is attacking, it has first strike" + )); + ability.addEffect(new ConditionalContinuousEffect( + new MustBeBlockedByAtLeastOneAttachedEffect(), + AttachedAttackingCondition.instance, "and must be blocked if able" + )); + this.addAbility(ability); + + // Equipped creature has "If a creature dying causes a triggered ability of this creature or an emblem you own to trigger, that ability triggers an additional time." + this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect( + new SimpleStaticAbility(new TheMasamuneEffect()), AttachmentType.EQUIPMENT + ))); + + // Equip {2} + this.addAbility(new EquipAbility(2)); + } + + private TheMasamune(final TheMasamune card) { + super(card); + } + + @Override + public TheMasamune copy() { + return new TheMasamune(this); + } +} + +class TheMasamuneEffect extends ReplacementEffectImpl { + + TheMasamuneEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "If a creature dying causes a triggered ability of this creature " + + "or an emblem you own to trigger, that ability triggers an additional time."; + } + + private TheMasamuneEffect(final TheMasamuneEffect effect) { + super(effect); + } + + @Override + public TheMasamuneEffect copy() { + return new TheMasamuneEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.NUMBER_OF_TRIGGERS; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return Optional + .ofNullable(event) + .filter(NumberOfTriggersEvent.class::isInstance) + .map(NumberOfTriggersEvent.class::cast) + .map(NumberOfTriggersEvent::getSourceEvent) + .filter(ZoneChangeEvent.class::isInstance) + .map(ZoneChangeEvent.class::cast) + .filter(ZoneChangeEvent::isDiesEvent) + .map(ZoneChangeEvent::getTarget) + .map(permanent -> permanent.isCreature(game)) + .orElse(false) + && source.isControlledBy(event.getPlayerId()) + && (source.getSourceId().equals(event.getSourceId()) + || Optional + .ofNullable(event) + .map(GameEvent::getSourceId) + .map(game::getEmblem) + .map(Emblem.class::cast) + .map(Emblem::getControllerOrOwnerId) + .map(source::isControlledBy) + .orElse(false)); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + event.setAmount(CardUtil.overflowInc(event.getAmount(), 1)); + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/FinalFantasy.java b/Mage.Sets/src/mage/sets/FinalFantasy.java index ff16aaa7ea4..fe2a186a85f 100644 --- a/Mage.Sets/src/mage/sets/FinalFantasy.java +++ b/Mage.Sets/src/mage/sets/FinalFantasy.java @@ -521,6 +521,8 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("The Lord Master of Hell", 219, Rarity.UNCOMMON, mage.cards.t.TheLordMasterOfHell.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Lord Master of Hell", 484, Rarity.UNCOMMON, mage.cards.t.TheLordMasterOfHell.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Lunar Whale", 60, Rarity.RARE, mage.cards.t.TheLunarWhale.class)); + cards.add(new SetCardInfo("The Masamune", 264, Rarity.RARE, mage.cards.t.TheMasamune.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("The Masamune", 353, Rarity.RARE, mage.cards.t.TheMasamune.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Prima Vista", 64, Rarity.UNCOMMON, mage.cards.t.ThePrimaVista.class)); cards.add(new SetCardInfo("The Regalia", 267, Rarity.RARE, mage.cards.t.TheRegalia.class)); cards.add(new SetCardInfo("The Water Crystal", 333, Rarity.RARE, mage.cards.t.TheWaterCrystal.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage/src/main/java/mage/abilities/condition/common/AttachedAttackingCondition.java b/Mage/src/main/java/mage/abilities/condition/common/AttachedAttackingCondition.java new file mode 100644 index 00000000000..4d65a49a7e3 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/condition/common/AttachedAttackingCondition.java @@ -0,0 +1,30 @@ +package mage.abilities.condition.common; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.game.Game; +import mage.game.permanent.Permanent; + +import java.util.Optional; + +/** + * @author TheElk801 + */ +public enum AttachedAttackingCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + return Optional + .ofNullable(source.getSourcePermanentIfItStillExists(game)) + .map(Permanent::getAttachedTo) + .map(game::getPermanent) + .map(Permanent::isAttacking) + .orElse(false); + } + + @Override + public String toString() { + return "equipped creature is attacking"; + } +}