mirror of
https://github.com/correl/mage.git
synced 2025-04-13 09:11:06 -09:00
[AFR] Implemented The Deck of Many Things
This commit is contained in:
parent
b929b28e43
commit
e79e9f1194
3 changed files with 228 additions and 7 deletions
Mage.Sets/src/mage
Mage/src/main/java/mage/abilities/effects/common
204
Mage.Sets/src/mage/cards/t/TheDeckOfManyThings.java
Normal file
204
Mage.Sets/src/mage/cards/t/TheDeckOfManyThings.java
Normal file
|
@ -0,0 +1,204 @@
|
|||
package mage.cards.t;
|
||||
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.DelayedTriggeredAbility;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.effects.common.LoseGameTargetPlayerEffect;
|
||||
import mage.abilities.effects.common.RollDieWithResultTableEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.common.TargetCardInGraveyard;
|
||||
import mage.target.common.TargetCardInYourGraveyard;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class TheDeckOfManyThings extends CardImpl {
|
||||
|
||||
public TheDeckOfManyThings(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
|
||||
|
||||
this.addSuperType(SuperType.LEGENDARY);
|
||||
|
||||
// {2}, {T}: Roll a d20 and subtract the number of cards in your hand. If the result is 0 or less, discard your hand.
|
||||
// 1-9 | Return a card at random from your graveyard to your hand.
|
||||
// 10-19 | Draw two cards.
|
||||
// 20 | Put a creature card from any graveyard onto the battlefield under your control. When that creature dies, its owner loses the game.
|
||||
Ability ability = new SimpleActivatedAbility(new TheDeckOfManyThingsEffect(), new GenericManaCost(2));
|
||||
ability.addCost(new TapSourceCost());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private TheDeckOfManyThings(final TheDeckOfManyThings card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TheDeckOfManyThings copy() {
|
||||
return new TheDeckOfManyThings(this);
|
||||
}
|
||||
}
|
||||
|
||||
class TheDeckOfManyThingsEffect extends RollDieWithResultTableEffect {
|
||||
|
||||
TheDeckOfManyThingsEffect() {
|
||||
super(20, "roll a d20 and subtract the number of cards in your hand. If the result is 0 or less, discard your hand.");
|
||||
this.addTableEntry(1, 9, new TheDeckOfManyThingsRandomEffect());
|
||||
this.addTableEntry(10, 19, new DrawCardSourceControllerEffect(2));
|
||||
this.addTableEntry(20, 20, new TheDeckOfManyThingsReturnEffect());
|
||||
}
|
||||
|
||||
private TheDeckOfManyThingsEffect(final TheDeckOfManyThingsEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TheDeckOfManyThingsEffect copy() {
|
||||
return new TheDeckOfManyThingsEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
int result = player.rollDice(source, game, sides) - player.getHand().size();
|
||||
if (result <= 0) {
|
||||
player.discard(player.getHand(), false, source, game);
|
||||
}
|
||||
this.applyResult(result, game, source);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class TheDeckOfManyThingsRandomEffect extends OneShotEffect {
|
||||
|
||||
TheDeckOfManyThingsRandomEffect() {
|
||||
super(Outcome.ReturnToHand);
|
||||
staticText = "return a card at random from your graveyard to your hand";
|
||||
}
|
||||
|
||||
private TheDeckOfManyThingsRandomEffect(final TheDeckOfManyThingsRandomEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TheDeckOfManyThingsRandomEffect copy() {
|
||||
return new TheDeckOfManyThingsRandomEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player == null || player.getGraveyard().count(StaticFilters.FILTER_CARD, game) < 1) {
|
||||
return false;
|
||||
}
|
||||
TargetCard target = new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD);
|
||||
target.setRandom(true);
|
||||
target.setNotTarget(true);
|
||||
player.chooseTarget(outcome, target, source, game);
|
||||
Card card = game.getCard(target.getFirstTarget());
|
||||
return card != null && player.moveCards(card, Zone.HAND, source, game);
|
||||
}
|
||||
}
|
||||
|
||||
class TheDeckOfManyThingsReturnEffect extends OneShotEffect {
|
||||
|
||||
TheDeckOfManyThingsReturnEffect() {
|
||||
super(Outcome.PutCreatureInPlay);
|
||||
staticText = "put a creature card from any graveyard onto the battlefield under your control. " +
|
||||
"When that creature dies, its owner loses the game";
|
||||
}
|
||||
|
||||
private TheDeckOfManyThingsReturnEffect(final TheDeckOfManyThingsReturnEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TheDeckOfManyThingsReturnEffect copy() {
|
||||
return new TheDeckOfManyThingsReturnEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
TargetCardInGraveyard target = new TargetCardInGraveyard(StaticFilters.FILTER_CARD_CREATURE);
|
||||
target.setNotTarget(true);
|
||||
if (!target.canChoose(source.getSourceId(), source.getControllerId(), game)) {
|
||||
return false;
|
||||
}
|
||||
player.choose(outcome, target, source.getControllerId(), game);
|
||||
Card card = game.getCard(target.getFirstTarget());
|
||||
if (card == null) {
|
||||
return false;
|
||||
}
|
||||
player.moveCards(card, Zone.BATTLEFIELD, source, game);
|
||||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
game.addDelayedTriggeredAbility(new TheDeckOfManyThingsDelayedTriggeredAbility(permanent, game), source);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class TheDeckOfManyThingsDelayedTriggeredAbility extends DelayedTriggeredAbility {
|
||||
|
||||
private final MageObjectReference mor;
|
||||
|
||||
TheDeckOfManyThingsDelayedTriggeredAbility(Permanent permanent, Game game) {
|
||||
super(new LoseGameTargetPlayerEffect(), Duration.Custom, false, false);
|
||||
this.mor = new MageObjectReference(permanent, game);
|
||||
}
|
||||
|
||||
private TheDeckOfManyThingsDelayedTriggeredAbility(final TheDeckOfManyThingsDelayedTriggeredAbility ability) {
|
||||
super(ability);
|
||||
this.mor = ability.mor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||
if (!zEvent.isDiesEvent() || !mor.refersTo(zEvent.getTarget(), game)) {
|
||||
return false;
|
||||
}
|
||||
getEffects().setTargetPointer(new FixedTarget(zEvent.getTarget().getOwnerId(), game));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TheDeckOfManyThingsDelayedTriggeredAbility copy() {
|
||||
return new TheDeckOfManyThingsDelayedTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "When that creature dies, its owner loses the game.";
|
||||
}
|
||||
}
|
|
@ -115,6 +115,7 @@ public final class AdventuresInTheForgottenRealms extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Swarming Goblins", 162, Rarity.COMMON, mage.cards.s.SwarmingGoblins.class));
|
||||
cards.add(new SetCardInfo("Targ Nar, Demon-Fang Gnoll", 234, Rarity.UNCOMMON, mage.cards.t.TargNarDemonFangGnoll.class));
|
||||
cards.add(new SetCardInfo("Tasha's Hideous Laughter", 78, Rarity.RARE, mage.cards.t.TashasHideousLaughter.class));
|
||||
cards.add(new SetCardInfo("The Deck of Many Things", 241, Rarity.MYTHIC, mage.cards.t.TheDeckOfManyThings.class));
|
||||
cards.add(new SetCardInfo("Tiamat", 235, Rarity.MYTHIC, mage.cards.t.Tiamat.class));
|
||||
cards.add(new SetCardInfo("Trelasarra Moon Dancer", 236, Rarity.UNCOMMON, mage.cards.t.TrelasarraMoonDancer.class));
|
||||
cards.add(new SetCardInfo("Varis, Silverymoon Ranger", 209, Rarity.RARE, mage.cards.v.VarisSilverymoonRanger.class));
|
||||
|
|
|
@ -19,7 +19,8 @@ import java.util.List;
|
|||
*/
|
||||
public class RollDieWithResultTableEffect extends OneShotEffect {
|
||||
|
||||
private final int sides;
|
||||
protected final int sides;
|
||||
private final String prefixText;
|
||||
private final List<TableEntry> resultsTable = new ArrayList<>();
|
||||
|
||||
public RollDieWithResultTableEffect() {
|
||||
|
@ -27,13 +28,19 @@ public class RollDieWithResultTableEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
public RollDieWithResultTableEffect(int sides) {
|
||||
super(Outcome.Benefit);
|
||||
this.sides = sides;
|
||||
this(sides, null);
|
||||
}
|
||||
|
||||
private RollDieWithResultTableEffect(final RollDieWithResultTableEffect effect) {
|
||||
public RollDieWithResultTableEffect(int sides, String prefixText) {
|
||||
super(Outcome.Benefit);
|
||||
this.sides = sides;
|
||||
this.prefixText = prefixText;
|
||||
}
|
||||
|
||||
protected RollDieWithResultTableEffect(final RollDieWithResultTableEffect effect) {
|
||||
super(effect);
|
||||
this.sides = effect.sides;
|
||||
this.prefixText = effect.prefixText;
|
||||
for (TableEntry tableEntry : effect.resultsTable) {
|
||||
this.resultsTable.add(tableEntry.copy());
|
||||
}
|
||||
|
@ -51,18 +58,27 @@ public class RollDieWithResultTableEffect extends OneShotEffect {
|
|||
return false;
|
||||
}
|
||||
int result = player.rollDice(source, game, sides);
|
||||
this.applyResult(result, game, source);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void applyResult(int result, Game game, Ability source) {
|
||||
for (TableEntry tableEntry : this.resultsTable) {
|
||||
if (tableEntry.matches(result)) {
|
||||
tableEntry.apply(game, source);
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Mode mode) {
|
||||
StringBuilder sb = new StringBuilder("roll a d").append(sides).append('.');
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (prefixText != null) {
|
||||
sb.append(prefixText);
|
||||
} else {
|
||||
sb.append("roll a d").append(sides).append('.');
|
||||
}
|
||||
for (TableEntry tableEntry : this.resultsTable) {
|
||||
sb.append("<br>");
|
||||
if (tableEntry.min == tableEntry.max) {
|
||||
|
|
Loading…
Add table
Reference in a new issue