diff --git a/Mage.Sets/src/mage/cards/d/DelinaWildMage.java b/Mage.Sets/src/mage/cards/d/DelinaWildMage.java index 31e0db4035c..8e04bccb92c 100644 --- a/Mage.Sets/src/mage/cards/d/DelinaWildMage.java +++ b/Mage.Sets/src/mage/cards/d/DelinaWildMage.java @@ -57,7 +57,7 @@ class DelinaWildMageEffect extends OneShotEffect { super(Outcome.Benefit); staticText = "choose target creature you control, then roll a d20." + "
1-14 | Create a tapped and attacking token that's a copy of that creature, " + - "except it's not legendary and it has \"Exile this creature at end of combat.\"" + + "except it's not legendary and it has \"At end of combat, exile this token.\"" + "
15-20 | Create one of those tokens. You may roll again."; } @@ -81,9 +81,7 @@ class DelinaWildMageEffect extends OneShotEffect { false, 1, true, true ); effect.setIsntLegendary(true); - effect.addAdditionalAbilities(new EndOfCombatTriggeredAbility( - new ExileSourceEffect(), false, "Exile this creature at end of combat." - )); + effect.addAdditionalAbilities(new EndOfCombatTriggeredAbility(new ExileSourceEffect(), false)); effect.setTargetPointer(this.getTargetPointer().copy()); while (true) { int result = player.rollDice(outcome, source, game, 20); diff --git a/Mage.Sets/src/mage/cards/s/SidequestPlayBlitzball.java b/Mage.Sets/src/mage/cards/s/SidequestPlayBlitzball.java new file mode 100644 index 00000000000..75b783ff205 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SidequestPlayBlitzball.java @@ -0,0 +1,129 @@ +package mage.cards.s; + +import mage.abilities.Ability; +import mage.abilities.common.EndOfCombatTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.keyword.TransformAbility; +import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.WatcherScope; +import mage.game.Game; +import mage.game.events.DamagedEvent; +import mage.game.events.GameEvent; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.watchers.Watcher; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SidequestPlayBlitzball extends CardImpl { + + public SidequestPlayBlitzball(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}"); + + this.secondSideCardClazz = mage.cards.w.WorldChampionCelestialWeapon.class; + + // At the beginning of combat on your turn, target creature you control gets +2/+0 until end of turn. + Ability ability = new BeginningOfCombatTriggeredAbility(new BoostTargetEffect(2, 0)); + ability.addTarget(new TargetControlledCreaturePermanent()); + this.addAbility(ability); + + // At the end of combat on your turn, if a player was dealt 6 or more combat damage this turn, transform this enchantment, then attach it to a creature you control. + this.addAbility(new TransformAbility()); + ability = new EndOfCombatTriggeredAbility( + new TransformSourceEffect(), TargetController.YOU, false + ).withInterveningIf(SidequestPlayBlitzballCondition.instance); + ability.addEffect(new SidequestPlayBlitzballEffect()); + this.addAbility(ability, new SidequestPlayBlitzballWatcher()); + } + + private SidequestPlayBlitzball(final SidequestPlayBlitzball card) { + super(card); + } + + @Override + public SidequestPlayBlitzball copy() { + return new SidequestPlayBlitzball(this); + } +} + +enum SidequestPlayBlitzballCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + return SidequestPlayBlitzballWatcher.checkPlayers(game, source); + } + + @Override + public String toString() { + return "a player was dealt 6 or more combat damage this turn"; + } +} + +class SidequestPlayBlitzballEffect extends OneShotEffect { + + SidequestPlayBlitzballEffect() { + super(Outcome.Benefit); + staticText = ", then attach it to a creature you control"; + } + + private SidequestPlayBlitzballEffect(final SidequestPlayBlitzballEffect effect) { + super(effect); + } + + @Override + public SidequestPlayBlitzballEffect copy() { + return new SidequestPlayBlitzballEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } +} + +class SidequestPlayBlitzballWatcher extends Watcher { + + private final Map map = new HashMap<>(); + + SidequestPlayBlitzballWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER && ((DamagedEvent) event).isCombatDamage()) { + map.compute(event.getTargetId(), (u, i) -> i == null ? event.getAmount() : Integer.sum(i, event.getAmount())); + } + } + + @Override + public void reset() { + super.reset(); + map.clear(); + } + + private boolean checkMap(UUID playerId) { + return map.getOrDefault(playerId, 0) >= 6; + } + + static boolean checkPlayers(Game game, Ability source) { + return game + .getState() + .getPlayersInRange(source.getControllerId(), game) + .stream() + .anyMatch(game.getState().getWatcher(SidequestPlayBlitzballWatcher.class)::checkMap); + } +} diff --git a/Mage.Sets/src/mage/cards/w/WorldChampionCelestialWeapon.java b/Mage.Sets/src/mage/cards/w/WorldChampionCelestialWeapon.java new file mode 100644 index 00000000000..5b81bc4e926 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WorldChampionCelestialWeapon.java @@ -0,0 +1,50 @@ +package mage.cards.w; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.abilities.keyword.EquipAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class WorldChampionCelestialWeapon extends CardImpl { + + public WorldChampionCelestialWeapon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.EQUIPMENT); + this.nightCard = true; + this.color.setRed(true); + + // Double Overdrive -- Equipped creature gets +2/+0 and has double strike. + Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(2, 0)); + ability.addEffect(new GainAbilityAttachedEffect( + DoubleStrikeAbility.getInstance(), AttachmentType.EQUIPMENT + ).setText("and has double strike")); + this.addAbility(ability.withFlavorWord("Double Overdrive")); + + // Equip {3} + this.addAbility(new EquipAbility(3)); + } + + private WorldChampionCelestialWeapon(final WorldChampionCelestialWeapon card) { + super(card); + } + + @Override + public WorldChampionCelestialWeapon copy() { + return new WorldChampionCelestialWeapon(this); + } +} diff --git a/Mage.Sets/src/mage/sets/FinalFantasy.java b/Mage.Sets/src/mage/sets/FinalFantasy.java index d1c4e5ddba1..f5d610a376e 100644 --- a/Mage.Sets/src/mage/sets/FinalFantasy.java +++ b/Mage.Sets/src/mage/sets/FinalFantasy.java @@ -294,6 +294,7 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("Shiva, Warden of Ice", 523, Rarity.RARE, mage.cards.s.ShivaWardenOfIce.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Shiva, Warden of Ice", 58, Rarity.RARE, mage.cards.s.ShivaWardenOfIce.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sidequest: Catch a Fish", 31, Rarity.UNCOMMON, mage.cards.s.SidequestCatchAFish.class)); + cards.add(new SetCardInfo("Sidequest: Play Blitzball", 158, Rarity.UNCOMMON, mage.cards.s.SidequestPlayBlitzball.class)); cards.add(new SetCardInfo("Sin, Spira's Punishment", 242, Rarity.RARE, mage.cards.s.SinSpirasPunishment.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sin, Spira's Punishment", 348, Rarity.RARE, mage.cards.s.SinSpirasPunishment.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sin, Spira's Punishment", 508, Rarity.RARE, mage.cards.s.SinSpirasPunishment.class, NON_FULL_USE_VARIOUS)); @@ -395,6 +396,7 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("White Auracite", 41, Rarity.COMMON, mage.cards.w.WhiteAuracite.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("White Auracite", 579, Rarity.COMMON, mage.cards.w.WhiteAuracite.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("White Mage's Staff", 42, Rarity.COMMON, mage.cards.w.WhiteMagesStaff.class)); + cards.add(new SetCardInfo("World Champion, Celestial Weapon", 158, Rarity.UNCOMMON, mage.cards.w.WorldChampionCelestialWeapon.class)); cards.add(new SetCardInfo("Xande, Dark Mage", 516, Rarity.RARE, mage.cards.x.XandeDarkMage.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Xande, Dark Mage", 561, Rarity.RARE, mage.cards.x.XandeDarkMage.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Y'shtola Rhul", 443, Rarity.MYTHIC, mage.cards.y.YshtolaRhul.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage/src/main/java/mage/abilities/common/EndOfCombatTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/EndOfCombatTriggeredAbility.java index 76526cc7128..a6d36c6fa6a 100644 --- a/Mage/src/main/java/mage/abilities/common/EndOfCombatTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/EndOfCombatTriggeredAbility.java @@ -1,7 +1,8 @@ package mage.abilities.common; -import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; +import mage.abilities.triggers.AtStepTriggeredAbility; +import mage.constants.TargetController; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; @@ -9,23 +10,18 @@ import mage.game.events.GameEvent; /** * @author LevelX2 */ -public class EndOfCombatTriggeredAbility extends TriggeredAbilityImpl { - - private final String rule; +public class EndOfCombatTriggeredAbility extends AtStepTriggeredAbility { public EndOfCombatTriggeredAbility(Effect effect, boolean optional) { - this(effect, optional, null); + this(effect, TargetController.ANY, optional); } - public EndOfCombatTriggeredAbility(Effect effect, boolean optional, String rule) { - super(Zone.BATTLEFIELD, effect, optional); - this.rule = rule; - setTriggerPhrase("At end of combat, "); + public EndOfCombatTriggeredAbility(Effect effect, TargetController targetController, boolean optional) { + super(Zone.BATTLEFIELD, targetController, effect, optional); } protected EndOfCombatTriggeredAbility(final EndOfCombatTriggeredAbility ability) { super(ability); - this.rule = ability.rule; } @Override @@ -39,15 +35,14 @@ public class EndOfCombatTriggeredAbility extends TriggeredAbilityImpl { } @Override - public boolean checkTrigger(GameEvent event, Game game) { - return true; - } - - @Override - public String getRule() { - if (rule != null) { - return rule; + protected String generateTriggerPhrase() { + switch (targetController) { + case ANY: + return "At end of combat, "; + case YOU: + return "At the end of combat on your turn, "; + default: + throw new UnsupportedOperationException("Unsupported TargetController in EndOfCombatTriggeredAbility: " + targetController); } - return super.getRule(); } }