mirror of
https://github.com/correl/mage.git
synced 2024-12-25 11:11:16 +00:00
Merge origin/master
This commit is contained in:
commit
3d0409e1bb
35 changed files with 2470 additions and 243 deletions
|
@ -231,8 +231,11 @@ public enum UserStatsRepository {
|
||||||
outcome = 0.5;
|
outcome = 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultProtos.UserStatsProto player1StatsProto = getUserStatsProto(player1.getName(), matchEndTimeMs);
|
// get players stats
|
||||||
ResultProtos.UserStatsProto player2StatsProto = getUserStatsProto(player2.getName(), matchEndTimeMs);
|
UserStats player1Stats = getOrCreateUserStats(player1.getName(), tableEndTimeMs);
|
||||||
|
ResultProtos.UserStatsProto player1StatsProto = player1Stats.getProto();
|
||||||
|
UserStats player2Stats = getOrCreateUserStats(player2.getName(), tableEndTimeMs);
|
||||||
|
ResultProtos.UserStatsProto player2StatsProto = player2Stats.getProto();
|
||||||
|
|
||||||
ResultProtos.UserStatsProto.Builder player1StatsBuilder =
|
ResultProtos.UserStatsProto.Builder player1StatsBuilder =
|
||||||
ResultProtos.UserStatsProto.newBuilder(player1StatsProto);
|
ResultProtos.UserStatsProto.newBuilder(player1StatsProto);
|
||||||
|
@ -305,8 +308,8 @@ public enum UserStatsRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this.update(new UserStats(player1StatsBuilder.build(), matchEndTimeMs));
|
this.update(new UserStats(player1StatsBuilder.build(), player1Stats.getEndTimeMs()));
|
||||||
this.update(new UserStats(player2StatsBuilder.build(), matchEndTimeMs));
|
this.update(new UserStats(player2StatsBuilder.build(), player2Stats.getEndTimeMs()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateRating(
|
private void updateRating(
|
||||||
|
@ -351,16 +354,14 @@ public enum UserStatsRepository {
|
||||||
.setLastGameTimeMs(tableEndTimeMs);
|
.setLastGameTimeMs(tableEndTimeMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResultProtos.UserStatsProto getUserStatsProto(String playerName, long endTimeMs) {
|
private UserStats getOrCreateUserStats(String playerName, long endTimeMs) {
|
||||||
UserStats player1Stats = this.getUser(playerName);
|
UserStats userStats = this.getUser(playerName);
|
||||||
ResultProtos.UserStatsProto player1StatsProto;
|
if (userStats == null) {
|
||||||
if (player1Stats != null) {
|
ResultProtos.UserStatsProto userStatsProto = ResultProtos.UserStatsProto.newBuilder().setName(playerName).build();
|
||||||
player1StatsProto = player1Stats.getProto();
|
userStats = new UserStats(userStatsProto, endTimeMs);
|
||||||
} else {
|
this.add(userStats);
|
||||||
player1StatsProto = ResultProtos.UserStatsProto.newBuilder().setName(playerName).build();
|
|
||||||
this.add(new UserStats(player1StatsProto, endTimeMs));
|
|
||||||
}
|
}
|
||||||
return player1StatsProto;
|
return userStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void closeDB() {
|
public void closeDB() {
|
||||||
|
|
101
Mage.Sets/src/mage/sets/darksteel/BurdenOfGreed.java
Normal file
101
Mage.Sets/src/mage/sets/darksteel/BurdenOfGreed.java
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* 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.darksteel;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.dynamicvalue.DynamicValue;
|
||||||
|
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
|
||||||
|
import mage.abilities.dynamicvalue.common.PermanentsTargetOpponentControlsCount;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.abilities.effects.common.LoseLifeTargetEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
import mage.filter.common.FilterArtifactPermanent;
|
||||||
|
import mage.filter.predicate.other.OwnerIdPredicate;
|
||||||
|
import mage.filter.predicate.permanent.ControllerIdPredicate;
|
||||||
|
import mage.filter.predicate.permanent.TappedPredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.target.TargetPlayer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author wetterlicht
|
||||||
|
*/
|
||||||
|
public class BurdenOfGreed extends CardImpl {
|
||||||
|
|
||||||
|
public BurdenOfGreed(UUID ownerId) {
|
||||||
|
super(ownerId, 38, "Burden of Greed", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{3}{B}");
|
||||||
|
this.expansionSetCode = "DST";
|
||||||
|
|
||||||
|
// Target player loses 1 life for each tapped artifact he or she controls.
|
||||||
|
getSpellAbility().addTarget(new TargetPlayer());
|
||||||
|
getSpellAbility().addEffect(new LoseLifeTargetEffect(new BurdenOfGreedCount()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public BurdenOfGreed(final BurdenOfGreed card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BurdenOfGreed copy() {
|
||||||
|
return new BurdenOfGreed(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BurdenOfGreedCount implements DynamicValue {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||||
|
if (sourceAbility.getFirstTarget() == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
FilterArtifactPermanent filter = new FilterArtifactPermanent();
|
||||||
|
filter.add(new TappedPredicate());
|
||||||
|
filter.add(new ControllerIdPredicate(sourceAbility.getFirstTarget()));
|
||||||
|
return game.getBattlefield().count(filter, sourceAbility.getSourceId(), sourceAbility.getControllerId(), game);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DynamicValue copy() {
|
||||||
|
return new BurdenOfGreedCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "1";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
return "tapped artifact he or she controls";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
90
Mage.Sets/src/mage/sets/darksteel/DrillSkimmer.java
Normal file
90
Mage.Sets/src/mage/sets/darksteel/DrillSkimmer.java
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* 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.darksteel;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.ObjectColor;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
|
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||||
|
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||||
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
import mage.abilities.keyword.LifelinkAbility;
|
||||||
|
import mage.abilities.keyword.ShroudAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.filter.common.FilterControlledArtifactPermanent;
|
||||||
|
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||||
|
import mage.filter.common.FilterControlledPlaneswalkerPermanent;
|
||||||
|
import mage.filter.predicate.mageobject.CardTypePredicate;
|
||||||
|
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||||
|
import mage.filter.predicate.permanent.AnotherPredicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author wetterlicht
|
||||||
|
*/
|
||||||
|
public class DrillSkimmer extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("you control another artifact creature");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(new AnotherPredicate());
|
||||||
|
filter.add(new CardTypePredicate(CardType.ARTIFACT));
|
||||||
|
}
|
||||||
|
|
||||||
|
public DrillSkimmer(UUID ownerId) {
|
||||||
|
super(ownerId, 118, "Drill-Skimmer", Rarity.COMMON, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}");
|
||||||
|
this.expansionSetCode = "DST";
|
||||||
|
this.subtype.add("Thopter");
|
||||||
|
this.power = new MageInt(2);
|
||||||
|
this.toughness = new MageInt(1);
|
||||||
|
|
||||||
|
// Flying
|
||||||
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
// Drill-Skimmer has shroud as long as you control another artifact creature.
|
||||||
|
Condition condition = new PermanentsOnTheBattlefieldCondition(filter, PermanentsOnTheBattlefieldCondition.CountType.MORE_THAN, 0);
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
|
||||||
|
new ConditionalContinuousEffect(new GainAbilitySourceEffect(ShroudAbility.getInstance(), Duration.WhileOnBattlefield),
|
||||||
|
condition, "{this} has shroud as long as you control another artifact creature.")));
|
||||||
|
}
|
||||||
|
|
||||||
|
public DrillSkimmer(final DrillSkimmer card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DrillSkimmer copy() {
|
||||||
|
return new DrillSkimmer(this);
|
||||||
|
}
|
||||||
|
}
|
143
Mage.Sets/src/mage/sets/darksteel/DroolingOgre.java
Normal file
143
Mage.Sets/src/mage/sets/darksteel/DroolingOgre.java
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
* 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.darksteel;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
|
import mage.abilities.effects.ContinuousEffect;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||||
|
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;
|
||||||
|
import mage.game.stack.Spell;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.target.targetpointer.FixedTarget;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author wetterlicht
|
||||||
|
*/
|
||||||
|
public class DroolingOgre extends CardImpl {
|
||||||
|
|
||||||
|
public DroolingOgre(UUID ownerId) {
|
||||||
|
super(ownerId, 58, "Drooling Ogre", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{R}");
|
||||||
|
this.expansionSetCode = "DST";
|
||||||
|
this.subtype.add("Ogre");
|
||||||
|
this.power = new MageInt(3);
|
||||||
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
|
// Whenever a player casts an artifact spell, that player gains control of Drooling Ogre.
|
||||||
|
this.addAbility(new DroolingOgreTriggeredAbility());
|
||||||
|
}
|
||||||
|
|
||||||
|
public DroolingOgre(final DroolingOgre card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DroolingOgre copy() {
|
||||||
|
return new DroolingOgre(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DroolingOgreEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
public DroolingOgreEffect() {
|
||||||
|
super(Outcome.GainControl);
|
||||||
|
this.staticText = "that player gains control of {this}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private DroolingOgreEffect(DroolingOgreEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
|
Player newController = game.getPlayer(this.getTargetPointer().getFirst(game, source));
|
||||||
|
if (newController != null && controller != null && !controller.equals(newController)) {
|
||||||
|
ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, newController.getId());
|
||||||
|
effect.setTargetPointer(new FixedTarget(source.getSourceId()));
|
||||||
|
game.addEffect(effect, source);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Effect copy() {
|
||||||
|
return new DroolingOgreEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class DroolingOgreTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
|
public DroolingOgreTriggeredAbility() {
|
||||||
|
super(Zone.BATTLEFIELD, new DroolingOgreEffect(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DroolingOgreTriggeredAbility(final DroolingOgreTriggeredAbility ability) {
|
||||||
|
super(ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DroolingOgreTriggeredAbility copy() {
|
||||||
|
return new DroolingOgreTriggeredAbility(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkEventType(GameEvent event, Game game) {
|
||||||
|
return event.getType() == EventType.SPELL_CAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
|
Spell spell = game.getStack().getSpell(event.getTargetId());
|
||||||
|
if (spell != null && spell.getCardType().contains(CardType.ARTIFACT)) {
|
||||||
|
this.getEffects().get(0).setTargetPointer(new FixedTarget(event.getPlayerId()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRule() {
|
||||||
|
return "Whenever a player casts an artifact spell, that player gains control of {this}.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
100
Mage.Sets/src/mage/sets/darksteel/EmissaryOfDespair.java
Normal file
100
Mage.Sets/src/mage/sets/darksteel/EmissaryOfDespair.java
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* 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.darksteel;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
|
||||||
|
import mage.abilities.dynamicvalue.DynamicValue;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.abilities.effects.common.LoseLifeTargetEffect;
|
||||||
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
import mage.filter.common.FilterArtifactPermanent;
|
||||||
|
import mage.filter.predicate.permanent.ControllerIdPredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author wetterlicht
|
||||||
|
*/
|
||||||
|
public class EmissaryOfDespair extends CardImpl {
|
||||||
|
|
||||||
|
public EmissaryOfDespair(UUID ownerId) {
|
||||||
|
super(ownerId, 42, "Emissary of Despair", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{B}{B}");
|
||||||
|
this.expansionSetCode = "DST";
|
||||||
|
this.subtype.add("Spirit");
|
||||||
|
this.power = new MageInt(2);
|
||||||
|
this.toughness = new MageInt(1);
|
||||||
|
|
||||||
|
// Flying
|
||||||
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
// Whenever Emissary of Despair deals combat damage to a player, that player loses 1 life for each artifact he or she controls.
|
||||||
|
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new LoseLifeTargetEffect(new EmissaryOfDespairCount()), false, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public EmissaryOfDespair(final EmissaryOfDespair card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EmissaryOfDespair copy() {
|
||||||
|
return new EmissaryOfDespair(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EmissaryOfDespairCount implements DynamicValue {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||||
|
if (effect.getTargetPointer().getFirst(game, sourceAbility) == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
FilterArtifactPermanent filter = new FilterArtifactPermanent();
|
||||||
|
filter.add(new ControllerIdPredicate(effect.getTargetPointer().getFirst(game, sourceAbility)));
|
||||||
|
return game.getBattlefield().count(filter, sourceAbility.getSourceId(), sourceAbility.getControllerId(), game);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DynamicValue copy() {
|
||||||
|
return new EmissaryOfDespairCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "1";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
return "artifact he or she controls";
|
||||||
|
}
|
||||||
|
}
|
123
Mage.Sets/src/mage/sets/darksteel/MurderousSpoils.java
Normal file
123
Mage.Sets/src/mage/sets/darksteel/MurderousSpoils.java
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* 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.darksteel;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.ObjectColor;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.effects.ContinuousEffect;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
|
import mage.filter.predicate.Predicates;
|
||||||
|
import mage.filter.predicate.mageobject.CardTypePredicate;
|
||||||
|
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
import mage.target.targetpointer.FixedTarget;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author wetterlicht
|
||||||
|
*/
|
||||||
|
public class MurderousSpoils extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterCreaturePermanent FILTER = new FilterCreaturePermanent("nonblack creature");
|
||||||
|
|
||||||
|
static {
|
||||||
|
FILTER.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MurderousSpoils(UUID ownerId) {
|
||||||
|
super(ownerId, 48, "Murderous Spoils", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{5}{B}");
|
||||||
|
this.expansionSetCode = "DST";
|
||||||
|
|
||||||
|
// Destroy target nonblack creature. It can't be regenerated. You gain control of all Equipment that was attached to it.
|
||||||
|
this.getSpellAbility().addTarget(new TargetCreaturePermanent(FILTER));
|
||||||
|
this.getSpellAbility().addEffect(new MurderousSpoilsEffect());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public MurderousSpoils(final MurderousSpoils card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MurderousSpoils copy() {
|
||||||
|
return new MurderousSpoils(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MurderousSpoilsEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
public MurderousSpoilsEffect() {
|
||||||
|
super(Outcome.DestroyPermanent);
|
||||||
|
staticText = "Destroy target nonblack creature. It can't be regenerated. You gain control of all Equipment that was attached to it.";
|
||||||
|
}
|
||||||
|
|
||||||
|
public MurderousSpoilsEffect(final MurderousSpoilsEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Permanent target = game.getPermanent(source.getFirstTarget());
|
||||||
|
if (target != null) {
|
||||||
|
List<Permanent> attachments = new ArrayList<Permanent>();
|
||||||
|
for (UUID uuid : target.getAttachments()) {
|
||||||
|
Permanent attached = game.getBattlefield().getPermanent(uuid);
|
||||||
|
if (attached.getSubtype().contains("Equipment")) {
|
||||||
|
attachments.add(attached);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Permanent p : attachments) {
|
||||||
|
ContinuousEffect gainControl = new GainControlTargetEffect(Duration.Custom);
|
||||||
|
gainControl.setTargetPointer(new FixedTarget(p, game));
|
||||||
|
game.addEffect(gainControl, source);
|
||||||
|
}
|
||||||
|
target.destroy(source.getId(), game, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MurderousSpoilsEffect copy() {
|
||||||
|
return new MurderousSpoilsEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
90
Mage.Sets/src/mage/sets/darksteel/PsychicOverload.java
Normal file
90
Mage.Sets/src/mage/sets/darksteel/PsychicOverload.java
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* 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.darksteel;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.costs.common.DiscardTargetCost;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.abilities.effects.common.AttachEffect;
|
||||||
|
import mage.abilities.effects.common.DontUntapInControllersUntapStepEnchantedEffect;
|
||||||
|
import mage.abilities.effects.common.TapEnchantedEffect;
|
||||||
|
import mage.abilities.effects.common.UntapSourceEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
|
||||||
|
import mage.abilities.keyword.EnchantAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.AttachmentType;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.filter.common.FilterArtifactCard;
|
||||||
|
import mage.target.TargetPermanent;
|
||||||
|
import mage.target.common.TargetCardInHand;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author wetterlicht
|
||||||
|
*/
|
||||||
|
public class PsychicOverload extends CardImpl {
|
||||||
|
|
||||||
|
public PsychicOverload(UUID ownerId) {
|
||||||
|
super(ownerId, 28, "Psychic Overload", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}");
|
||||||
|
this.expansionSetCode = "DST";
|
||||||
|
this.subtype.add("Aura");
|
||||||
|
|
||||||
|
// Enchant permanent
|
||||||
|
TargetPermanent auraTarget = new TargetPermanent();
|
||||||
|
this.getSpellAbility().addTarget(auraTarget);
|
||||||
|
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
|
||||||
|
this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
|
||||||
|
|
||||||
|
// When Psychic Overload enters the battlefield, tap enchanted permanent.
|
||||||
|
this.addAbility(new EntersBattlefieldTriggeredAbility(new TapEnchantedEffect()));
|
||||||
|
// Enchanted permanent doesn't untap during its controller's untap step.
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepEnchantedEffect()));
|
||||||
|
|
||||||
|
// Enchanted permanent has "Discard two artifact cards: Untap this permanent."
|
||||||
|
Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new UntapSourceEffect(), new DiscardTargetCost(new TargetCardInHand(2, new FilterArtifactCard("two artifact cards"))));
|
||||||
|
Effect effect = new GainAbilityAttachedEffect(gainedAbility, AttachmentType.AURA, Duration.WhileOnBattlefield, "Enchanted permanent has \"Discard two artifact cards: Untap this permanent.\"");
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PsychicOverload(final PsychicOverload card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PsychicOverload copy() {
|
||||||
|
return new PsychicOverload(this);
|
||||||
|
}
|
||||||
|
}
|
118
Mage.Sets/src/mage/sets/darksteel/PulseOfTheTangle.java
Normal file
118
Mage.Sets/src/mage/sets/darksteel/PulseOfTheTangle.java
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
* 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.darksteel;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.CreateTokenEffect;
|
||||||
|
import mage.cards.Card;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||||
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
|
import mage.filter.predicate.permanent.ControllerIdPredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.token.BeastToken;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.target.TargetPlayer;
|
||||||
|
import mage.target.common.TargetOpponent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author wetterlicht
|
||||||
|
*/
|
||||||
|
public class PulseOfTheTangle extends CardImpl {
|
||||||
|
|
||||||
|
public PulseOfTheTangle(UUID ownerId) {
|
||||||
|
super(ownerId, 80, "Pulse of the Tangle", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{1}{G}{G}");
|
||||||
|
this.expansionSetCode = "DST";
|
||||||
|
|
||||||
|
// Put a 3/3 green Beast creature token onto the battlefield. Then if an opponent controls more creatures than you, return Pulse of the Tangle to its owner's hand.
|
||||||
|
this.getSpellAbility().addEffect(new CreateTokenEffect(new BeastToken()));
|
||||||
|
this.getSpellAbility().addEffect(new PulseOfTheTangleReturnToHandEffect());
|
||||||
|
}
|
||||||
|
|
||||||
|
public PulseOfTheTangle(final PulseOfTheTangle card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PulseOfTheTangle copy() {
|
||||||
|
return new PulseOfTheTangle(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PulseOfTheTangleReturnToHandEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
PulseOfTheTangleReturnToHandEffect() {
|
||||||
|
super(Outcome.Benefit);
|
||||||
|
this.staticText = "Then if an opponent controls more creatures than you, return {this} to its owner's hand";
|
||||||
|
}
|
||||||
|
|
||||||
|
PulseOfTheTangleReturnToHandEffect(final PulseOfTheTangleReturnToHandEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PulseOfTheTangleReturnToHandEffect copy() {
|
||||||
|
return new PulseOfTheTangleReturnToHandEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
|
FilterControlledCreaturePermanent controllerFilter = new FilterControlledCreaturePermanent();
|
||||||
|
PermanentsOnBattlefieldCount controllerCount = new PermanentsOnBattlefieldCount(controllerFilter);
|
||||||
|
int controllerAmount = controllerCount.calculate(game, source, this);
|
||||||
|
boolean check = false;
|
||||||
|
if (controller != null) {
|
||||||
|
for (UUID opponentID : game.getOpponents(controller.getId())) {
|
||||||
|
if (opponentID != null) {
|
||||||
|
FilterCreaturePermanent opponentFilter = new FilterCreaturePermanent();
|
||||||
|
opponentFilter.add(new ControllerIdPredicate(opponentID));
|
||||||
|
PermanentsOnBattlefieldCount opponentCreatureCount = new PermanentsOnBattlefieldCount(opponentFilter);
|
||||||
|
check = opponentCreatureCount.calculate(game, source, this) > controllerAmount;
|
||||||
|
if (check) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (check) {
|
||||||
|
Card card = game.getCard(source.getSourceId());
|
||||||
|
controller.moveCards(card, Zone.HAND, source, game);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
60
Mage.Sets/src/mage/sets/darksteel/RebukingCeremony.java
Normal file
60
Mage.Sets/src/mage/sets/darksteel/RebukingCeremony.java
Normal file
|
@ -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.darksteel;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
import mage.target.common.TargetArtifactPermanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author wetterlicht
|
||||||
|
*/
|
||||||
|
public class RebukingCeremony extends CardImpl {
|
||||||
|
|
||||||
|
public RebukingCeremony(UUID ownerId) {
|
||||||
|
super(ownerId, 82, "Rebuking Ceremony", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{3}{G}{G}");
|
||||||
|
this.expansionSetCode = "DST";
|
||||||
|
|
||||||
|
// Put two target artifacts on top of their owners' libraries.
|
||||||
|
getSpellAbility().addEffect(new PutOnLibraryTargetEffect(true));
|
||||||
|
getSpellAbility().addTarget(new TargetArtifactPermanent(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public RebukingCeremony(final RebukingCeremony card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RebukingCeremony copy() {
|
||||||
|
return new RebukingCeremony(this);
|
||||||
|
}
|
||||||
|
}
|
74
Mage.Sets/src/mage/sets/darksteel/TelJiladWolf.java
Normal file
74
Mage.Sets/src/mage/sets/darksteel/TelJiladWolf.java
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* 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.darksteel;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.common.BecomesBlockedAllTriggeredAbility;
|
||||||
|
import mage.abilities.common.BecomesBlockedByCreatureTriggeredAbility;
|
||||||
|
import mage.abilities.common.BecomesBlockedTriggeredAbility;
|
||||||
|
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
|
import mage.filter.predicate.mageobject.CardTypePredicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author wetterlicht
|
||||||
|
*/
|
||||||
|
public class TelJiladWolf extends CardImpl {
|
||||||
|
|
||||||
|
private static FilterCreaturePermanent filter = new FilterCreaturePermanent("artifact creature");
|
||||||
|
|
||||||
|
static{
|
||||||
|
filter.add(new CardTypePredicate(CardType.ARTIFACT));
|
||||||
|
}
|
||||||
|
|
||||||
|
public TelJiladWolf(UUID ownerId) {
|
||||||
|
super(ownerId, 88, "Tel-Jilad Wolf", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{G}");
|
||||||
|
this.expansionSetCode = "DST";
|
||||||
|
this.subtype.add("Wolf");
|
||||||
|
this.power = new MageInt(2);
|
||||||
|
this.toughness = new MageInt(2);
|
||||||
|
|
||||||
|
// Whenever Tel-Jilad Wolf becomes blocked by an artifact creature, Tel-Jilad Wolf gets +3/+3 until end of turn.
|
||||||
|
this.addAbility(new BecomesBlockedByCreatureTriggeredAbility(new BoostSourceEffect(3, 3, Duration.EndOfTurn), filter, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
public TelJiladWolf(final TelJiladWolf card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TelJiladWolf copy() {
|
||||||
|
return new TelJiladWolf(this);
|
||||||
|
}
|
||||||
|
}
|
109
Mage.Sets/src/mage/sets/darksteel/Unforge.java
Normal file
109
Mage.Sets/src/mage/sets/darksteel/Unforge.java
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
* permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are those of the
|
||||||
|
* authors and should not be interpreted as representing official policies, either expressed
|
||||||
|
* or implied, of BetaSteward_at_googlemail.com.
|
||||||
|
*/
|
||||||
|
package mage.sets.darksteel;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
import mage.filter.common.FilterArtifactPermanent;
|
||||||
|
import mage.filter.predicate.mageobject.SubtypePredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.target.common.TargetArtifactPermanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author wetterlicht
|
||||||
|
*/
|
||||||
|
public class Unforge extends CardImpl {
|
||||||
|
|
||||||
|
private static FilterArtifactPermanent filter = new FilterArtifactPermanent("equipment");
|
||||||
|
|
||||||
|
static{
|
||||||
|
filter.add(new SubtypePredicate("Equipment"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Unforge(UUID ownerId) {
|
||||||
|
super(ownerId, 71, "Unforge", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{2}{R}");
|
||||||
|
this.expansionSetCode = "DST";
|
||||||
|
|
||||||
|
// Destroy target Equipment. If that Equipment was attached to a creature, Unforge deals 2 damage to that creature.
|
||||||
|
getSpellAbility().addTarget(new TargetArtifactPermanent(filter));
|
||||||
|
getSpellAbility().addEffect(new DestroyTargetEffect());
|
||||||
|
getSpellAbility().addEffect(new UnforgeEffect());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Unforge(final Unforge card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Unforge copy() {
|
||||||
|
return new Unforge(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class UnforgeEffect extends OneShotEffect{
|
||||||
|
|
||||||
|
public UnforgeEffect(){
|
||||||
|
super(Outcome.Damage);
|
||||||
|
staticText = "If that Equipment was attached to a creature, Unforge deals 2 damage to that creature.";
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnforgeEffect(final UnforgeEffect effect){
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Permanent equipment = game.getPermanentOrLKIBattlefield(this.getTargetPointer().getFirst(game, source));
|
||||||
|
if(equipment != null){
|
||||||
|
Permanent creature = game.getPermanent(equipment.getAttachedTo());
|
||||||
|
if(creature != null){
|
||||||
|
creature.damage(2, source.getId(), game, false, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Effect copy() {
|
||||||
|
return new UnforgeEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
104
Mage.Sets/src/mage/sets/darksteel/Vex.java
Normal file
104
Mage.Sets/src/mage/sets/darksteel/Vex.java
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* 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.darksteel;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.CounterTargetEffect;
|
||||||
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
|
import mage.abilities.effects.common.DrawCardTargetEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.stack.Spell;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.target.Target;
|
||||||
|
import mage.target.TargetSpell;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author wetterlicht
|
||||||
|
*/
|
||||||
|
public class Vex extends CardImpl {
|
||||||
|
|
||||||
|
public Vex(UUID ownerId) {
|
||||||
|
super(ownerId, 36, "Vex", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{2}{U}");
|
||||||
|
this.expansionSetCode = "DST";
|
||||||
|
|
||||||
|
// Counter target spell. That spell's controller may draw a card.
|
||||||
|
getSpellAbility().addTarget(new TargetSpell());
|
||||||
|
getSpellAbility().addEffect(new VexEffect());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vex(final Vex card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vex copy() {
|
||||||
|
return new Vex(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class VexEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
public VexEffect() {
|
||||||
|
super(Outcome.Neutral);
|
||||||
|
this.staticText = "That spell's controller may draw a card";
|
||||||
|
}
|
||||||
|
|
||||||
|
public VexEffect(final VexEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VexEffect copy() {
|
||||||
|
return new VexEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
UUID targetId = source.getFirstTarget();
|
||||||
|
Player controller = null;
|
||||||
|
boolean countered = false;
|
||||||
|
if (targetId != null) {
|
||||||
|
controller = game.getPlayer(game.getControllerId(targetId));
|
||||||
|
}
|
||||||
|
if (targetId != null
|
||||||
|
&& game.getStack().counter(targetId, source.getSourceId(), game)) {
|
||||||
|
countered = true;
|
||||||
|
}
|
||||||
|
if (controller != null) {
|
||||||
|
controller.drawCards(1, game);
|
||||||
|
}
|
||||||
|
return countered;
|
||||||
|
}
|
||||||
|
}
|
76
Mage.Sets/src/mage/sets/futuresight/ArcBlade.java
Normal file
76
Mage.Sets/src/mage/sets/futuresight/ArcBlade.java
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* 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.futuresight;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
|
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.abilities.effects.common.DamageTargetEffect;
|
||||||
|
import mage.abilities.effects.common.ExileSpellEffect;
|
||||||
|
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
|
import mage.abilities.keyword.SuspendAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
import mage.counters.CounterType;
|
||||||
|
import mage.target.common.TargetCreatureOrPlayer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author emerald000
|
||||||
|
*/
|
||||||
|
public class ArcBlade extends CardImpl {
|
||||||
|
|
||||||
|
public ArcBlade(UUID ownerId) {
|
||||||
|
super(ownerId, 94, "Arc Blade", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{3}{R}{R}");
|
||||||
|
this.expansionSetCode = "FUT";
|
||||||
|
|
||||||
|
// Arc Blade deals 2 damage to target creature or player.
|
||||||
|
this.getSpellAbility().addEffect(new DamageTargetEffect(2));
|
||||||
|
// Exile Arc Blade
|
||||||
|
this.getSpellAbility().addEffect(ExileSpellEffect.getInstance());
|
||||||
|
// with three time counters on it.
|
||||||
|
Effect effect = new AddCountersSourceEffect(CounterType.TIME.createInstance(), new StaticValue(3), false, true);
|
||||||
|
effect.setText("with 3 time counters on it");
|
||||||
|
this.getSpellAbility().addEffect(effect);
|
||||||
|
this.getSpellAbility().addTarget(new TargetCreatureOrPlayer());
|
||||||
|
|
||||||
|
// Suspend 3-{2}{R}
|
||||||
|
this.addAbility(new SuspendAbility(3, new ManaCostsImpl<>("{2}{R}"), this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArcBlade(final ArcBlade card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArcBlade copy() {
|
||||||
|
return new ArcBlade(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,9 +27,6 @@
|
||||||
*/
|
*/
|
||||||
package mage.sets.journeyintonyx;
|
package mage.sets.journeyintonyx;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.TriggeredAbilityImpl;
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
|
@ -47,7 +44,6 @@ import mage.cards.CardsImpl;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.ColoredManaSymbol;
|
import mage.constants.ColoredManaSymbol;
|
||||||
import mage.constants.Rarity;
|
import mage.constants.Rarity;
|
||||||
import mage.constants.WatcherScope;
|
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
|
@ -55,7 +51,7 @@ import mage.game.events.GameEvent.EventType;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.common.TargetCreatureOrPlayer;
|
import mage.target.common.TargetCreatureOrPlayer;
|
||||||
import mage.watchers.Watcher;
|
import mage.watchers.common.CardsAmountDrawnThisTurnWatcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -83,7 +79,7 @@ public class KeranosGodOfStorms extends CardImpl {
|
||||||
// Reveal the first card you draw on each of your turns.
|
// Reveal the first card you draw on each of your turns.
|
||||||
// Whenever you reveal a land card this way, draw a card.
|
// Whenever you reveal a land card this way, draw a card.
|
||||||
// Whenever you reveal a nonland card this way, Keranos deals 3 damage to target creature or player.
|
// Whenever you reveal a nonland card this way, Keranos deals 3 damage to target creature or player.
|
||||||
this.addAbility(new KeranosGodOfStormsTriggeredAbility(), new CardsDrawnDuringTurnWatcher());
|
this.addAbility(new KeranosGodOfStormsTriggeredAbility(), new CardsAmountDrawnThisTurnWatcher());
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -122,7 +118,8 @@ class KeranosGodOfStormsTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
if (event.getPlayerId().equals(this.getControllerId())) {
|
if (event.getPlayerId().equals(this.getControllerId())) {
|
||||||
if (game.getActivePlayerId().equals(this.getControllerId())) {
|
if (game.getActivePlayerId().equals(this.getControllerId())) {
|
||||||
CardsDrawnDuringTurnWatcher watcher = (CardsDrawnDuringTurnWatcher) game.getState().getWatchers().get("CardsDrawnDuringTurn");
|
CardsAmountDrawnThisTurnWatcher watcher =
|
||||||
|
(CardsAmountDrawnThisTurnWatcher) game.getState().getWatchers().get(CardsAmountDrawnThisTurnWatcher.BASIC_KEY);
|
||||||
if (watcher != null && watcher.getAmountCardsDrawn(event.getPlayerId()) != 1) {
|
if (watcher != null && watcher.getAmountCardsDrawn(event.getPlayerId()) != 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -148,56 +145,7 @@ class KeranosGodOfStormsTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return "Reveal the first card you draw on each of your turns. Whenever you reveal a land card this way, draw a card. Whenever you reveal a nonland card this way, Keranos deals 3 damage to target creature or player.";
|
return "Reveal the first card you draw on each of your turns. Whenever you reveal a land card this way, draw a card. " +
|
||||||
|
"Whenever you reveal a nonland card this way, Keranos deals 3 damage to target creature or player.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CardsDrawnDuringTurnWatcher extends Watcher {
|
|
||||||
|
|
||||||
private final Map<UUID, Integer> amountOfCardsDrawnThisTurn = new HashMap<>();
|
|
||||||
|
|
||||||
public CardsDrawnDuringTurnWatcher() {
|
|
||||||
super("CardsDrawnDuringTurn", WatcherScope.GAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CardsDrawnDuringTurnWatcher(final CardsDrawnDuringTurnWatcher watcher) {
|
|
||||||
super(watcher);
|
|
||||||
for (Entry<UUID, Integer> entry : watcher.amountOfCardsDrawnThisTurn.entrySet()) {
|
|
||||||
amountOfCardsDrawnThisTurn.put(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void watch(GameEvent event, Game game) {
|
|
||||||
if (event.getType() == GameEvent.EventType.DREW_CARD) {
|
|
||||||
UUID playerId = event.getPlayerId();
|
|
||||||
if (playerId != null) {
|
|
||||||
Integer amount = amountOfCardsDrawnThisTurn.get(playerId);
|
|
||||||
if (amount == null) {
|
|
||||||
amount = 1;
|
|
||||||
} else {
|
|
||||||
amount++;
|
|
||||||
}
|
|
||||||
amountOfCardsDrawnThisTurn.put(playerId, amount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getAmountCardsDrawn(UUID playerId) {
|
|
||||||
Integer amount = amountOfCardsDrawnThisTurn.get(playerId);
|
|
||||||
if (amount != null) {
|
|
||||||
return amount;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
amountOfCardsDrawnThisTurn.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CardsDrawnDuringTurnWatcher copy() {
|
|
||||||
return new CardsDrawnDuringTurnWatcher(this);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -28,12 +28,12 @@
|
||||||
package mage.sets.legends;
|
package mage.sets.legends;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import mage.ObjectColor;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.TriggeredAbilityImpl;
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
import mage.abilities.costs.mana.GenericManaCost;
|
import mage.abilities.costs.mana.GenericManaCost;
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
import mage.abilities.effects.common.CounterUnlessPaysEffect;
|
import mage.abilities.effects.common.CounterUnlessPaysEffect;
|
||||||
import mage.cards.Card;
|
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Rarity;
|
import mage.constants.Rarity;
|
||||||
|
@ -92,54 +92,31 @@ class InvokePrejudiceTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
Card card = game.getCard(event.getSourceId());
|
if (game.getOpponents(getControllerId()).contains(event.getPlayerId())) {
|
||||||
|
Spell spell = (Spell) game.getObject(event.getTargetId());
|
||||||
if (card == null || !(card.getCardType().contains(CardType.CREATURE))) {
|
if (spell != null && spell.getCardType().contains(CardType.CREATURE)) {
|
||||||
return false;
|
boolean creatureSharesAColor = false;
|
||||||
}
|
ObjectColor spellColor = spell.getColor(game);
|
||||||
|
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterControlledCreaturePermanent(), getControllerId(), game)) {
|
||||||
// Get colors of the card
|
if (spellColor.shares(permanent.getColor(game))) {
|
||||||
boolean castCreatureIsWhite = card.getColor(game).isWhite();
|
creatureSharesAColor = true;
|
||||||
boolean castCreatureIsBlue = card.getColor(game).isBlue();
|
break;
|
||||||
boolean castCreatureIsBlack = card.getColor(game).isBlack();
|
}
|
||||||
boolean castCreatureIsRed = card.getColor(game).isRed();
|
}
|
||||||
boolean castCreatureIsGreen = card.getColor(game).isGreen();
|
if (!creatureSharesAColor) {
|
||||||
|
for (Effect effect : getEffects()) {
|
||||||
// Compare to colours of creatures of controller on bf
|
effect.setTargetPointer(new FixedTarget(event.getTargetId()));
|
||||||
boolean hasToPay = true;
|
}
|
||||||
boolean gotACreature = false;
|
return true;
|
||||||
|
}
|
||||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), getControllerId(), game)) {
|
|
||||||
gotACreature = true;
|
|
||||||
if (castCreatureIsWhite && permanent.getColor(game).isWhite()) {
|
|
||||||
hasToPay = false;
|
|
||||||
}
|
|
||||||
if (castCreatureIsBlue && permanent.getColor(game).isBlue()) {
|
|
||||||
hasToPay = false;
|
|
||||||
}
|
|
||||||
if (castCreatureIsBlack && permanent.getColor(game).isBlack()) {
|
|
||||||
hasToPay = false;
|
|
||||||
}
|
|
||||||
if (castCreatureIsRed && permanent.getColor(game).isRed()) {
|
|
||||||
hasToPay = false;
|
|
||||||
}
|
|
||||||
if (castCreatureIsGreen && permanent.getColor(game).isGreen()) {
|
|
||||||
hasToPay = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
if (hasToPay || !gotACreature) {
|
|
||||||
for (Effect effect : getEffects()) {
|
|
||||||
effect.setTargetPointer(new FixedTarget(card.getId()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hasToPay || !gotACreature;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return "Whenever an opponent casts a creature spell that doesn't share a color with a creature you control, counter that spell unless that player pays {X}, where X is its converted mana cost.";
|
return "Whenever an opponent casts a creature spell that doesn't share a color with a creature you control, " + super.getRule();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,14 +140,10 @@ class InvokePrejudiceEffect extends CounterUnlessPaysEffect {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
boolean result = true;
|
boolean result = true;
|
||||||
Spell spell = game.getStack().getSpell(getTargetPointer().getFirst(game, source));
|
Spell spell = game.getStack().getSpell(getTargetPointer().getFirst(game, source));
|
||||||
|
|
||||||
if (spell != null) {
|
if (spell != null) {
|
||||||
Card card = spell.getCard();
|
CounterUnlessPaysEffect effect = new CounterUnlessPaysEffect(new GenericManaCost(spell.getConvertedManaCost()));
|
||||||
if (card != null) {
|
effect.setTargetPointer(getTargetPointer());
|
||||||
CounterUnlessPaysEffect effect = new CounterUnlessPaysEffect(new GenericManaCost(card.getConvertedManaCost()));
|
result = effect.apply(game, source);
|
||||||
effect.setTargetPointer(new FixedTarget(spell.getId()));
|
|
||||||
result = effect.apply(game, source);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ import mage.constants.Zone;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -87,11 +88,6 @@ class CoatOfArmsEffect extends ContinuousEffectImpl {
|
||||||
return new CoatOfArmsEffect(this);
|
return new CoatOfArmsEffect(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Ability source, Game game) {
|
|
||||||
super.init(source, game);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
List<Permanent> permanents = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game);
|
List<Permanent> permanents = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game);
|
||||||
|
@ -112,9 +108,11 @@ class CoatOfArmsEffect extends ContinuousEffectImpl {
|
||||||
for (Permanent permanent : permanents) {
|
for (Permanent permanent : permanents) {
|
||||||
if (!permanent.getId().equals(target.getId())) {
|
if (!permanent.getId().equals(target.getId())) {
|
||||||
for (String subtype : targetSubtype) {
|
for (String subtype : targetSubtype) {
|
||||||
if (permanent.hasSubtype(subtype)) {
|
if (!CardUtil.isNonCreatureSubtype(subtype)) {
|
||||||
amount++;
|
if (permanent.hasSubtype(subtype)) {
|
||||||
break;
|
amount++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
134
Mage.Sets/src/mage/sets/morningtide/BattletideAlchemist.java
Normal file
134
Mage.Sets/src/mage/sets/morningtide/BattletideAlchemist.java
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
* 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.morningtide;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
|
||||||
|
import mage.abilities.effects.PreventionEffectImpl;
|
||||||
|
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.filter.common.FilterControlledCreaturePermanent;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.game.events.GameEvent.EventType;
|
||||||
|
import mage.players.Player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author emerald000
|
||||||
|
*/
|
||||||
|
public class BattletideAlchemist extends CardImpl {
|
||||||
|
|
||||||
|
public BattletideAlchemist(UUID ownerId) {
|
||||||
|
super(ownerId, 2, "Battletide Alchemist", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{W}{W}");
|
||||||
|
this.expansionSetCode = "MOR";
|
||||||
|
this.subtype.add("Kithkin");
|
||||||
|
this.subtype.add("Cleric");
|
||||||
|
this.power = new MageInt(3);
|
||||||
|
this.toughness = new MageInt(4);
|
||||||
|
|
||||||
|
// If a source would deal damage to a player, you may prevent X of that damage, where X is the number of Clerics you control.
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BattletideAlchemistEffect()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public BattletideAlchemist(final BattletideAlchemist card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BattletideAlchemist copy() {
|
||||||
|
return new BattletideAlchemist(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BattletideAlchemistEffect extends PreventionEffectImpl {
|
||||||
|
|
||||||
|
BattletideAlchemistEffect() {
|
||||||
|
super(Duration.WhileOnBattlefield);
|
||||||
|
this.staticText = "If a source would deal damage to a player, you may prevent X of that damage, where X is the number of Clerics you control";
|
||||||
|
}
|
||||||
|
|
||||||
|
BattletideAlchemistEffect(final BattletideAlchemistEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BattletideAlchemistEffect copy() {
|
||||||
|
return new BattletideAlchemistEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||||
|
boolean result = false;
|
||||||
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
|
Player targetPlayer = game.getPlayer(event.getTargetId());
|
||||||
|
if (controller != null) {
|
||||||
|
int numberOfClericsControlled = new PermanentsOnBattlefieldCount(new FilterControlledCreaturePermanent("Cleric", "Clerics")).calculate(game, source, this);
|
||||||
|
int toPrevent = Math.min(numberOfClericsControlled, event.getAmount());
|
||||||
|
if (toPrevent > 0 && controller.chooseUse(Outcome.PreventDamage, "Prevent " + toPrevent + " damage to " + targetPlayer.getName() + "?", source, game)) {
|
||||||
|
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, targetPlayer.getId(), source.getSourceId(), source.getControllerId(), toPrevent, false);
|
||||||
|
if (!game.replaceEvent(preventEvent)) {
|
||||||
|
if (event.getAmount() >= toPrevent) {
|
||||||
|
event.setAmount(event.getAmount() - toPrevent);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
event.setAmount(0);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
if (toPrevent > 0) {
|
||||||
|
game.informPlayers("Battletide Alchemist prevented " + toPrevent + " damage to " + targetPlayer.getName());
|
||||||
|
game.fireEvent(GameEvent.getEvent(
|
||||||
|
GameEvent.EventType.PREVENTED_DAMAGE,
|
||||||
|
targetPlayer.getId(),
|
||||||
|
source.getSourceId(),
|
||||||
|
source.getControllerId(),
|
||||||
|
toPrevent));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checksEventType(GameEvent event, Game game) {
|
||||||
|
return event.getType() == EventType.DAMAGE_PLAYER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||||
|
return super.applies(event, source, game);
|
||||||
|
}
|
||||||
|
}
|
117
Mage.Sets/src/mage/sets/morningtide/BoldwyrHeavyweights.java
Normal file
117
Mage.Sets/src/mage/sets/morningtide/BoldwyrHeavyweights.java
Normal file
|
@ -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.sets.morningtide;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.keyword.TrampleAbility;
|
||||||
|
import mage.cards.Card;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.filter.common.FilterCreatureCard;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.target.common.TargetCardInLibrary;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author emerald000
|
||||||
|
*/
|
||||||
|
public class BoldwyrHeavyweights extends CardImpl {
|
||||||
|
|
||||||
|
public BoldwyrHeavyweights(UUID ownerId) {
|
||||||
|
super(ownerId, 85, "Boldwyr Heavyweights", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{R}{R}");
|
||||||
|
this.expansionSetCode = "MOR";
|
||||||
|
this.subtype.add("Giant");
|
||||||
|
this.subtype.add("Warrior");
|
||||||
|
this.power = new MageInt(8);
|
||||||
|
this.toughness = new MageInt(8);
|
||||||
|
|
||||||
|
// Trample
|
||||||
|
this.addAbility(TrampleAbility.getInstance());
|
||||||
|
|
||||||
|
// When Boldwyr Heavyweights enters the battlefield, each opponent may search his or her library for a creature card and put it onto the battlefield. Then each player who searched his or her library this way shuffles it.
|
||||||
|
this.addAbility(new EntersBattlefieldTriggeredAbility(new BoldwyrHeavyweightsEffect()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoldwyrHeavyweights(final BoldwyrHeavyweights card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BoldwyrHeavyweights copy() {
|
||||||
|
return new BoldwyrHeavyweights(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BoldwyrHeavyweightsEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
BoldwyrHeavyweightsEffect() {
|
||||||
|
super(Outcome.Detriment);
|
||||||
|
this.staticText = "each opponent may search his or her library for a creature card and put it onto the battlefield. Then each player who searched his or her library this way shuffles it";
|
||||||
|
}
|
||||||
|
|
||||||
|
BoldwyrHeavyweightsEffect(final BoldwyrHeavyweightsEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BoldwyrHeavyweightsEffect copy() {
|
||||||
|
return new BoldwyrHeavyweightsEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Set<Player> playersThatSearched = new HashSet<>(1);
|
||||||
|
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
|
||||||
|
Player opponent = game.getPlayer(opponentId);
|
||||||
|
if (opponent != null && opponent.chooseUse(Outcome.PutCreatureInPlay, "Search your library for a creature card and put it onto the battlefield?", source, game)) {
|
||||||
|
TargetCardInLibrary target = new TargetCardInLibrary(new FilterCreatureCard());
|
||||||
|
if (opponent.searchLibrary(target, game)) {
|
||||||
|
Card targetCard = opponent.getLibrary().getCard(target.getFirstTarget(), game);
|
||||||
|
if (targetCard != null) {
|
||||||
|
opponent.moveCards(targetCard, Zone.BATTLEFIELD, source, game);
|
||||||
|
playersThatSearched.add(opponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Player opponent : playersThatSearched) {
|
||||||
|
opponent.shuffleLibrary(source, game);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
109
Mage.Sets/src/mage/sets/morningtide/CoordinatedBarrage.java
Normal file
109
Mage.Sets/src/mage/sets/morningtide/CoordinatedBarrage.java
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
* permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are those of the
|
||||||
|
* authors and should not be interpreted as representing official policies, either expressed
|
||||||
|
* or implied, of BetaSteward_at_googlemail.com.
|
||||||
|
*/
|
||||||
|
package mage.sets.morningtide;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.repository.CardRepository;
|
||||||
|
import mage.choices.Choice;
|
||||||
|
import mage.choices.ChoiceImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
import mage.filter.common.FilterControlledPermanent;
|
||||||
|
import mage.filter.predicate.mageobject.SubtypePredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.target.common.TargetAttackingOrBlockingCreature;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author emerald000
|
||||||
|
*/
|
||||||
|
public class CoordinatedBarrage extends CardImpl {
|
||||||
|
|
||||||
|
public CoordinatedBarrage(UUID ownerId) {
|
||||||
|
super(ownerId, 7, "Coordinated Barrage", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{W}");
|
||||||
|
this.expansionSetCode = "MOR";
|
||||||
|
|
||||||
|
// Choose a creature type. Coordinated Barrage deals damage to target attacking or blocking creature equal to the number of permanents you control of the chosen type.
|
||||||
|
this.getSpellAbility().addEffect(new CoordinatedBarrageEffect());
|
||||||
|
this.getSpellAbility().addTarget(new TargetAttackingOrBlockingCreature());
|
||||||
|
}
|
||||||
|
|
||||||
|
public CoordinatedBarrage(final CoordinatedBarrage card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CoordinatedBarrage copy() {
|
||||||
|
return new CoordinatedBarrage(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CoordinatedBarrageEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
CoordinatedBarrageEffect() {
|
||||||
|
super(Outcome.Damage);
|
||||||
|
this.staticText = "Choose a creature type. Coordinated Barrage deals damage to target attacking or blocking creature equal to the number of permanents you control of the chosen type";
|
||||||
|
}
|
||||||
|
|
||||||
|
CoordinatedBarrageEffect(final CoordinatedBarrageEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CoordinatedBarrageEffect copy() {
|
||||||
|
return new CoordinatedBarrageEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
|
if (controller != null) {
|
||||||
|
Choice choice = new ChoiceImpl(true);
|
||||||
|
choice.setMessage("Choose a creature type");
|
||||||
|
choice.setChoices(CardRepository.instance.getCreatureTypes());
|
||||||
|
if (controller.choose(Outcome.Damage, choice, game)) {
|
||||||
|
String chosenType = choice.getChoice();
|
||||||
|
FilterControlledPermanent filter = new FilterControlledPermanent();
|
||||||
|
filter.add(new SubtypePredicate(chosenType));
|
||||||
|
int damageDealt = game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game);
|
||||||
|
Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source));
|
||||||
|
if (permanent != null) {
|
||||||
|
permanent.damage(damageDealt, source.getSourceId(), game, false, true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
85
Mage.Sets/src/mage/sets/morningtide/HostileRealm.java
Normal file
85
Mage.Sets/src/mage/sets/morningtide/HostileRealm.java
Normal file
|
@ -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.sets.morningtide;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.abilities.effects.common.AttachEffect;
|
||||||
|
import mage.abilities.effects.common.combat.CantBlockTargetEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
|
||||||
|
import mage.abilities.keyword.EnchantAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.AttachmentType;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.target.TargetPermanent;
|
||||||
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
import mage.target.common.TargetLandPermanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author emerald000
|
||||||
|
*/
|
||||||
|
public class HostileRealm extends CardImpl {
|
||||||
|
|
||||||
|
public HostileRealm(UUID ownerId) {
|
||||||
|
super(ownerId, 91, "Hostile Realm", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
|
||||||
|
this.expansionSetCode = "MOR";
|
||||||
|
this.subtype.add("Aura");
|
||||||
|
|
||||||
|
// Enchant land
|
||||||
|
TargetPermanent auraTarget = new TargetLandPermanent();
|
||||||
|
this.getSpellAbility().addTarget(auraTarget);
|
||||||
|
this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility));
|
||||||
|
Ability ability = new EnchantAbility(auraTarget.getTargetName());
|
||||||
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
// Enchanted land has "{T}: Target creature can't block this turn."
|
||||||
|
Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CantBlockTargetEffect(Duration.EndOfTurn), new TapSourceCost());
|
||||||
|
gainedAbility.addTarget(new TargetCreaturePermanent());
|
||||||
|
Effect effect = new GainAbilityAttachedEffect(gainedAbility, AttachmentType.AURA);
|
||||||
|
effect.setText("Enchanted land has \"{T}: Target creature can't block this turn.\"");
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
|
||||||
|
}
|
||||||
|
|
||||||
|
public HostileRealm(final HostileRealm card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HostileRealm copy() {
|
||||||
|
return new HostileRealm(this);
|
||||||
|
}
|
||||||
|
}
|
79
Mage.Sets/src/mage/sets/morningtide/Stenchskipper.java
Normal file
79
Mage.Sets/src/mage/sets/morningtide/Stenchskipper.java
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* 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.morningtide;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
|
||||||
|
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||||
|
import mage.abilities.effects.common.SacrificeSourceEffect;
|
||||||
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
import mage.constants.TargetController;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author emerald000
|
||||||
|
*/
|
||||||
|
public class Stenchskipper extends CardImpl {
|
||||||
|
|
||||||
|
public Stenchskipper(UUID ownerId) {
|
||||||
|
super(ownerId, 79, "Stenchskipper", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{B}");
|
||||||
|
this.expansionSetCode = "MOR";
|
||||||
|
this.subtype.add("Elemental");
|
||||||
|
this.power = new MageInt(6);
|
||||||
|
this.toughness = new MageInt(5);
|
||||||
|
|
||||||
|
// Flying
|
||||||
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
|
// At the beginning of the end step, if you control no Goblins, sacrifice Stenchskipper.
|
||||||
|
this.addAbility(new BeginningOfEndStepTriggeredAbility(
|
||||||
|
Zone.BATTLEFIELD,
|
||||||
|
new SacrificeSourceEffect(),
|
||||||
|
TargetController.ANY,
|
||||||
|
new PermanentsOnTheBattlefieldCondition(
|
||||||
|
new FilterControlledCreaturePermanent("Goblin", "if you control no Goblins"),
|
||||||
|
PermanentsOnTheBattlefieldCondition.CountType.FEWER_THAN,
|
||||||
|
1),
|
||||||
|
false));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stenchskipper(final Stenchskipper card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stenchskipper copy() {
|
||||||
|
return new Stenchskipper(this);
|
||||||
|
}
|
||||||
|
}
|
214
Mage.Sets/src/mage/sets/morningtide/WeightOfConscience.java
Normal file
214
Mage.Sets/src/mage/sets/morningtide/WeightOfConscience.java
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
/*
|
||||||
|
* 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.morningtide;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.costs.common.TapTargetCost;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.AttachEffect;
|
||||||
|
import mage.abilities.effects.common.combat.CantAttackAttachedEffect;
|
||||||
|
import mage.abilities.keyword.EnchantAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.AttachmentType;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||||
|
import mage.filter.predicate.Predicates;
|
||||||
|
import mage.filter.predicate.permanent.TappedPredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.target.TargetPermanent;
|
||||||
|
import mage.target.common.TargetControlledCreaturePermanent;
|
||||||
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author emerald000
|
||||||
|
*/
|
||||||
|
public class WeightOfConscience extends CardImpl {
|
||||||
|
|
||||||
|
public WeightOfConscience(UUID ownerId) {
|
||||||
|
super(ownerId, 28, "Weight of Conscience", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}");
|
||||||
|
this.expansionSetCode = "MOR";
|
||||||
|
this.subtype.add("Aura");
|
||||||
|
|
||||||
|
// Enchant creature
|
||||||
|
TargetPermanent auraTarget = new TargetCreaturePermanent();
|
||||||
|
this.getSpellAbility().addTarget(auraTarget);
|
||||||
|
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
|
||||||
|
Ability ability = new EnchantAbility(auraTarget.getTargetName());
|
||||||
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
// Enchanted creature can't attack.
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackAttachedEffect(AttachmentType.AURA)));
|
||||||
|
|
||||||
|
// Tap two untapped creatures you control that share a creature type: Exile enchanted creature.
|
||||||
|
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new WeightOfConscienceEffect(), new TapTargetCost(new WeightOfConscienceTarget())));
|
||||||
|
}
|
||||||
|
|
||||||
|
public WeightOfConscience(final WeightOfConscience card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WeightOfConscience copy() {
|
||||||
|
return new WeightOfConscience(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WeightOfConscienceEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
WeightOfConscienceEffect() {
|
||||||
|
super(Outcome.Exile);
|
||||||
|
staticText = "Exile enchanted creature";
|
||||||
|
}
|
||||||
|
|
||||||
|
WeightOfConscienceEffect(final WeightOfConscienceEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WeightOfConscienceEffect copy() {
|
||||||
|
return new WeightOfConscienceEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
|
Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId());
|
||||||
|
if (controller != null && enchantment != null && enchantment.getAttachedTo() != null) {
|
||||||
|
Permanent creature = game.getPermanent(enchantment.getAttachedTo());
|
||||||
|
if (creature != null) {
|
||||||
|
controller.moveCardsToExile(creature, source, game, true, null, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WeightOfConscienceTarget extends TargetControlledCreaturePermanent {
|
||||||
|
|
||||||
|
private static final FilterControlledCreaturePermanent filterUntapped = new FilterControlledCreaturePermanent("untapped creatures you control that share a creature type");
|
||||||
|
static {
|
||||||
|
filterUntapped.add(Predicates.not(new TappedPredicate()));
|
||||||
|
}
|
||||||
|
|
||||||
|
WeightOfConscienceTarget() {
|
||||||
|
super(2, 2, filterUntapped, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
WeightOfConscienceTarget(final WeightOfConscienceTarget target) {
|
||||||
|
super(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
|
||||||
|
Player player = game.getPlayer(sourceControllerId);
|
||||||
|
Set<UUID> possibleTargets = new HashSet<>(0);
|
||||||
|
if (player != null) {
|
||||||
|
// Choosing first target
|
||||||
|
if (this.getTargets().isEmpty()) {
|
||||||
|
for (Permanent permanent : game.getBattlefield().getActivePermanents(filterUntapped, sourceControllerId, game)) {
|
||||||
|
for (String subtype : permanent.getSubtype()) {
|
||||||
|
if (!CardUtil.isNonCreatureSubtype(subtype)) {
|
||||||
|
if (game.getBattlefield().contains(new FilterControlledCreaturePermanent(subtype, subtype), sourceControllerId, game, 2)) {
|
||||||
|
possibleTargets.add(permanent.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Choosing second target
|
||||||
|
else {
|
||||||
|
UUID firstTargetId = this.getTargets().get(0);
|
||||||
|
Permanent firstTargetCreature = game.getPermanent(firstTargetId);
|
||||||
|
if (firstTargetCreature != null) {
|
||||||
|
for (Permanent permanent : game.getBattlefield().getActivePermanents(filterUntapped, sourceControllerId, game)) {
|
||||||
|
if (!permanent.getId().equals(firstTargetId) && CardUtil.shareSubtypes(firstTargetCreature, permanent)) {
|
||||||
|
possibleTargets.add(permanent.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return possibleTargets;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
|
||||||
|
for (Permanent permanent1 : game.getBattlefield().getActivePermanents(filterUntapped, sourceControllerId, game)) {
|
||||||
|
for (Permanent permanent2 : game.getBattlefield().getActivePermanents(filterUntapped, sourceControllerId, game)) {
|
||||||
|
if (permanent1 != permanent2 && CardUtil.shareSubtypes(permanent1, permanent2)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canTarget(UUID id, Ability source, Game game) {
|
||||||
|
if (super.canTarget(id, game)) {
|
||||||
|
Permanent targetPermanent = game.getPermanent(id);
|
||||||
|
if (targetPermanent != null) {
|
||||||
|
if (this.getTargets().isEmpty()) {
|
||||||
|
for (Permanent permanent : game.getBattlefield().getActivePermanents(filterUntapped, source.getControllerId(), game)) {
|
||||||
|
for (String subtype : permanent.getSubtype()) {
|
||||||
|
if (!CardUtil.isNonCreatureSubtype(subtype)) {
|
||||||
|
if (game.getBattlefield().contains(new FilterControlledCreaturePermanent(subtype, subtype), source.getControllerId(), game, 2)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Permanent firstTarget = game.getPermanent(this.getTargets().get(0));
|
||||||
|
if (firstTarget != null && CardUtil.shareSubtypes(firstTarget, targetPermanent)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WeightOfConscienceTarget copy() {
|
||||||
|
return new WeightOfConscienceTarget(this);
|
||||||
|
}
|
||||||
|
}
|
52
Mage.Sets/src/mage/sets/planarchaos/Torchling.java
Normal file
52
Mage.Sets/src/mage/sets/planarchaos/Torchling.java
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* 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.planarchaos;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author emerald000
|
||||||
|
*/
|
||||||
|
public class Torchling extends mage.sets.venservskoth.Torchling {
|
||||||
|
|
||||||
|
public Torchling(UUID ownerId) {
|
||||||
|
super(ownerId);
|
||||||
|
this.cardNumber = 110;
|
||||||
|
this.expansionSetCode = "PLC";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Torchling(final Torchling card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Torchling copy() {
|
||||||
|
return new Torchling(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,13 +28,13 @@
|
||||||
package mage.sets.planechase2012;
|
package mage.sets.planechase2012;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.constants.CardType;
|
|
||||||
import mage.constants.Outcome;
|
|
||||||
import mage.constants.Rarity;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.CreateTokenEffect;
|
import mage.abilities.effects.common.CreateTokenEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.Rarity;
|
||||||
import mage.filter.common.FilterControlledLandPermanent;
|
import mage.filter.common.FilterControlledLandPermanent;
|
||||||
import mage.filter.predicate.mageobject.SubtypePredicate;
|
import mage.filter.predicate.mageobject.SubtypePredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
@ -54,7 +54,6 @@ public class LastStand extends CardImpl {
|
||||||
super(ownerId, 100, "Last Stand", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{W}{U}{B}{R}{G}");
|
super(ownerId, 100, "Last Stand", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{W}{U}{B}{R}{G}");
|
||||||
this.expansionSetCode = "PC2";
|
this.expansionSetCode = "PC2";
|
||||||
|
|
||||||
|
|
||||||
// Target opponent loses 2 life for each Swamp you control. Last Stand deals damage equal to the number of Mountains you control to target creature. Put a 1/1 green Saproling creature token onto the battlefield for each Forest you control. You gain 2 life for each Plains you control. Draw a card for each Island you control, then discard that many cards.
|
// Target opponent loses 2 life for each Swamp you control. Last Stand deals damage equal to the number of Mountains you control to target creature. Put a 1/1 green Saproling creature token onto the battlefield for each Forest you control. You gain 2 life for each Plains you control. Draw a card for each Island you control, then discard that many cards.
|
||||||
this.getSpellAbility().addEffect(new LastStandEffect());
|
this.getSpellAbility().addEffect(new LastStandEffect());
|
||||||
this.getSpellAbility().addTarget(new TargetOpponent());
|
this.getSpellAbility().addTarget(new TargetOpponent());
|
||||||
|
@ -108,7 +107,7 @@ class LastStandEffect extends OneShotEffect {
|
||||||
Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source));
|
Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||||
if (opponent != null) {
|
if (opponent != null) {
|
||||||
int swamps = game.getBattlefield().count(filterSwamp, source.getSourceId(), source.getControllerId(), game);
|
int swamps = game.getBattlefield().count(filterSwamp, source.getSourceId(), source.getControllerId(), game);
|
||||||
opponent.damage(swamps, source.getSourceId(), game, false, true);
|
opponent.loseLife(swamps * 2, game);
|
||||||
}
|
}
|
||||||
// Last Stand deals damage equal to the number of Mountains you control to target creature.
|
// Last Stand deals damage equal to the number of Mountains you control to target creature.
|
||||||
Permanent creature = game.getPermanent(source.getTargets().get(1).getFirstTarget());
|
Permanent creature = game.getPermanent(source.getTargets().get(1).getFirstTarget());
|
||||||
|
@ -125,7 +124,7 @@ class LastStandEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
// You gain 2 life for each Plains you control.
|
// You gain 2 life for each Plains you control.
|
||||||
int plains = game.getBattlefield().count(filterPlains, source.getSourceId(), source.getControllerId(), game);
|
int plains = game.getBattlefield().count(filterPlains, source.getSourceId(), source.getControllerId(), game);
|
||||||
controller.gainLife(plains, game);
|
controller.gainLife(plains * 2, game);
|
||||||
// Draw a card for each Island you control, then discard that many cards
|
// Draw a card for each Island you control, then discard that many cards
|
||||||
int islands = game.getBattlefield().count(filterIsland, source.getSourceId(), source.getControllerId(), game);
|
int islands = game.getBattlefield().count(filterIsland, source.getSourceId(), source.getControllerId(), game);
|
||||||
if (islands > 0) {
|
if (islands > 0) {
|
||||||
|
|
|
@ -45,6 +45,7 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
import mage.abilities.keyword.KickerAbility;
|
import mage.abilities.keyword.KickerAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.AbilityType;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
|
@ -111,6 +112,9 @@ class DralnusPetEffect extends OneShotEffect {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||||
|
if (permanent == null && source.getAbilityType().equals(AbilityType.STATIC)) {
|
||||||
|
permanent = game.getPermanentEntering(source.getSourceId());
|
||||||
|
}
|
||||||
if (controller != null && permanent != null) {
|
if (controller != null && permanent != null) {
|
||||||
SpellAbility spellAbility = (SpellAbility) getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY);
|
SpellAbility spellAbility = (SpellAbility) getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY);
|
||||||
if (spellAbility != null
|
if (spellAbility != null
|
||||||
|
|
133
Mage.Sets/src/mage/sets/stronghold/Portcullis.java
Normal file
133
Mage.Sets/src/mage/sets/stronghold/Portcullis.java
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
/*
|
||||||
|
* 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.stronghold;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.TriggeredAbility;
|
||||||
|
import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
|
||||||
|
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
|
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||||
|
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.ReturnFromExileForSourceEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
import mage.constants.SetTargetPointer;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author spjspj
|
||||||
|
*/
|
||||||
|
public class Portcullis extends CardImpl {
|
||||||
|
|
||||||
|
private final static FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature");
|
||||||
|
|
||||||
|
public Portcullis(UUID ownerId) {
|
||||||
|
super(ownerId, 133, "Portcullis", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{4}");
|
||||||
|
this.expansionSetCode = "STH";
|
||||||
|
|
||||||
|
// Whenever a creature enters the battlefield, if there are two or more other creatures on the battlefield, exile that creature.
|
||||||
|
String rule = "Whenever a creature enters the battlefield, if there are two or more other creatures on the battlefield, exile that creature";
|
||||||
|
TriggeredAbility ability = new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new PortcullisExileEffect(), filter, false, SetTargetPointer.PERMANENT, rule);
|
||||||
|
|
||||||
|
MoreThanXCreaturesOnBFCondition condition = new MoreThanXCreaturesOnBFCondition(2);
|
||||||
|
this.addAbility(new ConditionalTriggeredAbility(ability, condition, rule));
|
||||||
|
|
||||||
|
// Return that card to the battlefield under its owner's control when Portcullis leaves the battlefield.
|
||||||
|
Ability ability2 = new LeavesBattlefieldTriggeredAbility(new ReturnFromExileForSourceEffect(Zone.BATTLEFIELD), false);
|
||||||
|
this.addAbility(ability2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Portcullis(final Portcullis card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Portcullis copy() {
|
||||||
|
return new Portcullis(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MoreThanXCreaturesOnBFCondition implements Condition {
|
||||||
|
|
||||||
|
protected final int value;
|
||||||
|
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures on field");
|
||||||
|
|
||||||
|
public MoreThanXCreaturesOnBFCondition(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean apply(Game game, Ability source) {
|
||||||
|
PermanentsOnBattlefieldCount amount = new PermanentsOnBattlefieldCount(filter);
|
||||||
|
int count = amount.calculate(game, source, null);
|
||||||
|
return count > value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PortcullisExileEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
public PortcullisExileEffect() {
|
||||||
|
super(Outcome.Neutral);
|
||||||
|
this.staticText = "Whenever a creature enters the battlefield, if there are two or more other creatures on the battlefield, exile that creature.";
|
||||||
|
}
|
||||||
|
|
||||||
|
public PortcullisExileEffect(final PortcullisExileEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PortcullisExileEffect copy() {
|
||||||
|
return new PortcullisExileEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||||
|
Permanent creature = game.getPermanent(targetPointer.getFirst(game, source));
|
||||||
|
|
||||||
|
if (permanent != null && creature != null) {
|
||||||
|
Player controller = game.getPlayer(creature.getControllerId());
|
||||||
|
Zone currentZone = game.getState().getZone(creature.getId());
|
||||||
|
if (currentZone.equals(Zone.BATTLEFIELD)) {
|
||||||
|
controller.moveCardsToExile(creature, source, game, true, CardUtil.getCardExileZoneId(game, source), permanent.getIdName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
138
Mage.Sets/src/mage/sets/venservskoth/Torchling.java
Normal file
138
Mage.Sets/src/mage/sets/venservskoth/Torchling.java
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
/*
|
||||||
|
* 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.venservskoth;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.MageObject;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.Mode;
|
||||||
|
import mage.abilities.SpellAbility;
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.costs.mana.ColoredManaCost;
|
||||||
|
import mage.abilities.costs.mana.GenericManaCost;
|
||||||
|
import mage.abilities.effects.common.ChooseNewTargetsTargetEffect;
|
||||||
|
import mage.abilities.effects.common.UntapSourceEffect;
|
||||||
|
import mage.abilities.effects.common.combat.MustBeBlockedByTargetSourceEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.ColoredManaSymbol;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.filter.FilterSpell;
|
||||||
|
import mage.filter.predicate.Predicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.stack.Spell;
|
||||||
|
import mage.target.Target;
|
||||||
|
import mage.target.TargetSpell;
|
||||||
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author emerald000
|
||||||
|
*/
|
||||||
|
public class Torchling extends CardImpl {
|
||||||
|
|
||||||
|
public Torchling(UUID ownerId) {
|
||||||
|
super(ownerId, 58, "Torchling", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{R}{R}");
|
||||||
|
this.expansionSetCode = "DDI";
|
||||||
|
this.subtype.add("Shapeshifter");
|
||||||
|
this.power = new MageInt(3);
|
||||||
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
|
// {R}: Untap Torchling.
|
||||||
|
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new UntapSourceEffect(), new ColoredManaCost(ColoredManaSymbol.R)));
|
||||||
|
|
||||||
|
// {R}: Target creature blocks Torchling this turn if able.
|
||||||
|
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MustBeBlockedByTargetSourceEffect(), new ColoredManaCost(ColoredManaSymbol.R));
|
||||||
|
ability.addTarget(new TargetCreaturePermanent());
|
||||||
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
// {R}: Change the target of target spell that targets only Torchling.
|
||||||
|
ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ChooseNewTargetsTargetEffect(true, true), new ColoredManaCost(ColoredManaSymbol.R));
|
||||||
|
FilterSpell filter = new FilterSpell("spell that targets only " + this.getName());
|
||||||
|
filter.add(new TorchlingTargetPredicate(this.getId()));
|
||||||
|
ability.addTarget(new TargetSpell(filter));
|
||||||
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
// {1}: Torchling gets +1/-1 until end of turn.
|
||||||
|
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, -1, Duration.EndOfTurn), new GenericManaCost(1)));
|
||||||
|
|
||||||
|
// {1}: Torchling gets -1/+1 until end of turn.
|
||||||
|
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(-1, 1, Duration.EndOfTurn), new GenericManaCost(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Torchling(final Torchling card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Torchling copy() {
|
||||||
|
return new Torchling(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TorchlingTargetPredicate implements Predicate<MageObject> {
|
||||||
|
|
||||||
|
private final UUID sourceId;
|
||||||
|
|
||||||
|
TorchlingTargetPredicate(UUID sourceId) {
|
||||||
|
this.sourceId = sourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(MageObject input, Game game) {
|
||||||
|
Spell spell = game.getStack().getSpell(input.getId());
|
||||||
|
if (spell != null) {
|
||||||
|
int numberOfTargets = 0;
|
||||||
|
for (SpellAbility spellAbility : spell.getSpellAbilities()) {
|
||||||
|
for (Mode mode : spellAbility.getModes().getSelectedModes()) {
|
||||||
|
for (Target target : mode.getTargets()) {
|
||||||
|
for (UUID targetId : target.getTargets()) {
|
||||||
|
if (!targetId.equals(sourceId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
numberOfTargets++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return numberOfTargets > 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "target spell that targets only {this}";
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,7 +41,7 @@ import mage.game.events.GameEvent;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.common.TargetCardInLibrary;
|
import mage.target.common.TargetCardInLibrary;
|
||||||
import mage.watchers.Watcher;
|
import mage.watchers.common.CardsAmountDrawnThisTurnWatcher;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -57,9 +57,10 @@ public class ArchmageAscension extends CardImpl {
|
||||||
|
|
||||||
|
|
||||||
// At the beginning of each end step, if you drew two or more cards this turn, you may put a quest counter on Archmage Ascension.
|
// At the beginning of each end step, if you drew two or more cards this turn, you may put a quest counter on Archmage Ascension.
|
||||||
this.addAbility(new ArchmageAscensionTriggeredAbility(), new CardsDrawnControllerWatcher());
|
this.addAbility(new ArchmageAscensionTriggeredAbility(), new CardsAmountDrawnThisTurnWatcher());
|
||||||
|
|
||||||
// As long as Archmage Ascension has six or more quest counters on it, if you would draw a card, you may instead search your library for a card, put that card into your hand, then shuffle your library.
|
// As long as Archmage Ascension has six or more quest counters on it, if you would draw a card,
|
||||||
|
// you may instead search your library for a card, put that card into your hand, then shuffle your library.
|
||||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ArchmageAscensionReplacementEffect()));
|
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ArchmageAscensionReplacementEffect()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -97,8 +98,9 @@ class ArchmageAscensionTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
@Override
|
@Override
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
Permanent archmage = game.getPermanent(super.getSourceId());
|
Permanent archmage = game.getPermanent(super.getSourceId());
|
||||||
CardsDrawnControllerWatcher watcher = (CardsDrawnControllerWatcher) game.getState().getWatchers().get("CardsControllerDrawn");
|
CardsAmountDrawnThisTurnWatcher watcher =
|
||||||
return archmage != null && watcher != null && watcher.conditionMet();
|
(CardsAmountDrawnThisTurnWatcher) game.getState().getWatchers().get(CardsAmountDrawnThisTurnWatcher.BASIC_KEY);
|
||||||
|
return archmage != null && watcher != null && watcher.getAmountCardsDrawn(this.getControllerId()) >= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -107,47 +109,12 @@ class ArchmageAscensionTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CardsDrawnControllerWatcher extends Watcher {
|
|
||||||
|
|
||||||
int cardsDrawn;
|
|
||||||
|
|
||||||
public CardsDrawnControllerWatcher() {
|
|
||||||
super("CardsControllerDrawn", WatcherScope.GAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CardsDrawnControllerWatcher(final CardsDrawnControllerWatcher watcher) {
|
|
||||||
super(watcher);
|
|
||||||
this.cardsDrawn = watcher.cardsDrawn;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void watch(GameEvent event, Game game) {
|
|
||||||
if (event.getType() == GameEvent.EventType.DREW_CARD
|
|
||||||
&& event.getPlayerId().equals(controllerId)) {
|
|
||||||
cardsDrawn += 1;
|
|
||||||
if (cardsDrawn >= 2) {
|
|
||||||
condition = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
super.reset();
|
|
||||||
cardsDrawn = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CardsDrawnControllerWatcher copy() {
|
|
||||||
return new CardsDrawnControllerWatcher(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ArchmageAscensionReplacementEffect extends ReplacementEffectImpl {
|
class ArchmageAscensionReplacementEffect extends ReplacementEffectImpl {
|
||||||
|
|
||||||
public ArchmageAscensionReplacementEffect() {
|
public ArchmageAscensionReplacementEffect() {
|
||||||
super(Duration.WhileOnBattlefield, Outcome.Benefit);
|
super(Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||||
staticText = "As long as {this} has six or more quest counters on it, if you would draw a card, you may instead search your library for a card, put that card into your hand, then shuffle your library";
|
staticText = "As long as {this} has six or more quest counters on it, if you would draw a card, " +
|
||||||
|
"you may instead search your library for a card, put that card into your hand, then shuffle your library";
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArchmageAscensionReplacementEffect(final ArchmageAscensionReplacementEffect effect) {
|
public ArchmageAscensionReplacementEffect(final ArchmageAscensionReplacementEffect effect) {
|
||||||
|
|
|
@ -27,8 +27,6 @@
|
||||||
*/
|
*/
|
||||||
package mage.sets.zendikar;
|
package mage.sets.zendikar;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.condition.Condition;
|
||||||
|
@ -40,12 +38,10 @@ import mage.abilities.effects.common.DamageTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Rarity;
|
import mage.constants.Rarity;
|
||||||
import mage.constants.WatcherScope;
|
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.TargetPlayer;
|
import mage.target.TargetPlayer;
|
||||||
import mage.watchers.Watcher;
|
import mage.watchers.common.CardsAmountDrawnThisTurnWatcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -59,7 +55,7 @@ public class RuneflareTrap extends CardImpl {
|
||||||
this.subtype.add("Trap");
|
this.subtype.add("Trap");
|
||||||
|
|
||||||
// If an opponent drew three or more cards this turn, you may pay {R} rather than pay Runeflare Trap's mana cost.
|
// If an opponent drew three or more cards this turn, you may pay {R} rather than pay Runeflare Trap's mana cost.
|
||||||
this.addAbility(new AlternativeCostSourceAbility(new ManaCostsImpl("{R}"), RavenousTrapCondition.getInstance()), new CardsDrawnWatcher());
|
this.addAbility(new AlternativeCostSourceAbility(new ManaCostsImpl("{R}"), RuneflareTrapCondition.getInstance()), new CardsAmountDrawnThisTurnWatcher());
|
||||||
|
|
||||||
// Runeflare Trap deals damage to target player equal to the number of cards in that player's hand.
|
// Runeflare Trap deals damage to target player equal to the number of cards in that player's hand.
|
||||||
this.getSpellAbility().addEffect(new DamageTargetEffect(new TargetPlayerCardsInHandCount()));
|
this.getSpellAbility().addEffect(new DamageTargetEffect(new TargetPlayerCardsInHandCount()));
|
||||||
|
@ -115,7 +111,8 @@ class RuneflareTrapCondition implements Condition {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
CardsDrawnWatcher watcher = (CardsDrawnWatcher) game.getState().getWatchers().get("CardsDrawnWatcher");
|
CardsAmountDrawnThisTurnWatcher watcher =
|
||||||
|
(CardsAmountDrawnThisTurnWatcher) game.getState().getWatchers().get(CardsAmountDrawnThisTurnWatcher.BASIC_KEY);
|
||||||
return watcher != null && watcher.opponentDrewXOrMoreCards(source.getControllerId(), 3, game);
|
return watcher != null && watcher.opponentDrewXOrMoreCards(source.getControllerId(), 3, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,53 +121,3 @@ class RuneflareTrapCondition implements Condition {
|
||||||
return "If an opponent drew three or more cards this turn";
|
return "If an opponent drew three or more cards this turn";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CardsDrawnWatcher extends Watcher {
|
|
||||||
|
|
||||||
private final Map<UUID, Integer> playerCardsDrawn = new HashMap<>();
|
|
||||||
|
|
||||||
public CardsDrawnWatcher() {
|
|
||||||
super("CardsDrawnWatcher", WatcherScope.GAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CardsDrawnWatcher(final CardsDrawnWatcher watcher) {
|
|
||||||
super(watcher);
|
|
||||||
playerCardsDrawn.putAll(watcher.playerCardsDrawn);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void watch(GameEvent event, Game game) {
|
|
||||||
if (event.getType() == GameEvent.EventType.DREW_CARD) {
|
|
||||||
if (playerCardsDrawn.containsKey(event.getPlayerId())) {
|
|
||||||
playerCardsDrawn.put(event.getPlayerId(), playerCardsDrawn.get(event.getPlayerId()) + 1);
|
|
||||||
} else {
|
|
||||||
playerCardsDrawn.put(event.getPlayerId(), 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
super.reset();
|
|
||||||
playerCardsDrawn.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean opponentDrewXOrMoreCards(UUID playerId, int x, Game game) {
|
|
||||||
Player player = game.getPlayer(playerId);
|
|
||||||
if (player != null) {
|
|
||||||
for (Map.Entry<UUID, Integer> entry : playerCardsDrawn.entrySet()) {
|
|
||||||
if (game.isOpponent(player, playerId)) {
|
|
||||||
if (entry.getValue() >= x) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CardsDrawnWatcher copy() {
|
|
||||||
return new CardsDrawnWatcher(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -163,4 +163,26 @@ public class SuspendTest extends CardTestPlayerBase {
|
||||||
assertHandCount(playerA, "Ancestral Vision", 1);
|
assertHandCount(playerA, "Ancestral Vision", 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suppression Field incorrectly makes suspend cards cost 2 more to suspend.
|
||||||
|
* It made my Rift Bolt cost 2R to suspend instead of R
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testCostManipulation() {
|
||||||
|
// Rift Bolt deals 3 damage to target creature or player.
|
||||||
|
// Suspend 1-{R}
|
||||||
|
addCard(Zone.HAND, playerA, "Rift Bolt", 1);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Suppression Field", 1);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Suspend");
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertHandCount(playerA, "Rift Bolt", 0);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -251,7 +251,8 @@ public class UndyingTest extends CardTestPlayerBase {
|
||||||
// Sacrifice a creature: Add {C}{C} to your mana pool.
|
// Sacrifice a creature: Add {C}{C} to your mana pool.
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Ashnod's Altar", 1);
|
addCard(Zone.BATTLEFIELD, playerA, "Ashnod's Altar", 1);
|
||||||
// Whenever a Human deals damage to you, destroy it.
|
// Whenever a Human deals damage to you, destroy it.
|
||||||
// Other non-Human creatures you control get +1/+1 and have undying.
|
// Other non-Human creatures you control get +1/+1 and have undying
|
||||||
|
// (When this creature dies, if it had no +1/+1 counters on it, return it to the battlefield under its owner's control with a +1/+1 counter on it.).
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Mikaeus, the Unhallowed", 1);
|
addCard(Zone.BATTLEFIELD, playerA, "Mikaeus, the Unhallowed", 1);
|
||||||
|
|
||||||
// Flying
|
// Flying
|
||||||
|
|
|
@ -30,8 +30,10 @@ package mage.abilities.common;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.abilities.TriggeredAbilityImpl;
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
import mage.target.targetpointer.FixedTarget;
|
import mage.target.targetpointer.FixedTarget;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,10 +42,17 @@ import mage.target.targetpointer.FixedTarget;
|
||||||
*/
|
*/
|
||||||
public class BecomesBlockedByCreatureTriggeredAbility extends TriggeredAbilityImpl {
|
public class BecomesBlockedByCreatureTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
|
private static FilterCreaturePermanent filter = new FilterCreaturePermanent();
|
||||||
|
|
||||||
public BecomesBlockedByCreatureTriggeredAbility(Effect effect, boolean optional) {
|
public BecomesBlockedByCreatureTriggeredAbility(Effect effect, boolean optional) {
|
||||||
super(Zone.BATTLEFIELD, effect, optional);
|
super(Zone.BATTLEFIELD, effect, optional);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BecomesBlockedByCreatureTriggeredAbility(Effect effect, FilterCreaturePermanent filter, boolean optional) {
|
||||||
|
super(Zone.BATTLEFIELD, effect, optional);
|
||||||
|
this.filter = filter;
|
||||||
|
}
|
||||||
|
|
||||||
public BecomesBlockedByCreatureTriggeredAbility(final BecomesBlockedByCreatureTriggeredAbility ability) {
|
public BecomesBlockedByCreatureTriggeredAbility(final BecomesBlockedByCreatureTriggeredAbility ability) {
|
||||||
super(ability);
|
super(ability);
|
||||||
}
|
}
|
||||||
|
@ -56,17 +65,20 @@ public class BecomesBlockedByCreatureTriggeredAbility extends TriggeredAbilityIm
|
||||||
@Override
|
@Override
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
if (event.getTargetId().equals(this.getSourceId())) {
|
if (event.getTargetId().equals(this.getSourceId())) {
|
||||||
for (Effect effect : this.getEffects()) {
|
Permanent blocker = game.getPermanent(event.getSourceId());
|
||||||
effect.setTargetPointer(new FixedTarget(event.getSourceId()));
|
if (filter.match(blocker, game)) {
|
||||||
|
for (Effect effect : this.getEffects()) {
|
||||||
|
effect.setTargetPointer(new FixedTarget(event.getSourceId()));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return "Whenever {this} becomes blocked by a creature, " + super.getRule();
|
return "Whenever {this} becomes blocked by a " + filter.getMessage() + ", " + super.getRule();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -32,7 +32,7 @@ import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.ActivatedAbilityImpl;
|
import mage.abilities.SpecialAction;
|
||||||
import mage.abilities.TriggeredAbilityImpl;
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||||
import mage.abilities.condition.common.SuspendedCondition;
|
import mage.abilities.condition.common.SuspendedCondition;
|
||||||
|
@ -142,7 +142,7 @@ import mage.target.targetpointer.FixedTarget;
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class SuspendAbility extends ActivatedAbilityImpl {
|
public class SuspendAbility extends SpecialAction {
|
||||||
|
|
||||||
private String ruleText;
|
private String ruleText;
|
||||||
private boolean gainedTemporary;
|
private boolean gainedTemporary;
|
||||||
|
@ -160,7 +160,9 @@ public class SuspendAbility extends ActivatedAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
public SuspendAbility(int suspend, ManaCost cost, Card card, boolean shortRule) {
|
public SuspendAbility(int suspend, ManaCost cost, Card card, boolean shortRule) {
|
||||||
super(Zone.HAND, new SuspendExileEffect(suspend), cost);
|
super(Zone.HAND);
|
||||||
|
this.addCost(cost);
|
||||||
|
this.addEffect(new SuspendExileEffect(suspend));
|
||||||
this.usesStack = false;
|
this.usesStack = false;
|
||||||
if (suspend == Integer.MAX_VALUE) {
|
if (suspend == Integer.MAX_VALUE) {
|
||||||
VariableManaCost xCosts = new VariableManaCost();
|
VariableManaCost xCosts = new VariableManaCost();
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* 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.watchers.common;
|
||||||
|
|
||||||
|
import mage.constants.WatcherScope;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.watchers.Watcher;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Quercitron
|
||||||
|
* @author LevelX2
|
||||||
|
* @author jeffwadsworth
|
||||||
|
*/
|
||||||
|
public class CardsAmountDrawnThisTurnWatcher extends Watcher {
|
||||||
|
|
||||||
|
public final static String BASIC_KEY = "CardsAmountDrawnThisTurnWatcher";
|
||||||
|
|
||||||
|
private final Map<UUID, Integer> amountOfCardsDrawnThisTurn = new HashMap<>();
|
||||||
|
|
||||||
|
public CardsAmountDrawnThisTurnWatcher() {
|
||||||
|
super(BASIC_KEY, WatcherScope.GAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CardsAmountDrawnThisTurnWatcher(final CardsAmountDrawnThisTurnWatcher watcher) {
|
||||||
|
super(watcher);
|
||||||
|
amountOfCardsDrawnThisTurn.putAll(watcher.amountOfCardsDrawnThisTurn);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void watch(GameEvent event, Game game) {
|
||||||
|
if (event.getType() == GameEvent.EventType.DREW_CARD) {
|
||||||
|
if (amountOfCardsDrawnThisTurn.containsKey(event.getPlayerId())) {
|
||||||
|
amountOfCardsDrawnThisTurn.put(event.getPlayerId(), amountOfCardsDrawnThisTurn.get(event.getPlayerId()) + 1);
|
||||||
|
} else {
|
||||||
|
amountOfCardsDrawnThisTurn.put(event.getPlayerId(), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
super.reset();
|
||||||
|
amountOfCardsDrawnThisTurn.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean opponentDrewXOrMoreCards(UUID playerId, int x, Game game) {
|
||||||
|
Player player = game.getPlayer(playerId);
|
||||||
|
if (player != null) {
|
||||||
|
for (Map.Entry<UUID, Integer> entry : amountOfCardsDrawnThisTurn.entrySet()) {
|
||||||
|
if (game.isOpponent(player, entry.getKey())) {
|
||||||
|
if (entry.getValue() >= x) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAmountCardsDrawn(UUID playerId) {
|
||||||
|
Integer amount = amountOfCardsDrawnThisTurn.get(playerId);
|
||||||
|
if (amount != null) {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CardsAmountDrawnThisTurnWatcher copy() {
|
||||||
|
return new CardsAmountDrawnThisTurnWatcher(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[![Join the chat at https://gitter.im/magefree/mage](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/magefree/mage?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[![Join the chat at https://gitter.im/magefree/mage](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/magefree/mage?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
|
||||||
XMage allows you to play Magic against one or more online players or computer opponents. It includes full rules enforcement for over **13,000** unique cards (26,000 counting all cards from different editions). Starting with Shadowmoor, all regular sets have nearly all the cards implemented ([detailed overview](http://ct-magefree.rhcloud.com/stats)).
|
XMage allows you to play Magic against one or more online players or computer opponents. It includes full rules enforcement for over **13,000** unique cards (over 26,000 counting all cards from different editions). Starting with Morningtide, all regular sets have nearly all the cards implemented ([detailed overview](http://ct-magefree.rhcloud.com/stats)).
|
||||||
|
|
||||||
There are public servers where you can play XMage against other players. You can also host your own server to play against the AI and/or your friends.
|
There are public servers where you can play XMage against other players. You can also host your own server to play against the AI and/or your friends.
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue