Fixed some problems with UUID comparing and some problems with card moving.

This commit is contained in:
LevelX2 2015-10-14 17:54:55 +02:00
parent 4d8263ff82
commit 52d0adcac1
45 changed files with 364 additions and 360 deletions

7
.gitignore vendored
View file

@ -50,7 +50,7 @@ Mage.Updater/target
mage.updater.client/target mage.updater.client/target
releases releases
Utils/author.txt Utils/author.txt
.DS_Store .DS_Store
.metadata .metadata
.project .project
@ -88,5 +88,6 @@ Mage.Server.Plugins/Mage.Draft.8PlayerBooster/target
/Utils/*_unimplemented.txt /Utils/*_unimplemented.txt
*.netbeans_automatic_build *.netbeans_automatic_build
*.txt *.txt
Mage.Client/serverlist.txt Mage.Client/serverlist.txt
/bin/ /bin/
/target/

View file

@ -184,7 +184,7 @@ public class GameView implements Serializable {
} }
if (isPlayer) { if (isPlayer) {
// has only to be set for active palyer with priority (e.g. pay mana by delve or Quenchable Fire special action) // has only to be set for active palyer with priority (e.g. pay mana by delve or Quenchable Fire special action)
if (state.getPriorityPlayerId() == createdForPlayerId && createdForPlayer != null) { if (createdForPlayer != null && createdForPlayerId.equals(state.getPriorityPlayerId())) {
this.special = state.getSpecialActions().getControlledBy(state.getPriorityPlayerId(), createdForPlayer.isInPayManaMode()).size() > 0; this.special = state.getSpecialActions().getControlledBy(state.getPriorityPlayerId(), createdForPlayer.isInPayManaMode()).size() > 0;
} }
} else { } else {

View file

@ -60,9 +60,6 @@ public class Thraximundar extends CardImpl {
this.subtype.add("Zombie"); this.subtype.add("Zombie");
this.subtype.add("Assassin"); this.subtype.add("Assassin");
this.power = new MageInt(6); this.power = new MageInt(6);
this.toughness = new MageInt(6); this.toughness = new MageInt(6);
@ -116,7 +113,8 @@ class ThraximundarTriggeredAbility extends TriggeredAbilityImpl {
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
if (event.getSourceId() == this.getSourceId()) { if (event.getSourceId() != null
&& event.getSourceId().equals(this.getSourceId())) {
UUID defender = game.getCombat().getDefendingPlayerId(this.getSourceId(), game); UUID defender = game.getCombat().getDefendingPlayerId(this.getSourceId(), game);
this.getEffects().get(0).setTargetPointer(new FixedTarget(defender)); this.getEffects().get(0).setTargetPointer(new FixedTarget(defender));
return true; return true;
@ -160,4 +158,4 @@ class PlayerSacrificesCreatureTriggeredAbility extends TriggeredAbilityImpl {
public PlayerSacrificesCreatureTriggeredAbility copy() { public PlayerSacrificesCreatureTriggeredAbility copy() {
return new PlayerSacrificesCreatureTriggeredAbility(this); return new PlayerSacrificesCreatureTriggeredAbility(this);
} }
} }

View file

@ -25,13 +25,9 @@
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.sets.apocalypse; package mage.sets.apocalypse;
import java.util.UUID; import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@ -41,6 +37,9 @@ import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.KickerAbility; import mage.abilities.keyword.KickerAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.filter.common.FilterLandPermanent; import mage.filter.common.FilterLandPermanent;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -79,6 +78,7 @@ public class DesolationAngel extends CardImpl {
} }
class DesolationAngelEntersBattlefieldEffect extends OneShotEffect { class DesolationAngelEntersBattlefieldEffect extends OneShotEffect {
DesolationAngelEntersBattlefieldEffect() { DesolationAngelEntersBattlefieldEffect() {
super(Outcome.DestroyPermanent); super(Outcome.DestroyPermanent);
staticText = "destroy all lands you control. If it was kicked, destroy all lands instead"; staticText = "destroy all lands you control. If it was kicked, destroy all lands instead";
@ -93,8 +93,8 @@ class DesolationAngelEntersBattlefieldEffect extends OneShotEffect {
Card p = game.getCard(source.getSourceId()); Card p = game.getCard(source.getSourceId());
boolean kicked = KickedCondition.getInstance().apply(game, source); boolean kicked = KickedCondition.getInstance().apply(game, source);
for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterLandPermanent(), source.getControllerId(), source.getSourceId(), game)) { for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterLandPermanent(), source.getControllerId(), source.getSourceId(), game)) {
if ((!kicked && permanent.getControllerId() == source.getControllerId()) if ((!kicked && permanent.getControllerId().equals(source.getControllerId()))
|| kicked) { || kicked) {
permanent.destroy(source.getSourceId(), game, false); permanent.destroy(source.getSourceId(), game, false);
} }
} }
@ -106,4 +106,4 @@ class DesolationAngelEntersBattlefieldEffect extends OneShotEffect {
return new DesolationAngelEntersBattlefieldEffect(this); return new DesolationAngelEntersBattlefieldEffect(this);
} }
} }

View file

@ -67,10 +67,10 @@ public class UlamogTheCeaselessHunger extends CardImpl {
// When you cast Ulamog, the Ceaseless Hunger, exile two target permanents. // When you cast Ulamog, the Ceaseless Hunger, exile two target permanents.
this.addAbility(new UlamogExilePermanentsOnCastAbility()); this.addAbility(new UlamogExilePermanentsOnCastAbility());
// Indestructible // Indestructible
this.addAbility(IndestructibleAbility.getInstance()); this.addAbility(IndestructibleAbility.getInstance());
// Whenever Ulamog attacks, defending player exiles the top twenty cards of his or her library. // Whenever Ulamog attacks, defending player exiles the top twenty cards of his or her library.
Effect effect = new UlamogExileLibraryEffect(); Effect effect = new UlamogExileLibraryEffect();
effect.setText("defending player exiles the top twenty cards of his or her library"); effect.setText("defending player exiles the top twenty cards of his or her library");
@ -139,18 +139,20 @@ class UlamogAttackTriggeredAbility extends TriggeredAbilityImpl {
public boolean checkEventType(GameEvent event, Game game) { public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == EventType.ATTACKER_DECLARED; return event.getType() == EventType.ATTACKER_DECLARED;
} }
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
Permanent sourcePermanent = game.getPermanent(this.getSourceId()); Permanent sourcePermanent = game.getPermanent(this.getSourceId());
if (sourcePermanent != null && event.getSourceId() == this.getSourceId()) { if (sourcePermanent != null
&& event.getSourceId() != null
&& event.getSourceId().equals(this.getSourceId())) {
UUID defender = game.getCombat().getDefendingPlayerId(this.getSourceId(), game); UUID defender = game.getCombat().getDefendingPlayerId(this.getSourceId(), game);
this.getEffects().get(0).setTargetPointer(new FixedTarget(defender)); this.getEffects().get(0).setTargetPointer(new FixedTarget(defender));
return true; return true;
}
return false;
} }
return false;
}
@Override @Override
public String getRule() { public String getRule() {
return new StringBuilder("Whenever {this} attacks, ").append(super.getRule()).toString(); return new StringBuilder("Whenever {this} attacks, ").append(super.getRule()).toString();
@ -184,8 +186,8 @@ class UlamogExileLibraryEffect extends OneShotEffect {
card.moveToExile(null, null, source.getSourceId(), game); card.moveToExile(null, null, source.getSourceId(), game);
} }
} }
return true; return true;
} }
return false; return false;
} }
} }

View file

@ -67,7 +67,7 @@ public class SpitefulReturned extends CardImpl {
effect.setText("defending player loses 2 life"); effect.setText("defending player loses 2 life");
this.addAbility(new SpitefulReturnedTriggeredAbility(effect)); this.addAbility(new SpitefulReturnedTriggeredAbility(effect));
// Enchanted creature gets +1/+1. // Enchanted creature gets +1/+1.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(1,1, Duration.WhileOnBattlefield))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(1, 1, Duration.WhileOnBattlefield)));
} }
public SpitefulReturned(final SpitefulReturned card) { public SpitefulReturned(final SpitefulReturned card) {
@ -105,7 +105,8 @@ class SpitefulReturnedTriggeredAbility extends TriggeredAbilityImpl {
Permanent sourcePermanent = game.getPermanent(this.getSourceId()); Permanent sourcePermanent = game.getPermanent(this.getSourceId());
if (sourcePermanent != null) { if (sourcePermanent != null) {
if (sourcePermanent.getCardType().contains(CardType.CREATURE)) { if (sourcePermanent.getCardType().contains(CardType.CREATURE)) {
if (event.getSourceId() == this.getSourceId()) { if (event.getSourceId() != null
&& event.getSourceId().equals(this.getSourceId())) {
UUID defender = game.getCombat().getDefendingPlayerId(this.getSourceId(), game); UUID defender = game.getCombat().getDefendingPlayerId(this.getSourceId(), game);
this.getEffects().get(0).setTargetPointer(new FixedTarget(defender)); this.getEffects().get(0).setTargetPointer(new FixedTarget(defender));
return true; return true;

View file

@ -69,7 +69,7 @@ public class HallOfTheBanditLord extends CardImpl {
// Hall of the Bandit Lord enters the battlefield tapped. // Hall of the Bandit Lord enters the battlefield tapped.
this.addAbility(new EntersBattlefieldTappedAbility()); this.addAbility(new EntersBattlefieldTappedAbility());
// {T}, Pay 3 life: Add {1} to your mana pool. If that mana is spent on a creature spell, it gains haste. // {T}, Pay 3 life: Add {1} to your mana pool. If that mana is spent on a creature spell, it gains haste.
Mana mana = Mana.ColorlessMana; Mana mana = Mana.ColorlessMana;
mana.setFlag(true); mana.setFlag(true);
@ -94,12 +94,12 @@ class HallOfTheBanditLordWatcher extends Watcher {
private final Ability source; private final Ability source;
private final List<UUID> creatures = new ArrayList<>(); private final List<UUID> creatures = new ArrayList<>();
HallOfTheBanditLordWatcher(Ability source) { HallOfTheBanditLordWatcher(Ability source) {
super("HallOfTheBanditLordWatcher", WatcherScope.CARD); super("HallOfTheBanditLordWatcher", WatcherScope.CARD);
this.source = source; this.source = source;
} }
HallOfTheBanditLordWatcher(final HallOfTheBanditLordWatcher watcher) { HallOfTheBanditLordWatcher(final HallOfTheBanditLordWatcher watcher) {
super(watcher); super(watcher);
this.creatures.addAll(watcher.creatures); this.creatures.addAll(watcher.creatures);
@ -110,22 +110,25 @@ class HallOfTheBanditLordWatcher extends Watcher {
public HallOfTheBanditLordWatcher copy() { public HallOfTheBanditLordWatcher copy() {
return new HallOfTheBanditLordWatcher(this); return new HallOfTheBanditLordWatcher(this);
} }
@Override @Override
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() == EventType.MANA_PAYED) { if (event.getType() == EventType.MANA_PAYED) {
MageObject target = game.getObject(event.getTargetId()); MageObject target = game.getObject(event.getTargetId());
if (event.getSourceId() == this.getSourceId() && target != null && target.getCardType().contains(CardType.CREATURE) && event.getFlag()) { if (event.getSourceId() != null
&& event.getSourceId().equals(this.getSourceId())
&& target != null && target.getCardType().contains(CardType.CREATURE)
&& event.getFlag()) {
if (target instanceof Spell) { if (target instanceof Spell) {
this.creatures.add(((Spell) target).getCard().getId()); this.creatures.add(((Spell) target).getCard().getId());
} }
} }
} }
if (event.getType() == EventType.COUNTERED) { if (event.getType() == EventType.COUNTERED) {
if (creatures.contains(event.getTargetId())) { if (creatures.contains(event.getTargetId())) {
creatures.remove(event.getSourceId()); creatures.remove(event.getSourceId());
} }
} }
if (event.getType() == EventType.ZONE_CHANGE) { if (event.getType() == EventType.ZONE_CHANGE) {
if (creatures.contains(event.getSourceId())) { if (creatures.contains(event.getSourceId())) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event; ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
@ -133,22 +136,22 @@ class HallOfTheBanditLordWatcher extends Watcher {
if (zEvent.getToZone() == Zone.STACK) { if (zEvent.getToZone() == Zone.STACK) {
creatures.remove(event.getSourceId()); creatures.remove(event.getSourceId());
} }
} }
} }
if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD) { if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD) {
if (creatures.contains(event.getSourceId())) { if (creatures.contains(event.getSourceId())) {
ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom); ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom);
effect.setTargetPointer(new FixedTarget(event.getSourceId())); effect.setTargetPointer(new FixedTarget(event.getSourceId()));
game.addEffect(effect, source); game.addEffect(effect, source);
creatures.remove(event.getSourceId()); creatures.remove(event.getSourceId());
} }
} }
} }
@Override @Override
public void reset() { public void reset() {
super.reset(); super.reset();
creatures.clear(); creatures.clear();
} }
} }

View file

@ -25,14 +25,9 @@
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.sets.championsofkamigawa; package mage.sets.championsofkamigawa;
import java.util.UUID; import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
@ -44,7 +39,10 @@ import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.Cards; import mage.cards.Cards;
import mage.cards.CardsImpl; import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.filter.Filter; import mage.filter.Filter;
import mage.filter.common.FilterNonlandCard; import mage.filter.common.FilterNonlandCard;
@ -61,7 +59,7 @@ import mage.target.common.TargetCardInLibrary;
*/ */
public class NightDealings extends CardImpl { public class NightDealings extends CardImpl {
public NightDealings (UUID ownerId) { public NightDealings(UUID ownerId) {
super(ownerId, 132, "Night Dealings", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}"); super(ownerId, 132, "Night Dealings", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}");
this.expansionSetCode = "CHK"; this.expansionSetCode = "CHK";
@ -74,7 +72,7 @@ public class NightDealings extends CardImpl {
this.addAbility(ability); this.addAbility(ability);
} }
public NightDealings (final NightDealings card) { public NightDealings(final NightDealings card) {
super(card); super(card);
} }
@ -83,7 +81,6 @@ public class NightDealings extends CardImpl {
return new NightDealings(this); return new NightDealings(this);
} }
private class NightDealingsTriggeredAbility extends TriggeredAbilityImpl { private class NightDealingsTriggeredAbility extends TriggeredAbilityImpl {
public NightDealingsTriggeredAbility() { public NightDealingsTriggeredAbility() {
@ -106,17 +103,17 @@ public class NightDealings extends CardImpl {
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
// to another player // to another player
if (this.getControllerId() != event.getTargetId()) { if (this.getControllerId() != event.getTargetId()) {
// a source you control // a source you control
UUID sourceControllerId = game.getControllerId(event.getSourceId()); UUID sourceControllerId = game.getControllerId(event.getSourceId());
if (sourceControllerId != null && sourceControllerId == this.getControllerId()) { if (sourceControllerId != null && sourceControllerId.equals(this.getControllerId())) {
// save amount of damage to effect // save amount of damage to effect
this.getEffects().get(0).setValue("damageAmount", event.getAmount()); this.getEffects().get(0).setValue("damageAmount", event.getAmount());
return true; return true;
} }
} }
return false; return false;
} }
@Override @Override
@ -181,9 +178,9 @@ public class NightDealings extends CardImpl {
int cmc = 0; int cmc = 0;
for (Cost cost : source.getCosts()) { for (Cost cost : source.getCosts()) {
if (cost instanceof RemoveVariableCountersSourceCost) { if (cost instanceof RemoveVariableCountersSourceCost) {
cmc = ((RemoveVariableCountersSourceCost)cost).getAmount(); cmc = ((RemoveVariableCountersSourceCost) cost).getAmount();
} }
} }
FilterNonlandCard filter = new FilterNonlandCard("nonland card with converted mana cost X = " + cmc); FilterNonlandCard filter = new FilterNonlandCard("nonland card with converted mana cost X = " + cmc);
filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.Equal, cmc)); filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.Equal, cmc));
@ -192,8 +189,8 @@ public class NightDealings extends CardImpl {
if (player.searchLibrary(target, game)) { if (player.searchLibrary(target, game)) {
Card card = player.getLibrary().getCard(target.getFirstTarget(), game); Card card = player.getLibrary().getCard(target.getFirstTarget(), game);
if (card != null) { if (card != null) {
card.moveToZone(Zone.HAND, source.getSourceId(), game, false); card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
String name = "Reveal"; String name = "Reveal";
Cards cards = new CardsImpl(); Cards cards = new CardsImpl();
cards.add(card); cards.add(card);

View file

@ -32,8 +32,8 @@ import mage.abilities.Ability;
import mage.abilities.condition.Condition; import mage.abilities.condition.Condition;
import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.common.discard.DiscardControllerEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.discard.DiscardControllerEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.CardType; import mage.constants.CardType;
@ -56,6 +56,7 @@ public class SiftThroughSands extends CardImpl {
private static final String rule = "If you've cast a spell named Peer Through Depths and a spell named Reach Through Mists this turn, you may search your library for a card named The Unspeakable, put it onto the battlefield, then shuffle your library"; private static final String rule = "If you've cast a spell named Peer Through Depths and a spell named Reach Through Mists this turn, you may search your library for a card named The Unspeakable, put it onto the battlefield, then shuffle your library";
private static final FilterCreatureCard filter = new FilterCreatureCard("a card named The Unspeakable"); private static final FilterCreatureCard filter = new FilterCreatureCard("a card named The Unspeakable");
static { static {
filter.add(new NamePredicate("The Unspeakable")); filter.add(new NamePredicate("The Unspeakable"));
} }
@ -65,13 +66,12 @@ public class SiftThroughSands extends CardImpl {
this.expansionSetCode = "CHK"; this.expansionSetCode = "CHK";
this.subtype.add("Arcane"); this.subtype.add("Arcane");
// Draw two cards, then discard a card. // Draw two cards, then discard a card.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2)); this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2));
Effect effect = new DiscardControllerEffect(1); Effect effect = new DiscardControllerEffect(1);
effect.setText(", then discard a card"); effect.setText(", then discard a card");
this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(effect);
// If you've cast a spell named Peer Through Depths and a spell named Reach Through Mists this turn, you may search your library for a card named The Unspeakable, put it onto the battlefield, then shuffle your library. // If you've cast a spell named Peer Through Depths and a spell named Reach Through Mists this turn, you may search your library for a card named The Unspeakable, put it onto the battlefield, then shuffle your library.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter), false, true), new SiftThroughSandsCondition(), rule)); this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter), false, true), new SiftThroughSandsCondition(), rule));
this.getSpellAbility().addWatcher(new SiftThroughSandsWatcher()); this.getSpellAbility().addWatcher(new SiftThroughSandsWatcher());
@ -125,7 +125,7 @@ class SiftThroughSandsWatcher extends Watcher {
return; return;
} }
if (event.getType() == EventType.SPELL_CAST if (event.getType() == EventType.SPELL_CAST
&& controllerId == event.getPlayerId()) { && controllerId.equals(event.getPlayerId())) {
Spell spell = game.getStack().getSpell(event.getTargetId()); Spell spell = game.getStack().getSpell(event.getTargetId());
if (spell.getCard().getName().equals("Peer Through Depths")) { if (spell.getCard().getName().equals("Peer Through Depths")) {
castPeerThroughDepths = true; castPeerThroughDepths = true;

View file

@ -44,8 +44,8 @@ import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent.EventType;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetCardInLibrary;
@ -98,7 +98,7 @@ class HibernationsEndAbility extends TriggeredAbilityImpl {
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
return event.getSourceId() == this.getSourceId(); return event.getSourceId() != null && event.getSourceId().equals(this.getSourceId());
} }
@Override @Override
@ -127,7 +127,7 @@ class HibernationsEndEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if(sourcePermanent != null && player != null) { if (sourcePermanent != null && player != null) {
int newConvertedCost = sourcePermanent.getCounters().getCount("age"); int newConvertedCost = sourcePermanent.getCounters().getCount("age");
FilterCard filter = new FilterCard("creature card with converted mana cost " + newConvertedCost); FilterCard filter = new FilterCard("creature card with converted mana cost " + newConvertedCost);
filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.Equal, newConvertedCost)); filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.Equal, newConvertedCost));
@ -138,4 +138,3 @@ class HibernationsEndEffect extends OneShotEffect {
return false; return false;
} }
} }

View file

@ -135,7 +135,7 @@ class ChorusOfTheConclaveReplacementEffect extends ReplacementEffectImpl {
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getPlayerId() == source.getControllerId()) { if (event.getPlayerId().equals(source.getControllerId())) {
MageObject spellObject = game.getObject(event.getSourceId()); MageObject spellObject = game.getObject(event.getSourceId());
if (spellObject != null) { if (spellObject != null) {
return spellObject.getCardType().contains(CardType.CREATURE); return spellObject.getCardType().contains(CardType.CREATURE);

View file

@ -92,9 +92,9 @@ class RubiniaSoulsingerCondition implements Condition {
controllerId = source.getControllerId(); controllerId = source.getControllerId();
} }
Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId()); Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId());
if (permanent != null){ if (permanent != null) {
if (permanent.isTapped()){ if (permanent.isTapped()) {
return controllerId == source.getControllerId(); return controllerId.equals(source.getControllerId());
} }
} }
return false; return false;

View file

@ -61,10 +61,9 @@ public class InfernalOffering extends CardImpl {
super(ownerId, 24, "Infernal Offering", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{4}{B}"); super(ownerId, 24, "Infernal Offering", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{4}{B}");
this.expansionSetCode = "C14"; this.expansionSetCode = "C14";
// Choose an opponent. You and that player each sacrifice a creature. Each player who sacrificed a creature this way draws two cards. // Choose an opponent. You and that player each sacrifice a creature. Each player who sacrificed a creature this way draws two cards.
this.getSpellAbility().addEffect(new InfernalOfferingSacrificeEffect()); this.getSpellAbility().addEffect(new InfernalOfferingSacrificeEffect());
// Choose an opponent. Return a creature card from your graveyard to the battlefield, then that player returns a creature card from his or her graveyard to the battlefield. // Choose an opponent. Return a creature card from your graveyard to the battlefield, then that player returns a creature card from his or her graveyard to the battlefield.
this.getSpellAbility().addEffect(new InfernalOfferingReturnEffect()); this.getSpellAbility().addEffect(new InfernalOfferingReturnEffect());
} }
@ -80,21 +79,21 @@ public class InfernalOffering extends CardImpl {
} }
class InfernalOfferingSacrificeEffect extends OneShotEffect { class InfernalOfferingSacrificeEffect extends OneShotEffect {
InfernalOfferingSacrificeEffect() { InfernalOfferingSacrificeEffect() {
super(Outcome.Sacrifice); super(Outcome.Sacrifice);
this.staticText = "Choose an opponent. You and that player each sacrifice a creature. Each player who sacrificed a creature this way draws two cards"; this.staticText = "Choose an opponent. You and that player each sacrifice a creature. Each player who sacrificed a creature this way draws two cards";
} }
InfernalOfferingSacrificeEffect(final InfernalOfferingSacrificeEffect effect) { InfernalOfferingSacrificeEffect(final InfernalOfferingSacrificeEffect effect) {
super(effect); super(effect);
} }
@Override @Override
public InfernalOfferingSacrificeEffect copy() { public InfernalOfferingSacrificeEffect copy() {
return new InfernalOfferingSacrificeEffect(this); return new InfernalOfferingSacrificeEffect(this);
} }
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
@ -106,7 +105,7 @@ class InfernalOfferingSacrificeEffect extends OneShotEffect {
//Choose creatures to sacrifice //Choose creatures to sacrifice
Map<UUID, UUID> toSacrifice = new HashMap<>(2); Map<UUID, UUID> toSacrifice = new HashMap<>(2);
for (UUID playerId : player.getInRange()) { for (UUID playerId : player.getInRange()) {
if (playerId == player.getId() || playerId == opponent.getId()) { if (playerId.equals(player.getId()) || playerId.equals(opponent.getId())) {
target = new TargetControlledCreaturePermanent(1, 1, new FilterControlledCreaturePermanent(), true); target = new TargetControlledCreaturePermanent(1, 1, new FilterControlledCreaturePermanent(), true);
if (target.choose(Outcome.Sacrifice, playerId, source.getControllerId(), game)) { if (target.choose(Outcome.Sacrifice, playerId, source.getControllerId(), game)) {
toSacrifice.put(playerId, target.getFirstTarget()); toSacrifice.put(playerId, target.getFirstTarget());
@ -138,21 +137,21 @@ class InfernalOfferingSacrificeEffect extends OneShotEffect {
} }
class InfernalOfferingReturnEffect extends OneShotEffect { class InfernalOfferingReturnEffect extends OneShotEffect {
InfernalOfferingReturnEffect() { InfernalOfferingReturnEffect() {
super(Outcome.PutCreatureInPlay); super(Outcome.PutCreatureInPlay);
this.staticText = "Choose an opponent. Return a creature card from your graveyard to the battlefield, then that player returns a creature card from his or her graveyard to the battlefield"; this.staticText = "Choose an opponent. Return a creature card from your graveyard to the battlefield, then that player returns a creature card from his or her graveyard to the battlefield";
} }
InfernalOfferingReturnEffect(final InfernalOfferingReturnEffect effect) { InfernalOfferingReturnEffect(final InfernalOfferingReturnEffect effect) {
super(effect); super(effect);
} }
@Override @Override
public InfernalOfferingReturnEffect copy() { public InfernalOfferingReturnEffect copy() {
return new InfernalOfferingReturnEffect(this); return new InfernalOfferingReturnEffect(this);
} }
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());

View file

@ -56,7 +56,7 @@ public class LichsTomb extends CardImpl {
// You don't lose the game for having 0 or less life. // You don't lose the game for having 0 or less life.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontLoseByZeroOrLessLifeEffect(Duration.WhileOnBattlefield))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontLoseByZeroOrLessLifeEffect(Duration.WhileOnBattlefield)));
// Whenever you lose life, sacrifice a permanent for each 1 life you lost. // Whenever you lose life, sacrifice a permanent for each 1 life you lost.
this.addAbility(new LichsTombTriggeredAbility()); this.addAbility(new LichsTombTriggeredAbility());
} }
@ -72,15 +72,15 @@ public class LichsTomb extends CardImpl {
} }
class LichsTombTriggeredAbility extends TriggeredAbilityImpl { class LichsTombTriggeredAbility extends TriggeredAbilityImpl {
LichsTombTriggeredAbility() { LichsTombTriggeredAbility() {
super(Zone.BATTLEFIELD, new SacrificeControllerEffect(new FilterPermanent(), 0, ""), false); super(Zone.BATTLEFIELD, new SacrificeControllerEffect(new FilterPermanent(), 0, ""), false);
} }
LichsTombTriggeredAbility(final LichsTombTriggeredAbility ability) { LichsTombTriggeredAbility(final LichsTombTriggeredAbility ability) {
super(ability); super(ability);
} }
@Override @Override
public LichsTombTriggeredAbility copy() { public LichsTombTriggeredAbility copy() {
return new LichsTombTriggeredAbility(this); return new LichsTombTriggeredAbility(this);
@ -90,16 +90,16 @@ class LichsTombTriggeredAbility extends TriggeredAbilityImpl {
public boolean checkEventType(GameEvent event, Game game) { public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == EventType.LOST_LIFE; return event.getType() == EventType.LOST_LIFE;
} }
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
if (event.getPlayerId() == this.getControllerId()) { if (event.getPlayerId().equals(this.getControllerId())) {
((SacrificeEffect) this.getEffects().get(0)).setAmount(new StaticValue(event.getAmount())); ((SacrificeEffect) this.getEffects().get(0)).setAmount(new StaticValue(event.getAmount()));
return true; return true;
} }
return false; return false;
} }
@Override @Override
public String getRule() { public String getRule() {
return "Whenever you lose life, sacrifice a permanent for each 1 life you lost."; return "Whenever you lose life, sacrifice a permanent for each 1 life you lost.";

View file

@ -53,7 +53,7 @@ import mage.watchers.Watcher;
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public class DreamThief extends CardImpl { public class DreamThief extends CardImpl {
private static final String rule = "draw a card if you've cast another blue spell this turn"; private static final String rule = "draw a card if you've cast another blue spell this turn";
public DreamThief(UUID ownerId) { public DreamThief(UUID ownerId) {
@ -70,7 +70,7 @@ public class DreamThief extends CardImpl {
// When Dream Thief enters the battlefield, draw a card if you've cast another blue spell this turn. // When Dream Thief enters the battlefield, draw a card if you've cast another blue spell this turn.
this.addAbility(new EntersBattlefieldTriggeredAbility(new ConditionalOneShotEffect(new DrawCardSourceControllerEffect(1), new CastBlueSpellThisTurnCondition(), rule)), new DreamThiefWatcher(this.getId())); this.addAbility(new EntersBattlefieldTriggeredAbility(new ConditionalOneShotEffect(new DrawCardSourceControllerEffect(1), new CastBlueSpellThisTurnCondition(), rule)), new DreamThiefWatcher(this.getId()));
} }
public DreamThief(final DreamThief card) { public DreamThief(final DreamThief card) {
@ -98,6 +98,7 @@ class CastBlueSpellThisTurnCondition implements Condition {
class DreamThiefWatcher extends Watcher { class DreamThiefWatcher extends Watcher {
private static final FilterSpell filter = new FilterSpell(); private static final FilterSpell filter = new FilterSpell();
static { static {
filter.add(new ColorPredicate(ObjectColor.BLUE)); filter.add(new ColorPredicate(ObjectColor.BLUE));
} }
@ -125,7 +126,7 @@ class DreamThiefWatcher extends Watcher {
return; return;
} }
if (event.getType() == EventType.SPELL_CAST if (event.getType() == EventType.SPELL_CAST
&& controllerId == event.getPlayerId()) { && controllerId.equals(event.getPlayerId())) {
Spell spell = game.getStack().getSpell(event.getTargetId()); Spell spell = game.getStack().getSpell(event.getTargetId());
if (!spell.getSourceId().equals(cardId) && filter.match(spell, game)) { if (!spell.getSourceId().equals(cardId) && filter.match(spell, game)) {
condition = true; condition = true;

View file

@ -40,11 +40,13 @@ import mage.constants.Outcome;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.common.FilterLandCard; import mage.filter.common.FilterLandCard;
import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.ExileZone; import mage.game.ExileZone;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetCardInLibrary;
import mage.util.CardUtil; import mage.util.CardUtil;
@ -58,7 +60,6 @@ public class EndlessHorizons extends CardImpl {
super(ownerId, 4, "Endless Horizons", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); super(ownerId, 4, "Endless Horizons", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}");
this.expansionSetCode = "EVE"; this.expansionSetCode = "EVE";
// When Endless Horizons enters the battlefield, search your library for any number of Plains cards and exile them. Then shuffle your library. // When Endless Horizons enters the battlefield, search your library for any number of Plains cards and exile them. Then shuffle your library.
this.addAbility(new EntersBattlefieldTriggeredAbility(new EndlessHorizonsEffect(), false)); this.addAbility(new EntersBattlefieldTriggeredAbility(new EndlessHorizonsEffect(), false));
@ -122,34 +123,41 @@ class EndlessHorizonsEffect extends SearchEffect {
} }
} }
class EndlessHorizonsEffect2 extends OneShotEffect { class EndlessHorizonsEffect2 extends OneShotEffect {
public EndlessHorizonsEffect2() { public EndlessHorizonsEffect2() {
super(Outcome.ReturnToHand); super(Outcome.ReturnToHand);
this.staticText = "you may put a card you own exiled with {this} into your hand"; this.staticText = "you may put a card you own exiled with {this} into your hand";
} }
public EndlessHorizonsEffect2(final EndlessHorizonsEffect2 effect) { public EndlessHorizonsEffect2(final EndlessHorizonsEffect2 effect) {
super(effect); super(effect);
} }
@Override @Override
public EndlessHorizonsEffect2 copy() { public EndlessHorizonsEffect2 copy() {
return new EndlessHorizonsEffect2(this); return new EndlessHorizonsEffect2(this);
} }
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
ExileZone exZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)); ExileZone exZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
if (exZone != null) { if (exZone != null) {
for (Card card : exZone.getCards(game)) { Card card = null;
if (card.getOwnerId() == source.getControllerId()) { if (exZone.size() > 1) {
card.moveToZone(Zone.HAND, source.getSourceId(), game, false); TargetCard target = new TargetCard(Zone.EXILED, new FilterCard());
break; // only one controller.choose(outcome, exZone, target, game);
} card = game.getCard(target.getFirstTarget());
} else {
card = exZone.getRandom(game);
} }
controller.moveCards(card, null, Zone.HAND, source, game);
} }
return true; return true;
} }
return false;
}
} }

View file

@ -67,11 +67,11 @@ public class HotheadedGiant extends CardImpl {
// Haste // Haste
this.addAbility(HasteAbility.getInstance()); this.addAbility(HasteAbility.getInstance());
// Hotheaded Giant enters the battlefield with two -1/-1 counters on it unless you've cast another red spell this turn. // Hotheaded Giant enters the battlefield with two -1/-1 counters on it unless you've cast another red spell this turn.
Condition condition = new CastRedSpellThisTurnCondition(); Condition condition = new CastRedSpellThisTurnCondition();
this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new AddCountersSourceEffect(CounterType.M1M1.createInstance(2)), new InvertCondition(condition), ""), "with two -1/-1 counters on it unless you've cast another red spell this turn"), new HotHeadedGiantWatcher(this.getId())); this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new AddCountersSourceEffect(CounterType.M1M1.createInstance(2)), new InvertCondition(condition), ""), "with two -1/-1 counters on it unless you've cast another red spell this turn"), new HotHeadedGiantWatcher(this.getId()));
} }
public HotheadedGiant(final HotheadedGiant card) { public HotheadedGiant(final HotheadedGiant card) {
@ -99,6 +99,7 @@ class CastRedSpellThisTurnCondition implements Condition {
class HotHeadedGiantWatcher extends Watcher { class HotHeadedGiantWatcher extends Watcher {
private static final FilterSpell filter = new FilterSpell(); private static final FilterSpell filter = new FilterSpell();
static { static {
filter.add(new ColorPredicate(ObjectColor.RED)); filter.add(new ColorPredicate(ObjectColor.RED));
} }
@ -126,7 +127,7 @@ class HotHeadedGiantWatcher extends Watcher {
return; return;
} }
if (event.getType() == EventType.SPELL_CAST if (event.getType() == EventType.SPELL_CAST
&& controllerId == event.getPlayerId()) { && controllerId.equals(event.getPlayerId())) {
Spell spell = game.getStack().getSpell(event.getTargetId()); Spell spell = game.getStack().getSpell(event.getTargetId());
if (!spell.getSourceId().equals(cardId) && filter.match(spell, game)) { if (!spell.getSourceId().equals(cardId) && filter.match(spell, game)) {
condition = true; condition = true;

View file

@ -32,7 +32,6 @@ import mage.ObjectColor;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.condition.Condition; import mage.abilities.condition.Condition;
import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.DestroyTargetEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -59,26 +58,25 @@ import mage.watchers.Watcher;
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public class SoulReap extends CardImpl { public class SoulReap extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nongreen creature"); private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nongreen creature");
static { static {
filter.add(Predicates.not(new ColorPredicate(ObjectColor.GREEN))); filter.add(Predicates.not(new ColorPredicate(ObjectColor.GREEN)));
} }
private String rule = "Its controller loses 3 life if you've cast another black spell this turn"; private String rule = "Its controller loses 3 life if you've cast another black spell this turn";
public SoulReap(UUID ownerId) { public SoulReap(UUID ownerId) {
super(ownerId, 44, "Soul Reap", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{1}{B}"); super(ownerId, 44, "Soul Reap", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{1}{B}");
this.expansionSetCode = "EVE"; this.expansionSetCode = "EVE";
// Destroy target nongreen creature. Its controller loses 3 life if you've cast another black spell this turn. // Destroy target nongreen creature. Its controller loses 3 life if you've cast another black spell this turn.
this.getSpellAbility().addEffect(new DestroyTargetEffect()); this.getSpellAbility().addEffect(new DestroyTargetEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new SoulReapEffect(), new CastBlackSpellThisTurnCondition(), rule)); this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new SoulReapEffect(), new CastBlackSpellThisTurnCondition(), rule));
this.getSpellAbility().addWatcher(new SoulReapWatcher(this.getId())); this.getSpellAbility().addWatcher(new SoulReapWatcher(this.getId()));
} }
public SoulReap(final SoulReap card) { public SoulReap(final SoulReap card) {
@ -106,7 +104,7 @@ class CastBlackSpellThisTurnCondition implements Condition {
class SoulReapWatcher extends Watcher { class SoulReapWatcher extends Watcher {
private static final FilterSpell filter = new FilterSpell(); private static final FilterSpell filter = new FilterSpell();
static { static {
filter.add(new ColorPredicate(ObjectColor.BLACK)); filter.add(new ColorPredicate(ObjectColor.BLACK));
} }
@ -134,7 +132,7 @@ class SoulReapWatcher extends Watcher {
return; return;
} }
if (event.getType() == EventType.SPELL_CAST if (event.getType() == EventType.SPELL_CAST
&& controllerId == event.getPlayerId()) { && controllerId.equals(event.getPlayerId())) {
Spell spell = game.getStack().getSpell(event.getTargetId()); Spell spell = game.getStack().getSpell(event.getTargetId());
if (!spell.getSourceId().equals(cardId) && filter.match(spell, game)) { if (!spell.getSourceId().equals(cardId) && filter.match(spell, game)) {
condition = true; condition = true;
@ -177,4 +175,4 @@ class SoulReapEffect extends OneShotEffect {
} }
return false; return false;
} }
} }

View file

@ -34,7 +34,6 @@ import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition; import mage.abilities.condition.Condition;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.CardType; import mage.constants.CardType;
@ -159,7 +158,7 @@ class TalarasBattalionWatcher extends Watcher {
return; return;
} }
if (event.getType() == EventType.SPELL_CAST if (event.getType() == EventType.SPELL_CAST
&& controllerId == event.getPlayerId()) { && controllerId.equals(event.getPlayerId())) {
Spell spell = game.getStack().getSpell(event.getTargetId()); Spell spell = game.getStack().getSpell(event.getTargetId());
if (!spell.getSourceId().equals(cardId) && filter.match(spell, game)) { if (!spell.getSourceId().equals(cardId) && filter.match(spell, game)) {
condition = true; condition = true;

View file

@ -99,7 +99,7 @@ class SoltariVisionaryTriggeredAbility extends TriggeredAbilityImpl {
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
Permanent soltari = game.getPermanent(event.getSourceId()); Permanent soltari = game.getPermanent(event.getSourceId());
if (soltari != null && soltari.getId() == this.getSourceId()) { if (soltari != null && soltari.getId().equals(this.getSourceId())) {
FilterEnchantmentPermanent filter = new FilterEnchantmentPermanent("enchantment that player controls."); FilterEnchantmentPermanent filter = new FilterEnchantmentPermanent("enchantment that player controls.");
filter.add(new ControllerIdPredicate(event.getPlayerId())); filter.add(new ControllerIdPredicate(event.getPlayerId()));
filter.setMessage("enchantment controlled by " + game.getPlayer(event.getTargetId()).getLogName()); filter.setMessage("enchantment controlled by " + game.getPlayer(event.getTargetId()).getLogName());

View file

@ -99,7 +99,7 @@ class MarduWoeReaperTriggeredAbility extends TriggeredAbilityImpl {
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
if (event.getPlayerId().equals(this.getControllerId())) { if (event.getPlayerId().equals(this.getControllerId())) {
Permanent permanent = game.getPermanent(event.getTargetId()); Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null && (permanent.getId() == this.getSourceId() || permanent.hasSubtype("Warrior"))) { if (permanent != null && (permanent.getId().equals(this.getSourceId()) || permanent.hasSubtype("Warrior"))) {
return true; return true;
} }
} }
@ -113,21 +113,21 @@ class MarduWoeReaperTriggeredAbility extends TriggeredAbilityImpl {
} }
class MarduWoeReaperEffect extends OneShotEffect { class MarduWoeReaperEffect extends OneShotEffect {
MarduWoeReaperEffect() { MarduWoeReaperEffect() {
super(Outcome.GainLife); super(Outcome.GainLife);
this.staticText = "you may exile target creature card from a graveyard. If you do, you gain 1 life"; this.staticText = "you may exile target creature card from a graveyard. If you do, you gain 1 life";
} }
MarduWoeReaperEffect(final MarduWoeReaperEffect effect) { MarduWoeReaperEffect(final MarduWoeReaperEffect effect) {
super(effect); super(effect);
} }
@Override @Override
public MarduWoeReaperEffect copy() { public MarduWoeReaperEffect copy() {
return new MarduWoeReaperEffect(this); return new MarduWoeReaperEffect(this);
} }
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());

View file

@ -58,11 +58,10 @@ public class WardscaleDragon extends CardImpl {
// Flying // Flying
this.addAbility(FlyingAbility.getInstance()); this.addAbility(FlyingAbility.getInstance());
// As long as Wardscale Dragon is attacking, defending player can't cast spells. // As long as Wardscale Dragon is attacking, defending player can't cast spells.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new WardscaleDragonRuleEffect())); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new WardscaleDragonRuleEffect()));
} }
public WardscaleDragon(final WardscaleDragon card) { public WardscaleDragon(final WardscaleDragon card) {
@ -105,7 +104,7 @@ class WardscaleDragonRuleEffect extends ContinuousRuleModifyingEffectImpl {
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
Permanent sourcePermanent = game.getPermanent(source.getSourceId()); Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (sourcePermanent != null && sourcePermanent.isAttacking()) { if (sourcePermanent != null && sourcePermanent.isAttacking()) {
return event.getPlayerId() == game.getCombat().getDefendingPlayerId(sourcePermanent.getId(), game); return event.getPlayerId().equals(game.getCombat().getDefendingPlayerId(sourcePermanent.getId(), game));
} }
return false; return false;
} }

View file

@ -92,6 +92,7 @@ public class InstillEnergy extends CardImpl {
} }
class CanAttackAsThoughItHadHasteEnchantedEffect extends AsThoughEffectImpl { class CanAttackAsThoughItHadHasteEnchantedEffect extends AsThoughEffectImpl {
public CanAttackAsThoughItHadHasteEnchantedEffect(Duration duration) { public CanAttackAsThoughItHadHasteEnchantedEffect(Duration duration) {
super(AsThoughEffectType.ATTACK, duration, Outcome.Benefit); super(AsThoughEffectType.ATTACK, duration, Outcome.Benefit);
staticText = "Enchanted creature can attack as though it had haste"; staticText = "Enchanted creature can attack as though it had haste";
@ -114,7 +115,7 @@ class CanAttackAsThoughItHadHasteEnchantedEffect extends AsThoughEffectImpl {
@Override @Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
Permanent enchantment = game.getPermanent(source.getSourceId()); Permanent enchantment = game.getPermanent(source.getSourceId());
return enchantment != null && enchantment.getAttachedTo() != null && enchantment.getAttachedTo() == objectId; return enchantment != null && enchantment.getAttachedTo() != null && enchantment.getAttachedTo().equals(objectId);
} }
} }

View file

@ -52,13 +52,11 @@ public class Fastbond extends CardImpl {
super(ownerId, 101, "Fastbond", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{G}"); super(ownerId, 101, "Fastbond", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{G}");
this.expansionSetCode = "LEA"; this.expansionSetCode = "LEA";
// You may play any number of additional lands on each of your turns. // You may play any number of additional lands on each of your turns.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PlayAdditionalLandsControllerEffect(Integer.MAX_VALUE, Duration.WhileOnBattlefield))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PlayAdditionalLandsControllerEffect(Integer.MAX_VALUE, Duration.WhileOnBattlefield)));
// Whenever you play a land, if it wasn't the first land you played this turn, Fastbond deals 1 damage to you. // Whenever you play a land, if it wasn't the first land you played this turn, Fastbond deals 1 damage to you.
this.addAbility(new PlayALandTriggeredAbility()); this.addAbility(new PlayALandTriggeredAbility());
} }
public Fastbond(final Fastbond card) { public Fastbond(final Fastbond card) {
super(card); super(card);
@ -70,7 +68,6 @@ public class Fastbond extends CardImpl {
} }
} }
class PlayALandTriggeredAbility extends TriggeredAbilityImpl { class PlayALandTriggeredAbility extends TriggeredAbilityImpl {
public PlayALandTriggeredAbility() { public PlayALandTriggeredAbility() {
@ -88,14 +85,14 @@ class PlayALandTriggeredAbility extends TriggeredAbilityImpl {
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId() == this.getControllerId(); return event.getPlayerId().equals(this.getControllerId());
} }
@Override @Override
public boolean checkInterveningIfClause(Game game) { public boolean checkInterveningIfClause(Game game) {
Player player = game.getPlayer(this.getControllerId()); Player player = game.getPlayer(this.getControllerId());
if (player != null){ if (player != null) {
if (player.getLandsPlayed() != 1){ if (player.getLandsPlayed() != 1) {
return true; return true;
} }
} }
@ -111,8 +108,5 @@ class PlayALandTriggeredAbility extends TriggeredAbilityImpl {
public String getRule() { public String getRule() {
return "Whenever you play a land, if it wasn't the first land you played this turn, {source} deals 1 damage to you"; return "Whenever you play a land, if it wasn't the first land you played this turn, {source} deals 1 damage to you";
} }
} }

View file

@ -77,7 +77,7 @@ public class GeneratorServant extends CardImpl {
ability.addCost(new SacrificeSourceCost()); ability.addCost(new SacrificeSourceCost());
ability.getEffects().get(0).setText("Add {2} to your mana pool. If that mana is spent on a creature spell, it gains haste until end of turn."); ability.getEffects().get(0).setText("Add {2} to your mana pool. If that mana is spent on a creature spell, it gains haste until end of turn.");
this.addAbility(ability); this.addAbility(ability);
this.addAbility(new SimpleStaticAbility(Zone.ALL, new GeneratorServantHasteEffect()), new GeneratorServantWatcher()); this.addAbility(new SimpleStaticAbility(Zone.ALL, new GeneratorServantHasteEffect()), new GeneratorServantWatcher());
} }
@ -94,11 +94,11 @@ public class GeneratorServant extends CardImpl {
class GeneratorServantWatcher extends Watcher { class GeneratorServantWatcher extends Watcher {
public List<UUID> creatures = new ArrayList<>(); public List<UUID> creatures = new ArrayList<>();
public GeneratorServantWatcher() { public GeneratorServantWatcher() {
super("GeneratorServantWatcher", WatcherScope.CARD); super("GeneratorServantWatcher", WatcherScope.CARD);
} }
public GeneratorServantWatcher(final GeneratorServantWatcher watcher) { public GeneratorServantWatcher(final GeneratorServantWatcher watcher) {
super(watcher); super(watcher);
this.creatures.addAll(watcher.creatures); this.creatures.addAll(watcher.creatures);
@ -108,13 +108,13 @@ class GeneratorServantWatcher extends Watcher {
public GeneratorServantWatcher copy() { public GeneratorServantWatcher copy() {
return new GeneratorServantWatcher(this); return new GeneratorServantWatcher(this);
} }
@Override @Override
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.MANA_PAYED) { if (event.getType() == GameEvent.EventType.MANA_PAYED) {
MageObject target = game.getObject(event.getTargetId()); MageObject target = game.getObject(event.getTargetId());
MageObject source = game.getObject(this.getSourceId()); if (event.getSourceId() != null
if (event.getSourceId() == this.getSourceId() && target != null && target.getCardType().contains(CardType.CREATURE) && event.getFlag()) { && event.getSourceId().equals(this.getSourceId()) && target != null && target.getCardType().contains(CardType.CREATURE) && event.getFlag()) {
if (target instanceof Spell) { if (target instanceof Spell) {
this.creatures.add(((Spell) target).getCard().getId()); this.creatures.add(((Spell) target).getCard().getId());
} }
@ -127,7 +127,7 @@ class GeneratorServantWatcher extends Watcher {
super.reset(); super.reset();
creatures.clear(); creatures.clear();
} }
} }
class GeneratorServantHasteEffect extends ContinuousEffectImpl { class GeneratorServantHasteEffect extends ContinuousEffectImpl {
@ -135,7 +135,7 @@ class GeneratorServantHasteEffect extends ContinuousEffectImpl {
public GeneratorServantHasteEffect() { public GeneratorServantHasteEffect() {
super(Duration.EndOfGame, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); super(Duration.EndOfGame, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
} }
public GeneratorServantHasteEffect(final GeneratorServantHasteEffect effect) { public GeneratorServantHasteEffect(final GeneratorServantHasteEffect effect) {
super(effect); super(effect);
} }
@ -144,7 +144,7 @@ class GeneratorServantHasteEffect extends ContinuousEffectImpl {
public ContinuousEffect copy() { public ContinuousEffect copy() {
return new GeneratorServantHasteEffect(this); return new GeneratorServantHasteEffect(this);
} }
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
GeneratorServantWatcher watcher = (GeneratorServantWatcher) game.getState().getWatchers().get("GeneratorServantWatcher", source.getSourceId()); GeneratorServantWatcher watcher = (GeneratorServantWatcher) game.getState().getWatchers().get("GeneratorServantWatcher", source.getSourceId());
@ -158,5 +158,5 @@ class GeneratorServantHasteEffect extends ContinuousEffectImpl {
} }
return false; return false;
} }
} }

View file

@ -105,7 +105,9 @@ class SigilOfValorTriggeredAbility extends TriggeredAbilityImpl {
if (game.getCombat().attacksAlone()) { if (game.getCombat().attacksAlone()) {
Permanent equipment = game.getPermanent(getSourceId()); Permanent equipment = game.getPermanent(getSourceId());
UUID attackerId = game.getCombat().getAttackers().get(0); UUID attackerId = game.getCombat().getAttackers().get(0);
if (equipment != null && equipment.getAttachedTo() == attackerId) { if (equipment != null
&& equipment.getAttachedTo() != null
&& equipment.getAttachedTo().equals(attackerId)) {
this.getEffects().get(0).setTargetPointer(new FixedTarget(attackerId)); this.getEffects().get(0).setTargetPointer(new FixedTarget(attackerId));
return true; return true;
} }

View file

@ -60,10 +60,10 @@ public class ThoughtLash extends CardImpl {
// Cumulative upkeep - Exile the top card of your library. // Cumulative upkeep - Exile the top card of your library.
this.addAbility(new CumulativeUpkeepAbility(new ExileFromTopOfLibraryCost(1))); this.addAbility(new CumulativeUpkeepAbility(new ExileFromTopOfLibraryCost(1)));
// When a player doesn't pay Thought Lash's cumulative upkeep, that player exiles all cards from his or her library. // When a player doesn't pay Thought Lash's cumulative upkeep, that player exiles all cards from his or her library.
this.addAbility(new ThoughtLashTriggeredAbility()); this.addAbility(new ThoughtLashTriggeredAbility());
// Exile the top card of your library: Prevent the next 1 damage that would be dealt to you this turn. // Exile the top card of your library: Prevent the next 1 damage that would be dealt to you this turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ThoughtLashPreventionEffect(), new ExileFromTopOfLibraryCost(1))); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ThoughtLashPreventionEffect(), new ExileFromTopOfLibraryCost(1)));
} }
@ -79,30 +79,30 @@ public class ThoughtLash extends CardImpl {
} }
class ThoughtLashTriggeredAbility extends TriggeredAbilityImpl { class ThoughtLashTriggeredAbility extends TriggeredAbilityImpl {
ThoughtLashTriggeredAbility() { ThoughtLashTriggeredAbility() {
super(Zone.BATTLEFIELD, new ThoughtLashExileLibraryEffect(), false); super(Zone.BATTLEFIELD, new ThoughtLashExileLibraryEffect(), false);
} }
ThoughtLashTriggeredAbility(final ThoughtLashTriggeredAbility ability) { ThoughtLashTriggeredAbility(final ThoughtLashTriggeredAbility ability) {
super(ability); super(ability);
} }
@Override @Override
public ThoughtLashTriggeredAbility copy() { public ThoughtLashTriggeredAbility copy() {
return new ThoughtLashTriggeredAbility(this); return new ThoughtLashTriggeredAbility(this);
} }
@Override @Override
public boolean checkEventType(GameEvent event, Game game) { public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == EventType.DIDNT_PAY_CUMULATIVE_UPKEEP; return event.getType() == EventType.DIDNT_PAY_CUMULATIVE_UPKEEP;
} }
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
return event.getSourceId() == this.getSourceId(); return event.getSourceId() != null && event.getSourceId().equals(this.getSourceId());
} }
@Override @Override
public String getRule() { public String getRule() {
return "When a player doesn't pay {this}'s cumulative upkeep, that player exiles all cards from his or her library."; return "When a player doesn't pay {this}'s cumulative upkeep, that player exiles all cards from his or her library.";
@ -110,21 +110,21 @@ class ThoughtLashTriggeredAbility extends TriggeredAbilityImpl {
} }
class ThoughtLashExileLibraryEffect extends OneShotEffect { class ThoughtLashExileLibraryEffect extends OneShotEffect {
ThoughtLashExileLibraryEffect() { ThoughtLashExileLibraryEffect() {
super(Outcome.Detriment); super(Outcome.Detriment);
this.staticText = "that player exiles all cards from his or her library"; this.staticText = "that player exiles all cards from his or her library";
} }
ThoughtLashExileLibraryEffect(final ThoughtLashExileLibraryEffect effect) { ThoughtLashExileLibraryEffect(final ThoughtLashExileLibraryEffect effect) {
super(effect); super(effect);
} }
@Override @Override
public ThoughtLashExileLibraryEffect copy() { public ThoughtLashExileLibraryEffect copy() {
return new ThoughtLashExileLibraryEffect(this); return new ThoughtLashExileLibraryEffect(this);
} }
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());

View file

@ -1,31 +1,30 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.sets.planeshift; package mage.sets.planeshift;
import java.util.UUID; import java.util.UUID;
@ -56,7 +55,6 @@ public class OrimsChant extends CardImpl {
super(ownerId, 11, "Orim's Chant", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{W}"); super(ownerId, 11, "Orim's Chant", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{W}");
this.expansionSetCode = "PLS"; this.expansionSetCode = "PLS";
// Kicker {W} (You may pay an additional {W} as you cast this spell.) // Kicker {W} (You may pay an additional {W} as you cast this spell.)
this.addAbility(new KickerAbility("{W}")); this.addAbility(new KickerAbility("{W}"));
@ -81,7 +79,7 @@ public class OrimsChant extends CardImpl {
class OrimsChantCantCastEffect extends ContinuousRuleModifyingEffectImpl { class OrimsChantCantCastEffect extends ContinuousRuleModifyingEffectImpl {
public OrimsChantCantCastEffect() { public OrimsChantCantCastEffect() {
super(Duration.EndOfTurn, Outcome.Benefit); super(Duration.EndOfTurn, Outcome.Benefit);
staticText = "Target player can't cast spells this turn"; staticText = "Target player can't cast spells this turn";
} }
@ -97,12 +95,12 @@ class OrimsChantCantCastEffect extends ContinuousRuleModifyingEffectImpl {
@Override @Override
public boolean checksEventType(GameEvent event, Game game) { public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.CAST_SPELL; return GameEvent.EventType.CAST_SPELL.equals(event.getType());
} }
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
return event.getPlayerId() == getTargetPointer().getFirst(game, source); return event.getPlayerId().equals(getTargetPointer().getFirst(game, source));
} }
} }

View file

@ -66,7 +66,7 @@ import mage.target.targetpointer.FixedTarget;
* Each Assassin token's triggered ability will trigger whenever it deals combat * Each Assassin token's triggered ability will trigger whenever it deals combat
* damage to any player, including you. * damage to any player, including you.
* *
* *
* @author LevelX2 * @author LevelX2
*/ */
public class VraskaTheUnseen extends CardImpl { public class VraskaTheUnseen extends CardImpl {
@ -76,11 +76,10 @@ public class VraskaTheUnseen extends CardImpl {
this.expansionSetCode = "RTR"; this.expansionSetCode = "RTR";
this.subtype.add("Vraska"); this.subtype.add("Vraska");
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false));
// +1: Until your next turn, whenever a creature deals combat damage to Vraska the Unseen, destroy that creature. // +1: Until your next turn, whenever a creature deals combat damage to Vraska the Unseen, destroy that creature.
this.addAbility(new LoyaltyAbility(new VraskaTheUnseenGainAbilityEffect(new VraskaTheUnseenTriggeredAbility()),1)); this.addAbility(new LoyaltyAbility(new VraskaTheUnseenGainAbilityEffect(new VraskaTheUnseenTriggeredAbility()), 1));
// -3: Destroy target nonland permanent. // -3: Destroy target nonland permanent.
LoyaltyAbility ability = new LoyaltyAbility(new DestroyTargetEffect(), -3); LoyaltyAbility ability = new LoyaltyAbility(new DestroyTargetEffect(), -3);
@ -101,7 +100,6 @@ public class VraskaTheUnseen extends CardImpl {
} }
} }
class VraskaTheUnseenGainAbilityEffect extends ContinuousEffectImpl { class VraskaTheUnseenGainAbilityEffect extends ContinuousEffectImpl {
protected Ability ability; protected Ability ability;
@ -142,8 +140,7 @@ class VraskaTheUnseenGainAbilityEffect extends ContinuousEffectImpl {
@Override @Override
public boolean isInactive(Ability source, Game game) { public boolean isInactive(Ability source, Game game) {
if (startingTurn != 0 && game.getTurnNum() != startingTurn) if (startingTurn != 0 && game.getTurnNum() != startingTurn) {
{
if (game.getActivePlayerId().equals(source.getControllerId())) { if (game.getActivePlayerId().equals(source.getControllerId())) {
return true; return true;
} }
@ -153,6 +150,7 @@ class VraskaTheUnseenGainAbilityEffect extends ContinuousEffectImpl {
} }
class AssassinToken extends Token { class AssassinToken extends Token {
AssassinToken() { AssassinToken() {
super("Assassin", "1/1 black Assassin creature tokens with \"Whenever this creature deals combat damage to a player, that player loses the game.\""); super("Assassin", "1/1 black Assassin creature tokens with \"Whenever this creature deals combat damage to a player, that player loses the game.\"");
cardType.add(CardType.CREATURE); cardType.add(CardType.CREATURE);
@ -160,7 +158,7 @@ class AssassinToken extends Token {
subtype.add("Assassin"); subtype.add("Assassin");
power = new MageInt(1); power = new MageInt(1);
toughness = new MageInt(1); toughness = new MageInt(1);
addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new LoseGameTargetPlayerEffect(),false, true)); addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new LoseGameTargetPlayerEffect(), false, true));
} }
} }
@ -186,7 +184,7 @@ class VraskaTheUnseenTriggeredAbility extends TriggeredAbilityImpl {
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
if (((DamagedPlaneswalkerEvent) event).isCombatDamage() && event.getTargetId() == sourceId) { if (((DamagedPlaneswalkerEvent) event).isCombatDamage() && getSourceId().equals(event.getTargetId())) {
Permanent sourceOfDamage = game.getPermanent(event.getSourceId()); Permanent sourceOfDamage = game.getPermanent(event.getSourceId());
if (sourceOfDamage != null && sourceOfDamage.getCardType().contains(CardType.CREATURE)) { if (sourceOfDamage != null && sourceOfDamage.getCardType().contains(CardType.CREATURE)) {
Effect effect = this.getEffects().get(0); Effect effect = this.getEffects().get(0);
@ -202,4 +200,4 @@ class VraskaTheUnseenTriggeredAbility extends TriggeredAbilityImpl {
return "Until your next turn, whenever a creature deals combat damage to {this}, destroy that creature"; return "Until your next turn, whenever a creature deals combat damage to {this}, destroy that creature";
} }
} }

View file

@ -25,25 +25,24 @@
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.sets.scarsofmirrodin; package mage.sets.scarsofmirrodin;
import mage.constants.CardType; import java.util.UUID;
import mage.constants.Rarity;
import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.ExileTargetEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import java.util.UUID;
/** /**
* *
* @author Loki * @author Loki
*/ */
public class RevokeExistence extends CardImpl { public class RevokeExistence extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("artifact or enchantment"); private static final FilterPermanent filter = new FilterPermanent("artifact or enchantment");
static { static {
@ -52,15 +51,16 @@ public class RevokeExistence extends CardImpl {
new CardTypePredicate(CardType.ENCHANTMENT))); new CardTypePredicate(CardType.ENCHANTMENT)));
} }
public RevokeExistence (UUID ownerId) { public RevokeExistence(UUID ownerId) {
super(ownerId, 18, "Revoke Existence", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{1}{W}"); super(ownerId, 18, "Revoke Existence", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{1}{W}");
this.expansionSetCode = "SOM"; this.expansionSetCode = "SOM";
// Exile target artifact or enchantment.
this.getSpellAbility().addEffect(new ExileTargetEffect()); this.getSpellAbility().addEffect(new ExileTargetEffect());
this.getSpellAbility().addTarget(new TargetPermanent(filter)); this.getSpellAbility().addTarget(new TargetPermanent(filter));
} }
public RevokeExistence (final RevokeExistence card) { public RevokeExistence(final RevokeExistence card) {
super(card); super(card);
} }

View file

@ -56,7 +56,7 @@ import mage.target.common.TargetControlledCreaturePermanent;
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public class MossbridgeTroll extends CardImpl { public class MossbridgeTroll extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped creatures you control"); private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped creatures you control");
static { static {
@ -78,7 +78,7 @@ public class MossbridgeTroll extends CardImpl {
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(20, 20, Duration.EndOfTurn), new MossbridgeTrollCost()); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(20, 20, Duration.EndOfTurn), new MossbridgeTrollCost());
ability.setAdditionalCostsRuleVisible(false); ability.setAdditionalCostsRuleVisible(false);
this.addAbility(ability); this.addAbility(ability);
} }
public MossbridgeTroll(final MossbridgeTroll card) { public MossbridgeTroll(final MossbridgeTroll card) {
@ -115,10 +115,11 @@ class MossbridgeTrollReplacementEffect extends ReplacementEffectImpl {
public boolean checksEventType(GameEvent event, Game game) { public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DESTROY_PERMANENT; return event.getType() == GameEvent.EventType.DESTROY_PERMANENT;
} }
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
return event.getTargetId() == source.getSourceId(); return event.getTargetId() != null
&& event.getTargetId().equals(source.getSourceId());
} }
@Override @Override
@ -150,7 +151,7 @@ class MossbridgeTrollCost extends CostImpl {
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) {
int sumPower = 0; int sumPower = 0;
if (targets.choose(Outcome.Tap, controllerId, sourceId, game)) { if (targets.choose(Outcome.Tap, controllerId, sourceId, game)) {
for (UUID targetId: targets.get(0).getTargets()) { for (UUID targetId : targets.get(0).getTargets()) {
Permanent permanent = game.getPermanent(targetId); Permanent permanent = game.getPermanent(targetId);
if (permanent != null && permanent.tap(game)) { if (permanent != null && permanent.tap(game)) {
sumPower += permanent.getPower().getValue(); sumPower += permanent.getPower().getValue();
@ -165,7 +166,7 @@ class MossbridgeTrollCost extends CostImpl {
@Override @Override
public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
int sumPower = 0; int sumPower = 0;
for (Permanent permanent :game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), controllerId, game)) { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), controllerId, game)) {
if (!permanent.getId().equals(sourceId)) { if (!permanent.getId().equals(sourceId)) {
sumPower += permanent.getPower().getValue(); sumPower += permanent.getPower().getValue();
} }
@ -178,4 +179,3 @@ class MossbridgeTrollCost extends CostImpl {
return new MossbridgeTrollCost(this); return new MossbridgeTrollCost(this);
} }
} }

View file

@ -50,7 +50,6 @@ public class ThoughtweftGambit extends CardImpl {
super(ownerId, 154, "Thoughtweft Gambit", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{4}{W/U}{W/U}"); super(ownerId, 154, "Thoughtweft Gambit", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{4}{W/U}{W/U}");
this.expansionSetCode = "SHM"; this.expansionSetCode = "SHM";
// Tap all creatures your opponents control and untap all creatures you control. // Tap all creatures your opponents control and untap all creatures you control.
this.getSpellAbility().addEffect(new ThoughtweftGambitEffect()); this.getSpellAbility().addEffect(new ThoughtweftGambitEffect());
@ -94,7 +93,7 @@ class ThoughtweftGambitEffect extends OneShotEffect {
} }
if (controller != null) { if (controller != null) {
for (Permanent creature : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) { for (Permanent creature : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
if (controller.getId() == creature.getControllerId()) { if (controller.getId().equals(creature.getControllerId())) {
creature.untap(game); creature.untap(game);
} }
} }

View file

@ -52,10 +52,8 @@ public class GatherSpecimens extends CardImpl {
super(ownerId, 45, "Gather Specimens", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{3}{U}{U}{U}"); super(ownerId, 45, "Gather Specimens", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{3}{U}{U}{U}");
this.expansionSetCode = "ALA"; this.expansionSetCode = "ALA";
// If a creature would enter the battlefield under an opponent's control this turn, it enters the battlefield under your control instead. // If a creature would enter the battlefield under an opponent's control this turn, it enters the battlefield under your control instead.
this.getSpellAbility().addEffect(new GatherSpecimensReplacementEffect()); this.getSpellAbility().addEffect(new GatherSpecimensReplacementEffect());
} }
public GatherSpecimens(final GatherSpecimens card) { public GatherSpecimens(final GatherSpecimens card) {
@ -114,7 +112,7 @@ class GatherSpecimensReplacementEffect extends ReplacementEffectImpl {
} }
return false; return false;
} }
@Override @Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) { public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
@ -122,5 +120,5 @@ class GatherSpecimensReplacementEffect extends ReplacementEffectImpl {
event.setPlayerId(controller.getId()); event.setPlayerId(controller.getId());
} }
return false; return false;
} }
} }

View file

@ -59,7 +59,7 @@ public class HelmOfPossession extends CardImpl {
// You may choose not to untap Helm of Possession during your untap step. // You may choose not to untap Helm of Possession during your untap step.
this.addAbility(new SkipUntapOptionalAbility()); this.addAbility(new SkipUntapOptionalAbility());
// {2}, {tap}, Sacrifice a creature: Gain control of target creature for as long as you control Helm of Possession and Helm of Possession remains tapped. // {2}, {tap}, Sacrifice a creature: Gain control of target creature for as long as you control Helm of Possession and Helm of Possession remains tapped.
ConditionalContinuousEffect effect = new ConditionalContinuousEffect( ConditionalContinuousEffect effect = new ConditionalContinuousEffect(
new GainControlTargetEffect(Duration.Custom), new GainControlTargetEffect(Duration.Custom),
@ -92,11 +92,11 @@ class HelmOfPossessionCondition implements Condition {
controllerId = source.getControllerId(); controllerId = source.getControllerId();
} }
Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId()); Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId());
if (permanent != null){ if (permanent != null) {
if (permanent.isTapped()){ if (permanent.isTapped()) {
return controllerId == source.getControllerId(); return controllerId.equals(source.getControllerId());
} }
} }
return false; return false;
} }
} }

View file

@ -100,7 +100,7 @@ class TuktukScrapperTriggeredAbility extends TriggeredAbilityImpl {
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanent(event.getTargetId()); Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null) { if (permanent != null) {
if (permanent.getId() == this.getSourceId()) { if (permanent.getId().equals(this.getSourceId())) {
return true; return true;
} }
if (permanent.hasSubtype("Ally") if (permanent.hasSubtype("Ally")

View file

@ -28,11 +28,6 @@
package mage.sets.worldwake; package mage.sets.worldwake;
import java.util.UUID; import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
@ -42,6 +37,11 @@ import mage.abilities.keyword.IslandwalkAbility;
import mage.abilities.keyword.SwampwalkAbility; import mage.abilities.keyword.SwampwalkAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.CardTypePredicate;
@ -50,7 +50,6 @@ import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent.EventType;
import mage.game.events.ZoneChangeEvent; import mage.game.events.ZoneChangeEvent;
import mage.game.stack.Spell;
import mage.game.stack.StackObject; import mage.game.stack.StackObject;
import mage.players.Player; import mage.players.Player;
import mage.target.Target; import mage.target.Target;
@ -156,29 +155,22 @@ class WrexialReplacementEffect extends ReplacementEffectImpl {
public boolean checksEventType(GameEvent event, Game game) { public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == EventType.ZONE_CHANGE; return event.getType() == EventType.ZONE_CHANGE;
} }
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event; ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
if (zEvent.getToZone() == Zone.GRAVEYARD return zEvent.getToZone() == Zone.GRAVEYARD
&& ((ZoneChangeEvent) event).getTargetId() == cardid) { && ((ZoneChangeEvent) event).getTargetId().equals(cardid);
return true;
}
return false;
} }
@Override @Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) { public boolean replaceEvent(GameEvent event, Ability source, Game game) {
UUID eventObject = ((ZoneChangeEvent) event).getTargetId(); UUID eventObject = ((ZoneChangeEvent) event).getTargetId();
StackObject card = game.getStack().getStackObject(eventObject); StackObject card = game.getStack().getStackObject(eventObject);
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (card != null && controller != null) { if (card != null && controller != null) {
if (card instanceof Spell) {
game.rememberLKI(card.getId(), Zone.STACK, (Spell) card);
}
if (card instanceof Card) { if (card instanceof Card) {
controller.moveCardToExileWithInfo((Card)card, null, "", source.getSourceId(), game, game.getState().getZone(event.getTargetId()), true); return controller.moveCards((Card) card, null, Zone.EXILED, source, game);
return true;
} }
} }
return false; return false;

View file

@ -90,6 +90,7 @@ public class OblivionRingTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5); addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
addCard(Zone.HAND, playerA, "Oblivion Ring"); addCard(Zone.HAND, playerA, "Oblivion Ring");
addCard(Zone.BATTLEFIELD, playerA, "Jace Beleren"); addCard(Zone.BATTLEFIELD, playerA, "Jace Beleren");
// Exile target artifact or enchantment.
addCard(Zone.HAND, playerA, "Revoke Existence"); addCard(Zone.HAND, playerA, "Revoke Existence");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-1: Target player draws a card", playerA); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-1: Target player draws a card", playerA);
@ -100,7 +101,10 @@ public class OblivionRingTest extends CardTestPlayerBase {
setStopAt(1, PhaseStep.END_TURN); setStopAt(1, PhaseStep.END_TURN);
execute(); execute();
assertExileCount("Oblivion Ring", 1);
assertGraveyardCount(playerA, "Revoke Existence", 1);
assertPermanentCount(playerA, "Oblivion Ring", 0); assertPermanentCount(playerA, "Oblivion Ring", 0);
assertGraveyardCount(playerA, "Jace Beleren", 0);
assertPermanentCount(playerA, "Jace Beleren", 1); // returns back assertPermanentCount(playerA, "Jace Beleren", 1); // returns back
assertHandCount(playerA, 2); // can use ability twice assertHandCount(playerA, 2); // can use ability twice
} }

View file

@ -1,31 +1,30 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.abilities.common; package mage.abilities.common;
import mage.abilities.StaticAbility; import mage.abilities.StaticAbility;
@ -41,15 +40,17 @@ import mage.constants.Zone;
public class EntersBattlefieldAbility extends StaticAbility { public class EntersBattlefieldAbility extends StaticAbility {
protected String abilityRule; protected String abilityRule;
public EntersBattlefieldAbility(Effect effect) { public EntersBattlefieldAbility(Effect effect) {
this(effect, true); this(effect, true);
} }
/**
* /**
* @param effect effect that happens when the permanent enters the battlefield *
* @param showRule show the rule for this ability * @param effect effect that happens when the permanent enters the
*/ * battlefield
* @param showRule show the rule for this ability
*/
public EntersBattlefieldAbility(Effect effect, Boolean showRule) { public EntersBattlefieldAbility(Effect effect, Boolean showRule) {
this(effect, null, showRule, null, null); this(effect, null, showRule, null, null);
} }
@ -57,16 +58,19 @@ public class EntersBattlefieldAbility extends StaticAbility {
public EntersBattlefieldAbility(Effect effect, String effectText) { public EntersBattlefieldAbility(Effect effect, String effectText) {
this(effect, null, true, null, effectText); this(effect, null, true, null, effectText);
} }
/**
* /**
* @param effect effect that happens when the permanent enters the battlefield *
* @param condition only if this condition is true, the effect will happen * @param effect effect that happens when the permanent enters the
* @param ruleVisible show the rule for this ability * battlefield
* @param abilityRule rule for this ability (no text from effects will be added) * @param condition only if this condition is true, the effect will happen
* @param effectText this text will be used for the EnterBattlefieldEffect * @param ruleVisible show the rule for this ability
*/ * @param abilityRule rule for this ability (no text from effects will be
* added)
* @param effectText this text will be used for the EnterBattlefieldEffect
*/
public EntersBattlefieldAbility(Effect effect, Condition condition, Boolean ruleVisible, String abilityRule, String effectText) { public EntersBattlefieldAbility(Effect effect, Condition condition, Boolean ruleVisible, String abilityRule, String effectText) {
super(Zone.BATTLEFIELD, new EntersBattlefieldEffect(effect, condition, effectText)); super(Zone.ALL, new EntersBattlefieldEffect(effect, condition, effectText));
this.setRuleVisible(ruleVisible); this.setRuleVisible(ruleVisible);
this.abilityRule = abilityRule; this.abilityRule = abilityRule;
} }
@ -96,7 +100,7 @@ public class EntersBattlefieldAbility extends StaticAbility {
@Override @Override
public String getRule() { public String getRule() {
if (!ruleVisible) { if (!ruleVisible) {
return ""; return "";
} }
if (abilityRule != null && !abilityRule.isEmpty()) { if (abilityRule != null && !abilityRule.isEmpty()) {
return abilityRule; return abilityRule;

View file

@ -68,7 +68,7 @@ public class DiscardTargetCost extends CostImpl {
@Override @Override
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) {
this.cards.clear(); this.cards.clear();
this.targets.clear(); this.targets.clearChosen();;
Player player = game.getPlayer(controllerId); Player player = game.getPlayer(controllerId);
if (player == null) { if (player == null) {
return false; return false;

View file

@ -1246,7 +1246,7 @@ public class ContinuousEffects implements Serializable {
HashSet<Ability> abilities = preventionEffects.getAbility(effect.getId()); HashSet<Ability> abilities = preventionEffects.getAbility(effect.getId());
for (Ability ability : abilities) { for (Ability ability : abilities) {
if (ability.getSourceId().equals(sourceId)) { if (ability.getSourceId().equals(sourceId)) {
if (controllerFound == null || controllerFound == ability.getControllerId()) { if (controllerFound == null || controllerFound.equals(ability.getControllerId())) {
controllerFound = ability.getControllerId(); controllerFound = ability.getControllerId();
} else { } else {
// not unique controller - No solution yet // not unique controller - No solution yet
@ -1260,7 +1260,7 @@ public class ContinuousEffects implements Serializable {
for (Ability ability : abilities) { for (Ability ability : abilities) {
if (ability.getSourceId() != null) { if (ability.getSourceId() != null) {
if (ability.getSourceId().equals(sourceId)) { if (ability.getSourceId().equals(sourceId)) {
if (controllerFound == null || controllerFound == ability.getControllerId()) { if (controllerFound == null || controllerFound.equals(ability.getControllerId())) {
controllerFound = ability.getControllerId(); controllerFound = ability.getControllerId();
} else { } else {
// not unique controller - No solution yet // not unique controller - No solution yet

View file

@ -101,7 +101,11 @@ public class ReturnFromExileForSourceEffect extends OneShotEffect {
} }
ExileZone exile = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), zoneChangeCounter)); ExileZone exile = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), zoneChangeCounter));
if (exile != null) { // null is valid if source left battlefield before enters the battlefield effect resolved if (exile != null) { // null is valid if source left battlefield before enters the battlefield effect resolved
controller.moveCards(exile, null, returnToZone, source, game); if (returnToZone.equals(Zone.BATTLEFIELD)) {
controller.moveCards(exile.getCards(game), returnToZone, source, game, false, false, true, null);
} else {
controller.moveCards(exile, null, returnToZone, source, game);
}
} }
return true; return true;
} }

View file

@ -1,31 +1,30 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.abilities.keyword; package mage.abilities.keyword;
import java.util.UUID; import java.util.UUID;
@ -48,28 +47,29 @@ import mage.game.stack.Spell;
import mage.players.Player; import mage.players.Player;
/** /**
* This ability has no effect by default and will always return false on the call * This ability has no effect by default and will always return false on the
* to apply. This is because of how the {@link ReboundEffect} works. It will * call to apply. This is because of how the {@link ReboundEffect} works. It
* install the effect if and only if the spell was cast from the {@link Zone#HAND Hand}. * will install the effect if and only if the spell was cast from the
* {@link Zone#HAND Hand}.
* <p/> * <p/>
* 702.85. Rebound * 702.85. Rebound
* <p/> * <p/>
* 702.85a Rebound appears on some instants and sorceries. It represents a static * 702.85a Rebound appears on some instants and sorceries. It represents a
* ability that functions while the spell is on the stack and may create a delayed * static ability that functions while the spell is on the stack and may create
* triggered ability. "Rebound" means "If this spell was cast from your hand, * a delayed triggered ability. "Rebound" means "If this spell was cast from
* instead of putting it into your graveyard as it resolves, exile it and, at * your hand, instead of putting it into your graveyard as it resolves, exile it
* the beginning of your next upkeep, you may cast this card from exile without * and, at the beginning of your next upkeep, you may cast this card from exile
* paying its mana cost." * without paying its mana cost."
* <p/> * <p/>
* 702.85b Casting a card without paying its mana cost as the result of a rebound * 702.85b Casting a card without paying its mana cost as the result of a
* ability follows the rules for paying alternative costs in rules 601.2b and 601.2e-g. * rebound ability follows the rules for paying alternative costs in rules
* 601.2b and 601.2e-g.
* <p/> * <p/>
* 702.85c Multiple instances of rebound on the same spell are redundant. * 702.85c Multiple instances of rebound on the same spell are redundant.
* *
* @author maurer.it_at_gmail.com, noxx * @author maurer.it_at_gmail.com, noxx
*/ */
public class ReboundAbility extends SimpleStaticAbility {
public class ReboundAbility extends SimpleStaticAbility {
public ReboundAbility() { public ReboundAbility() {
super(Zone.STACK, new ReboundCastFromHandReplacementEffect()); super(Zone.STACK, new ReboundCastFromHandReplacementEffect());
@ -81,8 +81,8 @@ public class ReboundAbility extends SimpleStaticAbility {
@Override @Override
public ReboundAbility copy() { public ReboundAbility copy() {
return new ReboundAbility(this); return new ReboundAbility(this);
} }
} }
class ReboundCastFromHandReplacementEffect extends ReplacementEffectImpl { class ReboundCastFromHandReplacementEffect extends ReplacementEffectImpl {
@ -95,7 +95,7 @@ class ReboundCastFromHandReplacementEffect extends ReplacementEffectImpl {
ReboundCastFromHandReplacementEffect(ReboundCastFromHandReplacementEffect effect) { ReboundCastFromHandReplacementEffect(ReboundCastFromHandReplacementEffect effect) {
super(effect); super(effect);
} }
@Override @Override
public boolean checksEventType(GameEvent event, Game game) { public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE; return event.getType() == GameEvent.EventType.ZONE_CHANGE;
@ -103,16 +103,18 @@ class ReboundCastFromHandReplacementEffect extends ReplacementEffectImpl {
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (((ZoneChangeEvent) event).getFromZone() == Zone.STACK && if (((ZoneChangeEvent) event).getFromZone() == Zone.STACK
((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD && && ((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD
event.getSourceId() == source.getSourceId()) { // if countered the source.sourceId is different or null if it fizzles && event.getSourceId() != null
&& event.getSourceId().equals(source.getSourceId())) { // if countered the source.sourceId is different or null if it fizzles
Spell spell = game.getStack().getSpell(event.getTargetId()); Spell spell = game.getStack().getSpell(event.getTargetId());
if (spell != null && spell.getFromZone().equals(Zone.HAND)) { if (spell != null && spell.getFromZone().equals(Zone.HAND)) {
return true; return true;
} }
} }
return false; return false;
} }
@Override @Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) { public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Spell sourceSpell = game.getStack().getSpell(source.getSourceId()); Spell sourceSpell = game.getStack().getSpell(source.getSourceId());
@ -126,9 +128,9 @@ class ReboundCastFromHandReplacementEffect extends ReplacementEffectImpl {
// Add the delayed triggered effect // Add the delayed triggered effect
ReboundEffectCastFromExileDelayedTrigger trigger = new ReboundEffectCastFromExileDelayedTrigger(source.getSourceId(), source.getSourceId()); ReboundEffectCastFromExileDelayedTrigger trigger = new ReboundEffectCastFromExileDelayedTrigger(source.getSourceId(), source.getSourceId());
trigger.setControllerId(source.getControllerId()); trigger.setControllerId(source.getControllerId());
trigger.setSourceObject(source.getSourceObject(game), game); trigger.setSourceObject(source.getSourceObject(game), game);
game.addDelayedTriggeredAbility(trigger); game.addDelayedTriggeredAbility(trigger);
player.moveCardToExileWithInfo(sourceCard, sourceCard.getId(), player.getName() + " Rebound", source.getSourceId(), game, Zone.STACK, true); player.moveCardToExileWithInfo(sourceCard, sourceCard.getId(), player.getName() + " Rebound", source.getSourceId(), game, Zone.STACK, true);
return true; return true;
} }
@ -144,7 +146,6 @@ class ReboundCastFromHandReplacementEffect extends ReplacementEffectImpl {
} }
class ReboundEffectCastFromExileDelayedTrigger extends DelayedTriggeredAbility { class ReboundEffectCastFromExileDelayedTrigger extends DelayedTriggeredAbility {
ReboundEffectCastFromExileDelayedTrigger(UUID cardId, UUID sourceId) { ReboundEffectCastFromExileDelayedTrigger(UUID cardId, UUID sourceId) {
@ -171,6 +172,7 @@ class ReboundEffectCastFromExileDelayedTrigger extends DelayedTriggeredAbility {
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
return MyTurnCondition.getInstance().apply(game, this); return MyTurnCondition.getInstance().apply(game, this);
} }
@Override @Override
public String getRule() { public String getRule() {
return "Rebound - You may cast {this} from exile without paying its mana cost."; return "Rebound - You may cast {this} from exile without paying its mana cost.";
@ -178,8 +180,8 @@ class ReboundEffectCastFromExileDelayedTrigger extends DelayedTriggeredAbility {
} }
/** /**
* Will be triggered by {@link ReboundEffectCastFromExileDelayedTrigger} and will * Will be triggered by {@link ReboundEffectCastFromExileDelayedTrigger} and
* simply cast the spell then remove it from its former home in exile. * will simply cast the spell then remove it from its former home in exile.
* *
* @author maurer.it_at_gmail.com * @author maurer.it_at_gmail.com
*/ */

View file

@ -507,8 +507,8 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
break; break;
case EXILED: case EXILED:
if (game.getExile().getCard(getId(), game) != null) { if (game.getExile().getCard(getId(), game) != null) {
game.getExile().removeCard(this, game); removed = game.getExile().removeCard(this, game);
removed = true;
} }
break; break;
case STACK: case STACK:
@ -552,8 +552,9 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
+ "] source [" + (sourceObject != null ? sourceObject.getName() : "null") + "]"); + "] source [" + (sourceObject != null ? sourceObject.getName() : "null") + "]");
break; break;
} }
game.rememberLKI(objectId, fromZone, lkiObject != null ? lkiObject : this); if (removed) {
if (!removed) { game.rememberLKI(objectId, fromZone, lkiObject != null ? lkiObject : this);
} else {
logger.warn("Couldn't find card in fromZone, card=" + getIdName() + ", fromZone=" + fromZone); logger.warn("Couldn't find card in fromZone, card=" + getIdName() + ", fromZone=" + fromZone);
} }
return removed; return removed;

View file

@ -107,12 +107,13 @@ public class Exile implements Serializable, Copyable<Exile> {
return cards; return cards;
} }
public void removeCard(Card card, Game game) { public boolean removeCard(Card card, Game game) {
for (ExileZone exile : exileZones.values()) { for (ExileZone exile : exileZones.values()) {
if (exile.contains(card.getId())) { if (exile.contains(card.getId())) {
exile.remove(card); return exile.remove(card.getId());
} }
} }
return false;
} }
@Override @Override

View file

@ -3052,7 +3052,7 @@ public abstract class PlayerImpl implements Player, Serializable {
ZoneChangeEvent event = new ZoneChangeEvent(card.getId(), source.getSourceId(), controllingPlayerId, fromZone, Zone.BATTLEFIELD, appliedEffects, tapped); ZoneChangeEvent event = new ZoneChangeEvent(card.getId(), source.getSourceId(), controllingPlayerId, fromZone, Zone.BATTLEFIELD, appliedEffects, tapped);
if (!game.replaceEvent(event)) { if (!game.replaceEvent(event)) {
// get permanent // get permanent
Permanent permanent = new PermanentCard(card, controllingPlayerId, game); Permanent permanent = new PermanentCard(card, event.getPlayerId(), game);// controlling player can be replaced so use event player now
permanents.add(permanent); permanents.add(permanent);
card.checkForCountersToAdd(permanent, game); card.checkForCountersToAdd(permanent, game);
permanent.setTapped(tapped); permanent.setTapped(tapped);