mirror of
https://github.com/correl/mage.git
synced 2024-12-26 11:09:27 +00:00
Implemented Unpredictable Cyclone
This commit is contained in:
parent
a5fb946fb3
commit
a689646735
4 changed files with 151 additions and 6 deletions
108
Mage.Sets/src/mage/cards/u/UnpredictableCyclone.java
Normal file
108
Mage.Sets/src/mage/cards/u/UnpredictableCyclone.java
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
package mage.cards.u;
|
||||||
|
|
||||||
|
import mage.MageObjectReference;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
|
import mage.abilities.effects.ReplacementEffectImpl;
|
||||||
|
import mage.abilities.keyword.CyclingAbility;
|
||||||
|
import mage.cards.*;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.players.Player;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class UnpredictableCyclone extends CardImpl {
|
||||||
|
|
||||||
|
public UnpredictableCyclone(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}{R}");
|
||||||
|
|
||||||
|
// If a cycling ability of another nonland card would cause you to draw a card, instead exile cards from the top of your library until you exile a card that shares a card type with the cycled card. You may cast that card without paying its mana cost. Then put the exiled cards that weren't cast this way on the bottom of your library in a random order.
|
||||||
|
this.addAbility(new SimpleStaticAbility(new ArchmageAscensionReplacementEffect()));
|
||||||
|
|
||||||
|
// Cycling {2}
|
||||||
|
this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}")));
|
||||||
|
}
|
||||||
|
|
||||||
|
private UnpredictableCyclone(final UnpredictableCyclone card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UnpredictableCyclone copy() {
|
||||||
|
return new UnpredictableCyclone(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ArchmageAscensionReplacementEffect extends ReplacementEffectImpl {
|
||||||
|
|
||||||
|
ArchmageAscensionReplacementEffect() {
|
||||||
|
super(Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||||
|
staticText = "If a cycling ability of another nonland card would cause you to draw a card, " +
|
||||||
|
"instead exile cards from the top of your library until you exile a card " +
|
||||||
|
"that shares a card type with the cycled card. You may cast that card without paying its mana cost. " +
|
||||||
|
"Then put the exiled cards that weren't cast this way on the bottom of your library in a random order.";
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArchmageAscensionReplacementEffect(final ArchmageAscensionReplacementEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArchmageAscensionReplacementEffect copy() {
|
||||||
|
return new ArchmageAscensionReplacementEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||||
|
Player player = game.getPlayer(event.getPlayerId());
|
||||||
|
Card sourceCard = game.getCard(event.getSourceId());
|
||||||
|
if (player == null || sourceCard == null || sourceCard.isLand()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Cards cards = new CardsImpl();
|
||||||
|
Card toCast = null;
|
||||||
|
for (Card card : player.getLibrary().getCards(game)) {
|
||||||
|
cards.add(card);
|
||||||
|
if (card.getCardType().stream().anyMatch(sourceCard.getCardType()::contains)) {
|
||||||
|
toCast = card;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
player.moveCards(cards, Zone.EXILED, source, game);
|
||||||
|
if (toCast != null && player.chooseUse(outcome, "Cast the exiled card?", source, game)) {
|
||||||
|
game.getState().setValue("PlayFromNotOwnHandZone" + toCast.getId(), Boolean.TRUE);
|
||||||
|
Boolean cardWasCast = player.cast(player.chooseAbilityForCast(toCast, game, true),
|
||||||
|
game, true, new MageObjectReference(source.getSourceObject(game), game));
|
||||||
|
game.getState().setValue("PlayFromNotOwnHandZone" + toCast.getId(), null);
|
||||||
|
if (cardWasCast) {
|
||||||
|
cards.remove(toCast);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
player.putCardsOnBottomOfLibrary(cards, game, source, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checksEventType(GameEvent event, Game game) {
|
||||||
|
return event.getType() == GameEvent.EventType.CYCLE_DRAW;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||||
|
return event.getPlayerId().equals(source.getControllerId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -307,6 +307,7 @@ public final class IkoriaLairOfBehemoths extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Unbreakable Bond", 101, Rarity.UNCOMMON, mage.cards.u.UnbreakableBond.class));
|
cards.add(new SetCardInfo("Unbreakable Bond", 101, Rarity.UNCOMMON, mage.cards.u.UnbreakableBond.class));
|
||||||
cards.add(new SetCardInfo("Unexpected Fangs", 102, Rarity.COMMON, mage.cards.u.UnexpectedFangs.class));
|
cards.add(new SetCardInfo("Unexpected Fangs", 102, Rarity.COMMON, mage.cards.u.UnexpectedFangs.class));
|
||||||
cards.add(new SetCardInfo("Unlikely Aid", 103, Rarity.COMMON, mage.cards.u.UnlikelyAid.class));
|
cards.add(new SetCardInfo("Unlikely Aid", 103, Rarity.COMMON, mage.cards.u.UnlikelyAid.class));
|
||||||
|
cards.add(new SetCardInfo("Unpredictable Cyclone", 139, Rarity.RARE, mage.cards.u.UnpredictableCyclone.class));
|
||||||
cards.add(new SetCardInfo("Vadrok, Apex of Thunder", 214, Rarity.MYTHIC, mage.cards.v.VadrokApexOfThunder.class));
|
cards.add(new SetCardInfo("Vadrok, Apex of Thunder", 214, Rarity.MYTHIC, mage.cards.v.VadrokApexOfThunder.class));
|
||||||
cards.add(new SetCardInfo("Vivien, Monsters' Advocate", 175, Rarity.MYTHIC, mage.cards.v.VivienMonstersAdvocate.class));
|
cards.add(new SetCardInfo("Vivien, Monsters' Advocate", 175, Rarity.MYTHIC, mage.cards.v.VivienMonstersAdvocate.class));
|
||||||
cards.add(new SetCardInfo("Void Beckoner", 104, Rarity.UNCOMMON, mage.cards.v.VoidBeckoner.class));
|
cards.add(new SetCardInfo("Void Beckoner", 104, Rarity.UNCOMMON, mage.cards.v.VoidBeckoner.class));
|
||||||
|
|
|
@ -1,18 +1,21 @@
|
||||||
|
|
||||||
package mage.abilities.keyword;
|
package mage.abilities.keyword;
|
||||||
|
|
||||||
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.ActivatedAbilityImpl;
|
import mage.abilities.ActivatedAbilityImpl;
|
||||||
import mage.abilities.costs.Cost;
|
import mage.abilities.costs.Cost;
|
||||||
import mage.abilities.costs.common.CyclingDiscardCost;
|
import mage.abilities.costs.common.CyclingDiscardCost;
|
||||||
import mage.abilities.costs.mana.ManaCost;
|
import mage.abilities.costs.mana.ManaCost;
|
||||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
|
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
|
||||||
|
import mage.constants.Outcome;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.filter.FilterCard;
|
import mage.filter.FilterCard;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.players.Player;
|
||||||
import mage.target.common.TargetCardInLibrary;
|
import mage.target.common.TargetCardInLibrary;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
public class CyclingAbility extends ActivatedAbilityImpl {
|
public class CyclingAbility extends ActivatedAbilityImpl {
|
||||||
|
@ -21,7 +24,7 @@ public class CyclingAbility extends ActivatedAbilityImpl {
|
||||||
private final String text;
|
private final String text;
|
||||||
|
|
||||||
public CyclingAbility(Cost cost) {
|
public CyclingAbility(Cost cost) {
|
||||||
super(Zone.HAND, new DrawCardSourceControllerEffect(1), cost);
|
super(Zone.HAND, new CyclingDrawEffect(), cost);
|
||||||
this.addCost(new CyclingDiscardCost());
|
this.addCost(new CyclingDiscardCost());
|
||||||
this.cost = cost;
|
this.cost = cost;
|
||||||
this.text = "Cycling";
|
this.text = "Cycling";
|
||||||
|
@ -56,5 +59,38 @@ public class CyclingAbility extends ActivatedAbilityImpl {
|
||||||
rule.append(cost.getText()).append(" <i>(").append(super.getRule(true)).append(")</i>");
|
rule.append(cost.getText()).append(" <i>(").append(super.getRule(true)).append(")</i>");
|
||||||
return rule.toString();
|
return rule.toString();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CyclingDrawEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
CyclingDrawEffect() {
|
||||||
|
super(Outcome.Benefit);
|
||||||
|
staticText = "draw a card";
|
||||||
|
}
|
||||||
|
|
||||||
|
private CyclingDrawEffect(final CyclingDrawEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CyclingDrawEffect copy() {
|
||||||
|
return new CyclingDrawEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player player = game.getPlayer(source.getSourceId());
|
||||||
|
if (player == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
GameEvent event = GameEvent.getEvent(
|
||||||
|
GameEvent.EventType.CYCLE_DRAW, source.getSourceId(),
|
||||||
|
source.getSourceId(), source.getControllerId()
|
||||||
|
);
|
||||||
|
if (game.replaceEvent(event)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
player.drawCards(1, game);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -85,7 +85,7 @@ public class GameEvent implements Serializable {
|
||||||
CONVOKED,
|
CONVOKED,
|
||||||
DISCARD_CARD,
|
DISCARD_CARD,
|
||||||
DISCARDED_CARD,
|
DISCARDED_CARD,
|
||||||
CYCLE_CARD, CYCLED_CARD,
|
CYCLE_CARD, CYCLED_CARD, CYCLE_DRAW,
|
||||||
CLASH, CLASHED,
|
CLASH, CLASHED,
|
||||||
DAMAGE_PLAYER,
|
DAMAGE_PLAYER,
|
||||||
/* DAMAGED_PLAYER
|
/* DAMAGED_PLAYER
|
||||||
|
|
Loading…
Reference in a new issue