Merge branch 'master' into type_api

This commit is contained in:
Derek M 2017-03-27 19:13:45 -04:00 committed by GitHub
commit 1dcd3d0a81
9 changed files with 164 additions and 77 deletions

View file

@ -28,6 +28,7 @@
package mage.cards.g; package mage.cards.g;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.LoseAbilityAllEffect; import mage.abilities.effects.common.continuous.LoseAbilityAllEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -36,7 +37,8 @@ import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import java.util.UUID; import java.util.UUID;
@ -46,12 +48,21 @@ import java.util.UUID;
*/ */
public class GravitySphere extends CardImpl { public class GravitySphere extends CardImpl {
final static private FilterPermanent filter = new FilterPermanent("All creatures");
static {
filter.add(new CardTypePredicate(CardType.CREATURE));
}
public GravitySphere(UUID ownerId, CardSetInfo setInfo) { public GravitySphere(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}"); super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}");
addSuperType(SuperType.WORLD); addSuperType(SuperType.WORLD);
// All creatures lose flying. // All creatures lose flying.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new LoseAbilityAllEffect(new FilterCreaturePermanent("All creatures"), FlyingAbility.getInstance(), Duration.WhileOnBattlefield))); Effect effect = new LoseAbilityAllEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield, filter);
effect.setText("All creatures lose flying");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
} }
public GravitySphere(final GravitySphere card) { public GravitySphere(final GravitySphere card) {

View file

@ -143,12 +143,12 @@ class IndomitableCreativityEffect extends OneShotEffect {
cards.add(card); cards.add(card);
} }
if (card.isCreature() || card.isArtifact()) {
controllerOfDestroyedCreature.moveCards(card, Zone.BATTLEFIELD, source, game);
}
if (!cards.isEmpty()) { if (!cards.isEmpty()) {
revealCards.addAll(cards); revealCards.addAll(cards);
if (card.isCreature() || card.isArtifact()) {
controllerOfDestroyedCreature.moveCards(card, Zone.EXILED, source, game);
controllerOfDestroyedCreature.moveCards(card, Zone.BATTLEFIELD, source, game);
}
Set<Card> cardsToShuffle = cards.getCards(game); Set<Card> cardsToShuffle = cards.getCards(game);
cardsToShuffle.remove(card); cardsToShuffle.remove(card);
library.addAll(cardsToShuffle, game); library.addAll(cardsToShuffle, game);

View file

@ -27,51 +27,58 @@
*/ */
package mage.cards.i; package mage.cards.i;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.condition.LockedInCondition; import mage.abilities.condition.LockedInCondition;
import mage.abilities.condition.common.ManaWasSpentCondition; import mage.abilities.condition.common.ManaWasSpentCondition;
import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.InfoEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.common.continuous.LoseAbilityAllEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.ColoredManaSymbol; import mage.constants.ColoredManaSymbol;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Layer; import mage.constants.TargetController;
import mage.constants.Outcome; import mage.filter.FilterPermanent;
import mage.constants.SubLayer; import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game; import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.permanent.Permanent;
import mage.watchers.common.ManaSpentToCastWatcher; import mage.watchers.common.ManaSpentToCastWatcher;
/** /**
* *
* @author jeffwadsworth * @author jeffwadsworth
*
*/ */
public class InvertTheSkies extends CardImpl { public class InvertTheSkies extends CardImpl {
public InvertTheSkies(UUID ownerId, CardSetInfo setInfo) { private static final FilterPermanent filter = new FilterPermanent();
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{G/U}");
static {
filter.add(new ControllerPredicate(TargetController.OPPONENT));
filter.add(new AbilityPredicate(FlyingAbility.class));
filter.add(new CardTypePredicate(CardType.CREATURE));
}
public InvertTheSkies(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{G/U}");
// Creatures your opponents control lose flying until end of turn if {G} was spent to cast Invert the Skies, and creatures you control gain flying until end of turn if {U} was spent to cast it. // Creatures your opponents control lose flying until end of turn if {G} was spent to cast Invert the Skies, and creatures you control gain flying until end of turn if {U} was spent to cast it.
this.getSpellAbility().addEffect(new ConditionalContinuousEffect( this.getSpellAbility().addEffect(new ConditionalContinuousEffect(
new InvertTheSkiesEffect(), new LoseAbilityAllEffect(FlyingAbility.getInstance(), Duration.EndOfTurn, filter),
new LockedInCondition(new ManaWasSpentCondition(ColoredManaSymbol.G)), new LockedInCondition(new ManaWasSpentCondition(ColoredManaSymbol.G)),
"Creatures your opponents control lose flying until end of turn if {G} was spent to cast {this},")); "Creatures your opponents control lose flying until end of turn if {G} was spent to cast {this},"));
this.getSpellAbility().addEffect(new ConditionalContinuousEffect( this.getSpellAbility().addEffect(new ConditionalContinuousEffect(
new GainAbilityControlledEffect(FlyingAbility.getInstance(), Duration.EndOfTurn), new GainAbilityControlledEffect(FlyingAbility.getInstance(), Duration.EndOfTurn),
new LockedInCondition(new ManaWasSpentCondition(ColoredManaSymbol.U)), new LockedInCondition(new ManaWasSpentCondition(ColoredManaSymbol.U)),
"and creatures you control gain flying until end of turn if {U} was spent to cast it")); "and creatures you control gain flying until end of turn if {U} was spent to cast it"));
this.getSpellAbility().addEffect(new InfoEffect("<i>(Do both if {G}{U} was spent.)</i>")); this.getSpellAbility().addEffect(new InfoEffect("<i>(Do both if {G}{U} was spent.)</i>"));
this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher()); this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher());
} }
public InvertTheSkies(final InvertTheSkies card) { public InvertTheSkies(final InvertTheSkies card) {
@ -83,33 +90,3 @@ public class InvertTheSkies extends CardImpl {
return new InvertTheSkies(this); return new InvertTheSkies(this);
} }
} }
class InvertTheSkiesEffect extends ContinuousEffectImpl {
private static FilterCreaturePermanent filter = new FilterCreaturePermanent();
public InvertTheSkiesEffect() {
super(Duration.EndOfTurn, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.LoseAbility);
}
public InvertTheSkiesEffect(final InvertTheSkiesEffect effect) {
super(effect);
}
@Override
public InvertTheSkiesEffect copy() {
return new InvertTheSkiesEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Set<UUID> opponents = game.getOpponents(source.getControllerId());
for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
if (opponents.contains(perm.getControllerId())) {
perm.getAbilities().remove(FlyingAbility.getInstance());
}
}
return true;
}
}

View file

@ -53,9 +53,9 @@ public class MysticDecree extends CardImpl {
addSuperType(SuperType.WORLD); addSuperType(SuperType.WORLD);
// All creatures lose flying and islandwalk. // All creatures lose flying and islandwalk.
Effect effect = new LoseAbilityAllEffect(new FilterCreaturePermanent("All creatures"), FlyingAbility.getInstance(), Duration.WhileOnBattlefield); Effect effect = new LoseAbilityAllEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield, new FilterCreaturePermanent("All creatures"));
effect.setText("All creatures lose flying"); effect.setText("All creatures lose flying");
Effect effect2 = new LoseAbilityAllEffect(new FilterCreaturePermanent("all creatures"), new IslandwalkAbility(), Duration.WhileOnBattlefield); Effect effect2 = new LoseAbilityAllEffect(new IslandwalkAbility(), Duration.WhileOnBattlefield, new FilterCreaturePermanent("all creatures"));
effect2.setText("and islandwalk"); effect2.setText("and islandwalk");
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
ability.addEffect(effect2); ability.addEffect(effect2);

View file

@ -31,6 +31,7 @@ import java.util.UUID;
import mage.MageInt; import mage.MageInt;
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.Effect;
import mage.abilities.effects.common.TapAllEffect; import mage.abilities.effects.common.TapAllEffect;
import mage.abilities.effects.common.continuous.LoseAbilityAllEffect; import mage.abilities.effects.common.continuous.LoseAbilityAllEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
@ -59,7 +60,7 @@ public class ThundercloudElemental extends CardImpl {
} }
public ThundercloudElemental(UUID ownerId, CardSetInfo setInfo) { public ThundercloudElemental(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{U}{U}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{U}");
this.subtype.add("Elemental"); this.subtype.add("Elemental");
this.power = new MageInt(3); this.power = new MageInt(3);
this.toughness = new MageInt(4); this.toughness = new MageInt(4);
@ -71,7 +72,10 @@ public class ThundercloudElemental extends CardImpl {
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new TapAllEffect(toughnessFilter), new ManaCostsImpl("{3}{U}"))); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new TapAllEffect(toughnessFilter), new ManaCostsImpl("{3}{U}")));
// {3}{U}: All other creatures lose flying until end of turn. // {3}{U}: All other creatures lose flying until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseAbilityAllEffect(flyingFilter, FlyingAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl("{3}{U}"))); Effect effect = new LoseAbilityAllEffect(FlyingAbility.getInstance(), Duration.EndOfTurn, flyingFilter);
effect.setText("All other creatures lose flying until end of turn");
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{3}{U}")));
} }
public ThundercloudElemental(final ThundercloudElemental card) { public ThundercloudElemental(final ThundercloudElemental card) {

View file

@ -30,6 +30,7 @@ package mage.cards.w;
import java.util.UUID; import java.util.UUID;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.ReturnToHandSourceEffect; import mage.abilities.effects.common.ReturnToHandSourceEffect;
import mage.abilities.effects.common.continuous.LoseAbilityAllEffect; import mage.abilities.effects.common.continuous.LoseAbilityAllEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
@ -56,10 +57,12 @@ public class Whiteout extends CardImpl {
} }
public Whiteout(UUID ownerId, CardSetInfo setInfo) { public Whiteout(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{G}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}");
// All creatures lose flying until end of turn. // All creatures lose flying until end of turn.
this.getSpellAbility().addEffect(new LoseAbilityAllEffect(new FilterCreaturePermanent(), FlyingAbility.getInstance(), Duration.EndOfTurn)); Effect effect = new LoseAbilityAllEffect(FlyingAbility.getInstance(), Duration.EndOfTurn, new FilterCreaturePermanent());
effect.setText("All creatures lose flying until end of turn");
this.getSpellAbility().addEffect(effect);
// Sacrifice a snow land: Return Whiteout from your graveyard to your hand. // Sacrifice a snow land: Return Whiteout from your graveyard to your hand.
this.addAbility(new SimpleActivatedAbility(Zone.GRAVEYARD, new ReturnToHandSourceEffect(), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); this.addAbility(new SimpleActivatedAbility(Zone.GRAVEYARD, new ReturnToHandSourceEffect(), new SacrificeTargetCost(new TargetControlledPermanent(filter))));

View file

@ -1,40 +1,102 @@
/* /*
* To change this license header, choose License Headers in Project Properties. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* To change this template file, choose Tools | Templates *
* and open the template in the editor. * 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.common.continuous; package mage.abilities.effects.common.continuous;
import java.util.HashMap;
import java.util.Iterator;
import java.util.UUID;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.CompoundAbility;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Layer; import mage.constants.Layer;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubLayer; import mage.constants.SubLayer;
import mage.constants.Zone;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
/** /**
* * @author BetaSteward_at_googlemail.com
* @author LevelX2
*/ */
public class LoseAbilityAllEffect extends ContinuousEffectImpl { public class LoseAbilityAllEffect extends ContinuousEffectImpl {
protected final FilterPermanent filter; protected CompoundAbility ability;
protected final Ability ability; protected boolean excludeSource;
protected FilterPermanent filter;
public LoseAbilityAllEffect(FilterPermanent filter, Ability ability, Duration duration) { public LoseAbilityAllEffect(Ability ability, Duration duration) {
this(ability, duration, new FilterPermanent("permanents"));
}
public LoseAbilityAllEffect(CompoundAbility ability, Duration duration) {
this(ability, duration, new FilterPermanent("permanents"));
}
public LoseAbilityAllEffect(Ability ability, Duration duration, FilterPermanent filter) {
this(ability, duration, filter, false);
}
public LoseAbilityAllEffect(CompoundAbility ability, Duration duration, FilterPermanent filter) {
this(ability, duration, filter, false);
}
public LoseAbilityAllEffect(Ability ability, Duration duration, FilterPermanent filter, boolean excludeSource) {
this(new CompoundAbility(ability), duration, filter, excludeSource);
}
public LoseAbilityAllEffect(CompoundAbility ability, Duration duration, FilterPermanent filter, boolean excludeSource) {
super(duration, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); super(duration, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
this.filter = filter;
this.ability = ability; this.ability = ability;
staticText = filter.getMessage() + " lose " + ability.toString() + (duration.toString().isEmpty() ? "" : ' ' + duration.toString()); this.filter = filter;
this.excludeSource = excludeSource;
} }
public LoseAbilityAllEffect(final LoseAbilityAllEffect effect) { public LoseAbilityAllEffect(final LoseAbilityAllEffect effect) {
super(effect); super(effect);
this.ability = effect.ability.copy();
this.filter = effect.filter.copy(); this.filter = effect.filter.copy();
this.ability = effect.ability; this.excludeSource = effect.excludeSource;
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
if (this.affectedObjectsSet) {
for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (!(excludeSource && perm.getId().equals(source.getSourceId()))) {
affectedObjectList.add(new MageObjectReference(perm, game));
}
}
}
} }
@Override @Override
@ -44,10 +106,40 @@ public class LoseAbilityAllEffect extends ContinuousEffectImpl {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { if (this.affectedObjectsSet) {
if (permanent != null) { for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext();) { // filter may not be used again, because object can have changed filter relevant attributes but still geets boost
while (permanent.getAbilities().contains(ability)) { Permanent perm = it.next().getPermanentOrLKIBattlefield(game); //LKI is neccessary for "dies triggered abilities" to work given to permanets (e.g. Showstopper)
permanent.getAbilities().remove(ability); if (perm != null) {
for (Ability ability : ability) {
perm.getAbilities().removeIf(entry -> entry.getId().equals(ability.getId()));
}
} else {
it.remove();
if (affectedObjectList.isEmpty()) {
discard();
}
}
}
} else {
for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (!(excludeSource && perm.getId().equals(source.getSourceId()))) {
for (Ability ability : ability) {
perm.getAbilities().removeIf(entry -> entry.getId().equals(ability.getId()));
}
}
}
// still as long as the prev. permanent is known to the LKI (e.g. Mikaeus, the Unhallowed) so gained dies triggered ability will trigger
HashMap<UUID, MageObject> LKIBattlefield = game.getLKI().get(Zone.BATTLEFIELD);
if (LKIBattlefield != null) {
for (MageObject mageObject : LKIBattlefield.values()) {
Permanent perm = (Permanent) mageObject;
if (!(excludeSource && perm.getId().equals(source.getSourceId()))) {
if (filter.match(perm, source.getSourceId(), source.getControllerId(), game)) {
for (Ability ability : ability) {
perm.getAbilities().removeIf(entry -> entry.getId().equals(ability.getId()));
}
}
}
} }
} }
} }

View file

@ -56,7 +56,7 @@ public class TargetCreaturePermanentSameController extends TargetCreaturePermane
UUID targetId = (UUID) object; UUID targetId = (UUID) object;
Permanent targetPermanent = game.getPermanent(targetId); Permanent targetPermanent = game.getPermanent(targetId);
if (targetPermanent != null) { if (targetPermanent != null) {
if (firstTargetPermanent.getId() != targetPermanent.getId()) { if (!firstTargetPermanent.getId().equals(targetPermanent.getId())) {
if (!firstTargetPermanent.getControllerId().equals(targetPermanent.getOwnerId())) { if (!firstTargetPermanent.getControllerId().equals(targetPermanent.getOwnerId())) {
return false; return false;
} }

View file

@ -61,7 +61,7 @@ public class TargetCreaturePermanentWithDifferentTypes extends TargetCreaturePer
for (Object object : getTargets()) { for (Object object : getTargets()) {
UUID targetId = (UUID) object; UUID targetId = (UUID) object;
Permanent selectedCreature = game.getPermanent(targetId); Permanent selectedCreature = game.getPermanent(targetId);
if (creature.getId() != selectedCreature.getId()) { if (!creature.getId().equals(selectedCreature.getId())) {
if (CardUtil.shareSubtypes(creature, selectedCreature, game)) { if (CardUtil.shareSubtypes(creature, selectedCreature, game)) {
return false; return false;
} }