diff --git a/Mage.Sets/src/mage/sets/magic2015/GarrukApexPredator.java b/Mage.Sets/src/mage/sets/magic2015/GarrukApexPredator.java new file mode 100644 index 00000000000..19b425c3062 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magic2015/GarrukApexPredator.java @@ -0,0 +1,178 @@ +/* + * 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.magic2015; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.AttackedByCreatureTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.GetEmblemTargetPlayerEffect; +import mage.abilities.effects.common.continious.BoostTargetEffect; +import mage.abilities.effects.common.continious.GainAbilityTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.TrampleAbility; +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.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.game.Game; +import mage.game.command.Emblem; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.Token; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetOpponent; + +/** + * + * @author LevelX2 + */ +public class GarrukApexPredator extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("another target planeswalker"); + + static { + filter.add(new CardTypePredicate(CardType.PLANESWALKER)); + filter.add(new AnotherPredicate()); + } + + public GarrukApexPredator(UUID ownerId) { + super(ownerId, 210, "Garruk, Apex Predator", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{5}{B}{G}"); + this.expansionSetCode = "M15"; + this.subtype.add("Garruk"); + + this.color.setGreen(true); + this.color.setBlack(true); + + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); + + // +1: Destroy another target planeswalker. + LoyaltyAbility ability = new LoyaltyAbility(new DestroyTargetEffect(), 1); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + + // +1: Put a 3/3 black Beast creature token with deathtouch onto the battlefield. + ability = new LoyaltyAbility(new CreateTokenEffect(new GarrukApexPredatorBeastToken()), 1); + this.addAbility(ability); + + // -3: Destroy target creature. You gain life equal to its toughness. + ability = new LoyaltyAbility(new DestroyTargetEffect(), -3); + ability.addEffect(new GarrukApexPredatorEffect3()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + + // -8: Target opponent gets an emblem with "Whenever a creature attacks you, it gets +5/+5 and gains trample until end of turn." + ability = new LoyaltyAbility(new GetEmblemTargetPlayerEffect(new GarrukApexPredatorEmblem()), -8); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + } + + public GarrukApexPredator(final GarrukApexPredator card) { + super(card); + } + + @Override + public GarrukApexPredator copy() { + return new GarrukApexPredator(this); + } +} + +class GarrukApexPredatorEffect3 extends OneShotEffect { + + public GarrukApexPredatorEffect3() { + super(Outcome.GainLife); + this.staticText = "You gain life equal to its toughness"; + } + + public GarrukApexPredatorEffect3(final GarrukApexPredatorEffect3 effect) { + super(effect); + } + + @Override + public GarrukApexPredatorEffect3 copy() { + return new GarrukApexPredatorEffect3(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Permanent creature = (Permanent) game.getLastKnownInformation(source.getFirstTarget(), Zone.BATTLEFIELD); + if (player != null && creature != null) { + player.gainLife(creature.getToughness().getValue(), game); + return true; + } + return false; + } +} + +class GarrukApexPredatorBeastToken extends Token { + + public GarrukApexPredatorBeastToken() { + super("Beast", "3/3 black Beast creature token with deathtouch"); + setOriginalExpansionSetCode("M15"); + cardType.add(CardType.CREATURE); + color.setBlack(true); + subtype.add("Beast"); + power = new MageInt(3); + toughness = new MageInt(3); + + abilities.add(DeathtouchAbility.getInstance()); + + } + +} + +/** + * Emblem with "Whenever a creature attacks you, it gets +5/+5 and gains trample until end of turn." + */ +class GarrukApexPredatorEmblem extends Emblem { + + public GarrukApexPredatorEmblem() { + Effect effect = new BoostTargetEffect(5,5,Duration.EndOfTurn); + effect.setText("it gets +5/+5"); + Ability ability = new AttackedByCreatureTriggeredAbility(effect, false, true); + effect = new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn, + "and gains trample until end of turn"); + ability.addEffect(effect); + this.getAbilities().add(ability); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/magic2015/SliverHivelord.java b/Mage.Sets/src/mage/sets/magic2015/SliverHivelord.java new file mode 100644 index 00000000000..552acca4059 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magic2015/SliverHivelord.java @@ -0,0 +1,78 @@ +/* + * 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.magic2015; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continious.GainAbilityControlledEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.IndestructibleAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class SliverHivelord extends CardImpl { + + public SliverHivelord(UUID ownerId) { + super(ownerId, 211, "Sliver Hivelord", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{W}{U}{B}{R}{G}"); + this.expansionSetCode = "M15"; + this.supertype.add("Legendary"); + this.subtype.add("Sliver"); + + this.color.setRed(true); + this.color.setBlue(true); + this.color.setGreen(true); + this.color.setBlack(true); + this.color.setWhite(true); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Sliver creatures you control have indestructible. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new GainAbilityControlledEffect(IndestructibleAbility.getInstance(), + Duration.WhileOnBattlefield, new FilterCreaturePermanent("Sliver","Sliver creatures")))); + + } + + public SliverHivelord(final SliverHivelord card) { + super(card); + } + + @Override + public SliverHivelord copy() { + return new SliverHivelord(this); + } +} diff --git a/Mage/src/mage/abilities/common/AttackedByCreatureTriggeredAbility.java b/Mage/src/mage/abilities/common/AttackedByCreatureTriggeredAbility.java new file mode 100644 index 00000000000..55299da9101 --- /dev/null +++ b/Mage/src/mage/abilities/common/AttackedByCreatureTriggeredAbility.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.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 + */ +public class AttackedByCreatureTriggeredAbility extends TriggeredAbilityImpl { + + protected boolean setTargetPointer; + + public AttackedByCreatureTriggeredAbility(Effect effect) { + this(effect, false); + } + + public AttackedByCreatureTriggeredAbility(Effect effect, boolean optional) { + this(effect, optional, false); + } + + public AttackedByCreatureTriggeredAbility(Effect effect, boolean optional, boolean setTargetPointer) { + super(Zone.BATTLEFIELD, effect, optional); + this.setTargetPointer = setTargetPointer; + } + + public AttackedByCreatureTriggeredAbility(AttackedByCreatureTriggeredAbility ability) { + super(ability); + this.setTargetPointer = ability.setTargetPointer; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.ATTACKER_DECLARED) { + UUID playerId = game.getCombat().getDefendingPlayerId(event.getSourceId(), game); + Permanent attackingCreature = game.getPermanent(event.getSourceId()); + if (getControllerId().equals(playerId) && attackingCreature != null) { + if (setTargetPointer) { + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(event.getSourceId())); + } + } + return true; + } + } + return false; + } + + @Override + public AttackedByCreatureTriggeredAbility copy() { + return new AttackedByCreatureTriggeredAbility(this); + } + + @Override + public String getRule() { + return "Whenever a creature attacks you, " + super.getRule(); + } + +} diff --git a/Mage/src/mage/abilities/effects/common/GetEmblemEffect.java b/Mage/src/mage/abilities/effects/common/GetEmblemEffect.java index d24a7c149fc..32204f54fcf 100644 --- a/Mage/src/mage/abilities/effects/common/GetEmblemEffect.java +++ b/Mage/src/mage/abilities/effects/common/GetEmblemEffect.java @@ -34,10 +34,11 @@ import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; import mage.game.Game; import mage.game.command.Emblem; +import mage.players.Player; /** * - * @author nantuko + * @author LevelX2 */ public class GetEmblemEffect extends OneShotEffect { @@ -46,7 +47,7 @@ public class GetEmblemEffect extends OneShotEffect { public GetEmblemEffect(Emblem emblem) { super(Outcome.Benefit); this.emblem = emblem; - this.staticText = "You get an emblem with \"" + emblem.getAbilities().getRules(null) + "\""; + this.staticText = "Target opponent gets an emblem with \"" + emblem.getAbilities().getRules(null) + "\""; } public GetEmblemEffect(final GetEmblemEffect effect) { @@ -65,7 +66,11 @@ public class GetEmblemEffect extends OneShotEffect { if (sourceObject == null) { return false; } - game.addEmblem(emblem, source); + Player toPlayer = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (toPlayer == null) { + return false; + } + game.addEmblem(emblem, source, toPlayer.getId()); return true; } diff --git a/Mage/src/mage/abilities/effects/common/GetEmblemTargetPlayerEffect.java b/Mage/src/mage/abilities/effects/common/GetEmblemTargetPlayerEffect.java new file mode 100644 index 00000000000..9b61d4ba145 --- /dev/null +++ b/Mage/src/mage/abilities/effects/common/GetEmblemTargetPlayerEffect.java @@ -0,0 +1,85 @@ +/* +* 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.MageObject; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.command.Emblem; +import mage.players.Player; + +/** + * + * @author LevelX2 + */ +public class GetEmblemTargetPlayerEffect extends OneShotEffect { + + private final Emblem emblem; + + public GetEmblemTargetPlayerEffect(Emblem emblem) { + super(Outcome.Benefit); + this.emblem = emblem; + + } + + public GetEmblemTargetPlayerEffect(final GetEmblemTargetPlayerEffect effect) { + super(effect); + this.emblem = effect.emblem; + } + + @Override + public GetEmblemTargetPlayerEffect copy() { + return new GetEmblemTargetPlayerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + MageObject sourceObject = game.getObject(source.getSourceId()); + if (sourceObject == null) { + return false; + } + Player toPlayer = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (toPlayer == null) { + return false; + } + game.addEmblem(emblem, source, toPlayer.getId()); + return true; + } + + @Override + public String getText(Mode mode) { + if (staticText != null && !staticText.isEmpty()) { + return staticText; + } + return "Target " + mode.getTargets().get(0).getTargetName() + " gets an emblem with \"" + emblem.getAbilities().getRules(null) + "\""; + } +} diff --git a/Mage/src/mage/game/Game.java b/Mage/src/mage/game/Game.java index 497dcb7a8b9..d740d431374 100644 --- a/Mage/src/mage/game/Game.java +++ b/Mage/src/mage/game/Game.java @@ -231,6 +231,7 @@ public interface Game extends MageItem, Serializable { void emptyManaPools(); void addEffect(ContinuousEffect continuousEffect, Ability source); void addEmblem(Emblem emblem, Ability source); + void addEmblem(Emblem emblem, Ability source, UUID toPlayerId); void addCommander(Commander commander); void addPermanent(Permanent permanent); diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index 9f28fb04d4a..a794c6f3ae0 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -1170,9 +1170,18 @@ public abstract class GameImpl implements Game, Serializable { @Override public void addEmblem(Emblem emblem, Ability source) { + addEmblem(emblem, source, null); + } + + @Override + public void addEmblem(Emblem emblem, Ability source, UUID toPlayerId) { Emblem newEmblem = emblem.copy(); newEmblem.setSourceId(source.getSourceId()); - newEmblem.setControllerId(source.getControllerId()); + if (toPlayerId == null) { + newEmblem.setControllerId(source.getControllerId()); + } else { + newEmblem.setControllerId(toPlayerId); + } newEmblem.assignNewId(); newEmblem.getAbilities().newId(); for (Ability ability : newEmblem.getAbilities()) {