[FIN] Implement Sidequest: Play Blitzball / World Champion, Celestial Weapon

This commit is contained in:
theelk801 2025-05-20 20:16:15 -04:00
parent 0a9b245331
commit 04e96bfa97
5 changed files with 197 additions and 23 deletions

View file

@ -57,7 +57,7 @@ class DelinaWildMageEffect extends OneShotEffect {
super(Outcome.Benefit);
staticText = "choose target creature you control, then roll a d20." +
"<br>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.\"" +
"<br>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);

View file

@ -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<UUID, Integer> 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);
}
}

View file

@ -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);
}
}

View file

@ -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));

View file

@ -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;
}
return super.getRule();
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);
}
}
}