Merge pull request #5291 from Zzooouhh/ugl

Implemented Jalum Grifter and Burning Cinder Fury (bugged)
This commit is contained in:
LevelX2 2018-09-30 10:36:08 +02:00 committed by GitHub
commit e614b8573e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 370 additions and 0 deletions

View file

@ -0,0 +1,226 @@
package mage.cards.b;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
import mage.target.common.TargetOpponent;
import mage.target.targetpointer.FixedTarget;
import mage.watchers.Watcher;
/**
*
* @author L_J
*/
public final class BurningCinderFuryOfCrimsonChaosFire extends CardImpl {
public BurningCinderFuryOfCrimsonChaosFire(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}");
// Whenever any player taps a permanent, that player choose one of their opponents. The chosen player gains control of that permanent at the beginning of the next end step.
this.addAbility(new BurningCinderFuryOfCrimsonChaosFireAbility());
// At the beginning of each players end step, if that player didnt tap any nonland permanents that turn, Burning Cinder Fury of Crimson Chaos Fire deals 3 damage to that player.
this.addAbility(new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, new DamageTargetEffect(3).setText("{this} deals 3 damage to that player"),
TargetController.ANY, new BurningCinderFuryOfCrimsonChaosFireCondition(), false), new BurningCinderFuryOfCrimsonChaosFireWatcher());
}
public BurningCinderFuryOfCrimsonChaosFire(final BurningCinderFuryOfCrimsonChaosFire card) {
super(card);
}
@Override
public BurningCinderFuryOfCrimsonChaosFire copy() {
return new BurningCinderFuryOfCrimsonChaosFire(this);
}
}
class BurningCinderFuryOfCrimsonChaosFireAbility extends TriggeredAbilityImpl {
public BurningCinderFuryOfCrimsonChaosFireAbility() {
super(Zone.BATTLEFIELD, new BurningCinderFuryOfCrimsonChaosFireEffect(), false);
}
public BurningCinderFuryOfCrimsonChaosFireAbility(BurningCinderFuryOfCrimsonChaosFireAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.TAPPED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null) {
BurningCinderFuryOfCrimsonChaosFireEffect effect = (BurningCinderFuryOfCrimsonChaosFireEffect) this.getEffects().get(0);
effect.setTargetPointer(new FixedTarget(permanent.getId()));
effect.setFirstController(permanent.getControllerId()); // it's necessary to remember the original controller, as the controller might change by the time the trigger resolves
return true;
}
return false;
}
@Override
public BurningCinderFuryOfCrimsonChaosFireAbility copy() {
return new BurningCinderFuryOfCrimsonChaosFireAbility(this);
}
@Override
public String getRule() {
return "Whenever any player taps a permanent, " + super.getRule();
}
}
class BurningCinderFuryOfCrimsonChaosFireEffect extends OneShotEffect {
private UUID firstController = null;
public BurningCinderFuryOfCrimsonChaosFireEffect() {
super(Outcome.Detriment);
this.staticText = "that player choose one of their opponents. The chosen player gains control of that permanent at the beginning of the next end step";
}
public BurningCinderFuryOfCrimsonChaosFireEffect(final BurningCinderFuryOfCrimsonChaosFireEffect effect) {
super(effect);
this.firstController = effect.firstController;
}
@Override
public BurningCinderFuryOfCrimsonChaosFireEffect copy() {
return new BurningCinderFuryOfCrimsonChaosFireEffect(this);
}
public void setFirstController(UUID newId) {
this.firstController = newId;
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(firstController);
if (player != null) {
Target target = new TargetOpponent(true);
if (target.canChoose(player.getId(), game)) {
while (!target.isChosen() && target.canChoose(player.getId(), game) && player.canRespond()) {
player.chooseTarget(outcome, target, source, game);
}
}
Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source));
Player chosenOpponent = game.getPlayer(target.getFirstTarget());
if (permanent != null && chosenOpponent != null) {
game.informPlayers(player.getLogName() + " chose " + chosenOpponent.getLogName() + " to gain control of " + permanent.getLogName() + " at the beginning of the next end step");
ContinuousEffect effect = new BurningCinderFuryOfCrimsonChaosFireCreatureGainControlEffect(Duration.Custom, chosenOpponent.getId());
effect.setTargetPointer(new FixedTarget(permanent.getId()));
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
return true;
}
}
return false;
}
}
class BurningCinderFuryOfCrimsonChaosFireCreatureGainControlEffect extends ContinuousEffectImpl {
private UUID controller;
public BurningCinderFuryOfCrimsonChaosFireCreatureGainControlEffect(Duration duration, UUID controller) {
super(duration, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
this.controller = controller;
this.staticText = "the chosen player gains control of that permanent";
}
public BurningCinderFuryOfCrimsonChaosFireCreatureGainControlEffect(final BurningCinderFuryOfCrimsonChaosFireCreatureGainControlEffect effect) {
super(effect);
this.controller = effect.controller;
}
@Override
public BurningCinderFuryOfCrimsonChaosFireCreatureGainControlEffect copy() {
return new BurningCinderFuryOfCrimsonChaosFireCreatureGainControlEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (targetPointer != null) {
permanent = game.getPermanent(targetPointer.getFirst(game, source));
}
if (permanent != null && controller != null) {
return permanent.changeControllerId(controller, game);
}
return false;
}
}
class BurningCinderFuryOfCrimsonChaosFireCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
BurningCinderFuryOfCrimsonChaosFireWatcher watcher = (BurningCinderFuryOfCrimsonChaosFireWatcher) game.getState().getWatchers().get(BurningCinderFuryOfCrimsonChaosFireWatcher.class.getSimpleName());
if (watcher != null) {
return !watcher.tappedNonlandThisTurn(game.getActivePlayerId());
}
return false;
}
public String toString() {
return "if that player didnt tap any nonland permanents that turn";
}
}
class BurningCinderFuryOfCrimsonChaosFireWatcher extends Watcher {
private final Set<UUID> tappedActivePlayerIds = new HashSet<>();
public BurningCinderFuryOfCrimsonChaosFireWatcher() {
super(BurningCinderFuryOfCrimsonChaosFireWatcher.class.getSimpleName(), WatcherScope.GAME);
}
public BurningCinderFuryOfCrimsonChaosFireWatcher(final BurningCinderFuryOfCrimsonChaosFireWatcher watcher) {
super(watcher);
this.tappedActivePlayerIds.addAll(watcher.tappedActivePlayerIds);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.TAPPED) {
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null && !permanent.isLand()) {
tappedActivePlayerIds.add(permanent.getControllerId());
}
}
}
public boolean tappedNonlandThisTurn(UUID playerId) {
return tappedActivePlayerIds.contains(playerId);
}
@Override
public void reset() {
tappedActivePlayerIds.clear();
}
@Override
public BurningCinderFuryOfCrimsonChaosFireWatcher copy() {
return new BurningCinderFuryOfCrimsonChaosFireWatcher(this);
}
}

View file

@ -0,0 +1,142 @@
package mage.cards.j;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.common.FilterControlledLandPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetCard;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledPermanent;
import mage.target.common.TargetOpponent;
/**
*
* @author L_J
*/
public final class JalumGrifter extends CardImpl {
public JalumGrifter(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}{R}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.DEVIL);
this.power = new MageInt(3);
this.toughness = new MageInt(5);
// {1}{R}, {T}: Shuffle Jalum Grifter and two lands you control face down. Target opponent chooses one of those cards. Turn the cards face up. If they chose Jalum Grifter, sacrifice it. Otherwise, destroy target permanent.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new JalumGrifterEffect(), new ManaCostsImpl("{1}{R}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetOpponent());
ability.addTarget(new TargetPermanent());
this.addAbility(ability);
}
public JalumGrifter(final JalumGrifter card) {
super(card);
}
@Override
public JalumGrifter copy() {
return new JalumGrifter(this);
}
}
class JalumGrifterEffect extends OneShotEffect {
public JalumGrifterEffect() {
super(Outcome.DestroyPermanent);
this.staticText = "Shuffle {this} and two lands you control face down. Target opponent chooses one of those cards. Turn the cards face up. If they chose {this}, sacrifice it. Otherwise, destroy target permanent";
}
public JalumGrifterEffect(final JalumGrifterEffect effect) {
super(effect);
}
@Override
public JalumGrifterEffect copy() {
return new JalumGrifterEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Player opponent = game.getPlayer(source.getTargets().get(0).getFirstTarget());
if (controller != null && opponent != null) {
List<Card> shellGamePile = new ArrayList<>();
Card sourceCard = game.getCard(source.getSourceId());
if (sourceCard != null) {
sourceCard = sourceCard.copy();
sourceCard.setFaceDown(true, game);
shellGamePile.add(sourceCard);
game.informPlayers(controller.getLogName() + " turns " + sourceCard.getLogName() + " face down");
}
Target target = new TargetControlledPermanent(2, 2, new FilterControlledLandPermanent(), true);
if (target.canChoose(source.getSourceId(), controller.getId(), game)) {
while (!target.isChosen() && target.canChoose(controller.getId(), game) && controller.canRespond()) {
controller.chooseTarget(outcome, target, source, game);
}
}
for (UUID cardId: target.getTargets()) {
Card card = game.getCard(cardId);
if (card != null) {
card = card.copy();
card.setFaceDown(true, game);
shellGamePile.add(card);
game.informPlayers(controller.getLogName() + " turns " + card.getLogName() + " face down");
}
}
if (shellGamePile.isEmpty()) {
return true;
}
Collections.shuffle(shellGamePile);
game.informPlayers(controller.getLogName() + " shuffles the face-down pile");
TargetCard targetCard = new TargetCard(Zone.HAND, new FilterCard());
CardsImpl cards = new CardsImpl();
cards.addAll(shellGamePile);
if (opponent.choose(Outcome.Sacrifice, cards, targetCard, game)) {
Card card = game.getCard(targetCard.getFirstTarget());
if (card != null) {
card.setFaceDown(false, game);
game.informPlayers(opponent.getLogName() + " reveals " + card.getLogName());
if (card.getId().equals(sourceCard.getId())) {
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (sourcePermanent != null) {
sourcePermanent.sacrifice(source.getSourceId(), game);
}
} else {
Permanent permanent = game.getPermanent(source.getTargets().get(1).getFirstTarget());
if (permanent != null) {
permanent.destroy(source.getSourceId(), game, false);
}
}
}
}
return true;
}
return false;
}
}

View file

@ -21,6 +21,7 @@ public final class Unglued extends ExpansionSet {
private Unglued() {
super("Unglued", "UGL", ExpansionSet.buildDate(1998, 8, 11), SetType.JOKESET);
cards.add(new SetCardInfo("Burning Cinder Fury of Crimson Chaos Fire", 40, Rarity.RARE, mage.cards.b.BurningCinderFuryOfCrimsonChaosFire.class));
cards.add(new SetCardInfo("Chicken Egg", 41, Rarity.COMMON, mage.cards.c.ChickenEgg.class));
cards.add(new SetCardInfo("Chicken a la King", 17, Rarity.RARE, mage.cards.c.ChickenALaKing.class));
cards.add(new SetCardInfo("Elvish Impersonators", 56, Rarity.COMMON, mage.cards.e.ElvishImpersonators.class));
@ -33,6 +34,7 @@ public final class Unglued extends ExpansionSet {
cards.add(new SetCardInfo("Incoming!", 64, Rarity.RARE, mage.cards.i.Incoming.class));
cards.add(new SetCardInfo("Island", 85, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(FrameStyle.UGL_FULL_ART_BASIC, false)));
cards.add(new SetCardInfo("Jack-in-the-Mox", 75, Rarity.RARE, mage.cards.j.JackInTheMox.class));
cards.add(new SetCardInfo("Jalum Grifter", 47, Rarity.RARE, mage.cards.j.JalumGrifter.class));
cards.add(new SetCardInfo("Jumbo Imp", 34, Rarity.UNCOMMON, mage.cards.j.JumboImp.class));
cards.add(new SetCardInfo("Krazy Kow", 48, Rarity.COMMON, mage.cards.k.KrazyKow.class));
cards.add(new SetCardInfo("Mine, Mine, Mine!", 65, Rarity.RARE, mage.cards.m.MineMineMine.class));