fixes for issues 18, 19, 20, 21 + more fixes

This commit is contained in:
BetaSteward 2010-11-25 03:15:35 +00:00
parent 2aad7682bd
commit 428609ab8b
58 changed files with 482 additions and 356 deletions

View file

@ -219,7 +219,7 @@ public class GameController implements GameCallback {
deck = Deck.load(deckList); deck = Deck.load(deckList);
game.loadCards(deck.getCards(), playerId); game.loadCards(deck.getCards(), playerId);
for (Card card: deck.getCards()) { for (Card card: deck.getCards()) {
card.putOntoBattlefield(game, Zone.OUTSIDE, playerId); card.putOntoBattlefield(game, Zone.OUTSIDE, null, playerId);
} }
} catch (GameException ex) { } catch (GameException ex) {
logger.warning(ex.getMessage()); logger.warning(ex.getMessage());
@ -477,7 +477,7 @@ public class GameController implements GameCallback {
*/ */
private void swapWithAnyCard(Game game, Player player, Card card, Zone zone) { private void swapWithAnyCard(Game game, Player player, Card card, Zone zone) {
if (zone.equals(Zone.BATTLEFIELD)) { if (zone.equals(Zone.BATTLEFIELD)) {
card.putOntoBattlefield(game, Zone.OUTSIDE, player.getId()); card.putOntoBattlefield(game, Zone.OUTSIDE, null, player.getId());
} else { } else {
card.moveToZone(zone, null, game, false); card.moveToZone(zone, null, game, false);
} }

View file

@ -100,7 +100,7 @@ class MartialCoupEffect extends OneShotEffect<MartialCoupEffect> {
} }
} }
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
token.putOntoBattlefield(game, source.getControllerId()); token.putOntoBattlefield(game, source.getId(), source.getControllerId());
} }
return true; return true;
} }

View file

@ -100,7 +100,7 @@ class PathToExileEffect extends OneShotEffect {
player.searchLibrary(target, game); player.searchLibrary(target, game);
Card card = player.getLibrary().remove(target.getFirstTarget(), game); Card card = player.getLibrary().remove(target.getFirstTarget(), game);
if (card != null) { if (card != null) {
if (card.putOntoBattlefield(game, Zone.LIBRARY, permanent.getControllerId())) { if (card.putOntoBattlefield(game, Zone.LIBRARY, source.getId(), permanent.getControllerId())) {
Permanent land = game.getPermanent(card.getId()); Permanent land = game.getPermanent(card.getId());
if (land != null) if (land != null)
land.setTapped(true); land.setTapped(true);

View file

@ -31,7 +31,7 @@ package mage.sets.magic2010;
import java.util.UUID; import java.util.UUID;
import mage.Constants.CardType; import mage.Constants.CardType;
import mage.Constants.Rarity; import mage.Constants.Rarity;
import mage.abilities.common.EntersBattlefieldStaticAbility; import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.effects.common.TapSourceUnlessControlsEffect; import mage.abilities.effects.common.TapSourceUnlessControlsEffect;
import mage.abilities.mana.BlackManaAbility; import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.RedManaAbility; import mage.abilities.mana.RedManaAbility;
@ -57,7 +57,7 @@ public class DragonskullSummit extends CardImpl<DragonskullSummit> {
public DragonskullSummit(UUID ownerId) { public DragonskullSummit(UUID ownerId) {
super(ownerId, 223, "Dragonskull Summit", Rarity.RARE, new CardType[]{CardType.LAND}, null); super(ownerId, 223, "Dragonskull Summit", Rarity.RARE, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "M10"; this.expansionSetCode = "M10";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceUnlessControlsEffect(filter), "tapped unless you control a " + filter.getMessage())); this.addAbility(new EntersBattlefieldAbility(new TapSourceUnlessControlsEffect(filter), "tapped unless you control a " + filter.getMessage()));
this.addAbility(new BlackManaAbility()); this.addAbility(new BlackManaAbility());
this.addAbility(new RedManaAbility()); this.addAbility(new RedManaAbility());
} }

View file

@ -31,7 +31,7 @@ package mage.sets.magic2010;
import java.util.UUID; import java.util.UUID;
import mage.Constants.CardType; import mage.Constants.CardType;
import mage.Constants.Rarity; import mage.Constants.Rarity;
import mage.abilities.common.EntersBattlefieldStaticAbility; import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.effects.common.TapSourceUnlessControlsEffect; import mage.abilities.effects.common.TapSourceUnlessControlsEffect;
import mage.abilities.mana.BlackManaAbility; import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.BlueManaAbility; import mage.abilities.mana.BlueManaAbility;
@ -57,7 +57,7 @@ public class DrownedCatacomb extends CardImpl<DrownedCatacomb> {
public DrownedCatacomb(UUID ownerId) { public DrownedCatacomb(UUID ownerId) {
super(ownerId, 224, "Drowned Catacomb", Rarity.RARE, new CardType[]{CardType.LAND}, null); super(ownerId, 224, "Drowned Catacomb", Rarity.RARE, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "M10"; this.expansionSetCode = "M10";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceUnlessControlsEffect(filter), "tapped unless you control a " + filter.getMessage())); this.addAbility(new EntersBattlefieldAbility(new TapSourceUnlessControlsEffect(filter), "tapped unless you control a " + filter.getMessage()));
this.addAbility(new BlackManaAbility()); this.addAbility(new BlackManaAbility());
this.addAbility(new BlueManaAbility()); this.addAbility(new BlueManaAbility());
} }

View file

@ -31,7 +31,9 @@ package mage.sets.magic2010;
import java.util.UUID; import java.util.UUID;
import mage.Constants.CardType; import mage.Constants.CardType;
import mage.Constants.Rarity; import mage.Constants.Rarity;
import mage.abilities.common.EntersBattlefieldStaticAbility; import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.EntersBattlefieldEffect;
import mage.abilities.effects.common.TapSourceUnlessControlsEffect; import mage.abilities.effects.common.TapSourceUnlessControlsEffect;
import mage.abilities.mana.BlueManaAbility; import mage.abilities.mana.BlueManaAbility;
import mage.abilities.mana.WhiteManaAbility; import mage.abilities.mana.WhiteManaAbility;
@ -57,7 +59,7 @@ public class GlacialFortress extends CardImpl<GlacialFortress> {
public GlacialFortress(UUID ownerId) { public GlacialFortress(UUID ownerId) {
super(ownerId, 226, "Glacial Fortress", Rarity.RARE, new CardType[]{CardType.LAND}, null); super(ownerId, 226, "Glacial Fortress", Rarity.RARE, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "M10"; this.expansionSetCode = "M10";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceUnlessControlsEffect(filter), "tapped unless you control a " + filter.getMessage())); this.addAbility(new EntersBattlefieldAbility(new TapSourceUnlessControlsEffect(filter), "tapped unless you control a " + filter.getMessage()));
this.addAbility(new BlueManaAbility()); this.addAbility(new BlueManaAbility());
this.addAbility(new WhiteManaAbility()); this.addAbility(new WhiteManaAbility());
} }

View file

@ -38,9 +38,6 @@ import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DiscardTargetEffect; import mage.abilities.effects.common.DiscardTargetEffect;
import mage.abilities.effects.common.DrawCardAllEffect;
import mage.abilities.effects.common.DrawCardTargetEffect;
import mage.abilities.effects.common.PutLibraryIntoGraveTargetEffect;
import mage.abilities.effects.common.SearchLibraryPutOnLibraryEffect; import mage.abilities.effects.common.SearchLibraryPutOnLibraryEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -104,7 +101,7 @@ class LilianaVessEffect extends OneShotEffect<LilianaVessEffect> {
for (Card card: player.getGraveyard().getCards(game)) { for (Card card: player.getGraveyard().getCards(game)) {
if (card.getCardType().contains(CardType.CREATURE)) { if (card.getCardType().contains(CardType.CREATURE)) {
player.getGraveyard().remove(card); player.getGraveyard().remove(card);
card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getControllerId()); card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getId(), source.getControllerId());
} }
} }
} }

View file

@ -38,10 +38,11 @@ import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility; import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldStaticAbility; import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.PreventionEffectImpl; import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.AddPlusOneCountersSourceEffect; import mage.abilities.effects.common.AddPlusOneCountersSourceEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -65,7 +66,8 @@ public class ProteanHydra extends CardImpl<ProteanHydra> {
this.power = new MageInt(0); this.power = new MageInt(0);
this.toughness = new MageInt(0); this.toughness = new MageInt(0);
this.addAbility(new EntersBattlefieldStaticAbility(new ProteanHydraEffect1(), "with X +1/+1 counters on it")); this.addAbility(new EntersBattlefieldAbility(new ProteanHydraEffect1(), "with X +1/+1 counters on it"));
this.addAbility(new ProteanHydraAbility());
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ProteanHydraEffect2())); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ProteanHydraEffect2()));
} }
@ -95,9 +97,9 @@ public class ProteanHydra extends CardImpl<ProteanHydra> {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
int amount = source.getCosts().getVariableCosts().get(0).getAmount();
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) { if (permanent != null) {
int amount = source.getManaCosts().getVariableCosts().get(0).getAmount();
permanent.addCounters(new PlusOneCounter(amount)); permanent.addCounters(new PlusOneCounter(amount));
} }
return true; return true;
@ -112,6 +114,7 @@ public class ProteanHydra extends CardImpl<ProteanHydra> {
public String getText(Ability source) { public String getText(Ability source) {
return "Protean Hydra enters the battlefield with X +1/+1 counters on it"; return "Protean Hydra enters the battlefield with X +1/+1 counters on it";
} }
} }
class ProteanHydraEffect2 extends PreventionEffectImpl<ProteanHydraEffect2> { class ProteanHydraEffect2 extends PreventionEffectImpl<ProteanHydraEffect2> {
@ -154,7 +157,7 @@ public class ProteanHydra extends CardImpl<ProteanHydra> {
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)) { if (super.applies(event, source, game)) {
if (event.getTargetId().equals(source.getId())) { if (event.getTargetId().equals(source.getSourceId())) {
return true; return true;
} }
} }
@ -171,7 +174,7 @@ public class ProteanHydra extends CardImpl<ProteanHydra> {
class ProteanHydraAbility extends TriggeredAbilityImpl<ProteanHydraAbility> { class ProteanHydraAbility extends TriggeredAbilityImpl<ProteanHydraAbility> {
public ProteanHydraAbility() { public ProteanHydraAbility() {
super(Zone.BATTLEFIELD, new CreateDelayedTriggeredAbilityEffect(new ProteanHydraDelayedTriggeredAbility()), true); super(Zone.BATTLEFIELD, new CreateDelayedTriggeredAbilityEffect(new ProteanHydraDelayedTriggeredAbility()), false);
} }
public ProteanHydraAbility(final ProteanHydraAbility ability) { public ProteanHydraAbility(final ProteanHydraAbility ability) {

View file

@ -31,7 +31,7 @@ package mage.sets.magic2010;
import java.util.UUID; import java.util.UUID;
import mage.Constants.CardType; import mage.Constants.CardType;
import mage.Constants.Rarity; import mage.Constants.Rarity;
import mage.abilities.common.EntersBattlefieldStaticAbility; import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.effects.common.TapSourceUnlessControlsEffect; import mage.abilities.effects.common.TapSourceUnlessControlsEffect;
import mage.abilities.mana.GreenManaAbility; import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.RedManaAbility; import mage.abilities.mana.RedManaAbility;
@ -57,7 +57,7 @@ public class RootboundCrag extends CardImpl<RootboundCrag> {
public RootboundCrag(UUID ownerId) { public RootboundCrag(UUID ownerId) {
super(ownerId, 227, "Rootbound Crag", Rarity.RARE, new CardType[]{CardType.LAND}, null); super(ownerId, 227, "Rootbound Crag", Rarity.RARE, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "M10"; this.expansionSetCode = "M10";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceUnlessControlsEffect(filter), "tapped unless you control a " + filter.getMessage())); this.addAbility(new EntersBattlefieldAbility(new TapSourceUnlessControlsEffect(filter), "tapped unless you control a " + filter.getMessage()));
this.addAbility(new RedManaAbility()); this.addAbility(new RedManaAbility());
this.addAbility(new GreenManaAbility()); this.addAbility(new GreenManaAbility());
} }

View file

@ -31,7 +31,7 @@ package mage.sets.magic2010;
import java.util.UUID; import java.util.UUID;
import mage.Constants.CardType; import mage.Constants.CardType;
import mage.Constants.Rarity; import mage.Constants.Rarity;
import mage.abilities.common.EntersBattlefieldStaticAbility; import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.effects.common.TapSourceUnlessControlsEffect; import mage.abilities.effects.common.TapSourceUnlessControlsEffect;
import mage.abilities.mana.GreenManaAbility; import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.WhiteManaAbility; import mage.abilities.mana.WhiteManaAbility;
@ -57,7 +57,7 @@ public class SunpetalGrove extends CardImpl<SunpetalGrove> {
public SunpetalGrove(UUID ownerId) { public SunpetalGrove(UUID ownerId) {
super(ownerId, 228, "Sunpetal Grove", Rarity.RARE, new CardType[]{CardType.LAND}, null); super(ownerId, 228, "Sunpetal Grove", Rarity.RARE, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "M10"; this.expansionSetCode = "M10";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceUnlessControlsEffect(filter), "tapped unless you control a " + filter.getMessage())); this.addAbility(new EntersBattlefieldAbility(new TapSourceUnlessControlsEffect(filter), "tapped unless you control a " + filter.getMessage()));
this.addAbility(new GreenManaAbility()); this.addAbility(new GreenManaAbility());
this.addAbility(new WhiteManaAbility()); this.addAbility(new WhiteManaAbility());
} }

View file

@ -112,7 +112,7 @@ class CultivateEffect extends OneShotEffect<CultivateEffect> {
target2.setRequired(true); target2.setRequired(true);
player.choose(revealed, target2, game); player.choose(revealed, target2, game);
Card card = revealed.get(target2.getFirstTarget(), game); Card card = revealed.get(target2.getFirstTarget(), game);
card.putOntoBattlefield(game, Zone.LIBRARY, source.getControllerId()); card.putOntoBattlefield(game, Zone.LIBRARY, source.getId(), source.getControllerId());
revealed.remove(card); revealed.remove(card);
Permanent permanent = game.getPermanent(card.getId()); Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) if (permanent != null)
@ -122,7 +122,7 @@ class CultivateEffect extends OneShotEffect<CultivateEffect> {
} }
else if (target.getTargets().size() == 1) { else if (target.getTargets().size() == 1) {
Card card = revealed.getCards(game).iterator().next(); Card card = revealed.getCards(game).iterator().next();
card.putOntoBattlefield(game, Zone.LIBRARY, source.getControllerId()); card.putOntoBattlefield(game, Zone.LIBRARY, source.getId(), source.getControllerId());
Permanent permanent = game.getPermanent(card.getId()); Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) if (permanent != null)
permanent.setTapped(true); permanent.setTapped(true);

View file

@ -105,7 +105,7 @@ class MassPolymorphEffect extends OneShotEffect<MassPolymorphEffect> {
} }
player.revealCards(revealed, game); player.revealCards(revealed, game);
for (Card creatureCard: creatureCards.getCards(game)) { for (Card creatureCard: creatureCards.getCards(game)) {
creatureCard.putOntoBattlefield(game, Zone.LIBRARY, source.getControllerId()); creatureCard.putOntoBattlefield(game, Zone.LIBRARY, source.getId(), source.getControllerId());
} }
player.getLibrary().addAll(nonCreatureCards.getCards(game), game); player.getLibrary().addAll(nonCreatureCards.getCards(game), game);
player.getLibrary().shuffle(); player.getLibrary().shuffle();

View file

@ -38,7 +38,6 @@ import mage.Constants.SubLayer;
import mage.Constants.TargetController; import mage.Constants.TargetController;
import mage.Constants.Zone; import mage.Constants.Zone;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
import mage.abilities.common.OnEventTriggeredAbility; import mage.abilities.common.OnEventTriggeredAbility;
import mage.abilities.common.PutIntoGraveFromBattlefieldTriggeredAbility; import mage.abilities.common.PutIntoGraveFromBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
@ -172,7 +171,7 @@ class NecroticPlagueEffect2 extends OneShotEffect<NecroticPlagueEffect2> {
if (controller.choose(Outcome.Detriment, target, game)) { if (controller.choose(Outcome.Detriment, target, game)) {
Card card = game.getCard(cardId); Card card = game.getCard(cardId);
if (card != null) { if (card != null) {
card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getControllerId()); card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getId(), source.getControllerId());
Permanent permanent = game.getPermanent(target.getFirstTarget()); Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) { if (permanent != null) {
return permanent.addAttachment(cardId, game); return permanent.addAttachment(cardId, game);

View file

@ -118,7 +118,7 @@ class ObstinateBalothEffect extends ReplacementEffectImpl<ObstinateBalothEffect>
if (card != null) { if (card != null) {
Player player = game.getPlayer(card.getOwnerId()); Player player = game.getPlayer(card.getOwnerId());
if (player != null) { if (player != null) {
if (card.putOntoBattlefield(game, Zone.HAND, player.getId())) { if (card.putOntoBattlefield(game, Zone.HAND, source.getId(), player.getId())) {
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DISCARDED_CARD, card.getId(), source.getId(), player.getId())); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DISCARDED_CARD, card.getId(), source.getId(), player.getId()));
return true; return true;
} }

View file

@ -107,9 +107,8 @@ class OverwhelmingStampedeEffect extends ContinuousEffectImpl<OverwhelmingStampe
} }
break; break;
} }
return true;
} }
return false; return true;
} }
@Override @Override

View file

@ -39,7 +39,6 @@ import mage.cards.CardImpl;
import mage.game.Game; 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.permanent.Permanent;
/** /**
* *
@ -90,13 +89,10 @@ public class PhantomBeast extends CardImpl<PhantomBeast> {
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
Permanent perm = game.getPermanent(sourceId); if (event.getType() == EventType.TARGETED && event.getTargetId().equals(sourceId)) {
if (perm != null) {
if (event.getTargetId().equals(perm.getId()) && event.getType() == EventType.TARGETED) {
trigger(game, event.getPlayerId()); trigger(game, event.getPlayerId());
return true; return true;
} }
}
return false; return false;
} }

View file

@ -30,13 +30,14 @@ package mage.sets.magic2011;
import java.util.UUID; import java.util.UUID;
import mage.Constants.CardType; import mage.Constants.CardType;
import mage.Constants.Outcome;
import mage.Constants.Rarity; import mage.Constants.Rarity;
import mage.Constants.Zone; import mage.Constants.Zone;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.StateTriggeredAbility; import mage.abilities.StateTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.effects.common.AddCountersTargetEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.SacrificeSourceEffect; import mage.abilities.effects.common.SacrificeSourceEffect;
import mage.abilities.keyword.IndestructibleAbility; import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -45,6 +46,8 @@ import mage.filter.common.FilterControlledPermanent;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetControlledPermanent;
/** /**
@ -53,13 +56,6 @@ import mage.target.common.TargetControlledPermanent;
*/ */
public class PhylacteryLich extends CardImpl<PhylacteryLich> { public class PhylacteryLich extends CardImpl<PhylacteryLich> {
private static FilterControlledPermanent filter = new FilterControlledPermanent("artifact");
static {
filter.getCardType().add(CardType.ARTIFACT);
filter.setScopeCardType(ComparisonScope.Any);
}
public PhylacteryLich(UUID ownerId) { public PhylacteryLich(UUID ownerId) {
super(ownerId, 110, "Phylactery Lich", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{B}{B}{B}"); super(ownerId, 110, "Phylactery Lich", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{B}{B}{B}");
this.expansionSetCode = "M11"; this.expansionSetCode = "M11";
@ -68,9 +64,7 @@ public class PhylacteryLich extends CardImpl<PhylacteryLich> {
this.power = new MageInt(5); this.power = new MageInt(5);
this.toughness = new MageInt(5); this.toughness = new MageInt(5);
Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect("phylactery", 1), false); this.addAbility(new EntersBattlefieldAbility(new PhylacteryLichEffect(), "put a phylactery counter on an artifact you control"));
ability.addTarget(new TargetControlledPermanent(filter));
this.addAbility(ability);
this.addAbility(IndestructibleAbility.getInstance()); this.addAbility(IndestructibleAbility.getInstance());
this.addAbility(new PhylacteryLichAbility()); this.addAbility(new PhylacteryLichAbility());
} }
@ -108,10 +102,11 @@ public class PhylacteryLich extends CardImpl<PhylacteryLich> {
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
for (Permanent perm: game.getBattlefield().getAllActivePermanents(controllerId)) { for (Permanent perm: game.getBattlefield().getAllActivePermanents(controllerId)) {
if (perm.getCounters().getCount("phylactery") > 0) if (perm.getCounters().getCount("phylactery") > 0)
return true;
}
return false; return false;
} }
trigger(game, controllerId);
return true;
}
@Override @Override
public String getRule() { public String getRule() {
@ -121,3 +116,49 @@ public class PhylacteryLich extends CardImpl<PhylacteryLich> {
} }
} }
class PhylacteryLichEffect extends OneShotEffect<PhylacteryLichEffect> {
private static FilterControlledPermanent filter = new FilterControlledPermanent("artifact");
static {
filter.getCardType().add(CardType.ARTIFACT);
filter.setScopeCardType(ComparisonScope.Any);
}
public PhylacteryLichEffect() {
super(Outcome.Neutral);
}
public PhylacteryLichEffect(final PhylacteryLichEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
TargetControlledPermanent target = new TargetControlledPermanent(filter);
if (target.canChoose(null, source.getControllerId(), game)) {
target.setRequired(true);
if (player.choose(Outcome.Neutral, target, game)) {
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
permanent.addCounters("phylactery", 1);
}
}
}
}
return false;
}
@Override
public PhylacteryLichEffect copy() {
return new PhylacteryLichEffect(this);
}
@Override
public String getText(Ability source) {
return "put a phylactery counter on an artifact you control";
}
}

View file

@ -131,10 +131,9 @@ class PrimalCocoonAbility2 extends TriggeredAbilityImpl<PrimalCocoonAbility2> {
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == EventType.ATTACKER_DECLARED || event.getType() == EventType.BLOCKER_DECLARED) {
Permanent enchantment = game.getPermanent(sourceId); Permanent enchantment = game.getPermanent(sourceId);
if (enchantment != null && enchantment.getAttachedTo() != null) { if (enchantment != null && enchantment.getAttachedTo() != null && event.getSourceId() != null && event.getSourceId().equals(enchantment.getAttachedTo())) {
if (event.getSourceId().equals(enchantment.getAttachedTo()) &&
(event.getType() == EventType.ATTACKER_DECLARED || event.getType() == EventType.BLOCKER_DECLARED)) {
trigger(game, event.getPlayerId()); trigger(game, event.getPlayerId());
return true; return true;
} }

View file

@ -32,8 +32,7 @@ import java.util.UUID;
import mage.Constants.CardType; import mage.Constants.CardType;
import mage.Constants.Rarity; import mage.Constants.Rarity;
import mage.MageInt; import mage.MageInt;
import mage.abilities.common.EntersBattlefieldStaticAbility; import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.effects.common.TapSourceEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
/** /**
@ -50,7 +49,7 @@ public class RottingLegion extends CardImpl<RottingLegion> {
this.power = new MageInt(4); this.power = new MageInt(4);
this.toughness = new MageInt(5); this.toughness = new MageInt(5);
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceEffect(), "tapped")); this.addAbility(EntersBattlefieldTappedAbility.getInstance());
} }
public RottingLegion(final RottingLegion card) { public RottingLegion(final RottingLegion card) {

View file

@ -34,7 +34,7 @@ import mage.Constants.Rarity;
import mage.Constants.Zone; import mage.Constants.Zone;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldStaticAbility; import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.RemoveCountersSourceCost; import mage.abilities.costs.common.RemoveCountersSourceCost;
import mage.abilities.effects.common.AddPlusOneCountersSourceEffect; import mage.abilities.effects.common.AddPlusOneCountersSourceEffect;
@ -55,7 +55,7 @@ public class Triskelion extends CardImpl<Triskelion> {
this.power = new MageInt(1); this.power = new MageInt(1);
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
this.addAbility(new EntersBattlefieldStaticAbility(new AddPlusOneCountersSourceEffect(3), "with three +1/+1 counters on it")); this.addAbility(new EntersBattlefieldAbility(new AddPlusOneCountersSourceEffect(3), "with three +1/+1 counters on it"));
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new RemoveCountersSourceCost("+1/+1", 1)); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new RemoveCountersSourceCost("+1/+1", 1));
ability.addTarget(new TargetCreatureOrPlayer()); ability.addTarget(new TargetCreatureOrPlayer());
this.addAbility(ability); this.addAbility(ability);

View file

@ -127,7 +127,7 @@ class WildEvocationEffect extends OneShotEffect<WildEvocationEffect> {
cards.add(card); cards.add(card);
player.revealCards(cards, game); player.revealCards(cards, game);
if (card.getCardType().contains(CardType.LAND)) { if (card.getCardType().contains(CardType.LAND)) {
card.putOntoBattlefield(game, Zone.HAND, player.getId()); card.putOntoBattlefield(game, Zone.HAND, source.getId(), player.getId());
} }
else { else {
player.cast(card.getSpellAbility(), game, true); player.cast(card.getSpellAbility(), game, true);

View file

@ -31,8 +31,7 @@ package mage.sets.shardsofalara;
import java.util.UUID; import java.util.UUID;
import mage.Constants.CardType; import mage.Constants.CardType;
import mage.Constants.Rarity; import mage.Constants.Rarity;
import mage.abilities.common.EntersBattlefieldStaticAbility; import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.mana.BlackManaAbility; import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.BlueManaAbility; import mage.abilities.mana.BlueManaAbility;
import mage.abilities.mana.RedManaAbility; import mage.abilities.mana.RedManaAbility;
@ -47,7 +46,7 @@ public class CrumblingNecropolis extends CardImpl<CrumblingNecropolis> {
public CrumblingNecropolis(UUID ownerId) { public CrumblingNecropolis(UUID ownerId) {
super(ownerId, 222, "Crumbling Necropolis", Rarity.UNCOMMON, new CardType[]{CardType.LAND}, null); super(ownerId, 222, "Crumbling Necropolis", Rarity.UNCOMMON, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "ALA"; this.expansionSetCode = "ALA";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceEffect(), "tapped")); this.addAbility(EntersBattlefieldTappedAbility.getInstance());
this.addAbility(new RedManaAbility()); this.addAbility(new RedManaAbility());
this.addAbility(new BlueManaAbility()); this.addAbility(new BlueManaAbility());
this.addAbility(new BlackManaAbility()); this.addAbility(new BlackManaAbility());

View file

@ -31,8 +31,7 @@ package mage.sets.shardsofalara;
import java.util.UUID; import java.util.UUID;
import mage.Constants.CardType; import mage.Constants.CardType;
import mage.Constants.Rarity; import mage.Constants.Rarity;
import mage.abilities.common.EntersBattlefieldStaticAbility; import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.mana.BlackManaAbility; import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.GreenManaAbility; import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.RedManaAbility; import mage.abilities.mana.RedManaAbility;
@ -47,7 +46,7 @@ public class SavageLands extends CardImpl<SavageLands> {
public SavageLands(UUID ownerId) { public SavageLands(UUID ownerId) {
super(ownerId, 228, "Savage Lands", Rarity.UNCOMMON, new CardType[]{CardType.LAND}, null); super(ownerId, 228, "Savage Lands", Rarity.UNCOMMON, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "ALA"; this.expansionSetCode = "ALA";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceEffect(), "tapped")); this.addAbility(EntersBattlefieldTappedAbility.getInstance());
this.addAbility(new RedManaAbility()); this.addAbility(new RedManaAbility());
this.addAbility(new GreenManaAbility()); this.addAbility(new GreenManaAbility());
this.addAbility(new BlackManaAbility()); this.addAbility(new BlackManaAbility());

View file

@ -33,11 +33,10 @@ import mage.Constants.CardType;
import mage.Constants.Rarity; import mage.Constants.Rarity;
import mage.Constants.Zone; import mage.Constants.Zone;
import mage.MageInt; import mage.MageInt;
import mage.abilities.common.EntersBattlefieldStaticAbility; import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.BecomesCreatureSourceEOTEffect; import mage.abilities.effects.common.BecomesCreatureSourceEOTEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.VigilanceAbility; import mage.abilities.keyword.VigilanceAbility;
import mage.abilities.mana.BlueManaAbility; import mage.abilities.mana.BlueManaAbility;
@ -54,7 +53,7 @@ public class CelestialColonnade extends CardImpl<CelestialColonnade> {
public CelestialColonnade(UUID ownerId) { public CelestialColonnade(UUID ownerId) {
super(ownerId, 133, "Celestial Colonnade", Rarity.RARE, new CardType[]{CardType.LAND}, null); super(ownerId, 133, "Celestial Colonnade", Rarity.RARE, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "WWK"; this.expansionSetCode = "WWK";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceEffect(), "tapped")); this.addAbility(EntersBattlefieldTappedAbility.getInstance());
this.addAbility(new BlueManaAbility()); this.addAbility(new BlueManaAbility());
this.addAbility(new WhiteManaAbility()); this.addAbility(new WhiteManaAbility());
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEOTEffect(new CelestialColonnadeToken(), "land"), new ManaCostsImpl("{3}{W}{U}"))); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEOTEffect(new CelestialColonnadeToken(), "land"), new ManaCostsImpl("{3}{W}{U}")));

View file

@ -32,10 +32,9 @@ import java.util.UUID;
import mage.Constants.CardType; import mage.Constants.CardType;
import mage.Constants.Rarity; import mage.Constants.Rarity;
import mage.MageInt; import mage.MageInt;
import mage.abilities.common.EntersBattlefieldStaticAbility; import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.mana.GreenManaAbility; import mage.abilities.mana.GreenManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.game.permanent.token.Token; import mage.game.permanent.token.Token;
@ -49,7 +48,7 @@ public class KhalniGarden extends CardImpl<KhalniGarden> {
public KhalniGarden(UUID ownerId) { public KhalniGarden(UUID ownerId) {
super(ownerId, 138, "Khalni Garden", Rarity.COMMON, new CardType[]{CardType.LAND}, null); super(ownerId, 138, "Khalni Garden", Rarity.COMMON, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "WWK"; this.expansionSetCode = "WWK";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceEffect(), "tapped")); this.addAbility(EntersBattlefieldTappedAbility.getInstance());
this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new PlantToken()), false)); this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new PlantToken()), false));
this.addAbility(new GreenManaAbility()); this.addAbility(new GreenManaAbility());
} }

View file

@ -34,12 +34,11 @@ import mage.Constants.Duration;
import mage.Constants.Rarity; import mage.Constants.Rarity;
import mage.Constants.Zone; import mage.Constants.Zone;
import mage.MageInt; import mage.MageInt;
import mage.abilities.common.EntersBattlefieldStaticAbility; import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.BecomesCreatureSourceEOTEffect; import mage.abilities.effects.common.BecomesCreatureSourceEOTEffect;
import mage.abilities.effects.common.BoostPowerXSourceEffect; import mage.abilities.effects.common.BoostPowerXSourceEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.mana.BlackManaAbility; import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.RedManaAbility; import mage.abilities.mana.RedManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -54,7 +53,7 @@ public class LavaclawReaches extends CardImpl<LavaclawReaches> {
public LavaclawReaches(UUID ownerId) { public LavaclawReaches(UUID ownerId) {
super(ownerId, 139, "Lavaclaw Reaches", Rarity.RARE, new CardType[]{CardType.LAND}, null); super(ownerId, 139, "Lavaclaw Reaches", Rarity.RARE, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "WWK"; this.expansionSetCode = "WWK";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceEffect(), "tapped")); this.addAbility(EntersBattlefieldTappedAbility.getInstance());
this.addAbility(new BlackManaAbility()); this.addAbility(new BlackManaAbility());
this.addAbility(new RedManaAbility()); this.addAbility(new RedManaAbility());
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEOTEffect(new LavaclawReachesToken(), "land"), new ManaCostsImpl("{1}{B}{R}"))); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEOTEffect(new LavaclawReachesToken(), "land"), new ManaCostsImpl("{1}{B}{R}")));

View file

@ -34,12 +34,11 @@ import mage.Constants.Rarity;
import mage.Constants.Zone; import mage.Constants.Zone;
import mage.MageInt; import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.EntersBattlefieldStaticAbility; import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.AddPlusOneCountersSourceEffect; import mage.abilities.effects.common.AddPlusOneCountersSourceEffect;
import mage.abilities.effects.common.BecomesCreatureSourceEOTEffect; import mage.abilities.effects.common.BecomesCreatureSourceEOTEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.mana.GreenManaAbility; import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.RedManaAbility; import mage.abilities.mana.RedManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -54,7 +53,7 @@ public class RagingRavine extends CardImpl<RagingRavine> {
public RagingRavine(UUID ownerId) { public RagingRavine(UUID ownerId) {
super(ownerId, 141, "Raging Ravine", Rarity.RARE, new CardType[]{CardType.LAND}, null); super(ownerId, 141, "Raging Ravine", Rarity.RARE, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "WWK"; this.expansionSetCode = "WWK";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceEffect(), "tapped")); this.addAbility(EntersBattlefieldTappedAbility.getInstance());
this.addAbility(new GreenManaAbility()); this.addAbility(new GreenManaAbility());
this.addAbility(new RedManaAbility()); this.addAbility(new RedManaAbility());
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEOTEffect(new RagingRavineToken(), "land"), new ManaCostsImpl("{2}{R}{G}"))); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEOTEffect(new RagingRavineToken(), "land"), new ManaCostsImpl("{2}{R}{G}")));

View file

@ -32,10 +32,9 @@ import java.util.UUID;
import mage.Constants.CardType; import mage.Constants.CardType;
import mage.Constants.Duration; import mage.Constants.Duration;
import mage.Constants.Rarity; import mage.Constants.Rarity;
import mage.abilities.common.EntersBattlefieldStaticAbility; import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.GainProtectionFromColorTargetEffect; import mage.abilities.effects.common.GainProtectionFromColorTargetEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.mana.WhiteManaAbility; import mage.abilities.mana.WhiteManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.choices.ChoiceColor; import mage.choices.ChoiceColor;
@ -50,7 +49,7 @@ public class SejiriSteppe extends CardImpl<SejiriSteppe> {
public SejiriSteppe(UUID ownerId) { public SejiriSteppe(UUID ownerId) {
super(ownerId, 142, "Sejiri Steppe", Rarity.COMMON, new CardType[]{CardType.LAND}, null); super(ownerId, 142, "Sejiri Steppe", Rarity.COMMON, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "WWK"; this.expansionSetCode = "WWK";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceEffect(), "tapped")); this.addAbility(EntersBattlefieldTappedAbility.getInstance());
EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new GainProtectionFromColorTargetEffect(Duration.EndOfTurn), false); EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new GainProtectionFromColorTargetEffect(Duration.EndOfTurn), false);
ability.addTarget(new TargetControlledCreaturePermanent()); ability.addTarget(new TargetControlledCreaturePermanent());
ability.addChoice(new ChoiceColor()); ability.addChoice(new ChoiceColor());

View file

@ -33,11 +33,10 @@ import mage.Constants.CardType;
import mage.Constants.Rarity; import mage.Constants.Rarity;
import mage.Constants.Zone; import mage.Constants.Zone;
import mage.MageInt; import mage.MageInt;
import mage.abilities.common.EntersBattlefieldStaticAbility; import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.BecomesCreatureSourceEOTEffect; import mage.abilities.effects.common.BecomesCreatureSourceEOTEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.keyword.ReachAbility; import mage.abilities.keyword.ReachAbility;
import mage.abilities.mana.GreenManaAbility; import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.WhiteManaAbility; import mage.abilities.mana.WhiteManaAbility;
@ -53,7 +52,7 @@ public class StirringWildwood extends CardImpl<StirringWildwood> {
public StirringWildwood(UUID ownerId) { public StirringWildwood(UUID ownerId) {
super(ownerId, 144, "Stirring Wildwood", Rarity.RARE, new CardType[]{CardType.LAND}, null); super(ownerId, 144, "Stirring Wildwood", Rarity.RARE, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "WWK"; this.expansionSetCode = "WWK";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceEffect(), "tapped")); this.addAbility(EntersBattlefieldTappedAbility.getInstance());
this.addAbility(new GreenManaAbility()); this.addAbility(new GreenManaAbility());
this.addAbility(new WhiteManaAbility()); this.addAbility(new WhiteManaAbility());
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEOTEffect(new StirringWildwoodToken(), "land"), new ManaCostsImpl("{1}{G}{W}"))); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEOTEffect(new StirringWildwoodToken(), "land"), new ManaCostsImpl("{1}{G}{W}")));

View file

@ -31,10 +31,9 @@ package mage.sets.zendikar;
import java.util.UUID; import java.util.UUID;
import mage.Constants.CardType; import mage.Constants.CardType;
import mage.Constants.Rarity; import mage.Constants.Rarity;
import mage.abilities.common.EntersBattlefieldStaticAbility; import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.mana.WhiteManaAbility; import mage.abilities.mana.WhiteManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -47,7 +46,7 @@ public class KabiraCrossroads extends CardImpl<KabiraCrossroads> {
public KabiraCrossroads(UUID ownerId) { public KabiraCrossroads(UUID ownerId) {
super(ownerId, 216, "Kabira Crossroads", Rarity.COMMON, new CardType[]{CardType.LAND}, null); super(ownerId, 216, "Kabira Crossroads", Rarity.COMMON, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "ZEN"; this.expansionSetCode = "ZEN";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceEffect(), "tapped")); this.addAbility(EntersBattlefieldTappedAbility.getInstance());
this.addAbility(new EntersBattlefieldTriggeredAbility(new GainLifeEffect(2), false)); this.addAbility(new EntersBattlefieldTriggeredAbility(new GainLifeEffect(2), false));
this.addAbility(new WhiteManaAbility()); this.addAbility(new WhiteManaAbility());
} }

View file

@ -34,11 +34,10 @@ import mage.Constants.Outcome;
import mage.Constants.Rarity; import mage.Constants.Rarity;
import mage.Constants.Zone; import mage.Constants.Zone;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldStaticAbility; import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.mana.GreenManaAbility; import mage.abilities.mana.GreenManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.counters.PlusOneCounter; import mage.counters.PlusOneCounter;
@ -55,7 +54,7 @@ public class OranRiefTheVastwood extends CardImpl<OranRiefTheVastwood> {
public OranRiefTheVastwood(UUID ownerId) { public OranRiefTheVastwood(UUID ownerId) {
super(ownerId, 221, "Oran-Rief, the Vastwood", Rarity.RARE, new CardType[]{CardType.LAND}, null); super(ownerId, 221, "Oran-Rief, the Vastwood", Rarity.RARE, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "ZEN"; this.expansionSetCode = "ZEN";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceEffect(), "tapped")); this.addAbility(EntersBattlefieldTappedAbility.getInstance());
this.addAbility(new GreenManaAbility()); this.addAbility(new GreenManaAbility());
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new OranRiefTheVastwoodEffect(), new TapSourceCost())); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new OranRiefTheVastwoodEffect(), new TapSourceCost()));
} }

View file

@ -33,10 +33,9 @@ import mage.Constants.CardType;
import mage.Constants.Duration; import mage.Constants.Duration;
import mage.Constants.Rarity; import mage.Constants.Rarity;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldStaticAbility; import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.BoostTargetEffect; import mage.abilities.effects.common.BoostTargetEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.mana.RedManaAbility; import mage.abilities.mana.RedManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
@ -50,7 +49,7 @@ public class TeeteringPeaks extends CardImpl<TeeteringPeaks> {
public TeeteringPeaks(UUID ownerId) { public TeeteringPeaks(UUID ownerId) {
super(ownerId, 226, "Teetering Peaks", Rarity.COMMON, new CardType[]{CardType.LAND}, null); super(ownerId, 226, "Teetering Peaks", Rarity.COMMON, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "ZEN"; this.expansionSetCode = "ZEN";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceEffect(), "tapped")); this.addAbility(EntersBattlefieldTappedAbility.getInstance());
Ability ability = new EntersBattlefieldTriggeredAbility(new BoostTargetEffect(2, 0, Duration.EndOfTurn), false); Ability ability = new EntersBattlefieldTriggeredAbility(new BoostTargetEffect(2, 0, Duration.EndOfTurn), false);
ability.addTarget(new TargetCreaturePermanent()); ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability); this.addAbility(ability);

View file

@ -177,14 +177,14 @@ public class AbilitiesImpl<T extends Ability> extends ArrayList<T> implements Ab
for (T ability: abilities) { for (T ability: abilities) {
boolean found = false; boolean found = false;
for (T test: this) { for (T test: this) {
if (ability.getRule().equals(test.getRule())) { if (ability.getId().equals(test.getId()) || ability.getRule().equals(test.getRule())) {
found = true; found = true;
break; break;
} }
}
if (!found) if (!found)
return false; return false;
} }
}
return true; return true;
} }

View file

@ -39,22 +39,22 @@ import mage.game.Game;
*/ */
public abstract class StateTriggeredAbility<T extends StateTriggeredAbility<T>> extends TriggeredAbilityImpl<T> { public abstract class StateTriggeredAbility<T extends StateTriggeredAbility<T>> extends TriggeredAbilityImpl<T> {
protected boolean triggered;
public StateTriggeredAbility(Zone zone, Effect effect) { public StateTriggeredAbility(Zone zone, Effect effect) {
super(zone, effect); super(zone, effect);
} }
public StateTriggeredAbility(final StateTriggeredAbility ability) { public StateTriggeredAbility(final StateTriggeredAbility ability) {
super(ability); super(ability);
this.triggered = ability.triggered;
} }
@Override @Override
public void trigger(Game game, UUID controllerId) { public void trigger(Game game, UUID controllerId) {
//20100716 - 603.8 //20100716 - 603.8
Boolean triggered = (Boolean) game.getState().getValue(this.id.toString() + "triggered");
if (triggered == null)
triggered = Boolean.FALSE;
if (!triggered) { if (!triggered) {
triggered = true; game.getState().setValue(this.id.toString() + "triggered", Boolean.TRUE);
super.trigger(game, controllerId); super.trigger(game, controllerId);
} }
} }
@ -62,11 +62,11 @@ public abstract class StateTriggeredAbility<T extends StateTriggeredAbility<T>>
@Override @Override
public boolean resolve(Game game) { public boolean resolve(Game game) {
//20100716 - 603.8 //20100716 - 603.8
triggered = false; game.getState().setValue(this.id.toString() + "triggered", Boolean.FALSE);
return super.resolve(game); return super.resolve(game);
} }
public void counter() { public void counter(Game game) {
triggered = false; game.getState().setValue(this.id.toString() + "triggered", Boolean.FALSE);
} }
} }

View file

@ -31,33 +31,25 @@ package mage.abilities.common;
import mage.Constants.Zone; import mage.Constants.Zone;
import mage.abilities.StaticAbility; import mage.abilities.StaticAbility;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.EntersBattlefieldEffect;
/** /**
* *
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class EntersBattlefieldStaticAbility extends StaticAbility<EntersBattlefieldStaticAbility> { public class EntersBattlefieldAbility extends StaticAbility<EntersBattlefieldAbility> {
protected String rule; public EntersBattlefieldAbility(Effect effect, String rule) {
super(Zone.BATTLEFIELD, new EntersBattlefieldEffect(effect, rule));
public EntersBattlefieldStaticAbility(Effect effect, String rule) {
super(Zone.BATTLEFIELD, effect);
this.rule = rule;
} }
public EntersBattlefieldStaticAbility(EntersBattlefieldStaticAbility ability) { public EntersBattlefieldAbility(EntersBattlefieldAbility ability) {
super(ability); super(ability);
this.rule = ability.rule;
} }
@Override @Override
public EntersBattlefieldStaticAbility copy() { public EntersBattlefieldAbility copy() {
return new EntersBattlefieldStaticAbility(this); return new EntersBattlefieldAbility(this);
}
@Override
public String getRule() {
return "{this} enters the battlefield " + rule + ".";
} }
} }

View file

@ -0,0 +1,67 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 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
* provided with the distribution.
*
* 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
* 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
* 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
* 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
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities.common;
import java.io.ObjectStreamException;
import mage.Constants.Zone;
import mage.abilities.StaticAbility;
import mage.abilities.effects.EntersBattlefieldEffect;
import mage.abilities.effects.common.TapSourceEffect;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class EntersBattlefieldTappedAbility extends StaticAbility<EntersBattlefieldTappedAbility> {
private static final EntersBattlefieldTappedAbility fINSTANCE = new EntersBattlefieldTappedAbility();
private Object readResolve() throws ObjectStreamException {
return fINSTANCE;
}
public static EntersBattlefieldTappedAbility getInstance() {
return fINSTANCE;
}
private EntersBattlefieldTappedAbility() {
super(Zone.BATTLEFIELD, new EntersBattlefieldEffect(new TapSourceEffect()));
}
@Override
public String getRule() {
return "{this} enters the battlefield tapped";
}
@Override
public EntersBattlefieldTappedAbility copy() {
return fINSTANCE;
}
}

View file

@ -64,7 +64,7 @@ public class ContinuousEffects implements Serializable {
private final List<AsThoughEffect> asThoughEffects = new ArrayList<AsThoughEffect>(); private final List<AsThoughEffect> asThoughEffects = new ArrayList<AsThoughEffect>();
//map Abilities to Continuous effects //map Abilities to Continuous effects
private final Map<ContinuousEffect, Ability> abilityMap = new HashMap<ContinuousEffect, Ability>(); private final Map<UUID, Ability> abilityMap = new HashMap<UUID, Ability>();
private final ApplyCountersEffect applyCounters; private final ApplyCountersEffect applyCounters;
private final PlaneswalkerRedirectionEffect planeswalkerRedirectionEffect; private final PlaneswalkerRedirectionEffect planeswalkerRedirectionEffect;
@ -89,8 +89,8 @@ public class ContinuousEffects implements Serializable {
for (AsThoughEffect entry: effect.asThoughEffects) { for (AsThoughEffect entry: effect.asThoughEffects) {
asThoughEffects.add((AsThoughEffect)entry.copy()); asThoughEffects.add((AsThoughEffect)entry.copy());
} }
for (Entry<ContinuousEffect, Ability> entry: effect.abilityMap.entrySet()) { for (Entry<UUID, Ability> entry: effect.abilityMap.entrySet()) {
abilityMap.put((ContinuousEffect)entry.getKey().copy(), entry.getValue().copy()); abilityMap.put(entry.getKey(), entry.getValue().copy());
} }
} }
@ -125,7 +125,7 @@ public class ContinuousEffects implements Serializable {
for (Iterator<ContinuousEffect> i = layeredEffects.iterator(); i.hasNext();) { for (Iterator<ContinuousEffect> i = layeredEffects.iterator(); i.hasNext();) {
ContinuousEffect entry = i.next(); ContinuousEffect entry = i.next();
if (entry.getDuration() == Duration.WhileOnBattlefield) { if (entry.getDuration() == Duration.WhileOnBattlefield) {
Permanent permanent = game.getPermanent(abilityMap.get(entry).getSourceId()); Permanent permanent = game.getPermanent(abilityMap.get(entry.getId()).getSourceId());
if (permanent == null || !permanent.isPhasedIn()) if (permanent == null || !permanent.isPhasedIn())
i.remove(); i.remove();
} }
@ -135,7 +135,7 @@ public class ContinuousEffects implements Serializable {
for (Iterator<ReplacementEffect> i = replacementEffects.iterator(); i.hasNext();) { for (Iterator<ReplacementEffect> i = replacementEffects.iterator(); i.hasNext();) {
ReplacementEffect entry = i.next(); ReplacementEffect entry = i.next();
if (entry.getDuration() == Duration.WhileOnBattlefield) { if (entry.getDuration() == Duration.WhileOnBattlefield) {
Permanent permanent = game.getPermanent(abilityMap.get(entry).getSourceId()); Permanent permanent = game.getPermanent(abilityMap.get(entry.getId()).getSourceId());
if (permanent == null || !permanent.isPhasedIn()) if (permanent == null || !permanent.isPhasedIn())
i.remove(); i.remove();
} }
@ -145,7 +145,7 @@ public class ContinuousEffects implements Serializable {
for (Iterator<PreventionEffect> i = preventionEffects.iterator(); i.hasNext();) { for (Iterator<PreventionEffect> i = preventionEffects.iterator(); i.hasNext();) {
PreventionEffect entry = i.next(); PreventionEffect entry = i.next();
if (entry.getDuration() == Duration.WhileOnBattlefield) { if (entry.getDuration() == Duration.WhileOnBattlefield) {
Permanent permanent = game.getPermanent(abilityMap.get(entry).getSourceId()); Permanent permanent = game.getPermanent(abilityMap.get(entry.getId()).getSourceId());
if (permanent == null || !permanent.isPhasedIn()) if (permanent == null || !permanent.isPhasedIn())
i.remove(); i.remove();
} }
@ -155,7 +155,7 @@ public class ContinuousEffects implements Serializable {
for (Iterator<AsThoughEffect> i = asThoughEffects.iterator(); i.hasNext();) { for (Iterator<AsThoughEffect> i = asThoughEffects.iterator(); i.hasNext();) {
AsThoughEffect entry = i.next(); AsThoughEffect entry = i.next();
if (entry.getDuration() == Duration.WhileOnBattlefield) { if (entry.getDuration() == Duration.WhileOnBattlefield) {
Permanent permanent = game.getPermanent(abilityMap.get(entry).getSourceId()); Permanent permanent = game.getPermanent(abilityMap.get(entry.getId()).getSourceId());
if (permanent == null || !permanent.isPhasedIn()) if (permanent == null || !permanent.isPhasedIn())
i.remove(); i.remove();
} }
@ -171,7 +171,7 @@ public class ContinuousEffects implements Serializable {
for (Ability ability: card.getAbilities().getStaticAbilities(game.getZone(card.getId()))) { for (Ability ability: card.getAbilities().getStaticAbilities(game.getZone(card.getId()))) {
for (Effect effect: ability.getEffects(EffectType.CONTINUOUS)) { for (Effect effect: ability.getEffects(EffectType.CONTINUOUS)) {
layerEffects.add((ContinuousEffect) effect); layerEffects.add((ContinuousEffect) effect);
abilityMap.put((ContinuousEffect) effect, ability); abilityMap.put(effect.getId(), ability);
} }
} }
} }
@ -180,7 +180,7 @@ public class ContinuousEffects implements Serializable {
for (Ability ability: permanent.getAbilities().getStaticAbilities(Zone.BATTLEFIELD)) { for (Ability ability: permanent.getAbilities().getStaticAbilities(Zone.BATTLEFIELD)) {
for (Effect effect: ability.getEffects(EffectType.CONTINUOUS)) { for (Effect effect: ability.getEffects(EffectType.CONTINUOUS)) {
layerEffects.add((ContinuousEffect) effect); layerEffects.add((ContinuousEffect) effect);
abilityMap.put((ContinuousEffect) effect, ability); abilityMap.put(effect.getId(), ability);
} }
} }
} }
@ -188,6 +188,15 @@ public class ContinuousEffects implements Serializable {
return layerEffects; return layerEffects;
} }
private List<ContinuousEffect> filterLayeredEffects(List<ContinuousEffect> effects, Layer layer) {
List<ContinuousEffect> layerEffects = new ArrayList<ContinuousEffect>();
for (ContinuousEffect effect: effects) {
if (effect.hasLayer(layer))
layerEffects.add(effect);
}
return layerEffects;
}
/** /**
* *
* @param event * @param event
@ -206,7 +215,14 @@ public class ContinuousEffects implements Serializable {
ReplacementEffect rEffect = (ReplacementEffect) effect; ReplacementEffect rEffect = (ReplacementEffect) effect;
if (rEffect.applies(event, ability, game)) { if (rEffect.applies(event, ability, game)) {
replaceEffects.add(rEffect); replaceEffects.add(rEffect);
abilityMap.put(rEffect, ability); abilityMap.put(rEffect.getId(), ability);
}
}
for (Effect effect: ability.getEffects(EffectType.PREVENTION)) {
ReplacementEffect rEffect = (ReplacementEffect) effect;
if (rEffect.applies(event, ability, game)) {
replaceEffects.add(rEffect);
abilityMap.put(rEffect.getId(), ability);
} }
} }
} }
@ -219,7 +235,14 @@ public class ContinuousEffects implements Serializable {
ReplacementEffect rEffect = (ReplacementEffect) effect; ReplacementEffect rEffect = (ReplacementEffect) effect;
if (rEffect.applies(event, ability, game)) { if (rEffect.applies(event, ability, game)) {
replaceEffects.add(rEffect); replaceEffects.add(rEffect);
abilityMap.put(rEffect, ability); abilityMap.put(rEffect.getId(), ability);
}
}
for (Effect effect: ability.getEffects(EffectType.PREVENTION)) {
ReplacementEffect rEffect = (ReplacementEffect) effect;
if (rEffect.applies(event, ability, game)) {
replaceEffects.add(rEffect);
abilityMap.put(rEffect.getId(), ability);
} }
} }
} }
@ -227,7 +250,14 @@ public class ContinuousEffects implements Serializable {
//get all applicable transient Replacement effects //get all applicable transient Replacement effects
for (ReplacementEffect effect: replacementEffects) { for (ReplacementEffect effect: replacementEffects) {
if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) { if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) {
if (effect.applies(event, abilityMap.get(effect), game)) { if (effect.applies(event, abilityMap.get(effect.getId()), game)) {
replaceEffects.add(effect);
}
}
}
for (PreventionEffect effect: preventionEffects) {
if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) {
if (effect.applies(event, abilityMap.get(effect.getId()), game)) {
replaceEffects.add(effect); replaceEffects.add(effect);
} }
} }
@ -250,7 +280,7 @@ public class ContinuousEffects implements Serializable {
AsThoughEffect effect = entry; AsThoughEffect effect = entry;
if (effect.getAsThoughEffectType() == type) { if (effect.getAsThoughEffectType() == type) {
if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) { if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) {
if (effect.applies(objectId, abilityMap.get(entry), game)) { if (effect.applies(objectId, abilityMap.get(entry.getId()), game)) {
return true; return true;
} }
} }
@ -273,7 +303,7 @@ public class ContinuousEffects implements Serializable {
index = player.chooseEffect(rEffects, game); index = player.chooseEffect(rEffects, game);
} }
ReplacementEffect rEffect = rEffects.get(index); ReplacementEffect rEffect = rEffects.get(index);
caught = rEffect.replaceEvent(event, abilityMap.get(rEffect), game); caught = rEffect.replaceEvent(event, abilityMap.get(rEffect.getId()), game);
} }
return caught; return caught;
@ -283,60 +313,69 @@ public class ContinuousEffects implements Serializable {
public void apply(Game game) { public void apply(Game game) {
removeInactiveEffects(game); removeInactiveEffects(game);
List<ContinuousEffect> layerEffects = getLayeredEffects(game); List<ContinuousEffect> layerEffects = getLayeredEffects(game);
for (ContinuousEffect effect: layerEffects) { List<ContinuousEffect> layer = filterLayeredEffects(layerEffects, Layer.CopyEffects_1);
effect.apply(Layer.CopyEffects_1, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect), game); for (ContinuousEffect effect: layer) {
effect.apply(Layer.CopyEffects_1, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect.getId()), game);
} }
for (ContinuousEffect effect: layerEffects) { for (ContinuousEffect effect: layer) {
effect.apply(Layer.CopyEffects_1, SubLayer.NA, abilityMap.get(effect), game); effect.apply(Layer.CopyEffects_1, SubLayer.NA, abilityMap.get(effect.getId()), game);
} }
for (ContinuousEffect effect: layerEffects) { layer = filterLayeredEffects(layerEffects, Layer.ControlChangingEffects_2);
effect.apply(Layer.ControlChangingEffects_2, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect), game); for (ContinuousEffect effect: layer) {
effect.apply(Layer.ControlChangingEffects_2, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect.getId()), game);
} }
for (ContinuousEffect effect: layerEffects) { for (ContinuousEffect effect: layer) {
effect.apply(Layer.ControlChangingEffects_2, SubLayer.NA, abilityMap.get(effect), game); effect.apply(Layer.ControlChangingEffects_2, SubLayer.NA, abilityMap.get(effect.getId()), game);
} }
for (ContinuousEffect effect: layerEffects) { layer = filterLayeredEffects(layerEffects, Layer.TextChangingEffects_3);
effect.apply(Layer.TextChangingEffects_3, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect), game); for (ContinuousEffect effect: layer) {
effect.apply(Layer.TextChangingEffects_3, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect.getId()), game);
} }
for (ContinuousEffect effect: layerEffects) { for (ContinuousEffect effect: layer) {
effect.apply(Layer.TextChangingEffects_3, SubLayer.NA, abilityMap.get(effect), game); effect.apply(Layer.TextChangingEffects_3, SubLayer.NA, abilityMap.get(effect.getId()), game);
} }
for (ContinuousEffect effect: layerEffects) { layer = filterLayeredEffects(layerEffects, Layer.TypeChangingEffects_4);
effect.apply(Layer.TypeChangingEffects_4, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect), game); for (ContinuousEffect effect: layer) {
effect.apply(Layer.TypeChangingEffects_4, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect.getId()), game);
} }
for (ContinuousEffect effect: layerEffects) { for (ContinuousEffect effect: layer) {
effect.apply(Layer.TypeChangingEffects_4, SubLayer.NA, abilityMap.get(effect), game); effect.apply(Layer.TypeChangingEffects_4, SubLayer.NA, abilityMap.get(effect.getId()), game);
} }
for (ContinuousEffect effect: layerEffects) { layer = filterLayeredEffects(layerEffects, Layer.ColorChangingEffects_5);
effect.apply(Layer.ColorChangingEffects_5, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect), game); for (ContinuousEffect effect: layer) {
effect.apply(Layer.ColorChangingEffects_5, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect.getId()), game);
} }
for (ContinuousEffect effect: layerEffects) { for (ContinuousEffect effect: layer) {
effect.apply(Layer.ColorChangingEffects_5, SubLayer.NA, abilityMap.get(effect), game); effect.apply(Layer.ColorChangingEffects_5, SubLayer.NA, abilityMap.get(effect.getId()), game);
} }
for (ContinuousEffect effect: layerEffects) { layer = filterLayeredEffects(layerEffects, Layer.AbilityAddingRemovingEffects_6);
effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect), game); for (ContinuousEffect effect: layer) {
effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect.getId()), game);
} }
for (ContinuousEffect effect: layerEffects) { for (ContinuousEffect effect: layer) {
effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, abilityMap.get(effect), game); effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, abilityMap.get(effect.getId()), game);
} }
for (ContinuousEffect effect: layerEffects) { layer = filterLayeredEffects(layerEffects, Layer.PTChangingEffects_7);
effect.apply(Layer.PTChangingEffects_7, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect), game); for (ContinuousEffect effect: layer) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect.getId()), game);
} }
for (ContinuousEffect effect: layerEffects) { for (ContinuousEffect effect: layer) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.SetPT_7b, abilityMap.get(effect), game); effect.apply(Layer.PTChangingEffects_7, SubLayer.SetPT_7b, abilityMap.get(effect.getId()), game);
} }
for (ContinuousEffect effect: layerEffects) { for (ContinuousEffect effect: layer) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, abilityMap.get(effect), game); effect.apply(Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, abilityMap.get(effect.getId()), game);
} }
applyCounters.apply(Layer.PTChangingEffects_7, SubLayer.Counters_7d, null, game); applyCounters.apply(Layer.PTChangingEffects_7, SubLayer.Counters_7d, null, game);
for (ContinuousEffect effect: layerEffects) { for (ContinuousEffect effect: layer) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.SwitchPT_e, abilityMap.get(effect), game); effect.apply(Layer.PTChangingEffects_7, SubLayer.SwitchPT_e, abilityMap.get(effect.getId()), game);
} }
for (ContinuousEffect effect: layerEffects) { layer = filterLayeredEffects(layerEffects, Layer.PlayerEffects);
effect.apply(Layer.PlayerEffects, SubLayer.NA, abilityMap.get(effect), game); for (ContinuousEffect effect: layer) {
effect.apply(Layer.PlayerEffects, SubLayer.NA, abilityMap.get(effect.getId()), game);
} }
for (ContinuousEffect effect: layerEffects) { layer = filterLayeredEffects(layerEffects, Layer.RulesEffects);
effect.apply(Layer.RulesEffects, SubLayer.NA, abilityMap.get(effect), game); for (ContinuousEffect effect: layer) {
effect.apply(Layer.RulesEffects, SubLayer.NA, abilityMap.get(effect.getId()), game);
} }
} }
@ -346,25 +385,25 @@ public class ContinuousEffects implements Serializable {
ReplacementEffect newReplacementEffect = (ReplacementEffect)effect.copy(); ReplacementEffect newReplacementEffect = (ReplacementEffect)effect.copy();
newReplacementEffect.setTimestamp(); newReplacementEffect.setTimestamp();
replacementEffects.add(newReplacementEffect); replacementEffects.add(newReplacementEffect);
abilityMap.put(newReplacementEffect, source); abilityMap.put(newReplacementEffect.getId(), source);
break; break;
case PREVENTION: case PREVENTION:
PreventionEffect newPreventionEffect = (PreventionEffect)effect.copy(); PreventionEffect newPreventionEffect = (PreventionEffect)effect.copy();
newPreventionEffect.setTimestamp(); newPreventionEffect.setTimestamp();
preventionEffects.add(newPreventionEffect); preventionEffects.add(newPreventionEffect);
abilityMap.put(newPreventionEffect, source); abilityMap.put(newPreventionEffect.getId(), source);
break; break;
case ASTHOUGH: case ASTHOUGH:
AsThoughEffect newAsThoughEffect = (AsThoughEffect)effect.copy(); AsThoughEffect newAsThoughEffect = (AsThoughEffect)effect.copy();
newAsThoughEffect.setTimestamp(); newAsThoughEffect.setTimestamp();
asThoughEffects.add(newAsThoughEffect); asThoughEffects.add(newAsThoughEffect);
abilityMap.put(newAsThoughEffect, source); abilityMap.put(newAsThoughEffect.getId(), source);
break; break;
default: default:
ContinuousEffect newEffect = (ContinuousEffect)effect.copy(); ContinuousEffect newEffect = (ContinuousEffect)effect.copy();
newEffect.setTimestamp(); newEffect.setTimestamp();
layeredEffects.add(newEffect); layeredEffects.add(newEffect);
abilityMap.put(newEffect, source); abilityMap.put(newEffect.getId(), source);
break; break;
} }
} }

View file

@ -29,6 +29,7 @@
package mage.abilities.effects; package mage.abilities.effects;
import java.io.Serializable; import java.io.Serializable;
import java.util.UUID;
import mage.Constants.EffectType; import mage.Constants.EffectType;
import mage.Constants.Outcome; import mage.Constants.Outcome;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -40,6 +41,7 @@ import mage.game.Game;
*/ */
public interface Effect<T extends Effect<T>> extends Serializable { public interface Effect<T extends Effect<T>> extends Serializable {
public UUID getId();
public String getText(Ability source); public String getText(Ability source);
public boolean apply(Game game, Ability source); public boolean apply(Game game, Ability source);
public Outcome getOutcome(); public Outcome getOutcome();

View file

@ -28,6 +28,7 @@
package mage.abilities.effects; package mage.abilities.effects;
import java.util.UUID;
import mage.Constants.EffectType; import mage.Constants.EffectType;
import mage.Constants.Outcome; import mage.Constants.Outcome;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -38,18 +39,26 @@ import mage.abilities.Ability;
*/ */
public abstract class EffectImpl<T extends Effect<T>> implements Effect<T> { public abstract class EffectImpl<T extends Effect<T>> implements Effect<T> {
protected final UUID id;
protected final Outcome outcome; protected final Outcome outcome;
protected EffectType effectType; protected EffectType effectType;
public EffectImpl(Outcome outcome) { public EffectImpl(Outcome outcome) {
this.id = UUID.randomUUID();
this.outcome = outcome; this.outcome = outcome;
} }
public EffectImpl(final EffectImpl effect) { public EffectImpl(final EffectImpl effect) {
this.id = effect.id;
this.outcome = effect.outcome; this.outcome = effect.outcome;
this.effectType = effect.effectType; this.effectType = effect.effectType;
} }
@Override
public UUID getId() {
return id;
}
@Override @Override
public String getText(Ability source) { public String getText(Ability source) {
return ""; return "";

View file

@ -1,96 +1,109 @@
///* /*
//* 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.effects; package mage.abilities.effects;
//
//import mage.Constants.Duration; import mage.Constants.Duration;
//import mage.Constants.Layer; import mage.abilities.Ability;
//import mage.Constants.SubLayer; import mage.game.Game;
//import mage.Constants.Zone; import mage.game.events.GameEvent;
//import mage.abilities.Ability; import mage.game.events.GameEvent.EventType;
//import mage.game.Game; import mage.game.stack.Spell;
//import mage.game.events.GameEvent; import mage.game.stack.StackObject;
//import mage.game.events.GameEvent.EventType;
//import mage.game.events.ZoneChangeEvent; /**
// *
///** * @author BetaSteward_at_googlemail.com
// * */
// * @author BetaSteward_at_googlemail.com public class EntersBattlefieldEffect extends ReplacementEffectImpl<EntersBattlefieldEffect> {
// */
//public class EntersBattlefieldEffect extends ReplacementEffectImpl<EntersBattlefieldEffect> { protected Effects baseEffects = new Effects();
// protected String text;
// protected Effects baseEffects = new Effects();
// public EntersBattlefieldEffect(Effect baseEffect) {
// public EntersBattlefieldEffect(Effect baseEffect) { this(baseEffect, "");
// super(Duration.WhileOnBattlefield, baseEffect.getOutcome()); }
// this.baseEffects.add(baseEffect);
// } public EntersBattlefieldEffect(Effect baseEffect, String text) {
// super(Duration.OneUse, baseEffect.getOutcome());
// public EntersBattlefieldEffect(EntersBattlefieldEffect effect) { this.baseEffects.add(baseEffect);
// super(effect); this.text = text;
// this.baseEffects = effect.baseEffects.copy(); }
// }
// public EntersBattlefieldEffect(EntersBattlefieldEffect effect) {
// @Override super(effect);
// public boolean applies(GameEvent event, Ability source, Game game) { this.baseEffects = effect.baseEffects.copy();
// if (event.getType() == EventType.ZONE_CHANGE && event.getTargetId().equals(source.getSourceId())) { this.text = effect.text;
// ZoneChangeEvent zEvent = (ZoneChangeEvent)event; }
// if (zEvent.getToZone() == Zone.BATTLEFIELD)
// return true; @Override
// } public boolean applies(GameEvent event, Ability source, Game game) {
// return false; if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(source.getSourceId())) {
// } return true;
// }
// @Override return false;
// public boolean apply(Game game, Ability source) { }
// for (Effect effect: baseEffects) {
// if (effect instanceof ContinuousEffect) { @Override
// game.addEffect((ContinuousEffect) effect, source); public boolean apply(Game game, Ability source) {
// } return false;
// else }
// effect.apply(game, source);
// } @Override
// return true; public boolean replaceEvent(GameEvent event, Ability source, Game game) {
// } Spell spell = game.getStack().getSpell(event.getSourceId());
// for (Effect effect: baseEffects) {
// @Override if (effect instanceof ContinuousEffect) {
// public boolean replaceEvent(GameEvent event, Ability source, Game game) { if (spell != null)
// return apply(game, source); game.addEffect((ContinuousEffect) effect, spell.getSpellAbility());
// } else
// game.addEffect((ContinuousEffect) effect, source);
// @Override }
// public String getText(Ability source) { else
// return "When {this} enters the battlefield, " + baseEffects.getText(source); if (spell != null)
// } effect.apply(game, spell.getSpellAbility());
// else
// @Override effect.apply(game, source);
// public EntersBattlefieldEffect copy() { }
// return new EntersBattlefieldEffect(this); return false;
// } }
//
//} @Override
public String getText(Ability source) {
if (text.length() == 0)
return "{this} enters the battlefield " + baseEffects.getText(source);
else
return "{this} enters the battlefield " + text;
}
@Override
public EntersBattlefieldEffect copy() {
return new EntersBattlefieldEffect(this);
}
}

View file

@ -32,6 +32,6 @@ package mage.abilities.effects;
* *
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public interface PreventionEffect<T extends PreventionEffect<T>> extends ContinuousEffect<T> { public interface PreventionEffect<T extends PreventionEffect<T>> extends ReplacementEffect<T> {
} }

View file

@ -67,7 +67,7 @@ public class CreateTokenEffect extends OneShotEffect<CreateTokenEffect> {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
token.putOntoBattlefield(game, source.getControllerId()); token.putOntoBattlefield(game, source.getId(), source.getControllerId());
} }
return true; return true;
} }

View file

@ -71,7 +71,7 @@ public class ReturnFromGraveyardToBattlefieldTargetEffect extends OneShotEffect<
Player player = game.getPlayer(card.getOwnerId()); Player player = game.getPlayer(card.getOwnerId());
if (player != null) { if (player != null) {
player.removeFromGraveyard(card, game); player.removeFromGraveyard(card, game);
if (card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getControllerId())) { if (card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getId(), source.getControllerId())) {
if (tapped) { if (tapped) {
Permanent permanent = game.getPermanent(card.getId()); Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) if (permanent != null)

View file

@ -70,7 +70,7 @@ public class ReturnSourceFromGraveyardToBattlefieldEffect extends OneShotEffect<
Card card = player.getGraveyard().get(source.getSourceId(), game); Card card = player.getGraveyard().get(source.getSourceId(), game);
if (card != null) { if (card != null) {
player.removeFromGraveyard(card, game); player.removeFromGraveyard(card, game);
if (card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getControllerId())) { if (card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getId(), source.getControllerId())) {
if (tapped) { if (tapped) {
Permanent permanent = game.getPermanent(card.getId()); Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) if (permanent != null)

View file

@ -79,7 +79,7 @@ public class SearchLibraryPutInPlayEffect extends SearchEffect<SearchLibraryPutI
for (UUID cardId: (List<UUID>)target.getTargets()) { for (UUID cardId: (List<UUID>)target.getTargets()) {
Card card = player.getLibrary().remove(cardId, game); Card card = player.getLibrary().remove(cardId, game);
if (card != null) { if (card != null) {
if (card.putOntoBattlefield(game, Zone.HAND, source.getControllerId())) { if (card.putOntoBattlefield(game, Zone.HAND, source.getId(), source.getControllerId())) {
if (tapped) { if (tapped) {
Permanent permanent = game.getPermanent(card.getId()); Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) if (permanent != null)

View file

@ -57,7 +57,7 @@ public interface Card extends MageObject {
public boolean moveToZone(Zone zone, UUID sourceId, Game game, boolean flag); public boolean moveToZone(Zone zone, UUID sourceId, Game game, boolean flag);
public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game); public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game);
public boolean putOntoBattlefield(Game game, Zone fromZone, UUID controllerId); public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId);
public void checkTriggers(Zone zone, GameEvent event, Game game); public void checkTriggers(Zone zone, GameEvent event, Game game);
@Override @Override

View file

@ -210,7 +210,7 @@ public abstract class CardImpl<T extends CardImpl<T>> extends MageObjectImpl<T>
case BATTLEFIELD: case BATTLEFIELD:
PermanentCard permanent = new PermanentCard(this, ownerId); PermanentCard permanent = new PermanentCard(this, ownerId);
game.getBattlefield().addPermanent(permanent); game.getBattlefield().addPermanent(permanent);
permanent.entersBattlefield(game); permanent.entersBattlefield(sourceId, game);
game.applyEffects(); game.applyEffects();
if (flag) if (flag)
permanent.setTapped(true); permanent.setTapped(true);
@ -242,11 +242,11 @@ public abstract class CardImpl<T extends CardImpl<T>> extends MageObjectImpl<T>
} }
@Override @Override
public boolean putOntoBattlefield(Game game, Zone fromZone, UUID controllerId) { public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId) {
PermanentCard permanent = new PermanentCard(this, controllerId); PermanentCard permanent = new PermanentCard(this, controllerId);
game.getBattlefield().addPermanent(permanent); game.getBattlefield().addPermanent(permanent);
game.setZone(objectId, Zone.BATTLEFIELD); game.setZone(objectId, Zone.BATTLEFIELD);
permanent.entersBattlefield(game); permanent.entersBattlefield(sourceId, game);
game.applyEffects(); game.applyEffects();
game.fireEvent(new ZoneChangeEvent(permanent, controllerId, fromZone, Zone.BATTLEFIELD)); game.fireEvent(new ZoneChangeEvent(permanent, controllerId, fromZone, Zone.BATTLEFIELD));
return true; return true;

View file

@ -372,7 +372,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
if (card.getAbilities().containsKey(LeylineAbility.getInstance().getId())) { if (card.getAbilities().containsKey(LeylineAbility.getInstance().getId())) {
if (player.chooseUse(Outcome.PutCardInPlay, "Do you wish to put " + card.getName() + " on the battlefield?", this)) { if (player.chooseUse(Outcome.PutCardInPlay, "Do you wish to put " + card.getName() + " on the battlefield?", this)) {
player.getHand().remove(card); player.getHand().remove(card);
card.putOntoBattlefield(this, Zone.HAND, player.getId()); card.putOntoBattlefield(this, Zone.HAND, null, player.getId());
} }
} }
} }
@ -555,7 +555,6 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
for (Player player: state.getPlayers().values()) { for (Player player: state.getPlayers().values()) {
if (!player.hasLost() && (player.getLife() <= 0 || player.isEmptyDraw() || player.getCounters().getCount("Poison") >= 10)) { if (!player.hasLost() && (player.getLife() <= 0 || player.isEmptyDraw() || player.getCounters().getCount("Poison") >= 10)) {
player.lost(this); player.lost(this);
return false;
} }
} }
for (Permanent perm: getBattlefield().getAllActivePermanents(CardType.CREATURE)) { for (Permanent perm: getBattlefield().getAllActivePermanents(CardType.CREATURE)) {
@ -593,7 +592,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
} }
} }
} }
//20091005 - 704.5n //20091005 - 704.5n, 702.14c
for (Permanent perm: getBattlefield().getAllActivePermanents(filterAura)) { for (Permanent perm: getBattlefield().getAllActivePermanents(filterAura)) {
if (perm.getAttachedTo() == null) { if (perm.getAttachedTo() == null) {
if (perm.moveToZone(Zone.GRAVEYARD, null, this, false)) if (perm.moveToZone(Zone.GRAVEYARD, null, this, false))
@ -608,7 +607,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
} }
else { else {
Filter auraFilter = perm.getSpellAbility().getTargets().get(0).getFilter(); Filter auraFilter = perm.getSpellAbility().getTargets().get(0).getFilter();
if (!auraFilter.match(attachedTo)) { if (!auraFilter.match(attachedTo) || attachedTo.hasProtectionFrom(perm)) {
if (perm.moveToZone(Zone.GRAVEYARD, null, this, false)) if (perm.moveToZone(Zone.GRAVEYARD, null, this, false))
somethingHappened = true; somethingHappened = true;
} }
@ -628,14 +627,14 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
} }
} }
} }
//20091005 - 704.5p //20091005 - 704.5p, 702.14d
for (Permanent perm: getBattlefield().getAllActivePermanents(filterEquipment)) { for (Permanent perm: getBattlefield().getAllActivePermanents(filterEquipment)) {
if (perm.getAttachedTo() != null) { if (perm.getAttachedTo() != null) {
Permanent creature = getPermanent(perm.getAttachedTo()); Permanent creature = getPermanent(perm.getAttachedTo());
if (creature == null) { if (creature == null) {
perm.attachTo(null); perm.attachTo(null);
} }
else if (!creature.getCardType().contains(CardType.CREATURE)) { else if (!creature.getCardType().contains(CardType.CREATURE) || creature.hasProtectionFrom(perm)) {
if (creature.removeAttachment(perm.getId(), this)) if (creature.removeAttachment(perm.getId(), this))
somethingHappened = true; somethingHappened = true;
} }
@ -647,7 +646,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
if (land == null) { if (land == null) {
perm.attachTo(null); perm.attachTo(null);
} }
else if (!land.getCardType().contains(CardType.LAND)) { else if (!land.getCardType().contains(CardType.LAND) || land.hasProtectionFrom(perm)) {
if (land.removeAttachment(perm.getId(), this)) if (land.removeAttachment(perm.getId(), this))
somethingHappened = true; somethingHappened = true;
} }

View file

@ -310,6 +310,7 @@ public class GameState implements Serializable, Copyable<GameState> {
if (event.getType() == EventType.ZONE_CHANGE) { if (event.getType() == EventType.ZONE_CHANGE) {
ZoneChangeEvent zEvent = (ZoneChangeEvent)event; ZoneChangeEvent zEvent = (ZoneChangeEvent)event;
if (zEvent.getFromZone() == Zone.BATTLEFIELD) { if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
zEvent.getTarget().checkTriggers(zEvent.getFromZone(), event, game);
zEvent.getTarget().checkTriggers(zEvent.getToZone(), event, game); zEvent.getTarget().checkTriggers(zEvent.getToZone(), event, game);
} }
} }

View file

@ -97,6 +97,7 @@ public class GameEvent {
SEARCH_LIBRARY, LIBRARY_SEARCHED, SEARCH_LIBRARY, LIBRARY_SEARCHED,
//permanent events //permanent events
ENTERS_THE_BATTLEFIELD,
TAP, TAPPED, TAP, TAPPED,
UNTAP, UNTAPPED, UNTAP, UNTAPPED,
FLIP, FLIPPED, FLIP, FLIPPED,

View file

@ -67,6 +67,7 @@ public interface Permanent extends Card {
public UUID getControllerId(); public UUID getControllerId();
public boolean changeControllerId(UUID controllerId, Game game); public boolean changeControllerId(UUID controllerId, Game game);
public boolean canBeTargetedBy(MageObject source); public boolean canBeTargetedBy(MageObject source);
public boolean hasProtectionFrom(MageObject source);
public int getDamage(); public int getDamage();
public int damage(int damage, UUID sourceId, Game game, boolean preventable); public int damage(int damage, UUID sourceId, Game game, boolean preventable);
public void removeAllDamage(Game game); public void removeAllDamage(Game game);
@ -77,7 +78,7 @@ public interface Permanent extends Card {
public void reset(Game game); public void reset(Game game);
public boolean destroy(UUID sourceId, Game game, boolean noRegen); public boolean destroy(UUID sourceId, Game game, boolean noRegen);
public boolean sacrifice(UUID sourceId, Game game); public boolean sacrifice(UUID sourceId, Game game);
public void entersBattlefield(Game game); public void entersBattlefield(UUID sourceId, Game game);
public String getValue(); public String getValue();
public void setArt(String art); public void setArt(String art);

View file

@ -112,18 +112,6 @@ public class PermanentCard extends PermanentImpl<PermanentCard> {
this.cardNumber = card.getCardNumber(); this.cardNumber = card.getCardNumber();
} }
// @Override
// public boolean moveToZone(Zone zone, Game game, boolean flag) {
// ZoneChangeEvent event = new ZoneChangeEvent(this.getId(), this.getControllerId(), Zone.BATTLEFIELD, zone);
// if (!game.replaceEvent(event)) {
// if (game.getPlayer(controllerId).removeFromBattlefield(this, game)) {
// CardImpl card = (CardImpl) game.getCard(objectId);
// return card.moveToZone(event.getToZone(), controllerId, game, flag);
// }
// }
// return false;
// }
@Override @Override
public boolean moveToZone(Zone toZone, UUID sourceId, Game game, boolean flag) { public boolean moveToZone(Zone toZone, UUID sourceId, Game game, boolean flag) {
Zone fromZone = game.getZone(objectId); Zone fromZone = game.getZone(objectId);

View file

@ -36,12 +36,7 @@ import mage.Constants.Zone;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.EvasionAbility; import mage.abilities.EvasionAbility;
import mage.abilities.StaticAbility;
import mage.abilities.TriggeredAbility; import mage.abilities.TriggeredAbility;
import mage.abilities.common.EntersBattlefieldStaticAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.DeathtouchAbility; import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.DefenderAbility; import mage.abilities.keyword.DefenderAbility;
import mage.abilities.keyword.HasteAbility; import mage.abilities.keyword.HasteAbility;
@ -279,7 +274,7 @@ public abstract class PermanentImpl<T extends PermanentImpl<T>> extends CardImpl
if (!phasedIn) { if (!phasedIn) {
if (!replaceEvent(EventType.PHASE_IN, game)) { if (!replaceEvent(EventType.PHASE_IN, game)) {
this.phasedIn = true; this.phasedIn = true;
addEffects(game); // addEffects(game);
fireEvent(EventType.PHASED_IN, game); fireEvent(EventType.PHASED_IN, game);
return true; return true;
} }
@ -470,9 +465,9 @@ public abstract class PermanentImpl<T extends PermanentImpl<T>> extends CardImpl
} }
@Override @Override
public void entersBattlefield(Game game) { public void entersBattlefield(UUID sourceId, Game game) {
controlledFromStartOfTurn = false; controlledFromStartOfTurn = false;
addEffects(game); game.replaceEvent(GameEvent.getEvent(EventType.ENTERS_THE_BATTLEFIELD, objectId, sourceId, ownerId));
} }
@Override @Override
@ -481,47 +476,38 @@ public abstract class PermanentImpl<T extends PermanentImpl<T>> extends CardImpl
if (abilities.containsKey(ShroudAbility.getInstance().getId())) if (abilities.containsKey(ShroudAbility.getInstance().getId()))
return false; return false;
for (ProtectionAbility ability: abilities.getProtectionAbilities()) { if (hasProtectionFrom(source))
if (!ability.canTarget(source))
return false; return false;
} }
}
return true; return true;
} }
@Override
public boolean hasProtectionFrom(MageObject source) {
for (ProtectionAbility ability: abilities.getProtectionAbilities()) {
if (!ability.canTarget(source))
return true;
}
return false;
}
protected boolean canDamage(MageObject source) { protected boolean canDamage(MageObject source) {
for (ProtectionAbility ability: abilities.getProtectionAbilities()) { return (!hasProtectionFrom(source));
if (!ability.canTarget(source))
return false;
}
return true;
} }
protected void addEffects(Game game) { // protected void addEffects(Game game) {
// for (StaticAbility ability: abilities.getStaticAbilities(Zone.BATTLEFIELD)) { // for (Ability ability: abilities.getStaticAbilities(Zone.BATTLEFIELD)) {
// if (ability.activate(game, false)) { // if (ability instanceof EntersBattlefieldStaticAbility) {
// for (Effect effect: ability.getEffects()) { // for (Effect effect: ability.getEffects()) {
// if (effect instanceof ContinuousEffect) // if (effect instanceof OneShotEffect) {
// game.addEffect((ContinuousEffect)effect, ability);
// else if (ability instanceof EntersBattlefieldStaticAbility && effect instanceof OneShotEffect) {
// //20100423 - 603.6e // //20100423 - 603.6e
// effect.apply(game, ability); // effect.apply(game, ability);
// } // }
// } // }
// } // }
// } // }
for (Ability ability: abilities.getStaticAbilities(Zone.BATTLEFIELD)) { // }
if (ability instanceof EntersBattlefieldStaticAbility) {
for (Effect effect: ability.getEffects()) {
if (effect instanceof OneShotEffect) {
//20100423 - 603.6e
effect.apply(game, ability);
}
}
}
}
}
@Override @Override
public boolean destroy(UUID sourceId, Game game, boolean noRegen) { public boolean destroy(UUID sourceId, Game game, boolean noRegen) {
@ -589,10 +575,8 @@ public abstract class PermanentImpl<T extends PermanentImpl<T>> extends CardImpl
if (!ability.canBlock(this, game)) if (!ability.canBlock(this, game))
return false; return false;
} }
for (ProtectionAbility ability: attacker.getAbilities().getProtectionAbilities()) { if (attacker.hasProtectionFrom(this))
if (!ability.canTarget(this))
return false; return false;
}
return true; return true;
} }

View file

@ -80,10 +80,10 @@ public class Token extends MageObjectImpl<Token> {
return new Token(this); return new Token(this);
} }
public boolean putOntoBattlefield(Game game, UUID controllerId) { public boolean putOntoBattlefield(Game game, UUID sourceId, UUID controllerId) {
PermanentToken permanent = new PermanentToken(this, controllerId); PermanentToken permanent = new PermanentToken(this, controllerId);
game.getBattlefield().addPermanent(permanent); game.getBattlefield().addPermanent(permanent);
permanent.entersBattlefield(game); permanent.entersBattlefield(sourceId, game);
game.applyEffects(); game.applyEffects();
game.fireEvent(new ZoneChangeEvent(permanent, controllerId, Zone.OUTSIDE, Zone.BATTLEFIELD)); game.fireEvent(new ZoneChangeEvent(permanent, controllerId, Zone.OUTSIDE, Zone.BATTLEFIELD));
return true; return true;

View file

@ -95,7 +95,7 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
} }
else if (card.getCardType().contains(CardType.ENCHANTMENT) && card.getSubtype().contains("Aura")) { else if (card.getCardType().contains(CardType.ENCHANTMENT) && card.getSubtype().contains("Aura")) {
if (ability.getTargets().stillLegal(ability, game)) { if (ability.getTargets().stillLegal(ability, game)) {
if (card.putOntoBattlefield(game, Zone.HAND, controllerId)) { if (card.putOntoBattlefield(game, Zone.HAND, ability.getId(), controllerId)) {
return ability.resolve(game); return ability.resolve(game);
} }
return false; return false;
@ -105,7 +105,7 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
return false; return false;
} }
else { else {
result = card.putOntoBattlefield(game, Zone.HAND, controllerId); result = card.putOntoBattlefield(game, Zone.HAND, ability.getId(), controllerId);
resolveKicker(game); resolveKicker(game);
return result; return result;
} }
@ -298,7 +298,7 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
} }
@Override @Override
public boolean putOntoBattlefield(Game game, Zone fromZone, UUID controllerId) { public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId) {
throw new UnsupportedOperationException("Not supported yet."); throw new UnsupportedOperationException("Not supported yet.");
} }

View file

@ -98,7 +98,7 @@ public class StackAbility implements StackObject, Ability {
public void counter(UUID sourceId, Game game) { public void counter(UUID sourceId, Game game) {
//20100716 - 603.8 //20100716 - 603.8
if (ability instanceof StateTriggeredAbility) { if (ability instanceof StateTriggeredAbility) {
((StateTriggeredAbility)ability).counter(); ((StateTriggeredAbility)ability).counter(game);
} }
} }

View file

@ -103,6 +103,7 @@ public interface Player extends MageItem, Copyable<Player> {
public boolean activateAbility(ActivatedAbility ability, Game game); public boolean activateAbility(ActivatedAbility ability, Game game);
public boolean triggerAbility(TriggeredAbility ability, Game game); public boolean triggerAbility(TriggeredAbility ability, Game game);
public boolean canBeTargetedBy(MageObject source); public boolean canBeTargetedBy(MageObject source);
public boolean hasProtectionFrom(MageObject source);
public boolean flipCoin(); public boolean flipCoin();
public void checkTriggers(GameEvent event, Game game); public void checkTriggers(GameEvent event, Game game);
public void discard(int amount, Ability source, Game game); public void discard(int amount, Ability source, Game game);

View file

@ -236,24 +236,29 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
if (abilities.containsKey(ShroudAbility.getInstance().getId())) if (abilities.containsKey(ShroudAbility.getInstance().getId()))
return false; return false;
for (ProtectionAbility ability: abilities.getProtectionAbilities()) { if (hasProtectionFrom(source))
if (!ability.canTarget(source))
return false; return false;
} }
}
return true; return true;
} }
@Override
public boolean hasProtectionFrom(MageObject source) {
for (ProtectionAbility ability: abilities.getProtectionAbilities()) {
if (!ability.canTarget(source))
return true;
}
return false;
}
protected boolean drawCard(Game game) { protected boolean drawCard(Game game) {
// if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DRAW_CARD, null, playerId))) {
Card card = getLibrary().removeFromTop(game); Card card = getLibrary().removeFromTop(game);
if (card != null) { if (card != null) {
card.moveToZone(Zone.HAND, null, game, false); card.moveToZone(Zone.HAND, null, game, false);
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DREW_CARD, card.getId(), playerId)); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DREW_CARD, card.getId(), playerId));
return true; return true;
} }
// }
return false; return false;
} }
@ -381,7 +386,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, card.getId(), playerId))) { if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, card.getId(), playerId))) {
game.bookmarkState(); game.bookmarkState();
removeFromHand(card, game); removeFromHand(card, game);
if (card.putOntoBattlefield(game, Zone.HAND, playerId)) { if (card.putOntoBattlefield(game, Zone.HAND, null, playerId)) {
landsPlayed++; landsPlayed++;
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LAND_PLAYED, card.getId(), playerId)); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LAND_PLAYED, card.getId(), playerId));
game.fireInformEvent(name + " plays " + card.getName()); game.fireInformEvent(name + " plays " + card.getName());