diff --git a/Mage.Sets/src/mage/sets/conflux/QuenchableFire.java b/Mage.Sets/src/mage/sets/conflux/QuenchableFire.java index fb8c888ef1..381ff57eae 100644 --- a/Mage.Sets/src/mage/sets/conflux/QuenchableFire.java +++ b/Mage.Sets/src/mage/sets/conflux/QuenchableFire.java @@ -56,7 +56,9 @@ public class QuenchableFire extends CardImpl { public QuenchableFire(UUID ownerId) { super(ownerId, 70, "Quenchable Fire", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{3}{R}"); this.expansionSetCode = "CON"; - this.color.setRed(true); + + // Quenchable Fire deals 3 damage to target player. + // It deals an additional 3 damage to that player at the beginning of your next upkeep step unless he or she pays {U} before that step. this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addEffect(new DamageTargetEffect(3)); this.getSpellAbility().addEffect(new QuenchableFireEffect()); @@ -97,6 +99,7 @@ class QuenchableFireEffect extends OneShotEffect { delayedAbility.setSourceObject(source.getSourceObject(game)); delayedAbility.getTargets().addAll(source.getTargets()); game.addDelayedTriggeredAbility(delayedAbility); + //create special action QuenchableFireSpecialAction newAction = new QuenchableFireSpecialAction(delayedAbility.getId()); delayedAbility.setSpecialActionId(newAction.getId()); @@ -149,6 +152,7 @@ class QuenchableFireDelayedTriggeredAbility extends DelayedTriggeredAbility { class QuenchableFireSpecialAction extends SpecialAction { public QuenchableFireSpecialAction(UUID effectId) { + super(); this.addCost(new ManaCostsImpl("{U}")); this.addEffect(new RemoveDelayedTriggeredAbilityEffect(effectId)); this.addEffect(new RemoveSpecialActionEffect(this.getId())); diff --git a/Mage.Sets/src/mage/sets/jacevsvraska/OhranViper.java b/Mage.Sets/src/mage/sets/jacevsvraska/OhranViper.java index 10cb589e3d..54ecd4de0f 100644 --- a/Mage.Sets/src/mage/sets/jacevsvraska/OhranViper.java +++ b/Mage.Sets/src/mage/sets/jacevsvraska/OhranViper.java @@ -34,6 +34,7 @@ import mage.abilities.common.DealsCombatDamageToACreatureTriggeredAbility; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.cards.CardImpl; @@ -56,12 +57,16 @@ public class OhranViper extends CardImpl { this.supertype.add("Snow"); this.subtype.add("Snake"); - this.color.setGreen(true); this.power = new MageInt(1); this.toughness = new MageInt(3); // Whenever Ohran Viper deals combat damage to a creature, destroy that creature at end of combat. - this.addAbility(new DealsCombatDamageToACreatureTriggeredAbility(new OhranViperDestroyEffect(), false, true)); + this.addAbility(new DealsCombatDamageToACreatureTriggeredAbility( + new CreateDelayedTriggeredAbilityEffect( + new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect("destroy that creature at end of combat")), true), + false, + true)); + // Whenever Ohran Viper deals combat damage to a player, you may draw a card. this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new DrawCardSourceControllerEffect(1), true)); } @@ -75,35 +80,3 @@ public class OhranViper extends CardImpl { return new OhranViper(this); } } - -class OhranViperDestroyEffect extends OneShotEffect { - - OhranViperDestroyEffect() { - super(Outcome.DestroyPermanent); - staticText = "destroy that creature at end of combat"; - } - - OhranViperDestroyEffect(final OhranViperDestroyEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent targetCreature = game.getPermanent(this.getTargetPointer().getFirst(game, source)); - if (targetCreature != null) { - AtTheEndOfCombatDelayedTriggeredAbility delayedAbility = new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()); - delayedAbility.setSourceId(source.getSourceId()); - delayedAbility.setControllerId(source.getControllerId()); - delayedAbility.setSourceObject(source.getSourceObject(game)); - delayedAbility.getEffects().get(0).setTargetPointer(new FixedTarget(targetCreature.getId())); - game.addDelayedTriggeredAbility(delayedAbility); - return true; - } - return false; - } - - @Override - public OhranViperDestroyEffect copy() { - return new OhranViperDestroyEffect(this); - } -} diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/ContestedWarZone.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/ContestedWarZone.java index f61d7dfae0..79ec587b60 100644 --- a/Mage.Sets/src/mage/sets/mirrodinbesieged/ContestedWarZone.java +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/ContestedWarZone.java @@ -28,6 +28,7 @@ package mage.sets.mirrodinbesieged; import java.util.UUID; +import mage.Mana; import mage.constants.CardType; import mage.constants.Duration; @@ -45,6 +46,7 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.common.continious.BoostAllEffect; import mage.abilities.mana.ColorlessManaAbility; +import mage.abilities.mana.SimpleManaAbility; import mage.cards.CardImpl; import mage.filter.common.FilterAttackingCreature; import mage.game.Game; @@ -102,13 +104,18 @@ class ContestedWarZoneAbility extends TriggeredAbilityImpl { return new ContestedWarZoneAbility(this); } + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; + } + @Override public boolean checkTrigger(GameEvent event, Game game) { - if (event instanceof DamagedPlayerEvent) { - DamagedPlayerEvent damageEvent = (DamagedPlayerEvent)event; - Permanent p = game.getPermanent(event.getSourceId()); - if (damageEvent.getPlayerId().equals(controllerId) && damageEvent.isCombatDamage() && p != null && p.getCardType().contains(CardType.CREATURE)) { - game.getState().setValue(sourceId.toString(), p.getControllerId()); + DamagedPlayerEvent damageEvent = (DamagedPlayerEvent)event; + if (damageEvent.isCombatDamage()) { + Permanent permanent = game.getPermanent(event.getSourceId()); + if (damageEvent.getPlayerId().equals(getControllerId()) && permanent != null && permanent.getCardType().contains(CardType.CREATURE)) { + game.getState().setValue(getSourceId().toString(), permanent.getControllerId()); return true; } } diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/LeoninArbiter.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/LeoninArbiter.java index 78a947af4e..4d57695e39 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/LeoninArbiter.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/LeoninArbiter.java @@ -27,16 +27,25 @@ */ package mage.sets.scarsofmirrodin; -import java.util.*; - -import mage.abilities.SpecialAction; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.*; -import mage.constants.*; +import java.util.AbstractMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.SpecialAction; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.ContinuousRuleModifiyingEffectImpl; +import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; @@ -62,6 +71,7 @@ public class LeoninArbiter extends CardImpl { // Players can't search libraries. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new LeoninArbiterCantSearchEffect(keyString))); + // Any player may pay {2} for that player to ignore this effect until end of turn. this.addAbility(new LeoninArbiterSpecialAction(keyString)); } diff --git a/Mage/src/mage/abilities/common/delayed/AtTheEndOfCombatDelayedTriggeredAbility.java b/Mage/src/mage/abilities/common/delayed/AtTheEndOfCombatDelayedTriggeredAbility.java index 33eef81a18..6cec07678c 100644 --- a/Mage/src/mage/abilities/common/delayed/AtTheEndOfCombatDelayedTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/delayed/AtTheEndOfCombatDelayedTriggeredAbility.java @@ -31,6 +31,10 @@ public class AtTheEndOfCombatDelayedTriggeredAbility extends DelayedTriggeredAbi @Override public String getRule() { - return "At end of combat, " + modes.getText(); + String ruleText = modes.getText(); + if (ruleText.contains("at end of combat")) { + return ruleText; + } + return "At end of combat, " + ruleText; } } diff --git a/Mage/src/mage/abilities/costs/common/ExileFromGraveCost.java b/Mage/src/mage/abilities/costs/common/ExileFromGraveCost.java index 7dd5fef4bd..8d7ce093b8 100644 --- a/Mage/src/mage/abilities/costs/common/ExileFromGraveCost.java +++ b/Mage/src/mage/abilities/costs/common/ExileFromGraveCost.java @@ -28,6 +28,8 @@ package mage.abilities.costs.common; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.CostImpl; @@ -46,10 +48,16 @@ import mage.util.CardUtil; */ public class ExileFromGraveCost extends CostImpl { + private final List exiledCards = new ArrayList<>(); + public ExileFromGraveCost(TargetCardInYourGraveyard target) { this.addTarget(target); if (target.getMaxNumberOfTargets() > 1) { - this.text = "Exile " + CardUtil.numberToText(target.getMaxNumberOfTargets()) + " " + target.getTargetName(); + this.text = "Exile " + + (target.getNumberOfTargets() < target.getMaxNumberOfTargets() ? "up to ":"") + + CardUtil.numberToText(target.getMaxNumberOfTargets()) + + " " + + target.getTargetName(); } else { this.text = "Exile " + target.getTargetName(); @@ -72,6 +80,7 @@ public class ExileFromGraveCost extends CostImpl { public ExileFromGraveCost(final ExileFromGraveCost cost) { super(cost); + this.exiledCards.addAll(cost.getExiledCards()); } @Override @@ -84,6 +93,7 @@ public class ExileFromGraveCost extends CostImpl { if (card == null || !game.getState().getZone(targetId).equals(Zone.GRAVEYARD)) { return false; } + exiledCards.add(card); paid |= controller.moveCardToExileWithInfo(card, null, null, sourceId, game, Zone.GRAVEYARD); } } @@ -102,4 +112,7 @@ public class ExileFromGraveCost extends CostImpl { return new ExileFromGraveCost(this); } + public List getExiledCards() { + return exiledCards; + } } diff --git a/Mage/src/mage/abilities/effects/common/CreateDelayedTriggeredAbilityEffect.java b/Mage/src/mage/abilities/effects/common/CreateDelayedTriggeredAbilityEffect.java index c896fb6652..08627a8d60 100644 --- a/Mage/src/mage/abilities/effects/common/CreateDelayedTriggeredAbilityEffect.java +++ b/Mage/src/mage/abilities/effects/common/CreateDelayedTriggeredAbilityEffect.java @@ -72,9 +72,15 @@ public class CreateDelayedTriggeredAbilityEffect extends OneShotEffect { delayedAbility.setControllerId(source.getControllerId()); delayedAbility.setSourceObject(source.getSourceObject(game)); if (this.copyTargets) { - delayedAbility.getTargets().addAll(source.getTargets()); - for(Effect effect : delayedAbility.getEffects()) { - effect.getTargetPointer().init(game, source); + if (source.getTargets().isEmpty()) { + for(Effect effect : delayedAbility.getEffects()) { + effect.setTargetPointer(targetPointer); + } + } else { + delayedAbility.getTargets().addAll(source.getTargets()); + for(Effect effect : delayedAbility.getEffects()) { + effect.getTargetPointer().init(game, source); + } } } game.addDelayedTriggeredAbility(delayedAbility); diff --git a/Mage/src/mage/util/ManaUtil.java b/Mage/src/mage/util/ManaUtil.java index 7dcb73a38b..160a483d45 100644 --- a/Mage/src/mage/util/ManaUtil.java +++ b/Mage/src/mage/util/ManaUtil.java @@ -85,7 +85,7 @@ public class ManaUtil { chosenManaAbility = chosenManaAbilityForHybrid != null ? chosenManaAbilityForHybrid : chosenManaAbility; } - if (countColored.size() == 0) { // seems there is no colorful mana we can pay for + if (countColored.isEmpty()) { // seems there is no colorful mana we can pay for // try to pay {1} if (unpaidMana.getColorless() > 0) { // use any (lets choose first)