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

View file

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

View file

@ -100,7 +100,7 @@ class PathToExileEffect extends OneShotEffect {
player.searchLibrary(target, game);
Card card = player.getLibrary().remove(target.getFirstTarget(), game);
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());
if (land != null)
land.setTapped(true);

View file

@ -31,7 +31,7 @@ package mage.sets.magic2010;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.abilities.common.EntersBattlefieldStaticAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.effects.common.TapSourceUnlessControlsEffect;
import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.RedManaAbility;
@ -57,7 +57,7 @@ public class DragonskullSummit extends CardImpl<DragonskullSummit> {
public DragonskullSummit(UUID ownerId) {
super(ownerId, 223, "Dragonskull Summit", Rarity.RARE, new CardType[]{CardType.LAND}, null);
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 RedManaAbility());
}

View file

@ -31,7 +31,7 @@ package mage.sets.magic2010;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.abilities.common.EntersBattlefieldStaticAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.effects.common.TapSourceUnlessControlsEffect;
import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.BlueManaAbility;
@ -57,7 +57,7 @@ public class DrownedCatacomb extends CardImpl<DrownedCatacomb> {
public DrownedCatacomb(UUID ownerId) {
super(ownerId, 224, "Drowned Catacomb", Rarity.RARE, new CardType[]{CardType.LAND}, null);
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 BlueManaAbility());
}

View file

@ -31,7 +31,9 @@ package mage.sets.magic2010;
import java.util.UUID;
import mage.Constants.CardType;
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.mana.BlueManaAbility;
import mage.abilities.mana.WhiteManaAbility;
@ -57,7 +59,7 @@ public class GlacialFortress extends CardImpl<GlacialFortress> {
public GlacialFortress(UUID ownerId) {
super(ownerId, 226, "Glacial Fortress", Rarity.RARE, new CardType[]{CardType.LAND}, null);
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 WhiteManaAbility());
}

View file

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

View file

@ -31,7 +31,7 @@ package mage.sets.magic2010;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.abilities.common.EntersBattlefieldStaticAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.effects.common.TapSourceUnlessControlsEffect;
import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.RedManaAbility;
@ -57,7 +57,7 @@ public class RootboundCrag extends CardImpl<RootboundCrag> {
public RootboundCrag(UUID ownerId) {
super(ownerId, 227, "Rootbound Crag", Rarity.RARE, new CardType[]{CardType.LAND}, null);
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 GreenManaAbility());
}

View file

@ -31,7 +31,7 @@ package mage.sets.magic2010;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.abilities.common.EntersBattlefieldStaticAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.effects.common.TapSourceUnlessControlsEffect;
import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.WhiteManaAbility;
@ -57,7 +57,7 @@ public class SunpetalGrove extends CardImpl<SunpetalGrove> {
public SunpetalGrove(UUID ownerId) {
super(ownerId, 228, "Sunpetal Grove", Rarity.RARE, new CardType[]{CardType.LAND}, null);
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 WhiteManaAbility());
}

View file

@ -112,7 +112,7 @@ class CultivateEffect extends OneShotEffect<CultivateEffect> {
target2.setRequired(true);
player.choose(revealed, target2, 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);
Permanent permanent = game.getPermanent(card.getId());
if (permanent != null)
@ -122,7 +122,7 @@ class CultivateEffect extends OneShotEffect<CultivateEffect> {
}
else if (target.getTargets().size() == 1) {
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());
if (permanent != null)
permanent.setTapped(true);

View file

@ -105,7 +105,7 @@ class MassPolymorphEffect extends OneShotEffect<MassPolymorphEffect> {
}
player.revealCards(revealed, 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().shuffle();

View file

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

View file

@ -118,7 +118,7 @@ class ObstinateBalothEffect extends ReplacementEffectImpl<ObstinateBalothEffect>
if (card != null) {
Player player = game.getPlayer(card.getOwnerId());
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()));
return true;
}

View file

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

View file

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

View file

@ -30,13 +30,14 @@ package mage.sets.magic2011;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Outcome;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.StateTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.AddCountersTargetEffect;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.SacrificeSourceEffect;
import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl;
@ -45,6 +46,8 @@ import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledPermanent;
/**
@ -53,13 +56,6 @@ import mage.target.common.TargetControlledPermanent;
*/
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) {
super(ownerId, 110, "Phylactery Lich", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{B}{B}{B}");
this.expansionSetCode = "M11";
@ -68,9 +64,7 @@ public class PhylacteryLich extends CardImpl<PhylacteryLich> {
this.power = new MageInt(5);
this.toughness = new MageInt(5);
Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect("phylactery", 1), false);
ability.addTarget(new TargetControlledPermanent(filter));
this.addAbility(ability);
this.addAbility(new EntersBattlefieldAbility(new PhylacteryLichEffect(), "put a phylactery counter on an artifact you control"));
this.addAbility(IndestructibleAbility.getInstance());
this.addAbility(new PhylacteryLichAbility());
}
@ -108,9 +102,10 @@ public class PhylacteryLich extends CardImpl<PhylacteryLich> {
public boolean checkTrigger(GameEvent event, Game game) {
for (Permanent perm: game.getBattlefield().getAllActivePermanents(controllerId)) {
if (perm.getCounters().getCount("phylactery") > 0)
return true;
return false;
}
return false;
trigger(game, controllerId);
return true;
}
@Override
@ -120,4 +115,50 @@ 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
public boolean checkTrigger(GameEvent event, Game game) {
Permanent enchantment = game.getPermanent(sourceId);
if (enchantment != null && enchantment.getAttachedTo() != null) {
if (event.getSourceId().equals(enchantment.getAttachedTo()) &&
(event.getType() == EventType.ATTACKER_DECLARED || event.getType() == EventType.BLOCKER_DECLARED)) {
if (event.getType() == EventType.ATTACKER_DECLARED || event.getType() == EventType.BLOCKER_DECLARED) {
Permanent enchantment = game.getPermanent(sourceId);
if (enchantment != null && enchantment.getAttachedTo() != null && event.getSourceId() != null && event.getSourceId().equals(enchantment.getAttachedTo())) {
trigger(game, event.getPlayerId());
return true;
}

View file

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

View file

@ -34,7 +34,7 @@ import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldStaticAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.RemoveCountersSourceCost;
import mage.abilities.effects.common.AddPlusOneCountersSourceEffect;
@ -55,7 +55,7 @@ public class Triskelion extends CardImpl<Triskelion> {
this.power = 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.addTarget(new TargetCreatureOrPlayer());
this.addAbility(ability);

View file

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

View file

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

View file

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

View file

@ -33,11 +33,10 @@ import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldStaticAbility;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.BecomesCreatureSourceEOTEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.abilities.mana.BlueManaAbility;
@ -54,7 +53,7 @@ public class CelestialColonnade extends CardImpl<CelestialColonnade> {
public CelestialColonnade(UUID ownerId) {
super(ownerId, 133, "Celestial Colonnade", Rarity.RARE, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "WWK";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceEffect(), "tapped"));
this.addAbility(EntersBattlefieldTappedAbility.getInstance());
this.addAbility(new BlueManaAbility());
this.addAbility(new WhiteManaAbility());
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.Rarity;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldStaticAbility;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.mana.GreenManaAbility;
import mage.cards.CardImpl;
import mage.game.permanent.token.Token;
@ -49,7 +48,7 @@ public class KhalniGarden extends CardImpl<KhalniGarden> {
public KhalniGarden(UUID ownerId) {
super(ownerId, 138, "Khalni Garden", Rarity.COMMON, new CardType[]{CardType.LAND}, null);
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 GreenManaAbility());
}

View file

@ -34,12 +34,11 @@ import mage.Constants.Duration;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldStaticAbility;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.BecomesCreatureSourceEOTEffect;
import mage.abilities.effects.common.BoostPowerXSourceEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.RedManaAbility;
import mage.cards.CardImpl;
@ -54,7 +53,7 @@ public class LavaclawReaches extends CardImpl<LavaclawReaches> {
public LavaclawReaches(UUID ownerId) {
super(ownerId, 139, "Lavaclaw Reaches", Rarity.RARE, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "WWK";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceEffect(), "tapped"));
this.addAbility(EntersBattlefieldTappedAbility.getInstance());
this.addAbility(new BlackManaAbility());
this.addAbility(new RedManaAbility());
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.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.EntersBattlefieldStaticAbility;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.AddPlusOneCountersSourceEffect;
import mage.abilities.effects.common.BecomesCreatureSourceEOTEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.RedManaAbility;
import mage.cards.CardImpl;
@ -54,7 +53,7 @@ public class RagingRavine extends CardImpl<RagingRavine> {
public RagingRavine(UUID ownerId) {
super(ownerId, 141, "Raging Ravine", Rarity.RARE, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "WWK";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceEffect(), "tapped"));
this.addAbility(EntersBattlefieldTappedAbility.getInstance());
this.addAbility(new GreenManaAbility());
this.addAbility(new RedManaAbility());
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.Duration;
import mage.Constants.Rarity;
import mage.abilities.common.EntersBattlefieldStaticAbility;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.GainProtectionFromColorTargetEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.mana.WhiteManaAbility;
import mage.cards.CardImpl;
import mage.choices.ChoiceColor;
@ -50,7 +49,7 @@ public class SejiriSteppe extends CardImpl<SejiriSteppe> {
public SejiriSteppe(UUID ownerId) {
super(ownerId, 142, "Sejiri Steppe", Rarity.COMMON, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "WWK";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceEffect(), "tapped"));
this.addAbility(EntersBattlefieldTappedAbility.getInstance());
EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new GainProtectionFromColorTargetEffect(Duration.EndOfTurn), false);
ability.addTarget(new TargetControlledCreaturePermanent());
ability.addChoice(new ChoiceColor());

View file

@ -33,11 +33,10 @@ import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldStaticAbility;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.BecomesCreatureSourceEOTEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.keyword.ReachAbility;
import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.WhiteManaAbility;
@ -53,7 +52,7 @@ public class StirringWildwood extends CardImpl<StirringWildwood> {
public StirringWildwood(UUID ownerId) {
super(ownerId, 144, "Stirring Wildwood", Rarity.RARE, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "WWK";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceEffect(), "tapped"));
this.addAbility(EntersBattlefieldTappedAbility.getInstance());
this.addAbility(new GreenManaAbility());
this.addAbility(new WhiteManaAbility());
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 mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.abilities.common.EntersBattlefieldStaticAbility;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.mana.WhiteManaAbility;
import mage.cards.CardImpl;
@ -47,7 +46,7 @@ public class KabiraCrossroads extends CardImpl<KabiraCrossroads> {
public KabiraCrossroads(UUID ownerId) {
super(ownerId, 216, "Kabira Crossroads", Rarity.COMMON, new CardType[]{CardType.LAND}, null);
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 WhiteManaAbility());
}

View file

@ -34,11 +34,10 @@ import mage.Constants.Outcome;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldStaticAbility;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.mana.GreenManaAbility;
import mage.cards.CardImpl;
import mage.counters.PlusOneCounter;
@ -55,7 +54,7 @@ public class OranRiefTheVastwood extends CardImpl<OranRiefTheVastwood> {
public OranRiefTheVastwood(UUID ownerId) {
super(ownerId, 221, "Oran-Rief, the Vastwood", Rarity.RARE, new CardType[]{CardType.LAND}, null);
this.expansionSetCode = "ZEN";
this.addAbility(new EntersBattlefieldStaticAbility(new TapSourceEffect(), "tapped"));
this.addAbility(EntersBattlefieldTappedAbility.getInstance());
this.addAbility(new GreenManaAbility());
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.Rarity;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldStaticAbility;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.BoostTargetEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.mana.RedManaAbility;
import mage.cards.CardImpl;
import mage.target.common.TargetCreaturePermanent;
@ -50,7 +49,7 @@ public class TeeteringPeaks extends CardImpl<TeeteringPeaks> {
public TeeteringPeaks(UUID ownerId) {
super(ownerId, 226, "Teetering Peaks", Rarity.COMMON, new CardType[]{CardType.LAND}, null);
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.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);

View file

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

View file

@ -39,22 +39,22 @@ import mage.game.Game;
*/
public abstract class StateTriggeredAbility<T extends StateTriggeredAbility<T>> extends TriggeredAbilityImpl<T> {
protected boolean triggered;
public StateTriggeredAbility(Zone zone, Effect effect) {
super(zone, effect);
}
public StateTriggeredAbility(final StateTriggeredAbility ability) {
super(ability);
this.triggered = ability.triggered;
}
@Override
public void trigger(Game game, UUID controllerId) {
//20100716 - 603.8
Boolean triggered = (Boolean) game.getState().getValue(this.id.toString() + "triggered");
if (triggered == null)
triggered = Boolean.FALSE;
if (!triggered) {
triggered = true;
game.getState().setValue(this.id.toString() + "triggered", Boolean.TRUE);
super.trigger(game, controllerId);
}
}
@ -62,11 +62,11 @@ public abstract class StateTriggeredAbility<T extends StateTriggeredAbility<T>>
@Override
public boolean resolve(Game game) {
//20100716 - 603.8
triggered = false;
game.getState().setValue(this.id.toString() + "triggered", Boolean.FALSE);
return super.resolve(game);
}
public void counter() {
triggered = false;
public void counter(Game game) {
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.abilities.StaticAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.EntersBattlefieldEffect;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class EntersBattlefieldStaticAbility extends StaticAbility<EntersBattlefieldStaticAbility> {
public class EntersBattlefieldAbility extends StaticAbility<EntersBattlefieldAbility> {
protected String rule;
public EntersBattlefieldStaticAbility(Effect effect, String rule) {
super(Zone.BATTLEFIELD, effect);
this.rule = rule;
public EntersBattlefieldAbility(Effect effect, String rule) {
super(Zone.BATTLEFIELD, new EntersBattlefieldEffect(effect, rule));
}
public EntersBattlefieldStaticAbility(EntersBattlefieldStaticAbility ability) {
public EntersBattlefieldAbility(EntersBattlefieldAbility ability) {
super(ability);
this.rule = ability.rule;
}
@Override
public EntersBattlefieldStaticAbility copy() {
return new EntersBattlefieldStaticAbility(this);
}
@Override
public String getRule() {
return "{this} enters the battlefield " + rule + ".";
public EntersBattlefieldAbility copy() {
return new EntersBattlefieldAbility(this);
}
}

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>();
//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 PlaneswalkerRedirectionEffect planeswalkerRedirectionEffect;
@ -89,8 +89,8 @@ public class ContinuousEffects implements Serializable {
for (AsThoughEffect entry: effect.asThoughEffects) {
asThoughEffects.add((AsThoughEffect)entry.copy());
}
for (Entry<ContinuousEffect, Ability> entry: effect.abilityMap.entrySet()) {
abilityMap.put((ContinuousEffect)entry.getKey().copy(), entry.getValue().copy());
for (Entry<UUID, Ability> entry: effect.abilityMap.entrySet()) {
abilityMap.put(entry.getKey(), entry.getValue().copy());
}
}
@ -125,7 +125,7 @@ public class ContinuousEffects implements Serializable {
for (Iterator<ContinuousEffect> i = layeredEffects.iterator(); i.hasNext();) {
ContinuousEffect entry = i.next();
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())
i.remove();
}
@ -135,7 +135,7 @@ public class ContinuousEffects implements Serializable {
for (Iterator<ReplacementEffect> i = replacementEffects.iterator(); i.hasNext();) {
ReplacementEffect entry = i.next();
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())
i.remove();
}
@ -145,7 +145,7 @@ public class ContinuousEffects implements Serializable {
for (Iterator<PreventionEffect> i = preventionEffects.iterator(); i.hasNext();) {
PreventionEffect entry = i.next();
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())
i.remove();
}
@ -155,7 +155,7 @@ public class ContinuousEffects implements Serializable {
for (Iterator<AsThoughEffect> i = asThoughEffects.iterator(); i.hasNext();) {
AsThoughEffect entry = i.next();
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())
i.remove();
}
@ -171,7 +171,7 @@ public class ContinuousEffects implements Serializable {
for (Ability ability: card.getAbilities().getStaticAbilities(game.getZone(card.getId()))) {
for (Effect effect: ability.getEffects(EffectType.CONTINUOUS)) {
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 (Effect effect: ability.getEffects(EffectType.CONTINUOUS)) {
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;
}
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
@ -206,7 +215,14 @@ public class ContinuousEffects implements Serializable {
ReplacementEffect rEffect = (ReplacementEffect) effect;
if (rEffect.applies(event, ability, game)) {
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;
if (rEffect.applies(event, ability, game)) {
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
for (ReplacementEffect effect: replacementEffects) {
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);
}
}
@ -250,7 +280,7 @@ public class ContinuousEffects implements Serializable {
AsThoughEffect effect = entry;
if (effect.getAsThoughEffectType() == type) {
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;
}
}
@ -273,7 +303,7 @@ public class ContinuousEffects implements Serializable {
index = player.chooseEffect(rEffects, game);
}
ReplacementEffect rEffect = rEffects.get(index);
caught = rEffect.replaceEvent(event, abilityMap.get(rEffect), game);
caught = rEffect.replaceEvent(event, abilityMap.get(rEffect.getId()), game);
}
return caught;
@ -283,60 +313,69 @@ public class ContinuousEffects implements Serializable {
public void apply(Game game) {
removeInactiveEffects(game);
List<ContinuousEffect> layerEffects = getLayeredEffects(game);
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.CopyEffects_1, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect), game);
List<ContinuousEffect> layer = filterLayeredEffects(layerEffects, Layer.CopyEffects_1);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.CopyEffects_1, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect.getId()), game);
}
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.CopyEffects_1, SubLayer.NA, abilityMap.get(effect), game);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.CopyEffects_1, SubLayer.NA, abilityMap.get(effect.getId()), game);
}
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.ControlChangingEffects_2, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect), game);
layer = filterLayeredEffects(layerEffects, Layer.ControlChangingEffects_2);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.ControlChangingEffects_2, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect.getId()), game);
}
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.ControlChangingEffects_2, SubLayer.NA, abilityMap.get(effect), game);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.ControlChangingEffects_2, SubLayer.NA, abilityMap.get(effect.getId()), game);
}
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.TextChangingEffects_3, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect), game);
layer = filterLayeredEffects(layerEffects, Layer.TextChangingEffects_3);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.TextChangingEffects_3, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect.getId()), game);
}
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.TextChangingEffects_3, SubLayer.NA, abilityMap.get(effect), game);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.TextChangingEffects_3, SubLayer.NA, abilityMap.get(effect.getId()), game);
}
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.TypeChangingEffects_4, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect), game);
layer = filterLayeredEffects(layerEffects, Layer.TypeChangingEffects_4);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.TypeChangingEffects_4, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect.getId()), game);
}
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.TypeChangingEffects_4, SubLayer.NA, abilityMap.get(effect), game);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.TypeChangingEffects_4, SubLayer.NA, abilityMap.get(effect.getId()), game);
}
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.ColorChangingEffects_5, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect), game);
layer = filterLayeredEffects(layerEffects, Layer.ColorChangingEffects_5);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.ColorChangingEffects_5, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect.getId()), game);
}
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.ColorChangingEffects_5, SubLayer.NA, abilityMap.get(effect), game);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.ColorChangingEffects_5, SubLayer.NA, abilityMap.get(effect.getId()), game);
}
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect), game);
layer = filterLayeredEffects(layerEffects, Layer.AbilityAddingRemovingEffects_6);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect.getId()), game);
}
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, abilityMap.get(effect), game);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, abilityMap.get(effect.getId()), game);
}
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect), game);
layer = filterLayeredEffects(layerEffects, Layer.PTChangingEffects_7);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.CharacteristicDefining_7a, abilityMap.get(effect.getId()), game);
}
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.SetPT_7b, abilityMap.get(effect), game);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.SetPT_7b, abilityMap.get(effect.getId()), game);
}
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, abilityMap.get(effect), game);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, abilityMap.get(effect.getId()), game);
}
applyCounters.apply(Layer.PTChangingEffects_7, SubLayer.Counters_7d, null, game);
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.SwitchPT_e, abilityMap.get(effect), game);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.SwitchPT_e, abilityMap.get(effect.getId()), game);
}
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.PlayerEffects, SubLayer.NA, abilityMap.get(effect), game);
layer = filterLayeredEffects(layerEffects, Layer.PlayerEffects);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.PlayerEffects, SubLayer.NA, abilityMap.get(effect.getId()), game);
}
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.RulesEffects, SubLayer.NA, abilityMap.get(effect), game);
layer = filterLayeredEffects(layerEffects, Layer.RulesEffects);
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();
newReplacementEffect.setTimestamp();
replacementEffects.add(newReplacementEffect);
abilityMap.put(newReplacementEffect, source);
abilityMap.put(newReplacementEffect.getId(), source);
break;
case PREVENTION:
PreventionEffect newPreventionEffect = (PreventionEffect)effect.copy();
newPreventionEffect.setTimestamp();
preventionEffects.add(newPreventionEffect);
abilityMap.put(newPreventionEffect, source);
abilityMap.put(newPreventionEffect.getId(), source);
break;
case ASTHOUGH:
AsThoughEffect newAsThoughEffect = (AsThoughEffect)effect.copy();
newAsThoughEffect.setTimestamp();
asThoughEffects.add(newAsThoughEffect);
abilityMap.put(newAsThoughEffect, source);
abilityMap.put(newAsThoughEffect.getId(), source);
break;
default:
ContinuousEffect newEffect = (ContinuousEffect)effect.copy();
newEffect.setTimestamp();
layeredEffects.add(newEffect);
abilityMap.put(newEffect, source);
abilityMap.put(newEffect.getId(), source);
break;
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -210,7 +210,7 @@ public abstract class CardImpl<T extends CardImpl<T>> extends MageObjectImpl<T>
case BATTLEFIELD:
PermanentCard permanent = new PermanentCard(this, ownerId);
game.getBattlefield().addPermanent(permanent);
permanent.entersBattlefield(game);
permanent.entersBattlefield(sourceId, game);
game.applyEffects();
if (flag)
permanent.setTapped(true);
@ -242,11 +242,11 @@ public abstract class CardImpl<T extends CardImpl<T>> extends MageObjectImpl<T>
}
@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);
game.getBattlefield().addPermanent(permanent);
game.setZone(objectId, Zone.BATTLEFIELD);
permanent.entersBattlefield(game);
permanent.entersBattlefield(sourceId, game);
game.applyEffects();
game.fireEvent(new ZoneChangeEvent(permanent, controllerId, fromZone, Zone.BATTLEFIELD));
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 (player.chooseUse(Outcome.PutCardInPlay, "Do you wish to put " + card.getName() + " on the battlefield?", this)) {
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()) {
if (!player.hasLost() && (player.getLife() <= 0 || player.isEmptyDraw() || player.getCounters().getCount("Poison") >= 10)) {
player.lost(this);
return false;
}
}
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)) {
if (perm.getAttachedTo() == null) {
if (perm.moveToZone(Zone.GRAVEYARD, null, this, false))
@ -608,7 +607,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
}
else {
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))
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)) {
if (perm.getAttachedTo() != null) {
Permanent creature = getPermanent(perm.getAttachedTo());
if (creature == 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))
somethingHappened = true;
}
@ -647,7 +646,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
if (land == 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))
somethingHappened = true;
}

View file

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

View file

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

View file

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

View file

@ -112,18 +112,6 @@ public class PermanentCard extends PermanentImpl<PermanentCard> {
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
public boolean moveToZone(Zone toZone, UUID sourceId, Game game, boolean flag) {
Zone fromZone = game.getZone(objectId);

View file

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

View file

@ -80,10 +80,10 @@ public class Token extends MageObjectImpl<Token> {
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);
game.getBattlefield().addPermanent(permanent);
permanent.entersBattlefield(game);
permanent.entersBattlefield(sourceId, game);
game.applyEffects();
game.fireEvent(new ZoneChangeEvent(permanent, controllerId, Zone.OUTSIDE, Zone.BATTLEFIELD));
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")) {
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 false;
@ -105,7 +105,7 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
return false;
}
else {
result = card.putOntoBattlefield(game, Zone.HAND, controllerId);
result = card.putOntoBattlefield(game, Zone.HAND, ability.getId(), controllerId);
resolveKicker(game);
return result;
}
@ -298,7 +298,7 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
}
@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.");
}

View file

@ -98,7 +98,7 @@ public class StackAbility implements StackObject, Ability {
public void counter(UUID sourceId, Game game) {
//20100716 - 603.8
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 triggerAbility(TriggeredAbility ability, Game game);
public boolean canBeTargetedBy(MageObject source);
public boolean hasProtectionFrom(MageObject source);
public boolean flipCoin();
public void checkTriggers(GameEvent event, 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()))
return false;
for (ProtectionAbility ability: abilities.getProtectionAbilities()) {
if (!ability.canTarget(source))
return false;
}
if (hasProtectionFrom(source))
return false;
}
return true;
}
protected boolean drawCard(Game game) {
// if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DRAW_CARD, null, playerId))) {
Card card = getLibrary().removeFromTop(game);
if (card != null) {
card.moveToZone(Zone.HAND, null, game, false);
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DREW_CARD, card.getId(), playerId));
@Override
public boolean hasProtectionFrom(MageObject source) {
for (ProtectionAbility ability: abilities.getProtectionAbilities()) {
if (!ability.canTarget(source))
return true;
}
// }
}
return false;
}
protected boolean drawCard(Game game) {
Card card = getLibrary().removeFromTop(game);
if (card != null) {
card.moveToZone(Zone.HAND, null, game, false);
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DREW_CARD, card.getId(), playerId));
return true;
}
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))) {
game.bookmarkState();
removeFromHand(card, game);
if (card.putOntoBattlefield(game, Zone.HAND, playerId)) {
if (card.putOntoBattlefield(game, Zone.HAND, null, playerId)) {
landsPlayed++;
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LAND_PLAYED, card.getId(), playerId));
game.fireInformEvent(name + " plays " + card.getName());