diff --git a/Mage.Sets/src/mage/cards/a/AnimateArtifact.java b/Mage.Sets/src/mage/cards/a/AnimateArtifact.java index 51b61411ef3..78532834470 100644 --- a/Mage.Sets/src/mage/cards/a/AnimateArtifact.java +++ b/Mage.Sets/src/mage/cards/a/AnimateArtifact.java @@ -61,6 +61,8 @@ public final class AnimateArtifact extends CardImpl { class AnimateArtifactContinuousEffect extends ContinuousEffectImpl { + private boolean addedCreatureType = false; + AnimateArtifactContinuousEffect(Duration duration) { super(duration, Outcome.Benefit); staticText = "As long as enchanted artifact isn't a creature, it's an artifact creature with power and toughness each equal to its mana value"; @@ -68,6 +70,7 @@ class AnimateArtifactContinuousEffect extends ContinuousEffectImpl { private AnimateArtifactContinuousEffect(final AnimateArtifactContinuousEffect effect) { super(effect); + this.addedCreatureType = effect.addedCreatureType; } @Override @@ -82,6 +85,7 @@ class AnimateArtifactContinuousEffect extends ContinuousEffectImpl { switch (layer) { case TypeChangingEffects_4: permanent.addCardType(game, CardType.CREATURE); + this.addedCreatureType = true; break; case PTChangingEffects_7: if (sublayer != SubLayer.SetPT_7b) { @@ -89,6 +93,7 @@ class AnimateArtifactContinuousEffect extends ContinuousEffectImpl { } permanent.getPower().setModifiedBaseValue(permanent.getManaValue()); permanent.getToughness().setModifiedBaseValue(permanent.getManaValue()); + this.addedCreatureType = false; } } } @@ -100,7 +105,7 @@ class AnimateArtifactContinuousEffect extends ContinuousEffectImpl { return false; } Permanent permanent = game.getPermanent(enchantment.getAttachedTo()); - if (permanent == null || permanent.isCreature(game)) { + if (permanent == null || (permanent.isCreature(game) && !this.addedCreatureType)) { return false; } affectedObjects.add(permanent); diff --git a/Mage.Sets/src/mage/cards/c/CairnWanderer.java b/Mage.Sets/src/mage/cards/c/CairnWanderer.java index 4c6029497c5..67297d6886d 100644 --- a/Mage.Sets/src/mage/cards/c/CairnWanderer.java +++ b/Mage.Sets/src/mage/cards/c/CairnWanderer.java @@ -1,10 +1,11 @@ package mage.cards.c; -import java.util.UUID; import mage.MageInt; +import mage.MageItem; +import mage.abilities.Abilities; +import mage.abilities.AbilitiesImpl; import mage.abilities.Ability; -import mage.abilities.MageSingleton; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.keyword.*; @@ -12,10 +13,13 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; +import java.util.*; + /** * * @author psykad @@ -47,6 +51,22 @@ public final class CairnWanderer extends CardImpl { static class CairnWandererEffect extends ContinuousEffectImpl { + private static final Set> KEYWORD_ABILITIES = new HashSet<>(Arrays.asList( + FlyingAbility.class, + FearAbility.class, + FirstStrikeAbility.class, + DoubleStrikeAbility.class, + DeathtouchAbility.class, + HasteAbility.class, + LandwalkAbility.class, + LifelinkAbility.class, + ProtectionAbility.class, + ReachAbility.class, + TrampleAbility.class, + ShroudAbility.class, + VigilanceAbility.class + )); + public CairnWandererEffect() { super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); this.addDependedToType(DependencyType.AddingAbility); @@ -58,45 +78,48 @@ public final class CairnWanderer extends CardImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + Abilities graveyardAbilities = new AbilitiesImpl<>(); + getAbilitiesInGraveyards(game, source, graveyardAbilities); + + for (MageItem object : affectedObjects) { + Permanent permanent = (Permanent) object; + for (Ability ability : graveyardAbilities) { + if (isValidKeywordAbility(ability.getClass())) { + permanent.addAbility(ability, source.getSourceId(), game); + } + } + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Permanent sourcePermanent = game.getPermanent(source.getSourceId()); if (sourcePermanent == null) { return false; } + affectedObjects.add(sourcePermanent); + return true; + } + private void getAbilitiesInGraveyards(Game game, Ability source, Abilities graveyardAbilities) { for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); - - if (player != null) { - for (Card card : player.getGraveyard().getCards(game)) { - if (card.isCreature(game)) { - for (Ability ability : card.getAbilities(game)) { - if (ability instanceof MageSingleton) { - if (ability instanceof FlyingAbility - || ability instanceof FearAbility - || ability instanceof FirstStrikeAbility - || ability instanceof DoubleStrikeAbility - || ability instanceof DeathtouchAbility - || ability instanceof HasteAbility - || ability instanceof LifelinkAbility - || ability instanceof ReachAbility - || ability instanceof TrampleAbility - || ability instanceof ShroudAbility - || ability instanceof VigilanceAbility) { - sourcePermanent.addAbility(ability, source.getSourceId(), game); - } - } else if (ability instanceof ProtectionAbility - || ability instanceof LandwalkAbility) { - sourcePermanent.addAbility(ability, source.getSourceId(), game); - } - } - } - } + if (player == null) { + continue; + } + for (Card card : player.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game)) { + graveyardAbilities.addAll(card.getAbilities(game)); } } + } - return true; + private boolean isValidKeywordAbility(Class abilityClass) { + return KEYWORD_ABILITIES.stream() + .anyMatch(keywordClass -> + keywordClass.isAssignableFrom(abilityClass) + ); } @Override diff --git a/Mage.Sets/src/mage/cards/c/CallForAid.java b/Mage.Sets/src/mage/cards/c/CallForAid.java index cfbcf2d5dd3..288d480ba48 100644 --- a/Mage.Sets/src/mage/cards/c/CallForAid.java +++ b/Mage.Sets/src/mage/cards/c/CallForAid.java @@ -1,5 +1,6 @@ package mage.cards.c; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.OneShotEffect; @@ -153,13 +154,20 @@ class CallForAidYouCantSacrificeEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + ((Permanent) object).setCanBeSacrificed(false); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)) { if (permanent.getControllerId().equals(playerId)) { - permanent.setCanBeSacrificed(false); + affectedObjects.add(permanent); } } - return true; + return !affectedObjects.isEmpty(); } } diff --git a/Mage.Sets/src/mage/cards/c/CaptivatingVampire.java b/Mage.Sets/src/mage/cards/c/CaptivatingVampire.java index c2c1f3224e8..2f8e6c92c97 100644 --- a/Mage.Sets/src/mage/cards/c/CaptivatingVampire.java +++ b/Mage.Sets/src/mage/cards/c/CaptivatingVampire.java @@ -1,6 +1,7 @@ package mage.cards.c; import mage.MageInt; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; @@ -18,6 +19,8 @@ import mage.game.permanent.Permanent; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetCreaturePermanent; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; /** @@ -78,19 +81,25 @@ class CaptivatingVampireEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (permanent != null) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Permanent permanent = (Permanent) object; switch (layer) { case ControlChangingEffects_2: - if (sublayer == SubLayer.NA) { - permanent.changeControllerId(source.getControllerId(), game, source); - } + permanent.changeControllerId(source.getControllerId(), game, source); break; case TypeChangingEffects_4: permanent.addSubType(game, SubType.VAMPIRE); break; } + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent != null) { + affectedObjects.add(permanent); return true; } discard(); @@ -98,7 +107,12 @@ class CaptivatingVampireEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + List affectedObjects = new ArrayList<>(); + if (queryAffectedObjects(layer, source, game, affectedObjects)) { + applyToObjects(layer, sublayer, source, game, affectedObjects); + return true; + } return false; } diff --git a/Mage.Sets/src/mage/cards/c/CarnelianOrbOfDragonkind.java b/Mage.Sets/src/mage/cards/c/CarnelianOrbOfDragonkind.java index 1ab31d117e4..128969f737b 100644 --- a/Mage.Sets/src/mage/cards/c/CarnelianOrbOfDragonkind.java +++ b/Mage.Sets/src/mage/cards/c/CarnelianOrbOfDragonkind.java @@ -1,5 +1,6 @@ package mage.cards.c; +import mage.MageItem; import mage.MageObject; import mage.Mana; import mage.abilities.Ability; @@ -111,17 +112,23 @@ class CarnelianOrbOfDragonkindHasteEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + ((Permanent) object).addAbility(HasteAbility.getInstance(), source.getSourceId(), game); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { CarnelianOrbOfDragonkindWatcher watcher = game.getState().getWatcher(CarnelianOrbOfDragonkindWatcher.class, source.getSourceId()); if (watcher == null) { return false; } - - for (Permanent perm : game.getBattlefield().getAllActivePermanents()) { - if (watcher.creatureCastWithOrbsMana(perm.getId())) { - perm.addAbility(HasteAbility.getInstance(), source.getSourceId(), game); + for (Permanent permanent : game.getBattlefield().getAllActivePermanents()) { + if (watcher.creatureCastWithOrbsMana(permanent.getId())) { + affectedObjects.add(permanent); } } - return true; + return !affectedObjects.isEmpty(); } } diff --git a/Mage.Sets/src/mage/cards/c/CaseOfTheUneatenFeast.java b/Mage.Sets/src/mage/cards/c/CaseOfTheUneatenFeast.java index 395749437da..5475727d708 100644 --- a/Mage.Sets/src/mage/cards/c/CaseOfTheUneatenFeast.java +++ b/Mage.Sets/src/mage/cards/c/CaseOfTheUneatenFeast.java @@ -1,5 +1,6 @@ package mage.cards.c; +import mage.MageItem; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.CaseAbility; @@ -22,6 +23,7 @@ import mage.game.Game; import mage.players.Player; import mage.watchers.common.PlayerGainedLifeWatcher; +import java.util.List; import java.util.Objects; import java.util.UUID; @@ -102,25 +104,30 @@ class CaseOfTheUneatenFeastEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Card card = (Card) object; + MayCastFromGraveyardSourceAbility ability = new MayCastFromGraveyardSourceAbility(); + ability.setSourceId(card.getId()); + ability.setControllerId(card.getOwnerId()); + game.getState().addOtherAbility(card, ability); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Player player = game.getPlayer(source.getControllerId()); if (player == null) { return false; } - player.getGraveyard() - .stream() - .filter(cardId -> affectedObjectList.contains(new MageObjectReference(cardId, game))) - .forEach(cardId -> { - Card card = game.getCard(cardId); - if (card == null) { - return; - } - MayCastFromGraveyardSourceAbility ability = new MayCastFromGraveyardSourceAbility(); - ability.setSourceId(cardId); - ability.setControllerId(card.getOwnerId()); - game.getState().addOtherAbility(card, ability); - }); - return true; + for (MageObjectReference mor : affectedObjectList) { + Card card = mor.getCard(game); + if (card == null) { + continue; + } + affectedObjects.add(card); + } + return !affectedObjects.isEmpty(); } } diff --git a/Mage.Sets/src/mage/cards/c/CelestialDawn.java b/Mage.Sets/src/mage/cards/c/CelestialDawn.java index 397cf682d29..a6ea8f3490e 100644 --- a/Mage.Sets/src/mage/cards/c/CelestialDawn.java +++ b/Mage.Sets/src/mage/cards/c/CelestialDawn.java @@ -1,5 +1,6 @@ package mage.cards.c; +import mage.MageItem; import mage.MageObject; import mage.ObjectColor; import mage.abilities.Ability; @@ -8,7 +9,6 @@ import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.AsThoughManaEffect; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.mana.WhiteManaAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -22,6 +22,7 @@ import mage.game.stack.Spell; import mage.players.ManaPoolItem; import mage.players.Player; +import java.util.List; import java.util.UUID; /** @@ -61,7 +62,7 @@ class CelestialDawnToPlainsEffect extends ContinuousEffectImpl { private static final FilterLandPermanent filter = new FilterLandPermanent(); CelestialDawnToPlainsEffect() { - super(Duration.WhileOnBattlefield, Outcome.Detriment); + super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Detriment); this.staticText = "Lands you control are Plains"; } @@ -69,36 +70,29 @@ class CelestialDawnToPlainsEffect extends ContinuousEffectImpl { super(effect); } - @Override - public boolean apply(Game game, Ability source) { - return false; - } - @Override public CelestialDawnToPlainsEffect copy() { return new CelestialDawnToPlainsEffect(this); } @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - for (Permanent land : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { - switch (layer) { - case AbilityAddingRemovingEffects_6: - land.removeAllAbilities(source.getSourceId(), game); - land.addAbility(new WhiteManaAbility(), source.getSourceId(), game); - break; - case TypeChangingEffects_4: - land.removeAllSubTypes(game, SubTypeSet.NonBasicLandType); - land.addSubType(game, SubType.PLAINS); - break; - } + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Permanent land = (Permanent) object; + // 305.7 Note that this doesn't remove any abilities that were granted to the land by other effects + // So the ability removing has to be done before Layer 6 + // Lands have their mana ability intrinsically, so that is added in layer 4 + land.removeAllAbilities(source.getSourceId(), game); + land.removeAllSubTypes(game, SubTypeSet.NonBasicLandType); + land.addSubType(game, SubType.PLAINS); + land.addAbility(new WhiteManaAbility(), source.getSourceId(), game); } - return true; } @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4; + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + affectedObjects.addAll(game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)); + return !affectedObjects.isEmpty(); } } @@ -113,56 +107,42 @@ class CelestialDawnToWhiteEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - for (Permanent perm : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { - setColor(perm.getColor(game), game); - } - // Stack - for (MageObject object : game.getStack()) { - if (object instanceof Spell && ((Spell) object).isControlledBy(controller.getId())) { - setColor(object.getColor(game), game); - } - } - // Exile - for (Card card : game.getExile().getAllCards(game)) { - if (card.isOwnedBy(controller.getId())) { - setColor(card.getColor(game), game); - } - } - // Command - for (CommandObject commandObject : game.getState().getCommand()) { - if (commandObject instanceof Commander) { - if (commandObject.isControlledBy(controller.getId())) { - setColor(commandObject.getColor(game), game); - } - } - } - - // Hand - for (Card card : controller.getHand().getCards(game)) { - setColor(card.getColor(game), game); - } - // Library - for (Card card : controller.getLibrary().getCards(game)) { - setColor(card.getColor(game), game); - } - // Graveyard - for (Card card : controller.getGraveyard().getCards(game)) { - setColor(card.getColor(game), game); - } - return true; + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + ((MageObject) object).getColor(game).setColor(ObjectColor.WHITE); } - return false; } - protected static void setColor(ObjectColor color, Game game) { - color.setWhite(true); - color.setGreen(false); - color.setBlue(false); - color.setBlack(false); - color.setRed(false); + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + // Battlefield + affectedObjects.addAll(game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)); + // Stack + for (MageObject object : game.getStack()) { + if (object instanceof Spell && ((Spell) object).isControlledBy(controller.getId())) { + affectedObjects.add(object); + } + } + // Exile + affectedObjects.addAll(game.getExile().getAllCards(game, controller.getId())); + // Command + for (CommandObject commandObject : game.getState().getCommand()) { + if (commandObject instanceof Commander && commandObject.isControlledBy(controller.getId())) { + affectedObjects.add(commandObject); + } + } + // Hand + affectedObjects.addAll(controller.getHand().getCards(game)); + // Library + affectedObjects.addAll(controller.getLibrary().getCards(game)); + // Graveyard + affectedObjects.addAll(controller.getGraveyard().getCards(game)); + + return !affectedObjects.isEmpty(); } @Override diff --git a/Mage.Sets/src/mage/cards/c/ChallengerTroll.java b/Mage.Sets/src/mage/cards/c/ChallengerTroll.java index 009c88a411d..692ae897b3d 100644 --- a/Mage.Sets/src/mage/cards/c/ChallengerTroll.java +++ b/Mage.Sets/src/mage/cards/c/ChallengerTroll.java @@ -1,14 +1,16 @@ package mage.cards.c; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.combat.CantBeBlockedByMoreThanOneAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.game.Game; -import mage.game.permanent.Permanent; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; import java.util.UUID; @@ -17,6 +19,13 @@ import java.util.UUID; */ public final class ChallengerTroll extends CardImpl { + private static final FilterPermanent filter = new FilterControlledCreaturePermanent(); + + static { + filter.add(new PowerPredicate(ComparisonType.OR_GREATER, 4)); + } + + public ChallengerTroll(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}"); @@ -25,7 +34,7 @@ public final class ChallengerTroll extends CardImpl { this.toughness = new MageInt(5); // Each creature you control with power 4 or greater can't be blocked by more than one creature. - this.addAbility(new SimpleStaticAbility(new ChallengerTrollEffect())); + this.addAbility(new SimpleStaticAbility(new CantBeBlockedByMoreThanOneAllEffect(filter))); } private ChallengerTroll(final ChallengerTroll card) { @@ -37,44 +46,3 @@ public final class ChallengerTroll extends CardImpl { return new ChallengerTroll(this); } } - -class ChallengerTrollEffect extends ContinuousEffectImpl { - - ChallengerTrollEffect() { - super(Duration.WhileOnBattlefield, Outcome.Benefit); - staticText = "Each creature you control with power 4 or greater can't be blocked by more than one creature."; - } - - private ChallengerTrollEffect(final ChallengerTrollEffect effect) { - super(effect); - } - - @Override - public ChallengerTrollEffect copy() { - return new ChallengerTrollEffect(this); - } - - @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - if (layer != Layer.RulesEffects) { - return false; - } - for (Permanent permanent : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) { - if (permanent != null && permanent.isControlledBy(source.getControllerId()) - && permanent.isCreature(game) && permanent.getPower().getValue() >= 4) { - permanent.setMaxBlockedBy(1); - } - } - return true; - } - - @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.RulesEffects; - } -} diff --git a/Mage.Sets/src/mage/cards/c/ChariotOfTheSun.java b/Mage.Sets/src/mage/cards/c/ChariotOfTheSun.java index ce2056672af..b4297ee232a 100644 --- a/Mage.Sets/src/mage/cards/c/ChariotOfTheSun.java +++ b/Mage.Sets/src/mage/cards/c/ChariotOfTheSun.java @@ -1,6 +1,6 @@ package mage.cards.c; -import java.util.UUID; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; @@ -10,15 +10,14 @@ import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.SubLayer; +import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetControlledCreaturePermanent; +import java.util.List; +import java.util.UUID; + /** * * @author TheElk801 @@ -70,13 +69,21 @@ class ChariotOfTheSunEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Permanent permanent = (Permanent) object; + permanent.getToughness().setModifiedBaseValue(1); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); if (permanent == null) { this.discard(); return false; } - permanent.getToughness().setModifiedBaseValue(1); + affectedObjects.add(permanent); return true; } } diff --git a/Mage.Sets/src/mage/cards/c/ChimericCoils.java b/Mage.Sets/src/mage/cards/c/ChimericCoils.java index 764a0b4ac98..8fb3cd572b6 100644 --- a/Mage.Sets/src/mage/cards/c/ChimericCoils.java +++ b/Mage.Sets/src/mage/cards/c/ChimericCoils.java @@ -4,15 +4,13 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.effects.common.continuous.BecomesXXConstructSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.util.CardUtil; +import mage.constants.CardType; +import mage.constants.Duration; import java.util.UUID; @@ -25,7 +23,7 @@ public final class ChimericCoils extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}"); // {X}{1}: Chimeric Coils becomes an X/X Construct artifact creature. Sacrifice it at the beginning of the next end step. - Ability ability = new SimpleActivatedAbility(new ChimericCoilsEffect(), new ManaCostsImpl<>("{X}{1}")); + Ability ability = new SimpleActivatedAbility(new BecomesXXConstructSourceEffect(Duration.Custom), new ManaCostsImpl<>("{X}{1}")); ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new SacrificeSourceEffect()))); this.addAbility(ability); } @@ -39,58 +37,3 @@ public final class ChimericCoils extends CardImpl { return new ChimericCoils(this); } } - -class ChimericCoilsEffect extends ContinuousEffectImpl { - - ChimericCoilsEffect() { - super(Duration.Custom, Outcome.BecomeCreature); - staticText = "{this} becomes an X/X Construct artifact creature"; - this.dependencyTypes.add(DependencyType.BecomeCreature); - } - - private ChimericCoilsEffect(final ChimericCoilsEffect effect) { - super(effect); - } - - @Override - public ChimericCoilsEffect copy() { - return new ChimericCoilsEffect(this); - } - - @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent == null) { - return false; - } - switch (layer) { - case TypeChangingEffects_4: - if (!permanent.isArtifact(game)) { - permanent.addCardType(game, CardType.ARTIFACT); - } - if (!permanent.isCreature(game)) { - permanent.addCardType(game, CardType.CREATURE); - } - permanent.removeAllCreatureTypes(game); - permanent.addSubType(game, SubType.CONSTRUCT); - break; - case PTChangingEffects_7: - if (sublayer == SubLayer.SetPT_7b) { - int xValue = CardUtil.getSourceCostsTag(game, source, "X", 0); - permanent.getPower().setModifiedBaseValue(xValue); - permanent.getToughness().setModifiedBaseValue(xValue); - } - } - return true; - } - - @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.PTChangingEffects_7 || layer == Layer.TypeChangingEffects_4; - } -} diff --git a/Mage.Sets/src/mage/cards/c/ChimericStaff.java b/Mage.Sets/src/mage/cards/c/ChimericStaff.java index ac323495b8f..f124f1818d3 100644 --- a/Mage.Sets/src/mage/cards/c/ChimericStaff.java +++ b/Mage.Sets/src/mage/cards/c/ChimericStaff.java @@ -1,15 +1,11 @@ package mage.cards.c; -import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.continuous.BecomesXXConstructSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.util.CardUtil; import java.util.UUID; @@ -22,7 +18,7 @@ public final class ChimericStaff extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); // {X}: Chimeric Staff becomes an X/X Construct artifact creature until end of turn. - this.addAbility(new SimpleActivatedAbility(new ChimericStaffEffect(), new ManaCostsImpl<>("{X}"))); + this.addAbility(new SimpleActivatedAbility(new BecomesXXConstructSourceEffect(Duration.EndOfTurn), new ManaCostsImpl<>("{X}"))); } private ChimericStaff(final ChimericStaff card) { @@ -34,58 +30,3 @@ public final class ChimericStaff extends CardImpl { return new ChimericStaff(this); } } - -class ChimericStaffEffect extends ContinuousEffectImpl { - - ChimericStaffEffect() { - super(Duration.EndOfTurn, Outcome.BecomeCreature); - staticText = "{this} becomes an X/X Construct artifact creature until end of turn"; - this.dependencyTypes.add(DependencyType.BecomeCreature); - } - - private ChimericStaffEffect(final ChimericStaffEffect effect) { - super(effect); - } - - @Override - public ChimericStaffEffect copy() { - return new ChimericStaffEffect(this); - } - - @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent == null) { - return false; - } - switch (layer) { - case TypeChangingEffects_4: - if (!permanent.isArtifact(game)) { - permanent.addCardType(game, CardType.ARTIFACT); - } - if (!permanent.isCreature(game)) { - permanent.addCardType(game, CardType.CREATURE); - } - permanent.removeAllCreatureTypes(game); - permanent.addSubType(game, SubType.CONSTRUCT); - break; - case PTChangingEffects_7: - if (sublayer == SubLayer.SetPT_7b) { - int xValue = CardUtil.getSourceCostsTag(game, source, "X", 0); - permanent.getPower().setModifiedBaseValue(xValue); - permanent.getToughness().setModifiedBaseValue(xValue); - } - } - return true; - } - - @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.PTChangingEffects_7 || layer == Layer.TypeChangingEffects_4; - } -} diff --git a/Mage.Sets/src/mage/cards/c/ChirrutImwe.java b/Mage.Sets/src/mage/cards/c/ChirrutImwe.java index 2e8be6534fe..20674e1ec84 100644 --- a/Mage.Sets/src/mage/cards/c/ChirrutImwe.java +++ b/Mage.Sets/src/mage/cards/c/ChirrutImwe.java @@ -1,6 +1,7 @@ package mage.cards.c; import mage.MageInt; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; @@ -14,6 +15,7 @@ import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; +import java.util.List; import java.util.UUID; /** @@ -52,7 +54,7 @@ public final class ChirrutImwe extends CardImpl { class ChirrutImweEffect extends ContinuousEffectImpl { public ChirrutImweEffect() { - super(Duration.WhileOnBattlefield, Outcome.Benefit); + super(Duration.WhileOnBattlefield, Layer.RulesEffects, SubLayer.NA, Outcome.Benefit); staticText = "{this} can block up to two additional creatures"; } @@ -66,28 +68,21 @@ class ChirrutImweEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - Permanent perm = game.getPermanent(source.getSourceId()); - if (perm != null) { - switch (layer) { - case RulesEffects: - // maxBlocks = 0 equals to "can block any number of creatures" - if (perm.getMaxBlocks() > 0) { - perm.setMaxBlocks(perm.getMaxBlocks() + 2); - } - break; - } + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Permanent permanent = (Permanent) object; + permanent.setMaxBlocks(permanent.getMaxBlocks() + 2); } - return false; } @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.RulesEffects; + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + Permanent permanent = game.getPermanent(source.getSourceId()); + // maxBlocks = 0 equals to "can block any number of creatures" + if (permanent == null || permanent.getMaxBlocks() == 0) { + return false; + } + affectedObjects.add(permanent); + return true; } } diff --git a/Mage.Sets/src/mage/cards/c/ChissGoriaForgeTyrant.java b/Mage.Sets/src/mage/cards/c/ChissGoriaForgeTyrant.java index 6eca6368d9e..52353debad0 100644 --- a/Mage.Sets/src/mage/cards/c/ChissGoriaForgeTyrant.java +++ b/Mage.Sets/src/mage/cards/c/ChissGoriaForgeTyrant.java @@ -1,6 +1,7 @@ package mage.cards.c; import mage.MageInt; +import mage.MageItem; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; @@ -158,25 +159,33 @@ class ChissGoriaForgeTyrantAffinityEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + game.getState().addOtherAbility((Card) object, new AffinityForArtifactsAbility()); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { if (!ChissGoriaForgeTyrantWatcher.checkRef(source, morSet, game)) { discard(); return false; } - for (Card card : game.getExile().getAllCardsByRange(game, source.getControllerId())) { - if (morSet.contains(new MageObjectReference(card, game)) && card.isArtifact(game)) { - game.getState().addOtherAbility(card, new AffinityForArtifactsAbility()); + for (MageObjectReference mor : morSet) { + Card card = mor.getCard(game); + if (card != null && card.isArtifact(game)) { + affectedObjects.add(card); } } for (StackObject stackObject : game.getStack()) { - if (!(stackObject instanceof Spell) || !stackObject.isControlledBy(source.getControllerId())) { + if (!(stackObject instanceof Spell) || !stackObject.isControlledBy(source.getControllerId())) { continue; } Card card = game.getCard(stackObject.getSourceId()); if (card != null && morSet.contains(new MageObjectReference(card, game, -1))) { - game.getState().addOtherAbility(card, new AffinityForArtifactsAbility()); + affectedObjects.add(card); } } return true; diff --git a/Mage.Sets/src/mage/cards/c/CircleOfTheMoonDruid.java b/Mage.Sets/src/mage/cards/c/CircleOfTheMoonDruid.java index 11b3632e532..fcbeb2ab7dc 100644 --- a/Mage.Sets/src/mage/cards/c/CircleOfTheMoonDruid.java +++ b/Mage.Sets/src/mage/cards/c/CircleOfTheMoonDruid.java @@ -1,6 +1,7 @@ package mage.cards.c; import mage.MageInt; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; @@ -10,6 +11,8 @@ import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; /** @@ -56,29 +59,43 @@ class CircleOfTheMoonDruidBearEffect extends ContinuousEffectImpl { return new CircleOfTheMoonDruidBearEffect(this); } + @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Permanent permanent = (Permanent) object; + switch (layer) { + case TypeChangingEffects_4: + permanent.removeAllCreatureTypes(game); + permanent.addSubType(game, SubType.BEAR); + break; + case PTChangingEffects_7: + if (sublayer == SubLayer.SetPT_7b) { + permanent.getPower().setModifiedBaseValue(4); + permanent.getToughness().setModifiedBaseValue(2); + } + break; + } + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Permanent permanent = source.getSourcePermanentIfItStillExists(game); if (permanent == null || !game.isActivePlayer(source.getControllerId())) { return false; } - switch (layer) { - case TypeChangingEffects_4: - permanent.removeAllCreatureTypes(game); - permanent.addSubType(game, SubType.BEAR); - return true; - case PTChangingEffects_7: - if (sublayer == SubLayer.SetPT_7b) { - permanent.getPower().setModifiedBaseValue(4); - permanent.getToughness().setModifiedBaseValue(2); - return true; - } - } - return false; + affectedObjects.add(permanent); + return true; } @Override - public boolean apply(Game game, Ability source) { + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + List affectedObjects = new ArrayList<>(); + if (queryAffectedObjects(layer, source, game, affectedObjects)) { + applyToObjects(layer, sublayer, source, game, affectedObjects); + return true; + } return false; } diff --git a/Mage.Sets/src/mage/cards/c/Clamavus.java b/Mage.Sets/src/mage/cards/c/Clamavus.java index f72aadc9623..2d05983076b 100644 --- a/Mage.Sets/src/mage/cards/c/Clamavus.java +++ b/Mage.Sets/src/mage/cards/c/Clamavus.java @@ -1,6 +1,7 @@ package mage.cards.c; import mage.MageInt; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; @@ -60,17 +61,23 @@ class ClamavusEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { - List permanents = game.getBattlefield().getActivePermanents( - StaticFilters.FILTER_CONTROLLED_CREATURE, source.getControllerId(), game - ); - for (Permanent permanent : permanents) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Permanent permanent = (Permanent) object; int count = permanent.getCounters(game).getCount(CounterType.P1P1); - if (count > 0) { - permanent.addPower(count); - permanent.addToughness(count); + permanent.addPower(count); + permanent.addToughness(count); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + for (Permanent permanent : game.getBattlefield().getActivePermanents( + StaticFilters.FILTER_CONTROLLED_CREATURE, source.getControllerId(), game)) { + if (permanent.getCounters(game).getCount(CounterType.P1P1) > 0) { + affectedObjects.add(permanent); } } - return true; + return !affectedObjects.isEmpty(); } } diff --git a/Mage.Sets/src/mage/cards/c/CoatOfArms.java b/Mage.Sets/src/mage/cards/c/CoatOfArms.java index 26b8c76254a..6e3ee79a399 100644 --- a/Mage.Sets/src/mage/cards/c/CoatOfArms.java +++ b/Mage.Sets/src/mage/cards/c/CoatOfArms.java @@ -1,6 +1,7 @@ package mage.cards.c; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; @@ -53,22 +54,26 @@ class CoatOfArmsEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { - List permanents = game.getBattlefield().getActivePermanents( - StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game - ); - for (Permanent permanent : permanents) { - int amount = getAmount(permanents, permanent, game); + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Permanent permanent = (Permanent) object; + int amount = getAmount(affectedObjects, permanent, game); permanent.addPower(amount); permanent.addToughness(amount); } - return true; } - private int getAmount(List permanents, Permanent target, Game game) { + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + affectedObjects.addAll(game.getBattlefield().getActivePermanents( + StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game)); + return !affectedObjects.isEmpty(); + } + + private int getAmount(List permanents, Permanent target, Game game) { int amount = 0; - for (Permanent permanent : permanents) { - if (!permanent.getId().equals(target.getId()) && permanent.shareCreatureTypes(game, target)) { + for (MageItem permanent : permanents) { + if (!permanent.getId().equals(target.getId()) && ((Permanent) permanent).shareCreatureTypes(game, target)) { amount++; } } diff --git a/Mage.Sets/src/mage/cards/c/CometStellarPup.java b/Mage.Sets/src/mage/cards/c/CometStellarPup.java index a971fb75333..9231561d959 100644 --- a/Mage.Sets/src/mage/cards/c/CometStellarPup.java +++ b/Mage.Sets/src/mage/cards/c/CometStellarPup.java @@ -1,5 +1,6 @@ package mage.cards.c; +import mage.MageItem; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; @@ -29,6 +30,7 @@ import mage.target.common.TargetCreatureOrPlayer; import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTargets; +import java.util.List; import java.util.UUID; /** @@ -177,11 +179,20 @@ class CometStellarPupContinuousEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Permanent comet = (Permanent) object; + comet.incrementLoyaltyActivationsAvailable(); + comet.incrementLoyaltyActivationsAvailable(); + + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Permanent comet = cometMOR.getPermanent(game); if (comet != null) { - comet.incrementLoyaltyActivationsAvailable(); - comet.incrementLoyaltyActivationsAvailable(); + affectedObjects.add(comet); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/c/CommandersPlate.java b/Mage.Sets/src/mage/cards/c/CommandersPlate.java index 6a04a1c38b5..2213329b1ec 100644 --- a/Mage.Sets/src/mage/cards/c/CommandersPlate.java +++ b/Mage.Sets/src/mage/cards/c/CommandersPlate.java @@ -1,5 +1,6 @@ package mage.cards.c; +import mage.MageItem; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; @@ -23,6 +24,7 @@ import mage.target.TargetPermanent; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.targetpointer.FixedTarget; +import java.util.List; import java.util.Set; import java.util.UUID; @@ -100,7 +102,40 @@ class CommandersPlateEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + Player player = game.getPlayer(source.getControllerId()); + Set commanders = game.getCommandersIds(player, CommanderCardType.COMMANDER_OR_OATHBREAKER, false); + for (MageItem object : affectedObjects) { + Permanent permanent = (Permanent) object; + ObjectColor color = new ObjectColor("WUBRG"); + for (UUID commanderId : commanders) { + Card card = game.getCard(commanderId); + if (card == null) { + continue; + } + FilterMana identity = card.getColorIdentity(); + if (identity.isWhite()) { + color.setWhite(false); + } + if (identity.isBlue()) { + color.setBlue(false); + } + if (identity.isBlack()) { + color.setBlack(false); + } + if (identity.isRed()) { + color.setRed(false); + } + if (identity.isGreen()) { + color.setGreen(false); + } + } + permanent.addAbility(ProtectionAbility.from(color), source.getSourceId(), game); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Player player = game.getPlayer(source.getControllerId()); if (player == null) { return false; @@ -119,35 +154,10 @@ class CommandersPlateEffect extends ContinuousEffectImpl { } } Set commanders = game.getCommandersIds(player, CommanderCardType.COMMANDER_OR_OATHBREAKER, false); - if (commanders.isEmpty()) { + if (commanders.isEmpty() || permanent == null) { return false; } - ObjectColor color = new ObjectColor("WUBRG"); - for (UUID commanderId : commanders) { - Card card = game.getCard(commanderId); - if (card == null) { - continue; - } - FilterMana identity = card.getColorIdentity(); - if (identity.isWhite()) { - color.setWhite(false); - } - if (identity.isBlue()) { - color.setBlue(false); - } - if (identity.isBlack()) { - color.setBlack(false); - } - if (identity.isRed()) { - color.setRed(false); - } - if (identity.isGreen()) { - color.setGreen(false); - } - } - if (permanent != null) { - permanent.addAbility(ProtectionAbility.from(color), source.getSourceId(), game); - } + affectedObjects.add(permanent); return true; } } diff --git a/Mage.Sets/src/mage/cards/c/ConfessionDial.java b/Mage.Sets/src/mage/cards/c/ConfessionDial.java index 4b7ddf5228d..245492e7b3f 100644 --- a/Mage.Sets/src/mage/cards/c/ConfessionDial.java +++ b/Mage.Sets/src/mage/cards/c/ConfessionDial.java @@ -1,7 +1,6 @@ package mage.cards.c; -import java.util.UUID; - +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; @@ -17,6 +16,9 @@ import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.target.common.TargetCardInYourGraveyard; +import java.util.List; +import java.util.UUID; + /** * @author Cguy7777 */ @@ -66,15 +68,23 @@ class ConfessionDialEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Card card = (Card) object; + Ability ability = new EscapeAbility(card, card.getManaCost().getText(), 3); + ability.setSourceId(card.getId()); + ability.setControllerId(card.getOwnerId()); + game.getState().addOtherAbility(card, ability); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Card card = game.getCard(getTargetPointer().getFirst(game, source)); if (card == null || card.getManaCost().getText().isEmpty()) { return false; } - Ability ability = new EscapeAbility(card, card.getManaCost().getText(), 3); - ability.setSourceId(card.getId()); - ability.setControllerId(card.getOwnerId()); - game.getState().addOtherAbility(card, ability); + affectedObjects.add(card); return true; } diff --git a/Mage.Sets/src/mage/cards/c/Conspiracy.java b/Mage.Sets/src/mage/cards/c/Conspiracy.java index c05affa5d3b..4bc2f3aa31c 100644 --- a/Mage.Sets/src/mage/cards/c/Conspiracy.java +++ b/Mage.Sets/src/mage/cards/c/Conspiracy.java @@ -1,5 +1,6 @@ package mage.cards.c; +import mage.MageItem; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; @@ -19,7 +20,6 @@ import mage.game.stack.StackObject; import mage.players.Player; import mage.util.SubTypes; -import java.util.Iterator; import java.util.List; import java.util.UUID; @@ -70,7 +70,21 @@ public final class Conspiracy extends CardImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + SubType subType = ChooseCreatureTypeEffect.getChosenCreatureType(source.getSourceId(), game); + for (MageItem object : affectedObjects) { + if (object instanceof Permanent) { + Permanent permanent = (Permanent) object; + permanent.removeAllSubTypes(game); + permanent.addSubType(game, subType); + } else { + setCreatureSubtype((MageObject) object, subType, game); + } + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Player controller = game.getPlayer(source.getControllerId()); SubType subType = ChooseCreatureTypeEffect.getChosenCreatureType(source.getSourceId(), game); if (controller == null || subType == null) { @@ -81,56 +95,54 @@ public final class Conspiracy extends CardImpl { for (UUID cardId : controller.getGraveyard()) { Card card = game.getCard(cardId); if (card != null && card.isCreature(game)) { - setCreatureSubtype(card, subType, game); + affectedObjects.add(card); } } // on Hand for (UUID cardId : controller.getHand()) { Card card = game.getCard(cardId); if (card != null && card.isCreature(game)) { - setCreatureSubtype(card, subType, game); + affectedObjects.add(card); } } // in Exile - for (Card card : game.getState().getExile().getAllCards(game)) { + for (Card card : game.getState().getExile().getAllCards(game, controller.getId())) { if (card.isOwnedBy(controller.getId()) && card.isCreature(game)) { - setCreatureSubtype(card, subType, game); + affectedObjects.add(card); } } // in Library (e.g. for Mystical Teachings) for (Card card : controller.getLibrary().getCards(game)) { if (card.isOwnedBy(controller.getId()) && card.isCreature(game)) { - setCreatureSubtype(card, subType, game); + affectedObjects.add(card); } } // in command zone for (CommandObject commandObject : game.getState().getCommand()) { if (commandObject instanceof Commander) { - Card card = game.getCard(((Commander) commandObject).getId()); + Card card = game.getCard(commandObject.getId()); if (card != null && card.isCreature(game) && card.isOwnedBy(controller.getId())) { - setCreatureSubtype(card, subType, game); + affectedObjects.add(card); } } } // creature spells you control - for (Iterator iterator = game.getStack().iterator(); iterator.hasNext(); ) { - StackObject stackObject = iterator.next(); + for (StackObject stackObject : game.getStack()) { if (stackObject instanceof Spell && stackObject.isControlledBy(controller.getId()) && stackObject.isCreature(game)) { - setCreatureSubtype(stackObject, subType, game); - setCreatureSubtype(((Spell) stackObject).getCard(), subType, game); + affectedObjects.add(stackObject); + affectedObjects.add(((Spell) stackObject).getCard()); } } // creatures you control List permanents = game.getBattlefield().getAllActivePermanents(controller.getId()); for (Permanent permanent : permanents) { if (permanent.isCreature(game)) { - permanent.removeAllCreatureTypes(game); - permanent.addSubType(game, subType); + affectedObjects.add(permanent); } } - return true; + return !affectedObjects.isEmpty(); } private void setCreatureSubtype(MageObject object, SubType subtype, Game game) { @@ -143,4 +155,5 @@ public final class Conspiracy extends CardImpl { subTypes.add(subtype); } } + } diff --git a/Mage.Sets/src/mage/cards/c/ConspiracyUnraveler.java b/Mage.Sets/src/mage/cards/c/ConspiracyUnraveler.java index 0804a14dfba..73222903d41 100644 --- a/Mage.Sets/src/mage/cards/c/ConspiracyUnraveler.java +++ b/Mage.Sets/src/mage/cards/c/ConspiracyUnraveler.java @@ -1,6 +1,7 @@ package mage.cards.c; import mage.MageInt; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.SourceIsSpellCondition; @@ -14,6 +15,7 @@ import mage.constants.*; import mage.game.Game; import mage.players.Player; +import java.util.List; import java.util.UUID; /** @@ -52,7 +54,7 @@ class ConspiracyUnravelerInsteadEffect extends ContinuousEffectImpl { private final AlternativeCostSourceAbility alternativeCastingCostAbility = new AlternativeCostSourceAbility(new CollectEvidenceCost(10), SourceIsSpellCondition.instance); ConspiracyUnravelerInsteadEffect() { - super(Duration.WhileOnBattlefield, Outcome.Detriment); + super(Duration.WhileOnBattlefield, Layer.RulesEffects, SubLayer.NA, Outcome.Detriment); staticText = "You may collect evidence 10 rather than pay the mana cost for spells that you cast"; } @@ -72,23 +74,20 @@ class ConspiracyUnravelerInsteadEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + ((Player) object).getAlternativeSourceCosts().add(alternativeCastingCostAbility); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - controller.getAlternativeSourceCosts().add(alternativeCastingCostAbility); + affectedObjects.add(controller); return true; } return false; } - @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.RulesEffects; - } - } diff --git a/Mage.Sets/src/mage/cards/c/Conversion.java b/Mage.Sets/src/mage/cards/c/Conversion.java index 73afd85c63a..edad79cd3ae 100644 --- a/Mage.Sets/src/mage/cards/c/Conversion.java +++ b/Mage.Sets/src/mage/cards/c/Conversion.java @@ -1,7 +1,7 @@ package mage.cards.c; +import mage.MageItem; import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.ContinuousEffect; @@ -9,10 +9,11 @@ import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect; import mage.abilities.mana.WhiteManaAbility; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; -import mage.filter.StaticFilters; +import mage.filter.common.FilterLandPermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -52,7 +53,7 @@ public final class Conversion extends CardImpl { static class ConversionEffect extends ContinuousEffectImpl { ConversionEffect() { - super(Duration.WhileOnBattlefield, Outcome.Detriment); + super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Detriment); this.staticText = "All Mountains are Plains"; } @@ -60,36 +61,27 @@ public final class Conversion extends CardImpl { super(effect); } - @Override - public boolean apply(Game game, Ability source) { - return false; - } - @Override public ConversionEffect copy() { return new ConversionEffect(this); } @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - for (Permanent land : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_LAND, source.getControllerId(), source, game)) { - switch (layer) { - case TypeChangingEffects_4: - if (land.hasSubtype(SubType.MOUNTAIN, game)) { - land.removeAllSubTypes(game, SubTypeSet.NonBasicLandType); - land.addSubType(game, SubType.PLAINS); - land.removeAllAbilities(source.getSourceId(), game); - land.addAbility(new WhiteManaAbility(), source.getSourceId(), game); - break; - } - } + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Permanent land = (Permanent) object; + land.removeAllSubTypes(game, SubTypeSet.NonBasicLandType); + land.addSubType(game, SubType.PLAINS); + land.removeAllAbilities(source.getSourceId(), game); + land.addAbility(new WhiteManaAbility(), source.getSourceId(), game); } - return true; } @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.TypeChangingEffects_4; + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + affectedObjects.addAll(game.getBattlefield().getActivePermanents( + new FilterLandPermanent(SubType.MOUNTAIN, "Mountains"), source.getControllerId(), source, game)); + return !affectedObjects.isEmpty(); } @Override diff --git a/Mage.Sets/src/mage/cards/c/ConvincingMirage.java b/Mage.Sets/src/mage/cards/c/ConvincingMirage.java index 08674d28a6a..919f7abcfd4 100644 --- a/Mage.Sets/src/mage/cards/c/ConvincingMirage.java +++ b/Mage.Sets/src/mage/cards/c/ConvincingMirage.java @@ -1,5 +1,6 @@ package mage.cards.c; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; @@ -16,6 +17,7 @@ import mage.game.permanent.Permanent; import mage.target.TargetPermanent; import mage.target.common.TargetLandPermanent; +import java.util.List; import java.util.UUID; /** @@ -96,7 +98,35 @@ class ConvincingMirageContinousEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + SubType choice = SubType.byDescription((String) game.getState().getValue(source.getSourceId().toString() + ChooseBasicLandTypeEffect.VALUE_KEY)); + for (MageItem object : affectedObjects) { + Permanent land = (Permanent) object; + land.removeAllSubTypes(game, SubTypeSet.NonBasicLandType); + land.addSubType(game, choice); + land.removeAllAbilities(source.getSourceId(), game); + switch (choice) { + case FOREST: + land.addAbility(new GreenManaAbility(), source.getSourceId(), game); + break; + case PLAINS: + land.addAbility(new WhiteManaAbility(), source.getSourceId(), game); + break; + case MOUNTAIN: + land.addAbility(new RedManaAbility(), source.getSourceId(), game); + break; + case ISLAND: + land.addAbility(new BlueManaAbility(), source.getSourceId(), game); + break; + case SWAMP: + land.addAbility(new BlackManaAbility(), source.getSourceId(), game); + break; + } + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Permanent enchantment = game.getPermanent(source.getSourceId()); SubType choice = SubType.byDescription((String) game.getState().getValue(source.getSourceId().toString() + ChooseBasicLandTypeEffect.VALUE_KEY)); if (enchantment == null || enchantment.getAttachedTo() == null || choice == null) { @@ -106,26 +136,7 @@ class ConvincingMirageContinousEffect extends ContinuousEffectImpl { if (land == null) { return false; } - land.removeAllSubTypes(game, SubTypeSet.NonBasicLandType); - land.addSubType(game, choice); - land.removeAllAbilities(source.getSourceId(), game); - switch (choice) { - case FOREST: - land.addAbility(new GreenManaAbility(), source.getSourceId(), game); - break; - case PLAINS: - land.addAbility(new WhiteManaAbility(), source.getSourceId(), game); - break; - case MOUNTAIN: - land.addAbility(new RedManaAbility(), source.getSourceId(), game); - break; - case ISLAND: - land.addAbility(new BlueManaAbility(), source.getSourceId(), game); - break; - case SWAMP: - land.addAbility(new BlackManaAbility(), source.getSourceId(), game); - break; - } + affectedObjects.add(land); return true; } } diff --git a/Mage.Sets/src/mage/cards/c/CosimaGodOfTheVoyage.java b/Mage.Sets/src/mage/cards/c/CosimaGodOfTheVoyage.java index 55dba3ec118..c8456517828 100644 --- a/Mage.Sets/src/mage/cards/c/CosimaGodOfTheVoyage.java +++ b/Mage.Sets/src/mage/cards/c/CosimaGodOfTheVoyage.java @@ -1,15 +1,16 @@ package mage.cards.c; import mage.MageInt; +import mage.MageItem; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.DealsDamageToAPlayerAllTriggeredAbility; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.CrewAbility; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.*; import mage.constants.*; import mage.counters.CounterType; @@ -21,6 +22,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; @@ -136,17 +138,25 @@ class CosimaGodOfTheVoyageGainAbilityEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { - Card card = mor.getCard(game); - if (card != null && game.getState().getZone(card.getId()) == Zone.EXILED) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Card card = (Card) object; Ability ability = new CosimaGodOfTheVoyageTriggeredAbility(); ability.setSourceId(card.getId()); ability.setControllerId(source.getControllerId()); game.getState().addOtherAbility(card, ability); - } else { - discard(); } - return true; + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + Card card = mor.getCard(game); + if (card != null && game.getState().getZone(card.getId()) == Zone.EXILED) { + affectedObjects.add(card); + return true; + } + discard(); + return false; } } diff --git a/Mage.Sets/src/mage/cards/c/CourageousResolve.java b/Mage.Sets/src/mage/cards/c/CourageousResolve.java index b3719ad8181..f0795242b8a 100644 --- a/Mage.Sets/src/mage/cards/c/CourageousResolve.java +++ b/Mage.Sets/src/mage/cards/c/CourageousResolve.java @@ -1,5 +1,6 @@ package mage.cards.c; +import mage.MageItem; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.condition.common.FatefulHourCondition; @@ -25,6 +26,7 @@ import mage.players.Player; import mage.target.common.TargetControlledCreaturePermanent; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.UUID; @@ -145,10 +147,17 @@ class CourageousResolveCantLoseLifeEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + ((Player) object).setCanLoseLife(false); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - player.setCanLoseLife(false); + affectedObjects.add(player); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/c/CrownOfEmpires.java b/Mage.Sets/src/mage/cards/c/CrownOfEmpires.java index d7c4e88a5e0..f8f88b7d381 100644 --- a/Mage.Sets/src/mage/cards/c/CrownOfEmpires.java +++ b/Mage.Sets/src/mage/cards/c/CrownOfEmpires.java @@ -1,7 +1,7 @@ package mage.cards.c; +import mage.MageItem; import mage.abilities.Ability; -import mage.abilities.Mode; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; @@ -17,6 +17,7 @@ import mage.target.common.TargetCreaturePermanent; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; +import java.util.List; import java.util.UUID; /** @@ -102,11 +103,20 @@ class CrownOfEmpiresControlEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + UUID controllerId = (UUID) game.getState().getValue(source.getSourceId().toString()); + for (MageItem object : affectedObjects) { + ((Permanent) object).changeControllerId(controllerId, game, source); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); UUID controllerId = (UUID) game.getState().getValue(source.getSourceId().toString()); if (permanent != null && controllerId != null) { - return permanent.changeControllerId(controllerId, game, source); + affectedObjects.add(permanent); + return true; } return false; } diff --git a/Mage.Sets/src/mage/cards/c/CurseOfConformity.java b/Mage.Sets/src/mage/cards/c/CurseOfConformity.java index 5ef27c7d9f6..34d38fba212 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfConformity.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfConformity.java @@ -1,5 +1,6 @@ package mage.cards.c; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; @@ -15,6 +16,8 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.TargetPlayer; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; /** @@ -73,10 +76,9 @@ class CurseOfConformityEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - for (Permanent permanent : game.getBattlefield().getActivePermanents( - filter, source.getControllerId(), source, game - )) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Permanent permanent = (Permanent) object; switch (layer) { case TypeChangingEffects_4: permanent.removeAllCreatureTypes(game); @@ -88,16 +90,26 @@ class CurseOfConformityEffect extends ContinuousEffectImpl { } } } - return true; + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + affectedObjects.addAll(game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)); + return !affectedObjects.isEmpty(); + } + + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + List affectedObjects = new ArrayList<>(); + if (queryAffectedObjects(layer, source, game, affectedObjects)) { + applyToObjects(layer, sublayer, source, game, affectedObjects); + return true; + } + return false; } @Override public boolean hasLayer(Layer layer) { return layer == Layer.TypeChangingEffects_4 || layer == Layer.PTChangingEffects_7; } - - @Override - public boolean apply(Game game, Ability source) { - return false; - } } diff --git a/Mage.Sets/src/mage/cards/c/CurseclothWrappings.java b/Mage.Sets/src/mage/cards/c/CurseclothWrappings.java index a74c3ed7b36..201f08e6e43 100644 --- a/Mage.Sets/src/mage/cards/c/CurseclothWrappings.java +++ b/Mage.Sets/src/mage/cards/c/CurseclothWrappings.java @@ -1,7 +1,6 @@ package mage.cards.c; -import java.util.UUID; - +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; @@ -12,17 +11,15 @@ import mage.abilities.keyword.EmbalmAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.SubLayer; -import mage.constants.SubType; +import mage.constants.*; import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.target.common.TargetCardInYourGraveyard; +import java.util.List; +import java.util.UUID; + /** * * @author Jmlundeen @@ -77,11 +74,19 @@ class CurseClothWrappingsEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { - Card card = game.getCard(getTargetPointer().getFirst(game, source)); - if (card != null) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Card card = (Card) object; EmbalmAbility embalmAbility = new EmbalmAbility(card.getManaCost(), card); game.getState().addOtherAbility(card, embalmAbility); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + Card card = game.getCard(getTargetPointer().getFirst(game, source)); + if (card != null) { + affectedObjects.add(card); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/c/CursedRack.java b/Mage.Sets/src/mage/cards/c/CursedRack.java index 570bf0a4858..6076e900e42 100644 --- a/Mage.Sets/src/mage/cards/c/CursedRack.java +++ b/Mage.Sets/src/mage/cards/c/CursedRack.java @@ -1,7 +1,7 @@ package mage.cards.c; -import java.util.UUID; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; @@ -13,6 +13,9 @@ import mage.constants.*; import mage.game.Game; import mage.players.Player; +import java.util.List; +import java.util.UUID; + /** * * @author MarcoMarin @@ -56,11 +59,19 @@ class CursedRackHandSizeEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + UUID playerId = (UUID) game.getState().getValue(source.getSourceId() + ChooseOpponentEffect.VALUE_KEY); + for (MageItem object : affectedObjects) { + ((Player) object).setMaxHandSize(4); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { UUID playerId = (UUID) game.getState().getValue(source.getSourceId() + ChooseOpponentEffect.VALUE_KEY); Player opponent = game.getPlayer(playerId); if (opponent != null) { - opponent.setMaxHandSize(4); + affectedObjects.add(opponent); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/c/CyberdriveAwakener.java b/Mage.Sets/src/mage/cards/c/CyberdriveAwakener.java index 469c5c7e081..db8921f8cdc 100644 --- a/Mage.Sets/src/mage/cards/c/CyberdriveAwakener.java +++ b/Mage.Sets/src/mage/cards/c/CyberdriveAwakener.java @@ -1,6 +1,7 @@ package mage.cards.c; import mage.MageInt; +import mage.MageItem; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -18,6 +19,7 @@ import mage.filter.predicate.Predicates; import mage.game.Game; import mage.game.permanent.Permanent; +import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.UUID; @@ -87,19 +89,10 @@ class CyberdriveAwakenerEffect extends ContinuousEffectImpl { .map(permanent -> new MageObjectReference(permanent, game)) .forEach(affectedObjectList::add); } - @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - List permanents = affectedObjectList - .stream() - .map(mor -> mor.getPermanent(game)) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - if (permanents.isEmpty()) { - discard(); - return false; - } - for (Permanent permanent : permanents) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Permanent permanent = (Permanent) object; switch (layer) { case TypeChangingEffects_4: permanent.addCardType(game, CardType.ARTIFACT, CardType.CREATURE); @@ -111,20 +104,39 @@ class CyberdriveAwakenerEffect extends ContinuousEffectImpl { } } } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + List permanents = affectedObjectList + .stream() + .map(mor -> mor.getPermanent(game)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + if (permanents.isEmpty()) { + discard(); + return false; + } + affectedObjects.addAll(permanents); return true; } + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + List affectedObjects = new ArrayList<>(); + if (queryAffectedObjects(layer, source, game, affectedObjects)) { + applyToObjects(layer, sublayer, source, game, affectedObjects); + return true; + } + return false; + } + @Override public boolean hasLayer(Layer layer) { return layer == Layer.TypeChangingEffects_4 || layer == Layer.PTChangingEffects_7; } - @Override - public boolean apply(Game game, Ability source) { - return false; - } - @Override public CyberdriveAwakenerEffect copy() { return new CyberdriveAwakenerEffect(this); diff --git a/Mage.Sets/src/mage/cards/d/DismissIntoDream.java b/Mage.Sets/src/mage/cards/d/DismissIntoDream.java index c504fd86cd4..e6f8492870a 100644 --- a/Mage.Sets/src/mage/cards/d/DismissIntoDream.java +++ b/Mage.Sets/src/mage/cards/d/DismissIntoDream.java @@ -1,7 +1,7 @@ package mage.cards.d; -import java.util.UUID; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.common.BecomesTargetSourceTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; @@ -15,6 +15,9 @@ import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; +import java.util.List; +import java.util.UUID; + /** * * @author LevelX2 @@ -56,27 +59,24 @@ class DismissIntoDreamEffect extends CreaturesBecomeOtherTypeEffect { super(effect); } - @Override - public boolean apply(Game game, Ability source) { - return false; - } - @Override public DismissIntoDreamEffect copy() { return new DismissIntoDreamEffect(this); } @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - super.apply(layer, sublayer, source, game); - - if (layer == Layer.AbilityAddingRemovingEffects_6) { - for (Permanent object: game.getBattlefield().getActivePermanents(this.filter, source.getControllerId(), game)) { - object.addAbility(new BecomesTargetSourceTriggeredAbility(new SacrificeSourceEffect()), source.getSourceId(), game); + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Permanent permanent = (Permanent) object; + switch (layer) { + case TypeChangingEffects_4: + permanent.addSubType(game, this.subType); + break; + case AbilityAddingRemovingEffects_6: + permanent.addAbility(new BecomesTargetSourceTriggeredAbility(new SacrificeSourceEffect()), source.getSourceId(), game); + break; } } - - return true; } @Override diff --git a/Mage.Sets/src/mage/cards/e/EverythingamajigC.java b/Mage.Sets/src/mage/cards/e/EverythingamajigC.java index 52e90c7f894..fc3f4adf73f 100644 --- a/Mage.Sets/src/mage/cards/e/EverythingamajigC.java +++ b/Mage.Sets/src/mage/cards/e/EverythingamajigC.java @@ -9,19 +9,19 @@ import mage.abilities.costs.VariableCostType; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.VariableManaCost; -import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.continuous.BecomesXXConstructSourceEffect; import mage.abilities.effects.common.discard.DiscardTargetEffect; import mage.abilities.effects.mana.ManaEffect; import mage.abilities.hint.common.MyTurnHint; import mage.abilities.mana.ActivatedManaAbilityImpl; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPlayer; -import mage.util.CardUtil; import java.util.ArrayList; import java.util.List; @@ -49,7 +49,7 @@ public final class EverythingamajigC extends CardImpl { // Chimeric Staff // X: Everythingamajig becomes an X/X Construct artifact creature until end of turn. - this.addAbility(new SimpleActivatedAbility(new ChimericStaffEffect(), new VariableManaCost(VariableCostType.NORMAL))); + this.addAbility(new SimpleActivatedAbility(new BecomesXXConstructSourceEffect(Duration.EndOfTurn), new VariableManaCost(VariableCostType.NORMAL))); } private EverythingamajigC(final EverythingamajigC card) { @@ -124,58 +124,3 @@ class ManaScrewEffect extends ManaEffect { return new Mana(); } } - -class ChimericStaffEffect extends ContinuousEffectImpl { - - ChimericStaffEffect() { - super(Duration.EndOfTurn, Outcome.BecomeCreature); - staticText = "{this} becomes an X/X Construct artifact creature until end of turn"; - this.dependencyTypes.add(DependencyType.BecomeCreature); - } - - private ChimericStaffEffect(final ChimericStaffEffect effect) { - super(effect); - } - - @Override - public ChimericStaffEffect copy() { - return new ChimericStaffEffect(this); - } - - @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent == null) { - return false; - } - switch (layer) { - case TypeChangingEffects_4: - if (!permanent.isArtifact(game)) { - permanent.addCardType(game, CardType.ARTIFACT); - } - if (!permanent.isCreature(game)) { - permanent.addCardType(game, CardType.CREATURE); - } - permanent.removeAllCreatureTypes(game); - permanent.addSubType(game, SubType.CONSTRUCT); - break; - case PTChangingEffects_7: - if (sublayer == SubLayer.SetPT_7b) { - int xValue = CardUtil.getSourceCostsTag(game, source, "X", 0); - permanent.getPower().setModifiedBaseValue(xValue); - permanent.getToughness().setModifiedBaseValue(xValue); - } - } - return true; - } - - @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.PTChangingEffects_7 || layer == Layer.TypeChangingEffects_4; - } -} diff --git a/Mage.Sets/src/mage/cards/l/LithoformBlight.java b/Mage.Sets/src/mage/cards/l/LithoformBlight.java index a515b49989b..09f4ed6d855 100644 --- a/Mage.Sets/src/mage/cards/l/LithoformBlight.java +++ b/Mage.Sets/src/mage/cards/l/LithoformBlight.java @@ -1,6 +1,6 @@ package mage.cards.l; -import java.util.UUID; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; @@ -19,6 +19,10 @@ import mage.game.permanent.Permanent; import mage.target.TargetPermanent; import mage.target.common.TargetLandPermanent; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + /** * @author TheElk801 */ @@ -71,32 +75,45 @@ class ChangeLandAttachedEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Permanent permanent = (Permanent) object; + switch (layer) { + case TypeChangingEffects_4: + permanent.removeAllSubTypes(game, SubTypeSet.NonBasicLandType); + break; + case AbilityAddingRemovingEffects_6: + permanent.removeAllAbilities(source.getSourceId(), game); + permanent.addAbility(new ColorlessManaAbility(), source.getSourceId(), game); + Ability ability = new AnyColorManaAbility(); + ability.addCost(new PayLifeCost(1)); + permanent.addAbility(ability, source.getSourceId(), game); + break; + } + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Permanent enchantment = game.getPermanent(source.getSourceId()); - if (enchantment == null) { + if (enchantment == null || enchantment.getAttachedTo() == null) { return false; } Permanent permanent = game.getPermanent(enchantment.getAttachedTo()); if (permanent == null) { - return true; - } - switch (layer) { - case TypeChangingEffects_4: - permanent.removeAllSubTypes(game, SubTypeSet.NonBasicLandType); - break; - case AbilityAddingRemovingEffects_6: - permanent.removeAllAbilities(source.getSourceId(), game); - permanent.addAbility(new ColorlessManaAbility(), source.getSourceId(), game); - Ability ability = new AnyColorManaAbility(); - ability.addCost(new PayLifeCost(1)); - permanent.addAbility(ability, source.getSourceId(), game); - break; + return false; } + affectedObjects.add(permanent); return true; } @Override - public boolean apply(Game game, Ability source) { + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + List affectedObjects = new ArrayList<>(); + if (queryAffectedObjects(layer, source, game, affectedObjects)) { + applyToObjects(layer, sublayer, source, game, affectedObjects); + return true; + } return false; } diff --git a/Mage.Sets/src/mage/cards/n/NewBlood.java b/Mage.Sets/src/mage/cards/n/NewBlood.java index eee9524c525..243100b77a8 100644 --- a/Mage.Sets/src/mage/cards/n/NewBlood.java +++ b/Mage.Sets/src/mage/cards/n/NewBlood.java @@ -1,8 +1,8 @@ package mage.cards.n; +import mage.MageItem; import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.Mode; import mage.abilities.costs.common.TapTargetCost; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffectImpl; @@ -22,6 +22,7 @@ import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetCreaturePermanent; import mage.target.targetpointer.FixedTarget; +import java.util.List; import java.util.UUID; /** @@ -129,11 +130,22 @@ class ChangeCreatureTypeTargetEffect extends ContinuousEffectImpl { } } } + @Override + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + MageObject mageObject = (MageObject) object; + mageObject.removeSubType(game, fromSubType); + mageObject.addSubType(game, toSubType); + } + } @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Player controller = game.getPlayer(source.getControllerId()); if (controller == null) { + if (duration == Duration.Custom) { + discard(); + } return false; } if (fromSubType == null) { @@ -145,29 +157,16 @@ class ChangeCreatureTypeTargetEffect extends ContinuousEffectImpl { if (targetObject != null) { objectFound = true; if (targetObject.hasSubtype(fromSubType, game)) { - targetObject.removeSubType(game, fromSubType); - if (!targetObject.hasSubtype(toSubType, game)) { - targetObject.addSubType(game, toSubType); - } + affectedObjects.add(targetObject); } } - if (!objectFound && this.getDuration() == Duration.Custom) { - this.discard(); - } + } + if (!objectFound && this.getDuration() == Duration.Custom) { + this.discard(); } return true; } - @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.TypeChangingEffects_4; - } - @Override public ChangeCreatureTypeTargetEffect copy() { return new ChangeCreatureTypeTargetEffect(this); diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CanBlockAdditionalCreatureAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CanBlockAdditionalCreatureAllEffect.java index 3e815aa31bb..aa156b95626 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CanBlockAdditionalCreatureAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CanBlockAdditionalCreatureAllEffect.java @@ -1,6 +1,7 @@ package mage.abilities.effects.common.combat; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.Duration; @@ -12,6 +13,8 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.util.CardUtil; +import java.util.List; + /** * @author emerald000 */ @@ -22,7 +25,7 @@ public class CanBlockAdditionalCreatureAllEffect extends ContinuousEffectImpl { protected FilterPermanent filter; public CanBlockAdditionalCreatureAllEffect(int amount, FilterPermanent filter, Duration duration) { - super(duration, Outcome.Benefit); + super(duration, Layer.RulesEffects, SubLayer.NA, Outcome.Benefit); this.amount = amount; this.filter = filter; staticText = setText(); @@ -40,25 +43,24 @@ public class CanBlockAdditionalCreatureAllEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)) { - if (permanent != null) { - // maxBlocks = 0 equals to "can block any number of creatures" - if (amount > 0) { - if (permanent.getMaxBlocks() > 0) { - permanent.setMaxBlocks(permanent.getMaxBlocks() + amount); - } - } else { - permanent.setMaxBlocks(0); + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Permanent permanent = (Permanent) object; + // maxBlocks = 0 equals to "can block any number of creatures" + if (amount > 0) { + if (permanent.getMaxBlocks() > 0) { + permanent.setMaxBlocks(permanent.getMaxBlocks() + amount); } + } else { + permanent.setMaxBlocks(amount); } } - return true; } @Override - public boolean apply(Game game, Ability source) { - return false; + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + affectedObjects.addAll(game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)); + return !affectedObjects.isEmpty(); } private String setText() { @@ -77,9 +79,4 @@ public class CanBlockAdditionalCreatureAllEffect extends ContinuousEffectImpl { } return sb.toString(); } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.RulesEffects; - } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CanBlockAdditionalCreatureEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CanBlockAdditionalCreatureEffect.java index a2630e7b7e4..4f9da4aac91 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CanBlockAdditionalCreatureEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CanBlockAdditionalCreatureEffect.java @@ -1,6 +1,7 @@ package mage.abilities.effects.common.combat; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.Duration; @@ -11,6 +12,8 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.util.CardUtil; +import java.util.List; + /** * @author LevelX2 */ @@ -32,7 +35,7 @@ public class CanBlockAdditionalCreatureEffect extends ContinuousEffectImpl { } public CanBlockAdditionalCreatureEffect(Duration duration, int amount) { - super(duration, Outcome.Benefit); + super(duration, Layer.RulesEffects, SubLayer.NA, Outcome.Benefit); this.amount = amount; staticText = setText(); } @@ -48,9 +51,9 @@ public class CanBlockAdditionalCreatureEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Permanent permanent = (Permanent) object; // maxBlocks = 0 equals to "can block any number of creatures" if (amount > 0) { if (permanent.getMaxBlocks() > 0) { @@ -59,13 +62,16 @@ public class CanBlockAdditionalCreatureEffect extends ContinuousEffectImpl { } else { permanent.setMaxBlocks(0); } - return true; } - return false; } @Override - public boolean apply(Game game, Ability source) { + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null) { + affectedObjects.add(permanent); + return true; + } return false; } @@ -87,9 +93,4 @@ public class CanBlockAdditionalCreatureEffect extends ContinuousEffectImpl { return sb.toString(); } - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.RulesEffects; - } - } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CanBlockAdditionalCreatureTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CanBlockAdditionalCreatureTargetEffect.java index 77011abb9a9..f627ce1d49f 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CanBlockAdditionalCreatureTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CanBlockAdditionalCreatureTargetEffect.java @@ -1,5 +1,6 @@ package mage.abilities.effects.common.combat; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.Duration; @@ -9,6 +10,8 @@ import mage.constants.SubLayer; import mage.game.Game; import mage.game.permanent.Permanent; +import java.util.List; + /** * @author mzulch */ @@ -30,7 +33,7 @@ public class CanBlockAdditionalCreatureTargetEffect extends ContinuousEffectImpl * @param amount 0 = any number */ public CanBlockAdditionalCreatureTargetEffect(Duration duration, int amount) { - super(duration, Outcome.Benefit); + super(duration, Layer.RulesEffects, SubLayer.NA, Outcome.Benefit); this.amount = amount; } @@ -45,31 +48,27 @@ public class CanBlockAdditionalCreatureTargetEffect extends ContinuousEffectImpl } @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - Permanent target = game.getPermanent(this.getTargetPointer().getFirst(game, source)); - if (target == null) { - return false; - } - - // maxBlocks = 0 equals to "can block any number of creatures" - if (amount > 0) { - if (target.getMaxBlocks() > 0) { - target.setMaxBlocks(target.getMaxBlocks() + amount); + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Permanent permanent = (Permanent) object; + // maxBlocks = 0 equals to "can block any number of creatures" + if (amount > 0) { + if (permanent.getMaxBlocks() > 0) { + permanent.setMaxBlocks(permanent.getMaxBlocks() + amount); + } + } else { + permanent.setMaxBlocks(0); } - } else { - target.setMaxBlocks(0); } - - return true; } @Override - public boolean apply(Game game, Ability source) { + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + Permanent target = game.getPermanent(this.getTargetPointer().getFirst(game, source)); + if (target != null) { + affectedObjects.add(target); + return true; + } return false; } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.RulesEffects; - } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByMoreThanOneAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByMoreThanOneAllEffect.java index da18fcfefaf..2148df0aafd 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByMoreThanOneAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByMoreThanOneAllEffect.java @@ -1,25 +1,26 @@ package mage.abilities.effects.common.combat; +import mage.MageItem; +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.Duration; import mage.constants.Layer; import mage.constants.Outcome; import mage.constants.SubLayer; -import mage.abilities.Ability; -import mage.abilities.effects.ContinuousEffectImpl; import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.permanent.Permanent; - - import mage.util.CardUtil; +import java.util.List; + /** * @author Quercitron */ public class CantBeBlockedByMoreThanOneAllEffect extends ContinuousEffectImpl { - private FilterPermanent filter; + private final FilterPermanent filter; protected int amount; public CantBeBlockedByMoreThanOneAllEffect(FilterPermanent filter) { @@ -31,11 +32,11 @@ public class CantBeBlockedByMoreThanOneAllEffect extends ContinuousEffectImpl { } public CantBeBlockedByMoreThanOneAllEffect(int amount, FilterPermanent filter, Duration duration) { - super(duration, Outcome.Benefit); + super(duration, Layer.RulesEffects, SubLayer.NA, Outcome.Benefit); this.amount = amount; this.filter = filter; - staticText = new StringBuilder("Each ").append(filter.getMessage()).append(" can't be blocked by more than ") - .append(CardUtil.numberToText(amount)).append(" creature").append(amount > 1 ? "s" : "").toString(); + staticText = "Each " + filter.getMessage() + " can't be blocked by more than " + + CardUtil.numberToText(amount) + " creature" + (amount > 1 ? "s" : ""); } protected CantBeBlockedByMoreThanOneAllEffect(final CantBeBlockedByMoreThanOneAllEffect effect) { @@ -50,24 +51,15 @@ public class CantBeBlockedByMoreThanOneAllEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - switch (layer) { - case RulesEffects: - for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)) { - perm.setMaxBlockedBy(amount); - } - break; + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + ((Permanent) object).setMaxBlockedBy(amount); } - return true; } @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.RulesEffects; + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + affectedObjects.addAll(game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)); + return !affectedObjects.isEmpty(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByMoreThanOneAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByMoreThanOneAttachedEffect.java index ba33d007780..e499e884c9a 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByMoreThanOneAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByMoreThanOneAttachedEffect.java @@ -1,5 +1,6 @@ package mage.abilities.effects.common.combat; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.*; @@ -7,6 +8,8 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.util.CardUtil; +import java.util.List; + /** * @author LevelX2, edited by Cguy7777 */ @@ -42,12 +45,19 @@ public class CantBeBlockedByMoreThanOneAttachedEffect extends ContinuousEffectIm } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + ((Permanent) object).setMaxBlockedBy(amount); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Permanent attachment = game.getPermanent(source.getSourceId()); if (attachment != null && attachment.getAttachedTo() != null) { - Permanent perm = game.getPermanent(attachment.getAttachedTo()); - if (perm != null) { - perm.setMaxBlockedBy(amount); + Permanent permanent = game.getPermanent(attachment.getAttachedTo()); + if (permanent != null) { + affectedObjects.add(permanent); return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByMoreThanOneSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByMoreThanOneSourceEffect.java index f4fbdca9873..dce414ce8d1 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByMoreThanOneSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByMoreThanOneSourceEffect.java @@ -1,18 +1,19 @@ package mage.abilities.effects.common.combat; +import mage.MageItem; +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.Duration; import mage.constants.Layer; import mage.constants.Outcome; import mage.constants.SubLayer; -import mage.abilities.Ability; -import mage.abilities.effects.ContinuousEffectImpl; import mage.game.Game; - - import mage.game.permanent.Permanent; import mage.util.CardUtil; +import java.util.List; + /** * @author Quercitron */ @@ -29,7 +30,7 @@ public class CantBeBlockedByMoreThanOneSourceEffect extends ContinuousEffectImpl } public CantBeBlockedByMoreThanOneSourceEffect(int amount, Duration duration) { - super(duration, Outcome.Benefit); + super(duration, Layer.RulesEffects, SubLayer.NA, Outcome.Benefit); this.amount = amount; staticText = "{this} can't be blocked by more than " + CardUtil.numberToText(amount) + " creature" + (amount > 1 ? "s" : "") + (duration == Duration.EndOfTurn ? " each combat this turn" : ""); @@ -46,24 +47,19 @@ public class CantBeBlockedByMoreThanOneSourceEffect extends ContinuousEffectImpl } @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - Permanent perm = game.getPermanent(source.getSourceId()); - if (perm != null) { - if (layer == Layer.RulesEffects) { - perm.setMaxBlockedBy(amount); - } + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + ((Permanent) object).setMaxBlockedBy(amount); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null) { + affectedObjects.add(permanent); return true; } return false; } - - @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.RulesEffects; - } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneAllEffect.java index e649ee0543d..ad23ce14107 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneAllEffect.java @@ -1,23 +1,26 @@ package mage.abilities.effects.common.combat; +import mage.MageItem; +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.Duration; import mage.constants.Layer; import mage.constants.Outcome; import mage.constants.SubLayer; -import mage.abilities.Ability; -import mage.abilities.effects.ContinuousEffectImpl; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.util.CardUtil; +import java.util.List; + /** * @author LevelX2 */ public class CantBeBlockedByOneAllEffect extends ContinuousEffectImpl { - private FilterCreaturePermanent filter; + private final FilterCreaturePermanent filter; protected int amount; public CantBeBlockedByOneAllEffect(int amount, FilterCreaturePermanent filter) { @@ -25,7 +28,7 @@ public class CantBeBlockedByOneAllEffect extends ContinuousEffectImpl { } public CantBeBlockedByOneAllEffect(int amount, FilterCreaturePermanent filter, Duration duration) { - super(duration, Outcome.Benefit); + super(duration, Layer.RulesEffects, SubLayer.NA, Outcome.Benefit); this.amount = amount; this.filter = filter; StringBuilder sb = new StringBuilder("each ").append(filter.getMessage()).append(" can't be blocked "); @@ -48,24 +51,15 @@ public class CantBeBlockedByOneAllEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - switch (layer) { - case RulesEffects: - for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)) { - perm.setMinBlockedBy(amount); - } - break; + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + ((Permanent) object).setMinBlockedBy(amount); } - return true; } @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.RulesEffects; + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + affectedObjects.addAll(game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)); + return !affectedObjects.isEmpty(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneAttachedEffect.java index 6292e5fc4f9..d2d46f1ccac 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneAttachedEffect.java @@ -1,16 +1,15 @@ package mage.abilities.effects.common.combat; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; -import mage.constants.AttachmentType; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.SubLayer; +import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; +import java.util.List; + /** * @author LevelX2 */ @@ -24,7 +23,7 @@ public class CantBeBlockedByOneAttachedEffect extends ContinuousEffectImpl { } public CantBeBlockedByOneAttachedEffect(AttachmentType attachmentType, int amount, Duration duration) { - super(duration, Outcome.Benefit); + super(duration, Layer.RulesEffects, SubLayer.NA, Outcome.Benefit); this.amount = amount; this.attachmentType = attachmentType; staticText = attachmentType.verb() + " creature can't be blocked except by " + amount + " or more creatures"; @@ -42,29 +41,22 @@ public class CantBeBlockedByOneAttachedEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - switch (layer) { - case RulesEffects: - Permanent attachment = game.getPermanent(source.getSourceId()); - if (attachment != null && attachment.getAttachedTo() != null) { - Permanent perm = game.getPermanent(attachment.getAttachedTo()); - if (perm != null) { - perm.setMinBlockedBy(amount); - return true; - } - } - break; + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + ((Permanent) object).setMinBlockedBy(amount); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + Permanent attachment = game.getPermanent(source.getSourceId()); + if (attachment != null && attachment.getAttachedTo() != null) { + Permanent permanent = game.getPermanent(attachment.getAttachedTo()); + if (permanent != null) { + affectedObjects.add(permanent); + return true; + } } return false; } - - @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.RulesEffects; - } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneEffect.java index 47a0cf7e4ee..02a6d9e6a00 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneEffect.java @@ -1,5 +1,6 @@ package mage.abilities.effects.common.combat; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.Duration; @@ -10,6 +11,8 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.util.CardUtil; +import java.util.List; + /** * @author North */ @@ -38,10 +41,17 @@ public class CantBeBlockedByOneEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { - Permanent perm = source.getSourcePermanentIfItStillExists(game); - if (perm != null) { - perm.setMinBlockedBy(amount); + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + ((Permanent) object).setMinBlockedBy(amount); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null) { + affectedObjects.add(permanent); return true; } return false; diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesXXConstructSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesXXConstructSourceEffect.java new file mode 100644 index 00000000000..44441ba679d --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesXXConstructSourceEffect.java @@ -0,0 +1,84 @@ +package mage.abilities.effects.common.continuous; + +import mage.MageItem; +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.constants.*; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.util.CardUtil; + +import java.util.ArrayList; +import java.util.List; + +public class BecomesXXConstructSourceEffect extends ContinuousEffectImpl { + + public BecomesXXConstructSourceEffect(Duration duration) { + super(duration, Outcome.BecomeCreature); + StringBuilder sb = new StringBuilder("{this} becomes an X/X Construct artifact creature"); + if (duration == Duration.EndOfTurn) { + sb.append(" until end of turn"); + } + this.staticText = sb.toString(); + this.dependencyTypes.add(DependencyType.BecomeCreature); + } + + private BecomesXXConstructSourceEffect(final BecomesXXConstructSourceEffect effect) { + super(effect); + } + + @Override + public BecomesXXConstructSourceEffect copy() { + return new BecomesXXConstructSourceEffect(this); + } + + @Override + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Permanent permanent = (Permanent) object; + switch (layer) { + case TypeChangingEffects_4: + if (!permanent.isArtifact(game)) { + permanent.addCardType(game, CardType.ARTIFACT); + } + if (!permanent.isCreature(game)) { + permanent.addCardType(game, CardType.CREATURE); + } + permanent.removeAllCreatureTypes(game); + permanent.addSubType(game, SubType.CONSTRUCT); + break; + case PTChangingEffects_7: + if (sublayer == SubLayer.SetPT_7b) { + int xValue = CardUtil.getSourceCostsTag(game, source, "X", 0); + permanent.getPower().setModifiedBaseValue(xValue); + permanent.getToughness().setModifiedBaseValue(xValue); + } + } + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent == null) { + return false; + } + affectedObjects.add(permanent); + return true; + } + + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + List affectedObjects = new ArrayList<>(); + if (queryAffectedObjects(layer, source, game, affectedObjects)) { + applyToObjects(layer, sublayer, source, game, affectedObjects); + return true; + } + return false; + } + + @Override + public boolean hasLayer(Layer layer) { + return layer == Layer.PTChangingEffects_7 || layer == Layer.TypeChangingEffects_4; + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/CantBeSacrificedSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/CantBeSacrificedSourceEffect.java index 447767db12a..6e5b5fa3ad4 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/CantBeSacrificedSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/CantBeSacrificedSourceEffect.java @@ -1,5 +1,6 @@ package mage.abilities.effects.common.continuous; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.Duration; @@ -9,6 +10,8 @@ import mage.constants.SubLayer; import mage.game.Game; import mage.game.permanent.Permanent; +import java.util.List; + /** * @author xenohedron */ @@ -29,7 +32,14 @@ public class CantBeSacrificedSourceEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + ((Permanent) object).setCanBeSacrificed(false); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (permanent == null) { permanent = source.getSourcePermanentIfItStillExists(game); @@ -38,8 +48,7 @@ public class CantBeSacrificedSourceEffect extends ContinuousEffectImpl { discard(); return false; } - permanent.setCanBeSacrificed(false); + affectedObjects.add(permanent); return true; } - } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeAllEffect.java index 0d363ea0da2..4f7c255b733 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeAllEffect.java @@ -1,5 +1,6 @@ package mage.abilities.effects.common.continuous; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.*; @@ -7,6 +8,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; +import java.util.List; import java.util.Optional; import java.util.UUID; @@ -15,7 +17,7 @@ import java.util.UUID; */ public class CantGainLifeAllEffect extends ContinuousEffectImpl { - private TargetController targetController; + private final TargetController targetController; public CantGainLifeAllEffect() { this(Duration.WhileOnBattlefield); @@ -43,7 +45,14 @@ public class CantGainLifeAllEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + ((Player) object).setCanGainLife(false); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Player controller = game.getPlayer(source.getControllerId()); if (controller == null) { return false; @@ -56,7 +65,7 @@ public class CantGainLifeAllEffect extends ContinuousEffectImpl { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null && !player.equals(controller)) { - player.setCanGainLife(false); + affectedObjects.add(player); } } break; @@ -65,7 +74,7 @@ public class CantGainLifeAllEffect extends ContinuousEffectImpl { if (controller.hasOpponent(playerId, game)) { Player player = game.getPlayer(playerId); if (player != null) { - player.setCanGainLife(false); + affectedObjects.add(player); } } } @@ -74,7 +83,7 @@ public class CantGainLifeAllEffect extends ContinuousEffectImpl { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - player.setCanGainLife(false); + affectedObjects.add(player); } } break; @@ -83,7 +92,7 @@ public class CantGainLifeAllEffect extends ContinuousEffectImpl { .ofNullable(source.getSourcePermanentIfItStillExists(game)) .map(Permanent::getAttachedTo) .map(game::getPlayer) - .ifPresent(player -> player.setCanGainLife(false)); + .ifPresent(affectedObjects::add); } return true; } @@ -112,7 +121,7 @@ public class CantGainLifeAllEffect extends ContinuousEffectImpl { if (duration == Duration.EndOfTurn) { sb.append("this turn"); } else { - sb.append(duration.toString()); + sb.append(duration); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeRestOfGameTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeRestOfGameTargetEffect.java index d2e8ef09b74..a870debf1ce 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeRestOfGameTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeRestOfGameTargetEffect.java @@ -1,5 +1,6 @@ package mage.abilities.effects.common.continuous; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.Duration; @@ -9,6 +10,8 @@ import mage.constants.SubLayer; import mage.game.Game; import mage.players.Player; +import java.util.List; + /** * @author Susucr */ @@ -29,11 +32,19 @@ public class CantGainLifeRestOfGameTargetEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + ((Player) object).setCanGainLife(false); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Player player = game.getPlayer(this.getTargetPointer().getFirst(game, source)); if (player != null) { - player.setCanGainLife(false); + affectedObjects.add(player); + return true; } - return true; + return false; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeTargetEffect.java index 1fb7ae08c03..4f2f3ebad3f 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeTargetEffect.java @@ -2,8 +2,7 @@ package mage.abilities.effects.common.continuous; -import java.util.UUID; - +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.Duration; @@ -13,6 +12,9 @@ import mage.constants.SubLayer; import mage.game.Game; import mage.players.Player; +import java.util.List; +import java.util.UUID; + /** * @author LevelX2 */ @@ -42,14 +44,21 @@ public class CantGainLifeTargetEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + ((Player) object).setCanGainLife(false); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { for (UUID playerId : this.getTargetPointer().getTargets(game, source)) { Player targetPlayer = game.getPlayer(playerId); if (targetPlayer != null) { - targetPlayer.setCanGainLife(false); + affectedObjects.add(targetPlayer); } } - return true; + return !affectedObjects.isEmpty(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/CastFromHandWithoutPayingManaCostEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/CastFromHandWithoutPayingManaCostEffect.java index 0a561f533a4..f4467b7065f 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/CastFromHandWithoutPayingManaCostEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/CastFromHandWithoutPayingManaCostEffect.java @@ -1,5 +1,6 @@ package mage.abilities.effects.common.continuous; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.condition.CompoundCondition; import mage.abilities.condition.Condition; @@ -16,6 +17,8 @@ import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; +import java.util.List; + public class CastFromHandWithoutPayingManaCostEffect extends ContinuousEffectImpl { private final AlternativeCostSourceAbility alternativeCastingCostAbility; @@ -29,7 +32,7 @@ public class CastFromHandWithoutPayingManaCostEffect extends ContinuousEffectImp } public CastFromHandWithoutPayingManaCostEffect(FilterCard filter, boolean fromHand, Duration duration) { - super(duration, Outcome.Detriment); + super(duration, Layer.RulesEffects, SubLayer.NA, Outcome.Detriment); Condition condition; if (fromHand) { condition = new CompoundCondition(SourceIsSpellCondition.instance, IsBeingCastFromHandCondition.instance); @@ -53,23 +56,21 @@ public class CastFromHandWithoutPayingManaCostEffect extends ContinuousEffectImp } @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + Player player = (Player) object; + alternativeCastingCostAbility.setSourceId(source.getSourceId()); + player.getAlternativeSourceCosts().add(alternativeCastingCostAbility); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Player controller = game.getPlayer(source.getControllerId()); if (controller == null) { return false; } - alternativeCastingCostAbility.setSourceId(source.getSourceId()); - controller.getAlternativeSourceCosts().add(alternativeCastingCostAbility); + affectedObjects.add(controller); return true; } - - @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.RulesEffects; - } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/ChangeMaxNumberThatCanAttackSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/ChangeMaxNumberThatCanAttackSourceEffect.java index 008ded32442..23872baa8d4 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/ChangeMaxNumberThatCanAttackSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/ChangeMaxNumberThatCanAttackSourceEffect.java @@ -1,5 +1,6 @@ package mage.abilities.effects.common.continuous; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.Duration; @@ -10,6 +11,8 @@ import mage.game.Game; import mage.players.Player; import mage.util.CardUtil; +import java.util.List; + /** * @author LevelX2 */ @@ -35,15 +38,19 @@ public class ChangeMaxNumberThatCanAttackSourceEffect extends ContinuousEffectIm } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + ((Player) object).setMaxAttackedBy(maxAttackedBy); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { + if (controller == null || controller.getMaxAttackedBy() < maxAttackedBy) { return false; } - // Change the rule - if (controller.getMaxAttackedBy() > maxAttackedBy) { - controller.setMaxAttackedBy(maxAttackedBy); - } + affectedObjects.add(controller); return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/ControlEnchantedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/ControlEnchantedEffect.java index 4a265da274b..ba8c65f2b10 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/ControlEnchantedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/ControlEnchantedEffect.java @@ -1,5 +1,6 @@ package mage.abilities.effects.common.continuous; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.Duration; @@ -9,6 +10,8 @@ import mage.constants.SubLayer; import mage.game.Game; import mage.game.permanent.Permanent; +import java.util.List; + /** * @author nantuko */ @@ -33,7 +36,14 @@ public class ControlEnchantedEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + ((Permanent) object).changeControllerId(source.getControllerId(), game, source); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Permanent enchantment = source.getSourcePermanentIfItStillExists(game); if (enchantment == null) { return false; @@ -42,7 +52,7 @@ public class ControlEnchantedEffect extends ContinuousEffectImpl { if (permanent == null) { return false; } - permanent.changeControllerId(source.getControllerId(), game, source); + affectedObjects.add(permanent); return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/CreaturesBecomeOtherTypeEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/CreaturesBecomeOtherTypeEffect.java index 1b0d7285847..d2d3c6c1ba5 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/CreaturesBecomeOtherTypeEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/CreaturesBecomeOtherTypeEffect.java @@ -1,17 +1,20 @@ package mage.abilities.effects.common.continuous; +import mage.MageItem; import mage.abilities.Ability; -import mage.abilities.Mode; import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.*; import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.permanent.Permanent; +import java.util.ArrayList; +import java.util.List; + public class CreaturesBecomeOtherTypeEffect extends ContinuousEffectImpl { protected final FilterPermanent filter; - private final SubType subType; + protected final SubType subType; public CreaturesBecomeOtherTypeEffect(FilterPermanent filter, SubType subType, Duration duration) { super(duration, Outcome.Neutral); @@ -20,7 +23,7 @@ public class CreaturesBecomeOtherTypeEffect extends ContinuousEffectImpl { this.dependendToTypes.add(DependencyType.BecomeCreature); // Opalescence and Starfield of Nyx this.staticText = this.filter.getMessage() + " is " + this.subType.getIndefiniteArticle() - + " " + this.subType.toString() + " in addition to its other types"; + + " " + this.subType + " in addition to its other types"; } protected CreaturesBecomeOtherTypeEffect(final CreaturesBecomeOtherTypeEffect effect) { @@ -29,29 +32,36 @@ public class CreaturesBecomeOtherTypeEffect extends ContinuousEffectImpl { this.subType = effect.subType; } - @Override - public boolean apply(Game game, Ability source) { - return false; - } - @Override public CreaturesBecomeOtherTypeEffect copy() { return new CreaturesBecomeOtherTypeEffect(this); } @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - if (layer == Layer.TypeChangingEffects_4) { - for (Permanent object : game.getBattlefield().getActivePermanents(this.filter, source.getControllerId(), game)) { - object.addSubType(game, this.subType); - } + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + ((Permanent) object).addSubType(game, this.subType); } + } - return true; + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + affectedObjects.addAll(game.getBattlefield().getActivePermanents(this.filter, source.getControllerId(), game)); + return !affectedObjects.isEmpty(); + } + + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + List affectedObjects = new ArrayList<>(); + if (queryAffectedObjects(layer, source, game, affectedObjects)) { + applyToObjects(layer, sublayer, source, game, affectedObjects); + return true; + } + return false; } @Override public boolean hasLayer(Layer layer) { return layer == Layer.TypeChangingEffects_4; } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/CreaturesCantGetOrHaveAbilityEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/CreaturesCantGetOrHaveAbilityEffect.java index 00be50e495e..8cc8b2c84a0 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/CreaturesCantGetOrHaveAbilityEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/CreaturesCantGetOrHaveAbilityEffect.java @@ -1,5 +1,6 @@ package mage.abilities.effects.common.continuous; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.DependencyType; @@ -13,6 +14,8 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; +import java.util.List; + /** * @author LevelX2 */ @@ -26,7 +29,7 @@ public class CreaturesCantGetOrHaveAbilityEffect extends ContinuousEffectImpl { } public CreaturesCantGetOrHaveAbilityEffect(Ability ability, Duration duration, FilterCreaturePermanent filter) { - super(duration, Outcome.Detriment); + super(duration, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.Detriment); this.ability = ability; this.filter = filter; staticText = filter.getMessage() + " lose " + ability.getRule() + " and can't have or gain " + ability.getRule(); @@ -45,27 +48,19 @@ public class CreaturesCantGetOrHaveAbilityEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)) { - if (permanent != null) { - permanent.removeAbility(ability, source.getSourceId(), game); - } - } - return true; + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects) { + ((Permanent) object).removeAbility(ability, source.getSourceId(), game); } - return false; - } @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.AbilityAddingRemovingEffects_6; + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + affectedObjects.addAll(game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)); + return !affectedObjects.isEmpty(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/cost/CostModificationEffectImpl.java b/Mage/src/main/java/mage/abilities/effects/common/cost/CostModificationEffectImpl.java index 8fb7bfa3ccf..db3b5e6a312 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/cost/CostModificationEffectImpl.java +++ b/Mage/src/main/java/mage/abilities/effects/common/cost/CostModificationEffectImpl.java @@ -1,13 +1,11 @@ package mage.abilities.effects.common.cost; -import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.CostModificationEffect; import mage.constants.CostModificationType; import mage.constants.Duration; import mage.constants.EffectType; import mage.constants.Outcome; -import mage.game.Game; /** * Simple implementation of a {@link CostModificationEffect} offering simplified @@ -40,19 +38,6 @@ public abstract class CostModificationEffectImpl extends ContinuousEffectImpl im this.worksOnStackOnly = effect.worksOnStackOnly; } - /** - * Overridden and 'no-op' implementation put in place. - * - * @param game - * @param source - * @return - * @see #apply(mage.game.Game, mage.abilities.Ability, mage.abilities.Ability) - */ - @Override - public final boolean apply(Game game, Ability source) { - return false; - } - @Override public CostModificationType getModificationType() { return this.modificationType; diff --git a/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessAllEffect.java index 3322d3ce9da..00dbc29d45e 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessAllEffect.java @@ -1,5 +1,6 @@ package mage.abilities.effects.common.ruleModifying; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.Duration; @@ -9,6 +10,9 @@ import mage.constants.SubLayer; import mage.filter.StaticFilters; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; +import mage.game.permanent.Permanent; + +import java.util.List; /** * @author TheElk801, xanderhall @@ -46,9 +50,18 @@ public class CombatDamageByToughnessAllEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { game.getCombat().setUseToughnessForDamage(true); game.getCombat().addUseToughnessForDamageFilter(filter); + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent == null) { + return false; + } + affectedObjects.add(permanent); return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessControlledEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessControlledEffect.java index d11473e1549..31ca452eaa6 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessControlledEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessControlledEffect.java @@ -1,5 +1,6 @@ package mage.abilities.effects.common.ruleModifying; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.Duration; @@ -10,6 +11,9 @@ import mage.filter.StaticFilters; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; +import mage.game.permanent.Permanent; + +import java.util.List; /** * @author TheElk801, xenohedron @@ -49,11 +53,20 @@ public class CombatDamageByToughnessControlledEffect extends ContinuousEffectImp } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { FilterCreaturePermanent filterPermanent = filter.copy(); filterPermanent.add(new ControllerIdPredicate(source.getControllerId())); game.getCombat().setUseToughnessForDamage(true); game.getCombat().addUseToughnessForDamageFilter(filterPermanent); + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent == null) { + return false; + } + affectedObjects.add(permanent); return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessSourceEffect.java index ffbd8c9476a..2483230d389 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessSourceEffect.java @@ -1,5 +1,6 @@ package mage.abilities.effects.common.ruleModifying; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.Duration; @@ -11,6 +12,8 @@ import mage.filter.predicate.mageobject.MageObjectReferencePredicate; import mage.game.Game; import mage.game.permanent.Permanent; +import java.util.List; + public class CombatDamageByToughnessSourceEffect extends ContinuousEffectImpl { public CombatDamageByToughnessSourceEffect(Duration duration) { @@ -28,17 +31,23 @@ public class CombatDamageByToughnessSourceEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + for (MageItem object : affectedObjects){ + Permanent permanent = (Permanent) object; + FilterCreaturePermanent filter = new FilterCreaturePermanent(); + filter.add(new MageObjectReferencePredicate(permanent.getId(), game)); + game.getCombat().setUseToughnessForDamage(true); + game.getCombat().addUseToughnessForDamageFilter(filter); + } + } + + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { Permanent permanent = source.getSourcePermanentIfItStillExists(game); if (permanent == null) { return false; } - - FilterCreaturePermanent filter = new FilterCreaturePermanent(); - filter.add(new MageObjectReferencePredicate(permanent.getId(), game)); - game.getCombat().setUseToughnessForDamage(true); - game.getCombat().addUseToughnessForDamageFilter(filter); - + affectedObjects.add(permanent); return true; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessTargetEffect.java index a55bf533ba6..182cf44191f 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CombatDamageByToughnessTargetEffect.java @@ -1,5 +1,6 @@ package mage.abilities.effects.common.ruleModifying; +import mage.MageItem; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.ContinuousEffectImpl; @@ -12,8 +13,8 @@ import mage.filter.predicate.permanent.PermanentReferenceInCollectionPredicate; import mage.game.Game; import mage.game.permanent.Permanent; +import java.util.List; import java.util.Objects; -import java.util.Set; import java.util.stream.Collectors; public class CombatDamageByToughnessTargetEffect extends ContinuousEffectImpl { @@ -36,18 +37,21 @@ public class CombatDamageByToughnessTargetEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { - Set set = getTargetPointer().getTargets(game, source).stream() - .map(game::getPermanent) - .filter(Objects::nonNull) - .collect(Collectors.toSet()); - + public void applyToObjects(Layer layer, SubLayer sublayer, Ability source, Game game, List affectedObjects) { + List permanents = affectedObjects.stream().map(Permanent.class::cast).collect(Collectors.toList()); FilterCreaturePermanent filter = new FilterCreaturePermanent(); - filter.add(new PermanentReferenceInCollectionPredicate(set, game)); + filter.add(new PermanentReferenceInCollectionPredicate(permanents, game)); game.getCombat().setUseToughnessForDamage(true); game.getCombat().addUseToughnessForDamageFilter(filter); + } - return true; + @Override + public boolean queryAffectedObjects(Layer layer, Ability source, Game game, List affectedObjects) { + affectedObjects.addAll(getTargetPointer().getTargets(game, source).stream() + .map(game::getPermanent) + .filter(Objects::nonNull) + .collect(Collectors.toList())); + return !affectedObjects.isEmpty(); } @Override @@ -55,7 +59,7 @@ public class CombatDamageByToughnessTargetEffect extends ContinuousEffectImpl { if (staticText != null && !staticText.isEmpty()) { return staticText; } - return (duration.toString().isEmpty() ? "" : duration.toString() + ", ") + return (duration.toString().isEmpty() ? "" : duration + ", ") + getTargetPointer().describeTargets(mode.getTargets(), "that creature") + " assigns combat damage equal to its toughness rather than its power"; }