diff --git a/Mage.Sets/src/mage/sets/magic2014/StrionicResonator.java b/Mage.Sets/src/mage/sets/magic2014/StrionicResonator.java index 03f256ba0d..1f56faed81 100644 --- a/Mage.Sets/src/mage/sets/magic2014/StrionicResonator.java +++ b/Mage.Sets/src/mage/sets/magic2014/StrionicResonator.java @@ -27,12 +27,9 @@ */ package mage.sets.magic2014; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.Mode; -import mage.abilities.TriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; @@ -42,14 +39,11 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.filter.Filter; -import mage.filter.FilterAbility; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.stack.StackAbility; -import mage.game.stack.StackObject; import mage.players.Player; -import mage.target.TargetObject; +import mage.target.common.TargetTriggeredAbility; /** * @@ -96,7 +90,7 @@ class StrionicResonatorEffect extends OneShotEffect { Permanent sourcePermanent = game.getPermanent(source.getSourceId()); if (controller != null && sourcePermanent != null) { stackAbility.createCopyOnStack(game, source, source.getControllerId(), true); - game.informPlayers(new StringBuilder(sourcePermanent.getName()).append(": ").append(controller.getLogName()).append(" copied activated ability").toString()); + game.informPlayers(new StringBuilder(sourcePermanent.getName()).append(": ").append(controller.getLogName()).append(" copied triggered ability").toString()); return true; } } @@ -116,76 +110,3 @@ class StrionicResonatorEffect extends OneShotEffect { return sb.toString(); } } - -class TargetTriggeredAbility extends TargetObject { - - public TargetTriggeredAbility() { - this.minNumberOfTargets = 1; - this.maxNumberOfTargets = 1; - this.zone = Zone.STACK; - this.targetName = "target triggered ability you control"; - } - - public TargetTriggeredAbility(final TargetTriggeredAbility target) { - super(target); - } - - @Override - public boolean canTarget(UUID id, Ability source, Game game) { - if (source != null && source.getSourceId().equals(id)) { - return false; - } - - StackObject stackObject = game.getStack().getStackObject(id); - return stackObject.getStackAbility() != null - && (stackObject.getStackAbility() instanceof TriggeredAbility) - && source != null - && stackObject.getStackAbility().getControllerId().equals(source.getControllerId()); - } - - @Override - public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { - return canChoose(sourceControllerId, game); - } - - @Override - public boolean canChoose(UUID sourceControllerId, Game game) { - for (StackObject stackObject : game.getStack()) { - if (stackObject.getStackAbility() != null - && stackObject.getStackAbility() instanceof TriggeredAbility - && stackObject.getStackAbility().getControllerId().equals(sourceControllerId)) { - return true; - } - } - return false; - } - - @Override - public Set possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) { - return possibleTargets(sourceControllerId, game); - } - - @Override - public Set possibleTargets(UUID sourceControllerId, Game game) { - Set possibleTargets = new HashSet<>(); - for (StackObject stackObject : game.getStack()) { - if (stackObject.getStackAbility() != null - && stackObject.getStackAbility() instanceof TriggeredAbility - && stackObject.getStackAbility().getControllerId().equals(sourceControllerId)) { - possibleTargets.add(stackObject.getStackAbility().getId()); - } - } - return possibleTargets; - } - - @Override - public TargetTriggeredAbility copy() { - return new TargetTriggeredAbility(this); - } - - @Override - public Filter getFilter() { - return new FilterAbility(); - } - -} diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/MelirasKeepers.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/MelirasKeepers.java index 899228b0ee..74510145dc 100644 --- a/Mage.Sets/src/mage/sets/mirrodinbesieged/MelirasKeepers.java +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/MelirasKeepers.java @@ -29,18 +29,12 @@ package mage.sets.mirrodinbesieged; import java.util.UUID; import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.common.ruleModifying.CantHaveCountersSourceEffect; import mage.cards.CardImpl; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; /** * @@ -58,7 +52,7 @@ public class MelirasKeepers extends CardImpl { this.toughness = new MageInt(4); // Melira's Keepers can't have counters placed on it - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MelirasKeepersEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantHaveCountersSourceEffect())); } public MelirasKeepers(final MelirasKeepers card) { @@ -71,31 +65,3 @@ public class MelirasKeepers extends CardImpl { } } - -class MelirasKeepersEffect extends ContinuousRuleModifyingEffectImpl { - - public MelirasKeepersEffect() { - super(Duration.WhileOnBattlefield, Outcome.PreventDamage); - staticText = "{this} can't have counters placed on it"; - } - - public MelirasKeepersEffect(final MelirasKeepersEffect effect) { - super(effect); - } - - @Override - public MelirasKeepersEffect copy() { - return new MelirasKeepersEffect(this); - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == EventType.ADD_COUNTER; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - return event.getTargetId().equals(source.getSourceId()); - } - -} diff --git a/Mage.Sets/src/mage/sets/prophecy/BlessedWind.java b/Mage.Sets/src/mage/sets/prophecy/BlessedWind.java new file mode 100644 index 0000000000..8f7f89c037 --- /dev/null +++ b/Mage.Sets/src/mage/sets/prophecy/BlessedWind.java @@ -0,0 +1,60 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.prophecy; + +import java.util.UUID; +import mage.abilities.effects.common.SetPlayerLifeTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.target.TargetPlayer; + +/** + * + * @author Styxo + */ +public class BlessedWind extends CardImpl { + + public BlessedWind(UUID ownerId) { + super(ownerId, 4, "Blessed Wind", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{7}{W}{W}"); + this.expansionSetCode = "PCY"; + + // Target player's life total becomes 20. + this.getSpellAbility().addEffect(new SetPlayerLifeTargetEffect(20)); + this.getSpellAbility().addTarget(new TargetPlayer()); + } + + public BlessedWind(final BlessedWind card) { + super(card); + } + + @Override + public BlessedWind copy() { + return new BlessedWind(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ravnica/TwilightDrover.java b/Mage.Sets/src/mage/sets/ravnica/TwilightDrover.java index 77d58ada0e..6d552e8984 100644 --- a/Mage.Sets/src/mage/sets/ravnica/TwilightDrover.java +++ b/Mage.Sets/src/mage/sets/ravnica/TwilightDrover.java @@ -30,7 +30,7 @@ package mage.sets.ravnica; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.LeavesBattlefieldAllTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.RemoveCountersSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; @@ -41,12 +41,8 @@ import mage.constants.CardType; import mage.constants.Rarity; import mage.constants.Zone; import mage.counters.CounterType; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.events.ZoneChangeEvent; -import mage.game.permanent.Permanent; -import mage.game.permanent.PermanentToken; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.TokenPredicate; import mage.game.permanent.token.SpiritWhiteToken; /** @@ -55,6 +51,12 @@ import mage.game.permanent.token.SpiritWhiteToken; */ public class TwilightDrover extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature token"); + + static { + filter.add(new TokenPredicate()); + } + public TwilightDrover(UUID ownerId) { super(ownerId, 33, "Twilight Drover", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{W}"); this.expansionSetCode = "RAV"; @@ -64,8 +66,8 @@ public class TwilightDrover extends CardImpl { this.toughness = new MageInt(1); // Whenever a creature token leaves the battlefield, put a +1/+1 counter on Twilight Drover. - this.addAbility(new TwilightDroverTriggeredAbility()); - + this.addAbility(new LeavesBattlefieldAllTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), filter)); + // {2}{W}, Remove a +1/+1 counter from Twilight Drover: Put two 1/1 white Spirit creature tokens with flying onto the battlefield. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new SpiritWhiteToken("RAV"), 2), new ManaCostsImpl<>("{2}{W}")); ability.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance())); @@ -81,42 +83,3 @@ public class TwilightDrover extends CardImpl { return new TwilightDrover(this); } } - -class TwilightDroverTriggeredAbility extends TriggeredAbilityImpl { - - TwilightDroverTriggeredAbility() { - super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false); - } - - TwilightDroverTriggeredAbility(final TwilightDroverTriggeredAbility ability) { - super(ability); - } - - @Override - public TwilightDroverTriggeredAbility copy() { - return new TwilightDroverTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.ZONE_CHANGE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - ZoneChangeEvent zEvent = (ZoneChangeEvent) event; - if (zEvent.getFromZone() == Zone.BATTLEFIELD) { - UUID targetId = event.getTargetId(); - Permanent permanent = game.getPermanentOrLKIBattlefield(targetId); - if (permanent != null) { - return permanent.getCardType().contains(CardType.CREATURE) && permanent instanceof PermanentToken; - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever a creature token leaves the battlefield, put a +1/+1 counter on {this}"; - } -} diff --git a/Mage.Sets/src/mage/sets/shadowmoor/Tatterkite.java b/Mage.Sets/src/mage/sets/shadowmoor/Tatterkite.java index f10c0e25d3..d17dedb4b1 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/Tatterkite.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/Tatterkite.java @@ -29,19 +29,14 @@ package mage.sets.shadowmoor; import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.common.ruleModifying.CantHaveCountersSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; /** * @@ -60,7 +55,7 @@ public class Tatterkite extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // Tatterkite can't have counters placed on it. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new CantHaveCountersSourceEffect(Duration.WhileOnBattlefield))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantHaveCountersSourceEffect())); } @@ -73,34 +68,3 @@ public class Tatterkite extends CardImpl { return new Tatterkite(this); } } - -class CantHaveCountersSourceEffect extends ContinuousRuleModifyingEffectImpl { - - public CantHaveCountersSourceEffect(Duration duration) { - super(duration, Outcome.Detriment); - staticText = "{this} can't have counters placed on it"; - } - - public CantHaveCountersSourceEffect(final CantHaveCountersSourceEffect effect) { - super(effect); - } - - @Override - public CantHaveCountersSourceEffect copy() { - return new CantHaveCountersSourceEffect(this); - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == EventType.ADD_COUNTERS; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - UUID sourceId = source.getSourceId(); - if (sourceId != null) { - return sourceId.equals(event.getTargetId()); - } - return false; - } -} diff --git a/Mage/src/main/java/mage/abilities/common/DealsCombatDamageToAPlayerTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/DealsCombatDamageToAPlayerTriggeredAbility.java index 429f9c3434..43f94d113c 100644 --- a/Mage/src/main/java/mage/abilities/common/DealsCombatDamageToAPlayerTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/DealsCombatDamageToAPlayerTriggeredAbility.java @@ -29,6 +29,7 @@ package mage.abilities.common; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; +import mage.constants.SetTargetPointer; import mage.constants.Zone; import mage.game.Game; import mage.game.events.DamagedPlayerEvent; @@ -41,7 +42,8 @@ import mage.target.targetpointer.FixedTarget; */ public class DealsCombatDamageToAPlayerTriggeredAbility extends TriggeredAbilityImpl { - private boolean setTargetPointer; + protected boolean setTargetPointer; + protected String text; public DealsCombatDamageToAPlayerTriggeredAbility(Effect effect, boolean optional) { this(effect, optional, false); @@ -52,8 +54,15 @@ public class DealsCombatDamageToAPlayerTriggeredAbility extends TriggeredAbility this.setTargetPointer = setTargetPointer; } + public DealsCombatDamageToAPlayerTriggeredAbility(Effect effect, boolean optional, String text, boolean setTargetPointer) { + super(Zone.BATTLEFIELD, effect, optional); + this.text = text; + this.setTargetPointer = setTargetPointer; + } + public DealsCombatDamageToAPlayerTriggeredAbility(final DealsCombatDamageToAPlayerTriggeredAbility ability) { super(ability); + this.text = ability.text; this.setTargetPointer = ability.setTargetPointer; } @@ -84,7 +93,10 @@ public class DealsCombatDamageToAPlayerTriggeredAbility extends TriggeredAbility @Override public String getRule() { - return "Whenever {this} deals combat damage to a player, " + super.getRule(); + if (text == null || text.isEmpty()) { + return "Whenever {this} deals combat damage to a player, " + super.getRule(); + } + return text; } } diff --git a/Mage/src/main/java/mage/abilities/common/LeavesBattlefieldAllTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/LeavesBattlefieldAllTriggeredAbility.java new file mode 100644 index 0000000000..2c05677467 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/common/LeavesBattlefieldAllTriggeredAbility.java @@ -0,0 +1,93 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.abilities.common; + +import java.util.UUID; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author Styxo + */ +public class LeavesBattlefieldAllTriggeredAbility extends TriggeredAbilityImpl { + + protected FilterPermanent filter; + + public LeavesBattlefieldAllTriggeredAbility(Effect effect, FilterPermanent filter) { + this(effect, filter, false); + } + + public LeavesBattlefieldAllTriggeredAbility(Effect effect, FilterPermanent filter, boolean optional) { + this(Zone.BATTLEFIELD, effect, filter, optional); + } + + public LeavesBattlefieldAllTriggeredAbility(Zone zone, Effect effect, FilterPermanent filter, boolean optional) { + super(zone, effect, optional); + this.filter = filter; + } + + public LeavesBattlefieldAllTriggeredAbility(final LeavesBattlefieldAllTriggeredAbility ability) { + super(ability); + filter = ability.filter; + } + + @Override + public LeavesBattlefieldAllTriggeredAbility copy() { + return new LeavesBattlefieldAllTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (zEvent.getFromZone() == Zone.BATTLEFIELD) { + UUID targetId = event.getTargetId(); + Permanent permanent = game.getPermanentOrLKIBattlefield(targetId); + if (permanent != null) { + return filter.match(permanent, getSourceId(), getControllerId(), game); + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever " + filter.getMessage() + " leaves the battlefield, " + super.getRule(); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/SetPlayerLifeTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/SetPlayerLifeTargetEffect.java new file mode 100644 index 0000000000..f38181d11e --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/SetPlayerLifeTargetEffect.java @@ -0,0 +1,81 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author Styxo + */ +public class SetPlayerLifeTargetEffect extends OneShotEffect { + + protected DynamicValue amount; + + public SetPlayerLifeTargetEffect(int amount) { + this(new StaticValue(amount)); + } + + public SetPlayerLifeTargetEffect(DynamicValue amount) { + super(Outcome.Neutral); + this.amount = amount; + this.staticText = setText(); + } + + public SetPlayerLifeTargetEffect(final SetPlayerLifeTargetEffect effect) { + super(effect); + this.amount = effect.amount; + } + + @Override + public SetPlayerLifeTargetEffect copy() { + return new SetPlayerLifeTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(targetPointer.getFirst(game, source)); + if (player != null) { + player.setLife(amount.calculate(game, source, this), game); + return true; + } + return false; + } + + private String setText() { + StringBuilder sb = new StringBuilder("Target player's life total becomes "); + sb.append(amount.toString()); + return sb.toString(); + } +} \ No newline at end of file diff --git a/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CantHaveCountersSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CantHaveCountersSourceEffect.java new file mode 100644 index 0000000000..e6ca45a18b --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CantHaveCountersSourceEffect.java @@ -0,0 +1,71 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.abilities.effects.common.ruleModifying; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.events.GameEvent; + +/** + * + * @author Styxo + */ +public class CantHaveCountersSourceEffect extends ContinuousRuleModifyingEffectImpl { + + public CantHaveCountersSourceEffect() { + super(Duration.WhileOnBattlefield, Outcome.Detriment); + staticText = "{this} can't have counters placed on it"; + } + + public CantHaveCountersSourceEffect(final CantHaveCountersSourceEffect effect) { + super(effect); + } + + @Override + public CantHaveCountersSourceEffect copy() { + return new CantHaveCountersSourceEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ADD_COUNTERS; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + UUID sourceId = source.getSourceId(); + if (sourceId != null) { + return sourceId.equals(event.getTargetId()); + } + return false; + } +} diff --git a/Mage/src/main/java/mage/target/common/TargetTriggeredAbility.java b/Mage/src/main/java/mage/target/common/TargetTriggeredAbility.java new file mode 100644 index 0000000000..22896eab0d --- /dev/null +++ b/Mage/src/main/java/mage/target/common/TargetTriggeredAbility.java @@ -0,0 +1,117 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.target.common; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbility; +import mage.constants.Zone; +import mage.filter.Filter; +import mage.filter.FilterAbility; +import mage.game.Game; +import mage.game.stack.StackObject; +import mage.target.TargetObject; + +/** + * + * @author Styxo + */ +public class TargetTriggeredAbility extends TargetObject { + + public TargetTriggeredAbility() { + this.minNumberOfTargets = 1; + this.maxNumberOfTargets = 1; + this.zone = Zone.STACK; + this.targetName = "target triggered ability you control"; + } + + public TargetTriggeredAbility(final TargetTriggeredAbility target) { + super(target); + } + + @Override + public boolean canTarget(UUID id, Ability source, Game game) { + if (source != null && source.getSourceId().equals(id)) { + return false; + } + + StackObject stackObject = game.getStack().getStackObject(id); + return stackObject.getStackAbility() != null + && (stackObject.getStackAbility() instanceof TriggeredAbility) + && source != null + && stackObject.getStackAbility().getControllerId().equals(source.getControllerId()); + } + + @Override + public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { + return canChoose(sourceControllerId, game); + } + + @Override + public boolean canChoose(UUID sourceControllerId, Game game) { + for (StackObject stackObject : game.getStack()) { + if (stackObject.getStackAbility() != null + && stackObject.getStackAbility() instanceof TriggeredAbility + && stackObject.getStackAbility().getControllerId().equals(sourceControllerId)) { + return true; + } + } + return false; + } + + @Override + public Set possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) { + return possibleTargets(sourceControllerId, game); + } + + @Override + public Set possibleTargets(UUID sourceControllerId, Game game) { + Set possibleTargets = new HashSet<>(); + for (StackObject stackObject : game.getStack()) { + if (stackObject.getStackAbility() != null + && stackObject.getStackAbility() instanceof TriggeredAbility + && stackObject.getStackAbility().getControllerId().equals(sourceControllerId)) { + possibleTargets.add(stackObject.getStackAbility().getId()); + } + } + return possibleTargets; + } + + @Override + public TargetTriggeredAbility copy() { + return new TargetTriggeredAbility(this); + } + + @Override + public Filter getFilter() { + return new FilterAbility(); + } + +}