Merge remote-tracking branch 'refs/remotes/magefree/master'

This commit is contained in:
CountAndromalius 2016-07-15 10:17:24 -03:00
commit 153f2a82b0
28 changed files with 563 additions and 162 deletions

View file

@ -122,20 +122,28 @@ public class ChatManager {
}
}
private static final String COMMANDS_LIST =
"<br/>List of commands:" +
"<br/>\\history or \\h [username] - shows the history of a player" +
"<br/>\\me - shows the history of the current player" +
"<br/>\\list or \\l - Show a list of commands" +
"<br/>\\whisper or \\w [player name] [text] - whisper to the player with the given name";
private boolean performUserCommand(User user, String message, UUID chatId, boolean doError) {
String command = message.substring(1).trim().toUpperCase(Locale.ENGLISH);
if (doError) {
message += new StringBuilder("<br/>Invalid User Command '" + message + "'.")
.append("<br/>List of commands:")
.append("<br/>\\history or \\h [username] - shows the history of a player")
.append("<br/>\\list or \\l - Show a list of commands")
.append("<br/>\\whisper or \\w [player name] [text] - whisper to the player with the given name").toString();
message += new StringBuilder("<br/>Invalid User Command '" + message + "'.").append(COMMANDS_LIST).toString();
chatSessions.get(chatId).broadcastInfoToUser(user, message);
return true;
}
if (command.startsWith("H ") || command.startsWith("HISTORY ")) {
message = UserManager.getInstance().getUserHistory(message.substring(command.startsWith("H ") ? 3 : 9));
message += "<br/>" + UserManager.getInstance().getUserHistory(message.substring(command.startsWith("H ") ? 3 : 9));
chatSessions.get(chatId).broadcastInfoToUser(user, message);
return true;
}
if (command.equals("ME")) {
message += "<br/>" + UserManager.getInstance().getUserHistory(user.getName());
chatSessions.get(chatId).broadcastInfoToUser(user, message);
return true;
}
@ -159,10 +167,7 @@ public class ChatManager {
}
}
if (command.equals("L") || command.equals("LIST")) {
message += new StringBuilder("<br/>List of commands:")
.append("<br/>\\history or \\h [username] - shows the history of a player")
.append("<br/>\\list or \\l - Show a list of commands")
.append("<br/>\\whisper or \\w [player name] [text] - whisper to the player with the given name").toString();
message += COMMANDS_LIST;
chatSessions.get(chatId).broadcastInfoToUser(user, message);
return true;
}

View file

@ -34,7 +34,6 @@ import mage.abilities.condition.common.DeliriumCondition;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalActivatedAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveControllerEffect;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.cards.CardImpl;
@ -44,7 +43,7 @@ import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.events.GameEvent;
import mage.target.common.TargetCardInGraveyard;
import mage.target.common.TargetCardInYourGraveyard;
/**
*
@ -69,12 +68,13 @@ public class CropSigil extends CardImpl {
// <i>Delirium</i> &mdash; {2}{G}, Sacrifice Crop Sigil: Return up to one target creature card and up to one target land card from your graveyard to your hand.
// Activate this ability only if there are four or more card types among cards in your graveyard.
Effect effect = new ReturnToHandTargetEffect(true, true);
effect.setText("Return up to one target creature card and up to one target land card from your graveyard to your hand");
Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{2}{G}"), DeliriumCondition.getInstance());
Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(true, true), new ManaCostsImpl<>("{2}{G}"),
DeliriumCondition.getInstance(),
"<i>Delirium</i> &mdash; {2}{G}, Sacrifice {this}: Return up to one target creature card and up to one target land card from your graveyard to your hand. "
+ "Activate this ability only if there are four or more card types among cards in your graveyard");
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetCardInGraveyard(0, 1, filterCreature));
ability.addTarget(new TargetCardInGraveyard(0, 1, filterLand));
ability.addTarget(new TargetCardInYourGraveyard(0, 1, filterCreature));
ability.addTarget(new TargetCardInYourGraveyard(0, 1, filterLand));
this.addAbility(ability);
}

View file

@ -33,6 +33,7 @@ import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
@ -54,7 +55,7 @@ import mage.target.common.TargetControlledCreaturePermanent;
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
*/
public class EmrakulsEvangel extends CardImpl {
public EmrakulsEvangel(UUID ownerId) {
super(ownerId, 156, "Emrakul's Evangel", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{G}");
this.expansionSetCode = "EMN";
@ -63,9 +64,11 @@ public class EmrakulsEvangel extends CardImpl {
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// {T}, Sacrifice Emrakul's Evangel and any number of other non-Eldrazi creatures:
// {T}, Sacrifice Emrakul's Evangel and any number of other non-Eldrazi creatures:
// Put a 3/2 colorless Eldrazi Horror creature token onto the battlefield for each creature sacrificed this way.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new EmrakulsEvangelEffect(), new EmrakulsEvangelCost()));
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new EmrakulsEvangelEffect(), new TapSourceCost());
ability.addCost(new EmrakulsEvangelCost());
this.addAbility(ability);
}
public EmrakulsEvangel(final EmrakulsEvangel card) {
@ -79,14 +82,14 @@ public class EmrakulsEvangel extends CardImpl {
}
class EmrakulsEvangelCost extends CostImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("non-Eldrazi creatures you control");
static {
filter.add(new AnotherPredicate());
filter.add(Predicates.not(new SubtypePredicate("Eldrazi")));
}
}
private int numSacrificed = 1; // always sacrifices self at least
public EmrakulsEvangelCost() {
@ -117,7 +120,7 @@ class EmrakulsEvangelCost extends CostImpl {
}
return paid;
}
public int getNumSacrificed() {
return numSacrificed;
}
@ -125,7 +128,7 @@ class EmrakulsEvangelCost extends CostImpl {
@Override
public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
Permanent permanent = game.getPermanent(sourceId);
return permanent != null && game.getPlayer(controllerId).canPaySacrificeCost(permanent, sourceId, controllerId, game);
}
@ -136,25 +139,25 @@ class EmrakulsEvangelCost extends CostImpl {
}
class EmrakulsEvangelEffect extends OneShotEffect {
EmrakulsEvangelEffect() {
super(Outcome.Sacrifice);
this.staticText = "Sacrifice {this} and any number of other non-Eldrazi creatures: Put a 3/2 colorless Eldrazi Horror creature token onto the battlefield for each creature sacrificed this way.";
this.staticText = "Put a 3/2 colorless Eldrazi Horror creature token onto the battlefield for each creature sacrificed this way.";
}
EmrakulsEvangelEffect(final EmrakulsEvangelEffect effect) {
super(effect);
}
@Override
public EmrakulsEvangelEffect copy() {
return new EmrakulsEvangelEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
if (player != null) {
int tokensToCreate = 0;
for (Cost cost : source.getCosts()) {
if (cost instanceof EmrakulsEvangelCost) {

View file

@ -32,6 +32,7 @@ import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DrawCardAllEffect;
import mage.abilities.effects.common.discard.DiscardEachPlayerEffect;
import mage.abilities.mana.ColorlessManaAbility;
@ -56,7 +57,9 @@ public class GeierReachSanitarium extends CardImpl {
// {2}, {T}: Each player draws a card, then discards a card.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardAllEffect(1), new GenericManaCost(2));
ability.addEffect(new DiscardEachPlayerEffect());
Effect effect = new DiscardEachPlayerEffect();
effect.setText(", then discards a card");
ability.addEffect(effect);
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}

View file

@ -66,7 +66,7 @@ public class GrimFlayer extends CardImpl {
// and the rest back on top of your library in any order.
Effect effect = new LookLibraryAndPickControllerEffect(
new StaticValue(3), false, new StaticValue(3), new FilterCard(), Zone.LIBRARY, true, false, true, Zone.GRAVEYARD, false);
effect.setText("look at the top three cards of your library. Put any number of them into your graveyard and the rest on top of your library in any order");
effect.setText("look at the top three cards of your library. Put any number of them into your graveyard and the rest back on top of your library in any order");
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(effect, false));
// <i>Delirium</i> &mdash; Grim Flayer gets +2/+2 as long as there are four or more card types among cards in your graveyard.

View file

@ -54,7 +54,7 @@ import mage.target.common.TargetOpponent;
*/
public class IshkanahGrafwidow extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("each Spider you control");
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("Spider you control");
static {
filter.add(new SubtypePredicate("Spider"));

View file

@ -32,15 +32,11 @@ import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastOpponentTriggeredAbility;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.constants.AsThoughEffectType;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
@ -64,8 +60,7 @@ public class MindsDilation extends CardImpl {
// Whenever an opponent casts his or her first spell each turn, that player exiles the top card of his or her library. If it's a nonland card,
// you may cast it without paying its mana cost.
Ability ability = new MindsDilationTriggeredAbility(new MindsDilationEffect(), false);
this.addAbility(ability, new SpellsCastWatcher());
this.addAbility(new MindsDilationTriggeredAbility(new MindsDilationEffect(), false), new SpellsCastWatcher());
}
public MindsDilation(final MindsDilation card) {
@ -113,7 +108,7 @@ class MindsDilationTriggeredAbility extends SpellCastOpponentTriggeredAbility {
@Override
public String getRule() {
return "Whenever an opponent casts his or her first spell each turn, that player exiles the top card of his or her library."
+ " If it's a nonland card, you may cast it without paying its mana cost";
+ " If it's a nonland card, you may cast it without paying its mana cost.";
}
}
@ -121,7 +116,7 @@ class MindsDilationEffect extends OneShotEffect {
MindsDilationEffect() {
super(Outcome.Benefit);
this.staticText = "that player exiles the top card of his or her library. If it's a nonland card, you may cast it without paying its mana cost.";
this.staticText = "that player exiles the top card of his or her library. If it's a nonland card, you may cast it without paying its mana cost";
}
MindsDilationEffect(final MindsDilationEffect effect) {
@ -140,12 +135,13 @@ class MindsDilationEffect extends OneShotEffect {
Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source));
if (controller != null && sourceObject != null && opponent != null) {
if (opponent.getLibrary().size() > 0) {
Card card = opponent.getLibrary().removeFromTop(game);
if (card != null) {
opponent.moveCardToExileWithInfo(card, source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true);
ContinuousEffect effect = new MindsDilationCastFromExileEffect();
effect.setTargetPointer(new FixedTarget(card.getId()));
game.addEffect(effect, source);
Card card = opponent.getLibrary().getFromTop(game);
if (card != null && opponent.moveCards(card, Zone.EXILED, source, game)) {
if (!card.getCardType().contains(CardType.LAND)) {
if (controller.chooseUse(outcome, "Cast " + card.getLogName() + " without paying its mana cost from exile?", source, game)) {
controller.cast(card.getSpellAbility(), game, true);
}
}
}
}
return true;
@ -153,41 +149,3 @@ class MindsDilationEffect extends OneShotEffect {
return false;
}
}
class MindsDilationCastFromExileEffect extends AsThoughEffectImpl {
MindsDilationCastFromExileEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
staticText = "If it's a nonland card, you may cast it without paying its mana cost";
}
MindsDilationCastFromExileEffect(final MindsDilationCastFromExileEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public MindsDilationCastFromExileEffect copy() {
return new MindsDilationCastFromExileEffect(this);
}
@Override
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
UUID targetId = getTargetPointer().getFirst(game, source);
Player controller = game.getPlayer(source.getControllerId());
if (targetId != null && controller != null) {
Card card = game.getCard(targetId);
if (card != null && !card.getCardType().contains(CardType.LAND) && game.getState().getZone(targetId) == Zone.EXILED) {
if (controller.chooseUse(outcome, "Cast " + card.getLogName() + "?", source, game)) {
controller.cast(card.getSpellAbility(), game, true);
}
return true;
}
}
return false;
}
}

View file

@ -30,6 +30,7 @@ package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.DiesTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
@ -52,7 +53,9 @@ public class PrimalDruid extends CardImpl {
this.toughness = new MageInt(3);
// When Primal Druid dies, you may search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library.
this.addAbility(new DiesTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(new FilterBasicLandCard()), true), true));
Effect effect = new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(new FilterBasicLandCard()), true);
effect.setText("you may search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library");
this.addAbility(new DiesTriggeredAbility(effect, true));
}

View file

@ -30,6 +30,7 @@ package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.keyword.FlashAbility;
import mage.cards.CardImpl;
@ -65,7 +66,9 @@ public class SpiritOfTheHunt extends CardImpl {
this.addAbility(FlashAbility.getInstance());
// When Spirit of the Hunt enters the battlefield, each other creature you control that's a Wolf or a Werewolf gets +0/+3 until end of turn.
this.addAbility(new EntersBattlefieldTriggeredAbility(new BoostControlledEffect(0, 3, Duration.EndOfTurn, filter, true), false));
Effect effect = new BoostControlledEffect(0, 3, Duration.EndOfTurn, filter, true);
effect.setText("each other creature you control that's a Wolf or a Werewolf gets +0/+3 until end of turn");
this.addAbility(new EntersBattlefieldTriggeredAbility(effect, false));
}
public SpiritOfTheHunt(final SpiritOfTheHunt card) {

View file

@ -45,8 +45,8 @@ import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent.EventType;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
/**
*
@ -68,7 +68,9 @@ public class StitchersGraft extends CardImpl {
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
// Whenever Stitcher's Graft becomes unattached from a permanent, sacrifice that permanent.
this.addAbility(new UnattachedTriggeredAbility(new SacrificeEquippedEffect(), false));
effect = new SacrificeEquippedEffect();
effect.setText("sacrifice that permanent");
this.addAbility(new UnattachedTriggeredAbility(effect, false));
// Equip {2}
this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2)));

View file

@ -157,7 +157,7 @@ class TamiyoFieldResearcherDelayedTriggeredAbility extends DelayedTriggeredAbili
private List<MageObjectReference> creatures;
public TamiyoFieldResearcherDelayedTriggeredAbility(List<MageObjectReference> creatures) {
super(new DrawCardSourceControllerEffect(1), Duration.UntilYourNextTurn);
super(new DrawCardSourceControllerEffect(1), Duration.UntilYourNextTurn, false);
this.creatures = creatures;
}

View file

@ -28,6 +28,7 @@
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.TransformTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
import mage.abilities.keyword.TrampleAbility;
@ -60,8 +61,11 @@ public class WaxingMoon extends CardImpl {
this.expansionSetCode = "EMN";
// Transform up to one target Werewolf you control.
this.getSpellAbility().addEffect(new TransformTargetEffect(false));
Effect effect = new TransformTargetEffect(false);
effect.setText("Transform up to one target Werewolf you control");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 1, filter, false));
// Creatures you control gain trample until end of turn.
this.getSpellAbility().addEffect(new GainAbilityAllEffect(TrampleAbility.getInstance(), Duration.EndOfTurn, new FilterControlledCreaturePermanent(), "Creatures you control gain trample until end of turn"));
}

View file

@ -32,13 +32,12 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.LockedInDynamicValue;
import mage.abilities.dynamicvalue.common.CountersCount;
import mage.abilities.dynamicvalue.common.PermanentsTargetOpponentControlsCount;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.PreventAllDamageToSourceEffect;
import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect;
import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl;
@ -46,7 +45,6 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
@ -74,7 +72,9 @@ public class GideonChampionOfJustice extends CardImpl {
this.addAbility(ability1);
// 0: Until end of turn, Gideon becomes an indestructible Human Soldier creature with power and toughness each equal to the number of loyalty counters on him. He's still a planeswalker. Prevent all damage that would be dealt to him this turn.
LoyaltyAbility ability2 = new LoyaltyAbility(new BecomesCreatureSourceEffect(new GideonChampionOfJusticeToken(), "planeswalker", Duration.EndOfTurn), 0);
LockedInDynamicValue loyaltyCount = new LockedInDynamicValue(new CountersCount(CounterType.LOYALTY));
LoyaltyAbility ability2 = new LoyaltyAbility(new BecomesCreatureSourceEffect(
new GideonChampionOfJusticeToken(), "planeswalker", Duration.EndOfTurn, false, false, loyaltyCount, loyaltyCount), 0);
ability2.addEffect(new PreventAllDamageToSourceEffect(Duration.EndOfTurn));
this.addAbility(ability2);
@ -131,7 +131,7 @@ class GideonChampionOfJusticeToken extends Token {
toughness = new MageInt(0);
this.addAbility(IndestructibleAbility.getInstance());
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new CountersCount(CounterType.LOYALTY), Duration.WhileOnBattlefield)));
}
}

View file

@ -42,7 +42,7 @@ import mage.game.permanent.token.DevilToken;
public class DevilsPlayground extends CardImpl {
public DevilsPlayground(UUID ownerId) {
super(ownerId, 151, "Devil's Playground", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{4}{R}{R}");
super(ownerId, 151, "Devils' Playground", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{4}{R}{R}");
this.expansionSetCode = "SOI";
// Put four 1/1 red Devil creature tokens onto the battlefield. They have "When this creature dies, it deals 1 damage to target creature or player."

View file

@ -0,0 +1,65 @@
/*
* 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 org.mage.test.cards.abilities.keywords;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class EscalateTest extends CardTestPlayerBase {
@Test
public void testUseOneMode() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
// Escalate {1} (Pay this cost for each mode chosen beyond the first.)
// Choose one or more &mdash;
// Creatures target player controls gain trample until end of turn.
// Savage Alliance deals 2 damage to target creature;
// Savage Alliance deals 1 damage to each creature target opponent controls.
addCard(Zone.HAND, playerA, "Savage Alliance"); // Instant {2}{R}
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Savage Alliance", "mode=2Silvercoat Lion");
setModeChoice(playerA, "2");
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertGraveyardCount(playerB, "Silvercoat Lion", 1);
assertGraveyardCount(playerA, "Savage Alliance", 1);
}
}

View file

@ -0,0 +1,72 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.mage.test.cards.enchantments;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
*/
public class MindsDilationTest extends CardTestPlayerBase {
@Test
public void testExileNonLandCardAndCastIt() {
/**
* Mind's Dilation {5}{U}{U} Enchantment Whenever an opponent casts his
* or her first spell each turn, that player exiles the top card of his
* or her library. If it's a nonland card, you may cast it without
* paying its mana cost.
*/
addCard(Zone.BATTLEFIELD, playerB, "Mind's Dilation", 1);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.HAND, playerA, "Lightning Bolt", 1);
addCard(Zone.LIBRARY, playerA, "Divination", 1); // draw 2 cards
skipInitShuffling();
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
setChoice(playerB, "Yes");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertLife(playerB, 17);
assertExileCount("Divination", 0);
assertHandCount(playerB, 2); // free divination!
}
@Test
public void testExileNonLandCardDontCastIt() {
removeAllCardsFromLibrary(playerA);
/**
* Mind's Dilation {5}{U}{U} Enchantment Whenever an opponent casts his
* or her first spell each turn, that player exiles the top card of his
* or her library. If it's a nonland card, you may cast it without
* paying its mana cost.
*/
addCard(Zone.BATTLEFIELD, playerB, "Mind's Dilation", 1);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.HAND, playerA, "Lightning Bolt", 1);
addCard(Zone.LIBRARY, playerA, "Divination", 1); // draw 2 cards
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
setChoice(playerB, "No"); // no, I don't want my free 2 cards
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertLife(playerB, 17);
assertExileCount("Divination", 1);
assertHandCount(playerB, 0); // Divination never cast
}
}

View file

@ -76,4 +76,43 @@ public class GideonTest extends CardTestPlayerBase {
assertAbility(playerB, "Silvercoat Lion", IndestructibleAbility.getInstance(), false);
}
/*
* Reported bug: When Gideon, Champion of Justice uses his +0 ability to become a creature,
* he is immediately sent to the grave instead.
*/
@Test
public void testGideonChampionOfJusticeSecondAbility() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
/*
Gideon, Champion of Justice {2}{W}{W} - 4 Loyalty
+1: Put a loyalty counter on Gideon, Champion of Justice for each creature target opponent controls.
0: Until end of turn, Gideon, Champion of Justice becomes a Human Soldier creature with power and toughness
each equal to the number of loyalty counters on him and gains indestructible. He's still a planeswalker.
Prevent all damage that would be dealt to him this turn.
LoyaltyAbility ability1 = new LoyaltyAbility(
-15: Exile all other permanents.
*/
addCard(Zone.HAND, playerA, "Gideon, Champion of Justice", 1);
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Gideon, Champion of Justice");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+0: Until end of turn");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Put a loyalty counter on", playerB);
activateAbility(5, PhaseStep.PRECOMBAT_MAIN, playerA, "+0: Until end of turn");
setStopAt(5, PhaseStep.BEGIN_COMBAT);
execute();
assertGraveyardCount(playerA, "Gideon, Champion of Justice", 0);
assertPermanentCount(playerA, "Gideon, Champion of Justice", 1);
assertCounterCount(playerA, "Gideon, Champion of Justice", CounterType.LOYALTY, 7);
assertPowerToughness(playerA, "Gideon, Champion of Justice", 7, 7);
}
}

View file

@ -29,7 +29,6 @@ package org.mage.test.cards.planeswalker;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
@ -40,120 +39,120 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
public class TamiyoTest extends CardTestPlayerBase {
/*
* Reported bug: I activated Tamiyo's +1 ability on a 5/5 Gideon and his 2/2 Knight Ally, but when they both attacked
* Reported bug: I activated Tamiyo's +1 ability on a 5/5 Gideon and his 2/2 Knight Ally, but when they both attacked
* and dealt damage I only drew one card when I'm pretty sure I was supposed to draw for each of the two.
*/
@Test
public void testFieldResearcherFirstEffectOnGideon() {
// Tamiyo, Field Researcher {1}{G}{W}{U} - 4 loyalty
// +1: Choose up to two target creatures. Until your next turn,
// +1: Choose up to two target creatures. Until your next turn,
// whenever either of those creatures deals combat damage, you draw a card.
addCard(Zone.BATTLEFIELD, playerA, "Tamiyo, Field Researcher", 1);
/* Gideon, Ally of Zendikar {2}{W}{W} - 4 loyalty
* +1: Until end of turn, Gideon, Ally of Zendikar becomes a 5/5 Human Soldier Ally creature with indestructible
* +1: Until end of turn, Gideon, Ally of Zendikar becomes a 5/5 Human Soldier Ally creature with indestructible
* that's still a planeswalker. Prevent all damage that would be dealt to him this turn.
* 0: Put a 2/2 white Knight Ally creature token onto the battlefield.
**/
addCard(Zone.BATTLEFIELD, playerA, "Gideon, Ally of Zendikar", 1);
// put 2/2 knight ally token on battlefield
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+0: Put a");
// next, activate Gideon to make him a 5/5 human soldier ally creature
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Until end of turn");
// finally, use Tamiyo +1 on both creatures
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Choose up to two");
addTarget(playerA, "Knight Ally^Gideon, Ally of Zendikar"); // both token and Gideon as creature
// attack with both unblocked
attack(3, playerA, "Knight Ally");
attack(3, playerA, "Knight Ally");
attack(3, playerA, "Gideon, Ally of Zendikar");
setStopAt(3, PhaseStep.END_COMBAT);
execute();
execute();
assertLife(playerB, 13); // 5 + 2 damage, 20 - 7 = 13
assertPermanentCount(playerA, "Tamiyo, Field Researcher", 1);
assertPermanentCount(playerA, "Gideon, Ally of Zendikar", 1);
assertPermanentCount(playerA, "Knight Ally", 1);
assertHandCount(playerA, 3); // two cards drawn from each creature dealing damage + 1 card drawn on turn
}
/*
* Testing more basic scenario with Tamiyo, Field of Researcher +1 effect
*/
@Test
public void testFieldResearcherFirstEffectSimpleCreatureAttacks() {
// Tamiyo, Field Researcher {1}{G}{W}{U} - 4 loyalty
// +1: Choose up to two target creatures. Until your next turn,
// +1: Choose up to two target creatures. Until your next turn,
// whenever either of those creatures deals combat damage, you draw a card.
addCard(Zone.BATTLEFIELD, playerA, "Tamiyo, Field Researcher", 1);
addCard(Zone.BATTLEFIELD, playerA, "Bronze Sable", 1); // 2/1
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Choose up to two");
addTarget(playerA, "Bronze Sable");
attack(1, playerA, "Bronze Sable");
setStopAt(1, PhaseStep.END_COMBAT);
execute();
assertLife(playerB, 18);
assertHandCount(playerA, 1);
}
/*
* Testing more basic scenario with Tamiyo, Field of Researcher +1 effect
*/
@Test
public void testFieldResearcherFirstEffectSimpleCreaturesAttacks() {
// Tamiyo, Field Researcher {1}{G}{W}{U} - 4 loyalty
// +1: Choose up to two target creatures. Until your next turn,
// +1: Choose up to two target creatures. Until your next turn,
// whenever either of those creatures deals combat damage, you draw a card.
addCard(Zone.BATTLEFIELD, playerA, "Tamiyo, Field Researcher", 1);
addCard(Zone.BATTLEFIELD, playerA, "Bronze Sable", 1); // 2/1
addCard(Zone.BATTLEFIELD, playerA, "Sylvan Advocate", 1); // 2/3
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Choose up to two");
addTarget(playerA, "Bronze Sable^Sylvan Advocate");
attack(1, playerA, "Bronze Sable");
attack(1, playerA, "Sylvan Advocate");
setStopAt(1, PhaseStep.END_COMBAT);
execute();
assertLife(playerB, 16);
assertHandCount(playerA, 2);
}
/*
* Testing more basic scenarios with Tamiyo, Field of Researcher +1 effect
*/
@Test
public void testFieldResearcherFirstEffectAttackAndBlock() {
// Tamiyo, Field Researcher {1}{G}{W}{U} - 4 loyalty
// +1: Choose up to two target creatures. Until your next turn,
// +1: Choose up to two target creatures. Until your next turn,
// whenever either of those creatures deals combat damage, you draw a card.
addCard(Zone.BATTLEFIELD, playerA, "Tamiyo, Field Researcher", 1);
addCard(Zone.BATTLEFIELD, playerA, "Sylvan Advocate", 1); // 2/3
addCard(Zone.BATTLEFIELD, playerB, "Memnite", 1);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Choose up to two");
addTarget(playerA, "Sylvan Advocate");
attack(1, playerA, "Sylvan Advocate");
attack(2, playerB, "Memnite");
block(2, playerA, "Sylvan Advocate", "Memnite");
setStopAt(2, PhaseStep.END_COMBAT);
execute();
assertLife(playerB, 18);
assertHandCount(playerA, 2); // Sylvan Advocate dealt combat damage twice
}

View file

@ -0,0 +1,55 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.mage.test.cards.replacement;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
*/
public class KalitasTraitorOfGhetTest extends CardTestPlayerBase {
/*
* Reported bug: Damnation with Kalitas, Traitor of Ghet on my side and 3 opponent creatures, it only exiled 1 creature giving me only 1 zombie instead of 3.
*/
@Test
public void testDamnation() {
/*
Kalitas, Traitor of Ghet {2}{B}{B} 3/4 lifelink - Legendary Vampire
If a nontoken creature an opponent controls would die, instead exile that card and put a 2/2 black Zombie creature token onto the battlefield.
*/
addCard(Zone.BATTLEFIELD, playerA, "Kalitas, Traitor of Ghet", 1);
/*
Damnation {2}{B}{B} - Sorcery
Destroy all creatures. They can't be regenerated.
*/
addCard(Zone.HAND, playerA, "Damnation", 1);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4);
addCard(Zone.BATTLEFIELD, playerB, "Bronze Sable", 1);
addCard(Zone.BATTLEFIELD, playerB, "Wall of Roots", 1);
addCard(Zone.BATTLEFIELD, playerB, "Sigiled Starfish", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Damnation");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertGraveyardCount(playerA, "Kalitas, Traitor of Ghet", 1);
assertGraveyardCount(playerA, "Damnation", 1);
assertExileCount("Bronze Sable", 1);
assertExileCount("Wall of Roots", 1);
assertExileCount("Sigiled Starfish", 1);
assertGraveyardCount(playerB, 0); // all 3 creatures of playerB should be exiled not in graveyard
assertExileCount("Kalitas, Traitor of Ghet", 0); // player controlled, not opponent so not exiled
assertPermanentCount(playerA, "Zombie", 3); // 3 tokens generated from exiling 3 opponent's creatures
}
}

View file

@ -0,0 +1,95 @@
/*
* 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 org.mage.test.cards.single;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
*/
public class UrzasIncubatorTest extends CardTestPlayerBase {
/*
* Reported bug: Urza's Incubator does not reduce the cost of Eldrazi creatures
*/
@Test
public void testEldraziCostReduction() {
/*
Urza's Incubator (3) Artifact
As Urza's Incubator enters the battlefield, choose a creature type.
Creature spells of the chosen type cost 2 less to cast.
*/
addCard(Zone.HAND, playerA, "Urza's Incubator", 1);
addCard(Zone.HAND, playerA, "Eldrazi Displacer", 1); // {2}{W} eldrazi 3/3
addCard(Zone.HAND, playerA, "Eldrazi Mimic", 2); // {2} eldrazi 2/1
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Urza's Incubator"); // taps 3 plains
setChoice(playerA, "Eldrazi");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Eldrazi Displacer"); // taps last plains
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Eldrazi Mimic"); // both mimics should be free
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Eldrazi Mimic");
setStopAt(1, PhaseStep.END_TURN);
execute();
assertPermanentCount(playerA, "Urza's Incubator", 1);
assertPermanentCount(playerA, "Eldrazi Displacer", 1);
assertPermanentCount(playerA, "Eldrazi Mimic", 2);
}
/*
* Test to make sure incubator only reduces generic cost. Cards with <> requirement
* still require specific colorless mana to cast.
*/
@Test
public void testEldraziCostReductionWastesRequirement() {
/*
Urza's Incubator (3) Artifact
As Urza's Incubator enters the battlefield, choose a creature type.
Creature spells of the chosen type cost 2 less to cast.
*/
addCard(Zone.HAND, playerA, "Urza's Incubator", 1);
addCard(Zone.HAND, playerA, "Thought-Knot Seer", 1); // {3}{<>} eldrazi 4/4
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Urza's Incubator"); // taps 3 plains
setChoice(playerA, "Eldrazi");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Thought-Knot Seer"); // 2 plains remaining, but <> required
setStopAt(1, PhaseStep.END_TURN);
execute();
assertPermanentCount(playerA, "Urza's Incubator", 1);
assertPermanentCount(playerA, "Thought-Knot Seer", 0); // should not be able to cast
}
}

View file

@ -574,6 +574,9 @@ public class TestPlayer implements Player {
i++;
}
}
if (modes.getMinModes() <= modes.getSelectedModes().size()) {
return null;
}
return computerPlayer.chooseMode(modes, source, game); //To change body of generated methods, choose Tools | Templates.
}
@ -1734,7 +1737,7 @@ public class TestPlayer implements Player {
public boolean canPaySacrificeCost(Permanent permanent, UUID sourceId, UUID controllerId, Game game) {
return computerPlayer.canPaySacrificeCost(permanent, sourceId, controllerId, game);
}
@Override
public FilterPermanent getSacrificeCostFilter() {
return computerPlayer.getSacrificeCostFilter();

View file

@ -0,0 +1,77 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities.dynamicvalue;
import mage.abilities.Ability;
import mage.abilities.effects.Effect;
import mage.game.Game;
/**
* The first calculated value is used as long as the class instance is in use
*
* IMPORTANT: If used the ability / effect that uses a locked in dynamic value
* has to really copy the dnamic value in its copy method (not reference)
*
* @author LevelX2
*/
public class LockedInDynamicValue implements DynamicValue {
private boolean valueChecked = false;
private int lockedInValue;
private final DynamicValue basicDynamicValue;
public LockedInDynamicValue(DynamicValue dynamicValue) {
this.basicDynamicValue = dynamicValue;
}
public LockedInDynamicValue(LockedInDynamicValue dynamicValue, final boolean copy) {
this.basicDynamicValue = dynamicValue.basicDynamicValue;
this.lockedInValue = dynamicValue.lockedInValue;
this.valueChecked = dynamicValue.valueChecked;
}
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
if (!valueChecked) {
lockedInValue = basicDynamicValue.calculate(game, sourceAbility, effect);
valueChecked = true;
}
return lockedInValue;
}
@Override
public LockedInDynamicValue copy() {
return new LockedInDynamicValue(this, true);
}
@Override
public String getMessage() {
return basicDynamicValue.getMessage();
}
}

View file

@ -159,7 +159,7 @@ public class DontUntapInControllersNextUntapStepTargetEffect extends ContinuousR
return staticText;
}
if (targetName != null && targetName.length() > 0) {
if (targetName.equals("Those creatures")) {
if (targetName.equals("Those creatures") || targetName.equals("They")) {
return targetName + " don't untap during their controller's next untap step";
} else
return targetName + " doesn't untap during its controller's next untap step";

View file

@ -27,9 +27,9 @@
*/
package mage.abilities.effects.common.continuous;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.repository.CardRepository;
import mage.constants.CardType;
@ -50,17 +50,25 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements
protected Token token;
protected String type;
protected boolean losePreviousTypes;
protected DynamicValue power = null;
protected DynamicValue toughness = null;
public BecomesCreatureSourceEffect(Token token, String type, Duration duration) {
this(token, type, duration, false, false);
}
public BecomesCreatureSourceEffect(Token token, String type, Duration duration, boolean losePreviousTypes, boolean characterDefining) {
this(token, type, duration, losePreviousTypes, characterDefining, null, null);
}
public BecomesCreatureSourceEffect(Token token, String type, Duration duration, boolean losePreviousTypes, boolean characterDefining, DynamicValue power, DynamicValue toughness) {
super(duration, Outcome.BecomeCreature);
this.characterDefining = characterDefining;
this.token = token;
this.type = type;
this.losePreviousTypes = losePreviousTypes;
this.power = power;
this.toughness = toughness;
setText();
}
@ -69,6 +77,12 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements
this.token = effect.token.copy();
this.type = effect.type;
this.losePreviousTypes = effect.losePreviousTypes;
if (effect.power != null) {
this.power = effect.power.copy();
}
if (effect.toughness != null) {
this.toughness = effect.toughness.copy();
}
}
@Override
@ -133,19 +147,21 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements
case PTChangingEffects_7:
if ((sublayer == SubLayer.CharacteristicDefining_7a && isCharacterDefining())
|| (sublayer == SubLayer.SetPT_7b && !isCharacterDefining())) {
MageInt power = token.getPower();
MageInt toughness = token.getToughness();
if (power != null && toughness != null) {
permanent.getPower().setValue(power.getValue());
permanent.getToughness().setValue(toughness.getValue());
if (power != null) {
permanent.getPower().setValue(power.calculate(game, source, this));
} else if (token.getPower() != null) {
permanent.getPower().setValue(token.getPower().getValue());
}
if (toughness != null) {
permanent.getToughness().setValue(toughness.calculate(game, source, this));
} else if (token.getToughness() != null) {
permanent.getToughness().setValue(token.getToughness().getValue());
}
}
}
return true;
} else {
if (duration.equals(Duration.Custom)) {
this.discard();
}
} else if (duration.equals(Duration.Custom)) {
this.discard();
}
return false;
}

View file

@ -24,21 +24,19 @@
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
*/
package mage.target;
import mage.constants.Zone;
import mage.cards.Card;
import mage.cards.Cards;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.cards.Card;
import mage.cards.Cards;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.players.Player;
/**
*
@ -87,9 +85,12 @@ public class TargetCard extends TargetObject {
@Override
public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
int possibleTargets = 0;
for (UUID playerId: game.getState().getPlayersInRange(sourceControllerId, game)) {
for (UUID playerId : game.getState().getPlayersInRange(sourceControllerId, game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
if (this.minNumberOfTargets == 0) {
return true;
}
switch (zone) {
case HAND:
for (Card card : player.getHand().getCards(filter, sourceId, sourceControllerId, game)) {
@ -200,7 +201,7 @@ public class TargetCard extends TargetObject {
public Set<UUID> possibleTargets(UUID sourceControllerId, Cards cards, Game game) {
Set<UUID> possibleTargets = new HashSet<>();
for (Card card: cards.getCards(filter, game)) {
for (Card card : cards.getCards(filter, game)) {
possibleTargets.add(card.getId());
}
return possibleTargets;

View file

@ -121,7 +121,7 @@ public class Targets extends ArrayList<Target> {
}
}
// it is legal when either there is no target or not all targets are illegal
return this.size() == 0 || this.size() != illegalCount;
return this.isEmpty() || this.size() != illegalCount;
}
/**

View file

@ -30,10 +30,10 @@ package mage.target.common;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.constants.Zone;
import mage.abilities.Ability;
import mage.cards.Card;
import mage.cards.Cards;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.game.events.GameEvent;
@ -122,10 +122,7 @@ public class TargetCardInYourGraveyard extends TargetCard {
*/
@Override
public boolean canChoose(UUID sourceControllerId, Game game) {
if (game.getPlayer(sourceControllerId).getGraveyard().count(filter, game) >= this.minNumberOfTargets) {
return true;
}
return false;
return game.getPlayer(sourceControllerId).getGraveyard().count(filter, game) >= this.minNumberOfTargets;
}
@Override

View file

@ -32,6 +32,7 @@ public class SpellsCastWatcher extends Watcher {
public SpellsCastWatcher(final SpellsCastWatcher watcher) {
super(watcher);
this.spellsCast.putAll(watcher.spellsCast);
}
@Override