* Added logic to add permitting object to play/cast events.

This commit is contained in:
LevelX2 2018-05-27 23:47:57 +02:00
parent b97a443a37
commit 27ced167fb
124 changed files with 1095 additions and 964 deletions

View file

@ -33,6 +33,7 @@ import java.util.*;
import java.util.Map.Entry;
import mage.ConditionalMana;
import mage.MageObject;
import mage.MageObjectReference;
import mage.Mana;
import mage.abilities.*;
import mage.abilities.costs.VariableCost;
@ -1027,7 +1028,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
findPlayables(game);
if (!playableAbilities.isEmpty()) {
for (ActivatedAbility ability : playableAbilities) {
if (ability.canActivate(playerId, game)) {
if (ability.canActivate(playerId, game).canActivate()) {
if (ability.getEffects().hasOutcome(Outcome.PutLandInPlay)) {
if (this.activateAbility(ability, game)) {
return true;
@ -1058,7 +1059,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
if (game.getStack().isEmpty()) {
if (!playableNonInstant.isEmpty()) {
for (Card card : playableNonInstant) {
if (card.getSpellAbility().canActivate(playerId, game)) {
if (card.getSpellAbility().canActivate(playerId, game).canActivate()) {
if (this.activateAbility(card.getSpellAbility(), game)) {
return true;
}
@ -1067,7 +1068,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
if (!playableAbilities.isEmpty()) {
for (ActivatedAbility ability : playableAbilities) {
if (ability.canActivate(playerId, game)) {
if (ability.canActivate(playerId, game).canActivate()) {
if (!(ability.getEffects().get(0) instanceof BecomesCreatureSourceEffect)) {
if (this.activateAbility(ability, game)) {
return true;
@ -1187,7 +1188,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
for (Mana avail : available) {
if (mana.enough(avail)) {
SpellAbility ability = card.getSpellAbility();
if (ability != null && ability.canActivate(playerId, game)
if (ability != null && ability.canActivate(playerId, game).canActivate()
&& game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, ability.getSourceId(), ability.getSourceId(), playerId), ability, game, true)) {
if (card.getCardType().contains(CardType.INSTANT)
|| card.hasAbility(FlashAbility.getInstance().getId(), game)) {
@ -1204,7 +1205,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) {
for (ActivatedAbility ability : permanent.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) {
if (!(ability instanceof ActivatedManaAbilityImpl) && ability.canActivate(playerId, game)) {
if (!(ability instanceof ActivatedManaAbilityImpl) && ability.canActivate(playerId, game).canActivate()) {
if (ability instanceof EquipAbility && permanent.getAttachedTo() != null) {
continue;
}
@ -1231,7 +1232,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
for (Card card : graveyard.getCards(game)) {
for (ActivatedAbility ability : card.getAbilities().getActivatedAbilities(Zone.GRAVEYARD)) {
if (ability.canActivate(playerId, game)) {
if (ability.canActivate(playerId, game).canActivate()) {
ManaOptions abilityOptions = ability.getManaCosts().getOptions();
if (abilityOptions.isEmpty()) {
playableAbilities.add(ability);
@ -1264,7 +1265,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
protected boolean playManaHandling(Ability ability, ManaCost unpaid, final Game game) {
// log.info("paying for " + unpaid.getText());
UUID spendAnyManaId = game.getContinuousEffects().asThough(ability.getSourceId(), AsThoughEffectType.SPEND_OTHER_MANA, ability, ability.getControllerId(), game);
MageObjectReference permittingObject = game.getContinuousEffects().asThough(ability.getSourceId(), AsThoughEffectType.SPEND_OTHER_MANA, ability, ability.getControllerId(), game);
ManaCost cost;
List<MageObject> producers;
if (unpaid instanceof ManaCosts) {
@ -1308,7 +1309,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
if (cost instanceof ColoredManaCost) {
for (Mana netMana : manaAbility.getNetMana(game)) {
if (cost.testPay(netMana) || spendAnyManaId != null) {
if (cost.testPay(netMana) || permittingObject != null) {
if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
continue;
}
@ -1323,7 +1324,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
if (cost instanceof SnowManaCost) {
for (Mana netMana : manaAbility.getNetMana(game)) {
if (cost.testPay(netMana) || spendAnyManaId != null) {
if (cost.testPay(netMana) || permittingObject != null) {
if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
continue;
}
@ -1338,7 +1339,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
if (cost instanceof HybridManaCost) {
for (Mana netMana : manaAbility.getNetMana(game)) {
if (cost.testPay(netMana) || spendAnyManaId != null) {
if (cost.testPay(netMana) || permittingObject != null) {
if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
continue;
}
@ -1353,7 +1354,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
if (cost instanceof MonoHybridManaCost) {
for (Mana netMana : manaAbility.getNetMana(game)) {
if (cost.testPay(netMana) || spendAnyManaId != null) {
if (cost.testPay(netMana) || permittingObject != null) {
if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
continue;
}
@ -1368,7 +1369,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
if (cost instanceof ColorlessManaCost) {
for (Mana netMana : manaAbility.getNetMana(game)) {
if (cost.testPay(netMana) || spendAnyManaId != null) {
if (cost.testPay(netMana) || permittingObject != null) {
if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
continue;
}
@ -1383,7 +1384,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
if (cost instanceof GenericManaCost) {
for (Mana netMana : manaAbility.getNetMana(game)) {
if (cost.testPay(netMana) || spendAnyManaId != null) {
if (cost.testPay(netMana) || permittingObject != null) {
if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
continue;
}
@ -1397,7 +1398,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
// pay phyrexian life costs
if (cost instanceof PhyrexianManaCost) {
if (cost.pay(null, game, null, playerId, false, null) || spendAnyManaId != null) {
if (cost.pay(null, game, null, playerId, false, null) || permittingObject != null) {
return true;
}
}
@ -2386,7 +2387,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
private void playRemoval(List<UUID> creatures, Game game) {
for (UUID creatureId : creatures) {
for (Card card : this.playableInstant) {
if (card.getSpellAbility().canActivate(playerId, game)) {
if (card.getSpellAbility().canActivate(playerId, game).canActivate()) {
for (Effect effect : card.getSpellAbility().getEffects()) {
if (effect.getOutcome() == Outcome.DestroyPermanent || effect.getOutcome() == Outcome.ReturnToHand) {
if (card.getSpellAbility().getTargets().get(0).canTarget(creatureId, card.getSpellAbility(), game)) {
@ -2405,7 +2406,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
for (UUID creatureId : creatures) {
Permanent creature = game.getPermanent(creatureId);
for (Card card : this.playableInstant) {
if (card.getSpellAbility().canActivate(playerId, game)) {
if (card.getSpellAbility().canActivate(playerId, game).canActivate()) {
for (Effect effect : card.getSpellAbility().getEffects()) {
if (effect instanceof DamageTargetEffect) {
if (card.getSpellAbility().getTargets().get(0).canTarget(creatureId, card.getSpellAbility(), game)) {

View file

@ -25,17 +25,16 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.player.ai;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.abilities.ActivatedAbility;
import mage.abilities.keyword.DoubleStrikeAbility;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.abilities.mana.ActivatedManaAbilityImpl;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.counters.BoostCounter;
import mage.counters.Counter;
import mage.counters.CounterType;
@ -71,18 +70,20 @@ public final class GameStateEvaluator {
Player player = game.getPlayer(playerId);
Player opponent = game.getPlayer(game.getOpponents(playerId).iterator().next());
if (game.checkIfGameIsOver()) {
if (player.hasLost() || opponent.hasWon())
if (player.hasLost() || opponent.hasWon()) {
return LOSE_SCORE;
if (opponent.hasLost() || player.hasWon())
}
if (opponent.hasLost() || player.hasWon()) {
return WIN_SCORE;
}
}
int lifeScore = (player.getLife() - opponent.getLife()) * LIFE_FACTOR;
int poisonScore = (opponent.getCounters().getCount(CounterType.POISON) - player.getCounters().getCount(CounterType.POISON)) * LIFE_FACTOR * 2;
int permanentScore = 0;
for (Permanent permanent: game.getBattlefield().getAllActivePermanents(playerId)) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) {
permanentScore += evaluatePermanent(permanent, game, ignoreTapped);
}
for (Permanent permanent: game.getBattlefield().getAllActivePermanents(opponent.getId())) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(opponent.getId())) {
permanentScore -= evaluatePermanent(permanent, game, ignoreTapped);
}
permanentScore *= PERMANENT_FACTOR;
@ -92,26 +93,29 @@ public final class GameStateEvaluator {
handScore *= HAND_FACTOR;
int score = lifeScore + poisonScore + permanentScore + handScore;
if (logger.isDebugEnabled())
if (logger.isDebugEnabled()) {
logger.debug("game state for player " + player.getName() + " evaluated to- lifeScore:" + lifeScore + " permanentScore:" + permanentScore + " handScore:" + handScore + " total:" + score);
}
return score;
}
public static int evaluatePermanent(Permanent permanent, Game game, boolean ignoreTapped) {
int value = 0;
if (ignoreTapped)
if (ignoreTapped) {
value = 5;
else
value = permanent.isTapped()?4:5;
} else {
value = permanent.isTapped() ? 4 : 5;
}
if (permanent.getCardType().contains(CardType.CREATURE)) {
value += evaluateCreature(permanent, game) * CREATURE_FACTOR;
}
value += permanent.getAbilities().getActivatedManaAbilities(Zone.BATTLEFIELD).size();
for (ActivatedAbility ability: permanent.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) {
if (!(ability instanceof ActivatedManaAbilityImpl) && ability.canActivate(ability.getControllerId(), game))
for (ActivatedAbility ability : permanent.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) {
if (!(ability instanceof ActivatedManaAbilityImpl) && ability.canActivate(ability.getControllerId(), game).canActivate()) {
value += ability.getEffects().size();
}
}
for (Counter counter: permanent.getCounters(game).values()) {
for (Counter counter : permanent.getCounters(game).values()) {
if (!(counter instanceof BoostCounter)) {
value += counter.getCount();
}
@ -133,9 +137,9 @@ public final class GameStateEvaluator {
// value += 2;
value += creature.getAbilities().getEvasionAbilities().size();
value += creature.getAbilities().getProtectionAbilities().size();
value += creature.getAbilities().containsKey(FirstStrikeAbility.getInstance().getId())?1:0;
value += creature.getAbilities().containsKey(DoubleStrikeAbility.getInstance().getId())?2:0;
value += creature.getAbilities().containsKey(TrampleAbility.getInstance().getId())?1:0;
value += creature.getAbilities().containsKey(FirstStrikeAbility.getInstance().getId()) ? 1 : 0;
value += creature.getAbilities().containsKey(DoubleStrikeAbility.getInstance().getId()) ? 2 : 0;
value += creature.getAbilities().containsKey(TrampleAbility.getInstance().getId()) ? 1 : 0;
return value;
}

View file

@ -29,6 +29,7 @@ package mage.cards.a;
import java.util.Set;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.PutIntoGraveFromBattlefieldAllTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
@ -55,7 +56,7 @@ import mage.target.common.TargetCardInLibrary;
public class AetherworksMarvel extends CardImpl {
public AetherworksMarvel(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
addSuperType(SuperType.LEGENDARY);
// Whenever a permanent you control is put into a graveyard, you get {E}.
@ -105,7 +106,7 @@ class AetherworksMarvelEffect extends OneShotEffect {
TargetCard target = new TargetCardInLibrary(0, 1, new FilterNonlandCard("card to cast without paying its mana cost"));
if (controller.choose(Outcome.PlayForFree, cards, target, game)) {
Card card = controller.getLibrary().getCard(target.getFirstTarget(), game);
if (card != null && controller.cast(card.getSpellAbility(), game, true)) {
if (card != null && controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
cards.remove(card);
}
}

View file

@ -28,6 +28,7 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.RemoveVariableCountersSourceCost;
@ -114,7 +115,7 @@ class BrainInAJarCastEffect extends OneShotEffect {
controller.chooseTarget(outcome, target, source, game);
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
controller.cast(card.getSpellAbility(), game, true);
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
return true;

View file

@ -31,6 +31,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.*;
@ -50,7 +51,7 @@ import mage.target.common.TargetOpponent;
public class BrilliantUltimatum extends CardImpl {
public BrilliantUltimatum(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{W}{W}{U}{U}{U}{B}{B}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W}{W}{U}{U}{U}{B}{B}");
// Exile the top five cards of your library. An opponent separates those cards into two piles. You may play any number of cards from one of those piles without paying their mana costs.
this.getSpellAbility().addEffect(new BrilliantUltimatumEffect());
@ -136,7 +137,7 @@ class BrilliantUltimatumEffect extends OneShotEffect {
TargetCard targetExiledCard = new TargetCard(Zone.EXILED, new FilterCard());
if (controller.chooseTarget(Outcome.PlayForFree, selectedPile, targetExiledCard, source, game)) {
Card card = selectedPile.get(targetExiledCard.getFirstTarget(), game);
if (controller.playCard(card, game, true, true)) {
if (controller.playCard(card, game, true, true, new MageObjectReference(source.getSourceObject(game), game))) {
selectedPileCards.remove(card);
selectedPile.remove(card);
}

View file

@ -28,6 +28,7 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.common.ColorsOfManaSpentToCastCount;
import mage.abilities.effects.OneShotEffect;
@ -54,7 +55,7 @@ import org.apache.log4j.Logger;
public class BringToLight extends CardImpl {
public BringToLight(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{G}{U}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}{U}");
// <i>Converge</i>-Search your library for a creature, instant, or sorcery card with converted mana
// cost less than or equal to the number of colors of mana spent to cast Bring to Light, exile that card,
@ -108,7 +109,7 @@ class BringToLightEffect extends OneShotEffect {
if (card != null) {
if (controller.chooseUse(outcome, "Cast " + card.getName() + " without paying its mana cost?", source, game)) {
if (card.getSpellAbility() != null) {
controller.cast(card.getSpellAbility(), game, true);
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
} else {
Logger.getLogger(BringToLightEffect.class).error("Bring to Light: spellAbility == null " + card.getName());
}

View file

@ -29,6 +29,7 @@ package mage.cards.c;
import java.util.Set;
import java.util.UUID;
import mage.MageObjectReference;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
@ -41,8 +42,8 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
@ -51,8 +52,8 @@ import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCardInGraveyard;
import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetCardInGraveyard;
import mage.target.common.TargetDiscard;
/**
@ -62,7 +63,7 @@ import mage.target.common.TargetDiscard;
public class ChandraAblaze extends CardImpl {
public ChandraAblaze(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.PLANESWALKER},"{4}{R}{R}");
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{R}{R}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
@ -198,7 +199,7 @@ class ChandraAblazeEffect5 extends OneShotEffect {
if (player.choose(outcome, target, source.getSourceId(), game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
player.cast(card.getSpellAbility(), game, true);
player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
player.getGraveyard().remove(card);
cards.remove(card);
}

View file

@ -287,17 +287,18 @@ class ChandraPyromasterEffect3 extends OneShotEffect {
if (controller.chooseTarget(Outcome.PlayForFree, cards, target, source, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
MageObjectReference mor = new MageObjectReference(source.getSourceObject(game), game);
if (controller.chooseUse(outcome, "Do you wish to cast copy 1 of " + card.getName(), source, game)) {
Card copy1 = game.copyCard(card, source, source.getControllerId());
controller.cast(copy1.getSpellAbility(), game, true);
controller.cast(copy1.getSpellAbility(), game, true, mor);
}
if (controller.chooseUse(outcome, "Do you wish to cast copy 2 of " + card.getName(), source, game)) {
Card copy2 = game.copyCard(card, source, source.getControllerId());
controller.cast(copy2.getSpellAbility(), game, true);
controller.cast(copy2.getSpellAbility(), game, true, mor);
}
if (controller.chooseUse(outcome, "Do you wish to cast copy 3 of " + card.getName(), source, game)) {
Card copy3 = game.copyCard(card, source, source.getControllerId());
controller.cast(copy3.getSpellAbility(), game, true);
controller.cast(copy3.getSpellAbility(), game, true, mor);
}
return true;
}

View file

@ -29,22 +29,23 @@ package mage.cards.c;
import java.util.UUID;
import mage.MageObject;
import mage.MageObjectReference;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.abilities.effects.common.DamagePlayersEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.GetEmblemEffect;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.TargetController;
import mage.constants.Zone;
@ -120,7 +121,7 @@ class ChandraTorchOfDefianceEffect extends OneShotEffect {
controller.moveCardToExileWithInfo(card, source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true);
if (!card.getManaCost().isEmpty()) {
if (controller.chooseUse(Outcome.Benefit, "Cast the card? (You still pay the costs)", source, game) && !card.isLand()) {
exiledCardWasCast = controller.cast(card.getSpellAbility(), game, false);
exiledCardWasCast = controller.cast(card.getSpellAbility(), game, false, new MageObjectReference(source.getSourceObject(game), game));
}
}
if (!exiledCardWasCast) {

View file

@ -98,12 +98,12 @@ class CharmedPendantAbility extends ActivatedManaAbilityImpl {
}
@Override
public boolean canActivate(UUID playerId, Game game) {
public ActivationStatus canActivate(UUID playerId, Game game) {
Player player = game.getPlayer(playerId);
if (player != null && !player.isInPayManaMode()) { // while paying the costs of a spell you cant activate this
return super.canActivate(playerId, game);
}
return false;
return ActivationStatus.getFalse();
}
@Override

View file

@ -27,7 +27,11 @@
*/
package mage.cards.c;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
@ -45,10 +49,6 @@ import mage.players.Player;
import mage.target.TargetSpell;
import mage.target.common.TargetCardInHand;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
*
* @author BetaSteward
@ -56,8 +56,7 @@ import java.util.UUID;
public class Counterlash extends CardImpl {
public Counterlash(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{4}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{U}{U}");
// Counter target spell. You may cast a nonland card in your hand that shares a card type with that spell without paying its mana cost.
this.getSpellAbility().addTarget(new TargetSpell());
@ -99,7 +98,7 @@ class CounterlashEffect extends OneShotEffect {
if (player.chooseUse(Outcome.PutCardInPlay, "Cast a nonland card in your hand that shares a card type with that spell without paying its mana cost?", source, game)) {
FilterCard filter = new FilterCard();
List<Predicate<MageObject>> types = new ArrayList<>();
for (CardType type: stackObject.getCardType()) {
for (CardType type : stackObject.getCardType()) {
if (type != CardType.LAND) {
types.add(new CardTypePredicate(type));
}
@ -109,7 +108,7 @@ class CounterlashEffect extends OneShotEffect {
if (player.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) {
Card card = player.getHand().get(target.getFirstTarget(), game);
if (card != null) {
player.cast(card.getSpellAbility(), game, true);
player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
}

View file

@ -112,14 +112,15 @@ class FortifyAbility extends ActivatedAbilityImpl {
}
@Override
public boolean canActivate(UUID playerId, Game game) {
if (super.canActivate(playerId, game)) {
public ActivationStatus canActivate(UUID playerId, Game game) {
ActivationStatus activationStatus = super.canActivate(playerId, game);
if (activationStatus.canActivate()) {
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null && permanent.hasSubtype(SubType.FORTIFICATION, game)) {
return true;
return activationStatus;
}
}
return false;
return ActivationStatus.getFalse();
}
public FortifyAbility(final FortifyAbility ability) {

View file

@ -41,8 +41,8 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.game.Game;
@ -139,10 +139,10 @@ class DereviEmpyrialTacticianAbility extends ActivatedAbilityImpl {
}
@Override
public boolean canActivate(UUID playerId, Game game) {
public ActivationStatus canActivate(UUID playerId, Game game) {
Zone currentZone = game.getState().getZone(this.getSourceId());
if (currentZone == null || currentZone != Zone.COMMAND) {
return false;
return ActivationStatus.getFalse();
}
return super.canActivate(playerId, game);
}

View file

@ -29,6 +29,7 @@ package mage.cards.d;
import java.util.UUID;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
@ -47,12 +48,12 @@ import mage.players.Player;
/**
*
* @author noxx
*
*/
public class DescendantsPath extends CardImpl {
public DescendantsPath(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{G}");
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}");
// At the beginning of your upkeep, reveal the top card of your library. If it's a creature card that shares a creature type with a creature you control, you may cast that card without paying its mana cost. Otherwise, put that card on the bottom of your library.
Ability ability = new BeginningOfUpkeepTriggeredAbility(new DescendantsPathEffect(), TargetController.YOU, false);
@ -99,7 +100,7 @@ class DescendantsPathEffect extends OneShotEffect {
if (card.isCreature()) {
FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent();
boolean found = false;
for (Permanent permanent: game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) {
if (card.shareSubtypes(permanent, game)) {
found = true;
break;
@ -108,7 +109,7 @@ class DescendantsPathEffect extends OneShotEffect {
if (found) {
game.informPlayers(sourceObject.getLogName() + ": Found a creature that shares a creature type with the revealed card.");
if (controller.chooseUse(Outcome.Benefit, "Cast the card?", source, game)) {
controller.cast(card.getSpellAbility(), game, true);
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
} else {
game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " canceled casting the card.");
controller.getLibrary().putOnBottom(card, game);
@ -128,4 +129,3 @@ class DescendantsPathEffect extends OneShotEffect {
return false;
}
}

View file

@ -29,6 +29,7 @@ package mage.cards.d;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.ContinuousEffect;
@ -39,9 +40,9 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
@ -63,7 +64,7 @@ import mage.target.targetpointer.FixedTarget;
public class DiluvianPrimordial extends CardImpl {
public DiluvianPrimordial(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{U}");
this.subtype.add(SubType.AVATAR);
this.power = new MageInt(5);
@ -128,7 +129,7 @@ class DiluvianPrimordialEffect extends OneShotEffect {
Card targetCard = game.getCard(target.getFirstTarget());
if (targetCard != null) {
if (controller.chooseUse(outcome, "Cast " + targetCard.getLogName() + '?', source, game)) {
if (controller.cast(targetCard.getSpellAbility(), game, true)) {
if (controller.cast(targetCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
ContinuousEffect effect = new DiluvianPrimordialReplacementEffect();
effect.setTargetPointer(new FixedTarget(targetCard.getId(), game.getState().getZoneChangeCounter(targetCard.getId())));
game.addEffect(effect, source);

View file

@ -30,6 +30,7 @@ package mage.cards.d;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleActivatedAbility;
@ -40,8 +41,8 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.*;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
@ -56,7 +57,7 @@ public class DjinnOfWishes extends CardImpl {
private static final String ruleText = "{this} enters the battlefield with three wish counters on it";
public DjinnOfWishes(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}");
this.subtype.add(SubType.DJINN);
this.color.setBlue(true);
@ -103,8 +104,8 @@ class DjinnOfWishesEffect extends OneShotEffect {
Cards cards = new CardsImpl(card);
controller.revealCards(sourceObject.getIdName(), cards, game);
if (!controller.chooseUse(Outcome.PlayForFree, "Play " + card.getName() + " without paying its mana cost?", source, game)
|| !controller.playCard(card, game, true, true)) {
card.moveToZone(Zone.EXILED, source.getSourceId(), game, false);
|| !controller.playCard(card, game, true, true, new MageObjectReference(source.getSourceObject(game), game))) {
controller.moveCards(card, Zone.EXILED, source, game);
}
return true;
}

View file

@ -102,7 +102,7 @@ class DrainPowerEffect extends OneShotEffect {
List<Permanent> ignorePermanents = new ArrayList<>();
Map<Permanent, List<ActivatedManaAbilityImpl>> manaAbilitiesMap = new HashMap<>();
TargetPermanent target = null;
while (true) {
manaAbilitiesMap.clear();
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, targetPlayer.getId(), game)) {
@ -112,7 +112,7 @@ class DrainPowerEffect extends OneShotEffect {
for (Ability ability : permanent.getAbilities()) {
if (ability instanceof ActivatedAbility && ability.getAbilityType() == AbilityType.MANA) {
ActivatedManaAbilityImpl manaAbility = (ActivatedManaAbilityImpl) ability;
if (manaAbility != null && manaAbility.canActivate(targetPlayer.getId(), game)) {
if (manaAbility != null && manaAbility.canActivate(targetPlayer.getId(), game).canActivate()) {
// canActivate can't check for mana abilities that require a mana cost, if the payment isn't possible (Cabal Coffers etc)
// so it's necessary to filter them out manually - might be buggy in some fringe cases
for (ManaCost manaCost : manaAbility.getManaCosts()) {

View file

@ -29,6 +29,7 @@ package mage.cards.e;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
@ -40,8 +41,8 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.CardTypePredicate;
@ -57,7 +58,7 @@ import mage.target.TargetCard;
public class EliteArcanist extends CardImpl {
public EliteArcanist(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WIZARD);
@ -79,7 +80,7 @@ public class EliteArcanist extends CardImpl {
@Override
public void adjustCosts(Ability ability, Game game) {
if(ability instanceof SimpleActivatedAbility){
if (ability instanceof SimpleActivatedAbility) {
Permanent sourcePermanent = game.getPermanent(ability.getSourceId());
if (sourcePermanent != null && sourcePermanent.getImprinted() != null && !sourcePermanent.getImprinted().isEmpty()) {
Card imprintedInstant = game.getCard(sourcePermanent.getImprinted().get(0));
@ -103,7 +104,8 @@ public class EliteArcanist extends CardImpl {
class EliteArcanistImprintEffect extends OneShotEffect {
private static final FilterCard filter = new FilterCard("instant card from your hand");
static {
static {
filter.add(new CardTypePredicate(CardType.INSTANT));
}
@ -174,10 +176,10 @@ class EliteArcanistCopyEffect extends OneShotEffect {
if (controller != null) {
Card copiedCard = game.copyCard(imprintedInstant, source, source.getControllerId());
if (copiedCard != null) {
game.getExile().add(source.getSourceId(), "",copiedCard);
game.getExile().add(source.getSourceId(), "", copiedCard);
game.getState().setZone(copiedCard.getId(), Zone.EXILED);
if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) {
return controller.cast(copiedCard.getSpellAbility(), game, true);
return controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
}

View file

@ -29,6 +29,7 @@ package mage.cards.e;
import java.util.UUID;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.*;
@ -51,7 +52,7 @@ import mage.target.TargetCard;
public class EpicExperiment extends CardImpl {
public EpicExperiment(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{U}{R}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{U}{R}");
// Exile the top X cards of your library. For each instant and sorcery card with
// converted mana cost X or less among them, you may cast that card without paying
@ -105,7 +106,7 @@ class EpicExperimentEffect extends OneShotEffect {
if (controller.choose(Outcome.PlayForFree, cardsToCast, targetCard, game)) {
Card card = game.getCard(targetCard.getFirstTarget());
if (card != null) {
if (controller.cast(card.getSpellAbility(), game, true)) {
if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
cardsToCast.remove(card);
} else {
game.informPlayer(controller, "You're not able to cast " + card.getIdName() + " or you canceled the casting.");

View file

@ -32,6 +32,7 @@ import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
@ -41,8 +42,8 @@ import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.FilterCard;
@ -127,7 +128,7 @@ class EtaliPrimalStormEffect extends OneShotEffect {
cardsToCast.addAll(currentExiledCards);
boolean alreadyCast = false;
while (!cardsToCast.isEmpty()) {
if (!controller.chooseUse(Outcome.PlayForFree, "Cast a" + (alreadyCast ? "nother" : "" ) + " card exiled with " + sourceObject.getLogName() + " without paying its mana cost?", source, game)) {
if (!controller.chooseUse(Outcome.PlayForFree, "Cast a" + (alreadyCast ? "nother" : "") + " card exiled with " + sourceObject.getLogName() + " without paying its mana cost?", source, game)) {
break;
}
TargetCard targetCard = new TargetCard(1, Zone.EXILED, new FilterCard("nonland card to cast for free"));
@ -135,7 +136,7 @@ class EtaliPrimalStormEffect extends OneShotEffect {
alreadyCast = true;
Card card = game.getCard(targetCard.getFirstTarget());
if (card != null) {
if (controller.cast(card.getSpellAbility(), game, true)) {
if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
cardsToCast.remove(card);
} else {
game.informPlayer(controller, "You're not able to cast " + card.getIdName() + " or you canceled the casting.");

View file

@ -28,6 +28,7 @@
package mage.cards.e;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
@ -180,7 +181,7 @@ class EyeOfTheStormEffect1 extends OneShotEffect {
if (cardToCopy != null) {
Card copy = game.copyCard(cardToCopy, source, source.getControllerId());
if (spellController.chooseUse(outcome, "Cast " + copy.getIdName() + " without paying mana cost?", source, game)) {
spellController.cast(copy.getSpellAbility(), game, true);
spellController.cast(copy.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
}

View file

@ -29,6 +29,7 @@ package mage.cards.g;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
@ -86,7 +87,7 @@ class GalvanothEffect extends OneShotEffect {
controller.lookAtCards(source, null, new CardsImpl(card), game);
if (card.isInstant() || card.isSorcery()) {
if (controller.chooseUse(Outcome.PlayForFree, "Cast " + card.getName() + " without paying its mana cost?", source, game)) {
controller.cast(card.getSpellAbility(), game, true);
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
}

View file

@ -29,6 +29,7 @@ package mage.cards.g;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.ContinuousEffect;
@ -39,10 +40,10 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.ComparisonType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterInstantOrSorceryCard;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
@ -58,22 +59,22 @@ import mage.target.targetpointer.FixedTarget;
* @author fireshoes
*/
public class GoblinDarkDwellers extends CardImpl {
private static final FilterInstantOrSorceryCard filter = new FilterInstantOrSorceryCard("instant or sorcery card with converted mana cost 3 or less");
static {
filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 4));
}
public GoblinDarkDwellers(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}{R}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}");
this.subtype.add(SubType.GOBLIN);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// Menace
this.addAbility(new MenaceAbility());
// When Goblin Dark-Dwellers enters the battlefield, you may cast target instant or sorcery card with converted mana cost 3 or less
// from your graveyard without paying its mana cost. If that card would be put into your graveyard this turn, exile it instead.
Ability ability = new EntersBattlefieldTriggeredAbility(new GoblinDarkDwellersEffect());
@ -115,7 +116,7 @@ class GoblinDarkDwellersEffect extends OneShotEffect {
Card card = game.getCard(this.getTargetPointer().getFirst(game, source));
if (card != null) {
if (controller.chooseUse(outcome, "Cast " + card.getLogName() + '?', source, game)) {
if (controller.cast(card.getSpellAbility(), game, true)) {
if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
ContinuousEffect effect = new GoblinDarkDwellersReplacementEffect(card.getId());
effect.setTargetPointer(new FixedTarget(card.getId(), game.getState().getZoneChangeCounter(card.getId())));
game.addEffect(effect, source);

View file

@ -53,10 +53,8 @@ import mage.target.common.TargetControlledPermanent;
*/
public class GreaterGargadon extends CardImpl {
public GreaterGargadon(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{9}{R}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{9}{R}");
this.subtype.add(SubType.BEAST);
this.power = new MageInt(9);
@ -78,14 +76,14 @@ public class GreaterGargadon extends CardImpl {
}
}
class GreaterGargadonAbility extends ActivatedAbilityImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent("artifact, creature, or land");
static {
filter.add(Predicates.or(new CardTypePredicate(CardType.ARTIFACT), new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.LAND)));
}
public GreaterGargadonAbility() {
super(Zone.EXILED, new RemoveCounterSourceEffect(CounterType.TIME.createInstance()), new SacrificeTargetCost(new TargetControlledPermanent(filter)));
}
@ -100,16 +98,14 @@ class GreaterGargadonAbility extends ActivatedAbilityImpl {
}
@Override
public boolean canActivate(UUID playerId, Game game) {
public ActivationStatus canActivate(UUID playerId, Game game) {
Card card = game.getCard(this.getSourceId());
if(super.canActivate(playerId, game) && card != null && card.getCounters(game).getCount(CounterType.TIME) > 0){
return true;
if (card == null || card.getCounters(game).getCount(CounterType.TIME) == 0) {
return ActivationStatus.getFalse();
}
return false;
return super.canActivate(playerId, game);
}
@Override
public String getRule() {
return super.getRule() + " Activate this ability only if Greater Gargadon is suspended.";

View file

@ -25,19 +25,19 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.g;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.costs.common.PayEnergyCost;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
@ -82,18 +82,18 @@ public class GreenbeltRampager extends CardImpl {
@Override
public boolean apply(Game game, Ability source) {
Permanent card = game.getPermanent(source.getSourceId());
Player player = game.getPlayer(source.getControllerId());
if (card == null || player == null) return false;
if (player.getCounters().getCount(CounterType.ENERGY) > 1) {
player.getCounters().removeCounter(CounterType.ENERGY, 2);
} else {
card.moveToZone(Zone.HAND, source.getSourceId(), game, true);
player.addCounters(CounterType.ENERGY.createInstance(), game);
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
if (!new PayEnergyCost(2).pay(source, game, source.getSourceId(), source.getControllerId(), true)) {
Permanent sourceObject = source.getSourcePermanentIfItStillExists(game);
if (sourceObject != null) {
controller.moveCards(sourceObject, Zone.HAND, source, game);
controller.addCounters(CounterType.ENERGY.createInstance(), game);
}
}
return true;
}

View file

@ -29,6 +29,7 @@ package mage.cards.g;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.PutIntoGraveFromAnywhereSourceTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
@ -39,9 +40,9 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
@ -57,7 +58,7 @@ import mage.players.Player;
public class Guile extends CardImpl {
public Guile(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}{U}");
this.subtype.add(SubType.ELEMENTAL);
this.subtype.add(SubType.INCARNATION);
this.power = new MageInt(6);
@ -113,7 +114,7 @@ class GuileReplacementEffect extends ReplacementEffectImpl {
if (!spell.isCopy()) {
Card spellCard = spell.getCard();
if (spellCard != null && controller.chooseUse(Outcome.PlayForFree, "Cast " + spellCard.getIdName() + " for free?", source, game)) {
controller.playCard(spellCard, game, true, true);
controller.playCard(spellCard, game, true, true, new MageObjectReference(source.getSourceObject(game), game));
}
return true;
}

View file

@ -28,6 +28,7 @@
package mage.cards.h;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.Effect;
@ -55,7 +56,7 @@ import mage.watchers.common.CastFromHandWatcher;
public class HarnessTheStorm extends CardImpl {
public HarnessTheStorm(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}");
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
// Whenever you cast an instant or sorcery spell from your hand, you may cast target card with the same name as that spell from your graveyard.
this.addAbility(new HarnessTheStormTriggeredAbility(new HarnessTheStormEffect(),
@ -132,7 +133,7 @@ class HarnessTheStormEffect extends OneShotEffect {
Card card = controller.getGraveyard().get(getTargetPointer().getFirst(game, source), game);
if (card != null) {
if (controller.chooseUse(outcome, "Cast " + card.getIdName() + " from your graveyard?", source, game)) {
controller.cast(card.getSpellAbility(), game, false);
controller.cast(card.getSpellAbility(), game, false, new MageObjectReference(source.getSourceObject(game), game));
}
}
return true;

View file

@ -29,6 +29,7 @@ package mage.cards.h;
import java.util.UUID;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DontUntapInControllersUntapStepAllEffect;
@ -129,7 +130,7 @@ class HazoretsUndyingFuryEffect extends OneShotEffect {
if (controller.choose(Outcome.PlayForFree, cardsToCast, targetCard, game)) {
Card card = game.getCard(targetCard.getFirstTarget());
if (card != null) {
if (controller.cast(card.getSpellAbility(), game, true)) {
if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
cardsToCast.remove(card);
} else {
game.informPlayer(controller, "You're not able to cast " + card.getIdName() + " or you canceled the casting.");

View file

@ -32,21 +32,21 @@ import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@ -110,14 +110,14 @@ class HellcarverDemonEffect extends OneShotEffect {
Set<Card> currentExiledCards = new HashSet<>();
currentExiledCards.addAll(controller.getLibrary().getTopCards(game, 6));
controller.moveCardsToExile(currentExiledCards, source, game, true, source.getSourceId(), sourceObject.getIdName());
// cast the possible cards without paying the mana
Cards cardsToCast = new CardsImpl();
cardsToCast.addAll(currentExiledCards);
boolean alreadyCast = false;
while (!cardsToCast.isEmpty()
&& controller.canRespond()) {
if (!controller.chooseUse(outcome, "Cast a" + (alreadyCast ? "nother" : "" ) + " card exiled with " + sourceObject.getLogName() + " without paying its mana cost?", source, game)) {
if (!controller.chooseUse(outcome, "Cast a" + (alreadyCast ? "nother" : "") + " card exiled with " + sourceObject.getLogName() + " without paying its mana cost?", source, game)) {
break;
}
TargetCard targetCard = new TargetCard(1, Zone.EXILED, new FilterCard("nonland card to cast for free"));
@ -125,7 +125,7 @@ class HellcarverDemonEffect extends OneShotEffect {
alreadyCast = true;
Card card = game.getCard(targetCard.getFirstTarget());
if (card != null) {
if (controller.cast(card.getSpellAbility(), game, true)) {
if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
cardsToCast.remove(card);
} else {
game.informPlayer(controller, "You're not able to cast " + card.getIdName() + " or you canceled the casting.");

View file

@ -29,6 +29,7 @@ package mage.cards.h;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
@ -59,7 +60,7 @@ public class HordeOfNotions extends CardImpl {
}
public HordeOfNotions(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}{U}{B}{R}{G}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{U}{B}{R}{G}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ELEMENTAL);
this.power = new MageInt(5);
@ -110,7 +111,7 @@ class HordeOfNotionsEffect extends OneShotEffect {
if (controller != null) {
Card card = game.getCard(getTargetPointer().getFirst(game, source));
if (card != null && controller.chooseUse(outcome, "Play " + card.getName() + " from your graveyard for free?", source, game)) {
controller.playCard(card, game, true, true);
controller.playCard(card, game, true, true, new MageObjectReference(source.getSourceObject(game), game));
}
return true;
}

View file

@ -28,6 +28,7 @@
package mage.cards.i;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
@ -58,7 +59,7 @@ import org.apache.log4j.Logger;
public class IsochronScepter extends CardImpl {
public IsochronScepter(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
// Imprint - When Isochron Scepter enters the battlefield, you may exile an instant card with converted mana cost 2 or less from your hand.
this.addAbility(new EntersBattlefieldTriggeredAbility(new IsochronScepterImprintEffect(), true, "<i>Imprint &mdash; </i>"));
@ -162,7 +163,7 @@ class IsochronScepterCopyEffect extends OneShotEffect {
game.getState().setZone(copiedCard.getId(), Zone.EXILED);
if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) {
if (copiedCard.getSpellAbility() != null) {
controller.cast(copiedCard.getSpellAbility(), game, true);
controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
} else {
Logger.getLogger(IsochronScepterCopyEffect.class).error("Isochron Scepter: spell ability == null " + copiedCard.getName());
}

View file

@ -29,6 +29,7 @@ package mage.cards.i;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
@ -43,8 +44,8 @@ import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.common.FilterOwnedCard;
@ -144,7 +145,7 @@ class IzzetChemisterCastFromExileEffect extends OneShotEffect {
while (cardsToExile.count(filter, game) > 0 && controller.choose(Outcome.PlayForFree, cardsToExile, target, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
controller.cast(card.getSpellAbility(), game, true);
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
cardsToExile.remove(card);
} else {
break OuterLoop;

View file

@ -30,6 +30,7 @@ package mage.cards.j;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.LoyaltyAbility;
@ -43,9 +44,9 @@ import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.FilterCard;
@ -290,7 +291,7 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect {
while (jaceExileZone.count(filter, game) > 0 && controller.choose(Outcome.PlayForFree, jaceExileZone, target, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
if (controller.cast(card.getSpellAbility(), game, true)) {
if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
game.getExile().removeCard(card, game);
}
}

View file

@ -31,6 +31,7 @@ import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
@ -41,8 +42,8 @@ import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.common.FilterInstantOrSorceryCard;
@ -132,7 +133,7 @@ class JaceMindseekerEffect extends OneShotEffect {
&& controller.choose(outcome, cardsToCast, target, game)) {
Card card = cardsToCast.get(target.getFirstTarget(), game);
if (card != null) {
controller.cast(card.getSpellAbility(), game, true);
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
}

View file

@ -32,6 +32,7 @@ import java.util.Map;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@ -41,8 +42,8 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.WatcherScope;
import mage.filter.common.FilterInstantOrSorceryCard;
@ -155,7 +156,7 @@ class JelevaNephaliasCastEffect extends OneShotEffect {
if (controller.choose(Outcome.PlayForFree, exileZone, target, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
return controller.cast(card.getSpellAbility(), game, true);
return controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
}

View file

@ -30,6 +30,7 @@ package mage.cards.k;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
@ -39,9 +40,9 @@ import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.SearchEffect;
import mage.cards.*;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.ComparisonType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.FilterCard;
@ -60,7 +61,7 @@ import mage.util.CardUtil;
public class KahoMinamoHistorian extends CardImpl {
public KahoMinamoHistorian(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WIZARD);
@ -154,7 +155,7 @@ class KahoMinamoHistorianCastEffect extends OneShotEffect {
if (!cards.isEmpty() && controller.choose(Outcome.PlayForFree, cards, target, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
controller.cast(card.getSpellAbility(), game, true);
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
return true;

View file

@ -28,6 +28,7 @@
package mage.cards.k;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.ProwlAbility;
@ -35,8 +36,8 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.common.FilterInstantOrSorceryCard;
import mage.game.Game;
import mage.players.Player;
@ -50,12 +51,12 @@ import mage.target.common.TargetOpponent;
public class KnowledgeExploitation extends CardImpl {
public KnowledgeExploitation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.TRIBAL,CardType.SORCERY},"{5}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.TRIBAL, CardType.SORCERY}, "{5}{U}{U}");
this.subtype.add(SubType.ROGUE);
// Prowl {3}{U}
this.addAbility(new ProwlAbility(this, "{3}{U}"));
// Search target opponent's library for an instant or sorcery card. You may cast that card without paying its mana cost. Then that player shuffles their library.
this.getSpellAbility().addEffect(new KnowledgeExploitationEffect());
this.getSpellAbility().addTarget(new TargetOpponent());
@ -72,21 +73,21 @@ public class KnowledgeExploitation extends CardImpl {
}
class KnowledgeExploitationEffect extends OneShotEffect {
KnowledgeExploitationEffect() {
super(Outcome.Benefit);
this.staticText = "Search target opponent's library for an instant or sorcery card. You may cast that card without paying its mana cost. Then that player shuffles their library";
}
KnowledgeExploitationEffect(final KnowledgeExploitationEffect effect) {
super(effect);
}
@Override
public KnowledgeExploitationEffect copy() {
return new KnowledgeExploitationEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
@ -96,7 +97,7 @@ class KnowledgeExploitationEffect extends OneShotEffect {
if (controller.searchLibrary(target, game, opponent.getId())) {
Card card = opponent.getLibrary().remove(target.getFirstTarget(), game);
if (card != null) {
controller.cast(card.getSpellAbility(), game, true);
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
opponent.shuffleLibrary(source, game);

View file

@ -29,6 +29,7 @@ package mage.cards.k;
import java.util.UUID;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@ -58,7 +59,7 @@ import mage.util.CardUtil;
public class KnowledgePool extends CardImpl {
public KnowledgePool(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{6}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{6}");
// Imprint - When Knowledge Pool enters the battlefield, each player exiles the top three cards of their library
this.addAbility(new EntersBattlefieldTriggeredAbility(new KnowledgePoolEffect1(), false));
@ -177,7 +178,7 @@ class KnowledgePoolEffect2 extends OneShotEffect {
while (player.choose(Outcome.PlayForFree, game.getExile().getExileZone(exileZoneId), target, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null && !card.getId().equals(spell.getSourceId())) {
return player.cast(card.getSpellAbility(), game, true);
return player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
target.clearChosen();
}

View file

@ -29,6 +29,7 @@ package mage.cards.l;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.abilityword.KinshipAbility;
import mage.abilities.effects.OneShotEffect;
@ -36,8 +37,8 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Game;
import mage.players.Player;
@ -48,7 +49,7 @@ import mage.players.Player;
public class LeafCrownedElder extends CardImpl {
public LeafCrownedElder(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}");
this.subtype.add(SubType.TREEFOLK);
this.subtype.add(SubType.SHAMAN);
@ -88,7 +89,7 @@ class LeafCrownedElderPlayEffect extends OneShotEffect {
Card card = game.getCard(getTargetPointer().getFirst(game, source));
if (controller != null && card != null) {
if (controller.chooseUse(Outcome.PlayForFree, "Play " + card.getIdName() + " without paying its mana cost?", source, game)) {
controller.playCard(card, game, true, true);
controller.playCard(card, game, true, true, new MageObjectReference(source.getSourceObject(game), game));
}
return true;
}

View file

@ -1,4 +1,4 @@
/*
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
@ -49,7 +49,7 @@ import mage.players.Player;
public class LionsEyeDiamond extends CardImpl {
public LionsEyeDiamond(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{0}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{0}");
// Sacrifice Lion's Eye Diamond, Discard your hand: Add three mana of any one color. Activate this ability only any time you could cast an instant.
this.addAbility(new LionsEyeDiamondAbility());
@ -65,18 +65,17 @@ public class LionsEyeDiamond extends CardImpl {
}
}
class LionsEyeDiamondAbility extends ActivatedManaAbilityImpl {
public LionsEyeDiamondAbility() {
super(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(3), new SacrificeSourceCost());
this.addCost(new DiscardHandCost());
this.netMana.add(new Mana(0,0,0,0,0,0,3, 0));
this.netMana.add(new Mana(0, 0, 0, 0, 0, 0, 3, 0));
}
public LionsEyeDiamondAbility(Zone zone, Mana mana, Cost cost) {
super(zone, new BasicManaEffect(mana), cost);
}
public LionsEyeDiamondAbility(final LionsEyeDiamondAbility ability) {
@ -84,12 +83,12 @@ class LionsEyeDiamondAbility extends ActivatedManaAbilityImpl {
}
@Override
public boolean canActivate(UUID playerId, Game game) {
public ActivationStatus canActivate(UUID playerId, Game game) {
Player player = game.getPlayer(playerId);
if (player != null && !player.isInPayManaMode()) {
return super.canActivate(playerId, game);
}
return false;
return ActivationStatus.getFalse();
}
@Override
@ -102,4 +101,3 @@ class LionsEyeDiamondAbility extends ActivatedManaAbilityImpl {
return super.getRule() + " Activate this ability only any time you could cast an instant.";
}
}

View file

@ -41,7 +41,6 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
@ -207,7 +206,7 @@ class LivingLoreSacrificeEffect extends OneShotEffect {
}
if (exiledCard != null) {
if (exiledCard.getSpellAbility().canChooseTarget(game)) {
controller.cast(exiledCard.getSpellAbility(), game, true);
controller.cast(exiledCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
}

View file

@ -29,6 +29,7 @@ package mage.cards.m;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
@ -37,8 +38,8 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.filter.common.FilterNonlandCard;
import mage.game.Game;
@ -53,7 +54,7 @@ import mage.target.common.TargetCardInHand;
public class MaelstromArchangel extends CardImpl {
public MaelstromArchangel(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}{U}{B}{R}{G}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{U}{B}{R}{G}");
this.subtype.add(SubType.ANGEL);
this.power = new MageInt(5);
@ -61,10 +62,10 @@ public class MaelstromArchangel extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever Maelstrom Archangel deals combat damage to a player, you may cast a nonland card from your hand without paying its mana cost.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new MaelstromArchangelCastEffect(), false));
}
public MaelstromArchangel(final MaelstromArchangel card) {
@ -100,8 +101,8 @@ class MaelstromArchangelCastEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Target target = new TargetCardInHand(filter);
if (target.canChoose(source.getSourceId(), controller.getId(), game) &&
controller.chooseUse(outcome, "Cast a nonland card from your hand without paying its mana cost?", source, game)) {
if (target.canChoose(source.getSourceId(), controller.getId(), game)
&& controller.chooseUse(outcome, "Cast a nonland card from your hand without paying its mana cost?", source, game)) {
Card cardToCast = null;
boolean cancel = false;
while (controller.canRespond() && !cancel) {
@ -115,7 +116,7 @@ class MaelstromArchangelCastEffect extends OneShotEffect {
}
}
if (cardToCast != null) {
controller.cast(cardToCast.getSpellAbility(), game, true);
controller.cast(cardToCast.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
return true;

View file

@ -65,7 +65,7 @@ public class ManaCache extends CardImpl {
// At the beginning of each player's end step, put a charge counter on Mana Cache for each untapped land that player controls.
TriggeredAbility ability = new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of each player's end step", true, new ManaCacheEffect());
this.addAbility(ability);
// Remove a charge counter from Mana Cache: Add {C}. Any player may activate this ability but only during their turn before the end step.
this.addAbility(new ManaCacheManaAbility());
}
@ -83,6 +83,7 @@ public class ManaCache extends CardImpl {
class ManaCacheEffect extends OneShotEffect {
private static final FilterPermanent filter = new FilterControlledLandPermanent();
static {
filter.add(Predicates.not(new TappedPredicate()));
}
@ -114,7 +115,7 @@ class ManaCacheManaAbility extends ActivatedManaAbilityImpl {
public ManaCacheManaAbility() {
super(Zone.BATTLEFIELD, new BasicManaEffect(Mana.ColorlessMana(1)), new RemoveCountersSourceCost(CounterType.CHARGE.createInstance(1)));
this.netMana.add(new Mana(0,0,0,0,0,0,0,1));
this.netMana.add(new Mana(0, 0, 0, 0, 0, 0, 0, 1));
}
public ManaCacheManaAbility(final ManaCacheManaAbility ability) {
@ -122,18 +123,18 @@ class ManaCacheManaAbility extends ActivatedManaAbilityImpl {
}
@Override
public boolean canActivate(UUID playerId, Game game) {
public ActivationStatus canActivate(UUID playerId, Game game) {
if (!super.hasMoreActivationsThisTurn(game) || !(condition == null || condition.apply(game, this))) {
return false;
return ActivationStatus.getFalse();
}
Player player = game.getPlayer(playerId);
if (player != null && playerId.equals(game.getActivePlayerId()) && game.getStep().getType().isBefore(PhaseStep.END_TURN)) {
if (costs.canPay(this, sourceId, playerId, game)) {
this.setControllerId(playerId);
return true;
return ActivationStatus.getTrue();
}
}
return false;
return ActivationStatus.getFalse();
}
@Override

View file

@ -126,7 +126,7 @@ class MartyrdomActivatedAbility extends ActivatedAbilityImpl {
}
@Override
public boolean canActivate(UUID playerId, Game game) {
public ActivationStatus canActivate(UUID playerId, Game game) {
if (playerId.equals(caster)) {
Permanent permanent = game.getBattlefield().getPermanent(this.getSourceId());
if (permanent != null) {
@ -135,7 +135,7 @@ class MartyrdomActivatedAbility extends ActivatedAbilityImpl {
}
}
}
return false;
return ActivationStatus.getFalse();
}
@Override

View file

@ -29,6 +29,7 @@ package mage.cards.m;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
@ -37,8 +38,8 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
@ -52,7 +53,7 @@ import mage.target.common.TargetCardInHand;
public class MasterOfPredicaments extends CardImpl {
public MasterOfPredicaments(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}");
this.subtype.add(SubType.SPHINX);
this.power = new MageInt(4);
@ -125,7 +126,7 @@ class MasterOfPredicamentsEffect extends OneShotEffect {
// If the revealed card is a land, you can't cast it. So nothing happens
} else {
if (controller.chooseUse(outcome, "Cast " + cardFromHand.getName() + " without paying its mana cost?", source, game)) {
controller.cast(cardFromHand.getSpellAbility(), game, true);
controller.cast(cardFromHand.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}

View file

@ -28,6 +28,7 @@
package mage.cards.m;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
@ -49,6 +50,7 @@ import mage.target.common.TargetCardInOpponentsGraveyard;
public class MemoryPlunder extends CardImpl {
private static final FilterCard filter = new FilterCard("instant or sorcery card from an opponent's graveyard");
static {
filter.add(Predicates.or(
new CardTypePredicate(CardType.INSTANT),
@ -56,8 +58,7 @@ public class MemoryPlunder extends CardImpl {
}
public MemoryPlunder(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U/B}{U/B}{U/B}{U/B}");
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U/B}{U/B}{U/B}{U/B}");
// You may cast target instant or sorcery card from an opponent's graveyard without paying its mana cost.
this.getSpellAbility().addEffect(new MemoryPlunderEffect());
@ -96,8 +97,8 @@ class MemoryPlunderEffect extends OneShotEffect {
Card card = game.getCard(getTargetPointer().getFirst(game, source));
if (card != null) {
Player player = game.getPlayer(source.getControllerId());
if (player != null && player.chooseUse(Outcome.Benefit, "Cast " + card.getName() +" without paying cost?", source, game)) {
player.cast(card.getSpellAbility(), game, true);
if (player != null && player.chooseUse(Outcome.Benefit, "Cast " + card.getName() + " without paying cost?", source, game)) {
player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
return false;

View file

@ -33,9 +33,9 @@ import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.SourceHasCounterCondition;
import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.Effects;
import mage.abilities.effects.common.AttachEffect;
@ -53,13 +53,13 @@ import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
*
* @author L_J
*/
public class Merseine extends CardImpl {
public Merseine(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{U}");
this.subtype.add(SubType.AURA);
// Enchant creature
@ -74,9 +74,9 @@ public class Merseine extends CardImpl {
this.addAbility(new EntersBattlefieldAbility(effect));
// Enchanted creature doesn't untap during its controller's untap step if Merseine has a net counter on it.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousRuleModifyingEffect(new DontUntapInControllersUntapStepEnchantedEffect(),
new SourceHasCounterCondition(CounterType.NET)).setText("Enchanted creature doesn't untap during its controller's untap step if Merseine has a net counter on it")));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousRuleModifyingEffect(new DontUntapInControllersUntapStepEnchantedEffect(),
new SourceHasCounterCondition(CounterType.NET)).setText("Enchanted creature doesn't untap during its controller's untap step if Merseine has a net counter on it")));
// Pay enchanted creature's mana cost: Remove a net counter from Merseine. Any player may activate this ability, but only if he or she controls the enchanted creature.
SimpleActivatedAbility ability = new MerseineActivatedAbility();
ability.setMayActivate(TargetController.ANY);
@ -94,7 +94,7 @@ public class Merseine extends CardImpl {
}
class MerseineActivatedAbility extends SimpleActivatedAbility {
public MerseineActivatedAbility() {
super(Zone.BATTLEFIELD, new RemoveCounterSourceEffect(CounterType.NET.createInstance()), new MerseineCost());
}
@ -109,7 +109,7 @@ class MerseineActivatedAbility extends SimpleActivatedAbility {
}
@Override
public boolean canActivate(UUID playerId, Game game) {
public ActivationStatus canActivate(UUID playerId, Game game) {
Permanent sourcePermanent = game.getBattlefield().getPermanent(this.getSourceId());
if (sourcePermanent != null) {
Permanent attachedTo = game.getPermanent(sourcePermanent.getAttachedTo());
@ -117,7 +117,7 @@ class MerseineActivatedAbility extends SimpleActivatedAbility {
return super.canActivate(attachedTo.getControllerId(), game);
}
}
return false;
return ActivationStatus.getFalse();
}
@Override

View file

@ -30,6 +30,7 @@ package mage.cards.m;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
@ -37,8 +38,8 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
@ -55,7 +56,7 @@ import mage.target.common.TargetOpponent;
public class MindclawShaman extends CardImpl {
public MindclawShaman(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}");
this.subtype.add(SubType.VIASHINO);
this.subtype.add(SubType.SHAMAN);
@ -81,13 +82,13 @@ public class MindclawShaman extends CardImpl {
class MindclawShamanEffect extends OneShotEffect {
private static final FilterCard filter = new FilterCard("instant or sorcery card");
static {
filter.add(Predicates.or(
new CardTypePredicate(CardType.INSTANT),
new CardTypePredicate(CardType.SORCERY)));
new CardTypePredicate(CardType.INSTANT),
new CardTypePredicate(CardType.SORCERY)));
}
public MindclawShamanEffect() {
super(Outcome.Discard);
this.staticText = "target opponent reveals their hand. You may cast an instant or sorcery card from it without paying its mana cost";
@ -106,7 +107,7 @@ class MindclawShamanEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player targetOpponent = game.getPlayer(source.getFirstTarget());
MageObject sourceObject = source.getSourceObject(game);
if (targetOpponent != null && sourceObject != null) {
if (targetOpponent != null && sourceObject != null) {
if (!targetOpponent.getHand().isEmpty()) {
targetOpponent.revealCards(sourceObject.getName(), targetOpponent.getHand(), game);
Player controller = game.getPlayer(source.getControllerId());
@ -117,9 +118,9 @@ class MindclawShamanEffect extends OneShotEffect {
Card chosenCard = targetOpponent.getHand().get(target.getFirstTarget(), game);
if (chosenCard != null) {
if (controller.chooseUse(Outcome.Benefit, "Cast the chosen card?", source, game)) {
controller.cast(chosenCard.getSpellAbility(), game, true);
controller.cast(chosenCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
} else {
game.informPlayers(sourceObject.getLogName() +": " + controller.getLogName() + " canceled casting the card.");
game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " canceled casting the card.");
}
}
}
@ -129,4 +130,4 @@ class MindclawShamanEffect extends OneShotEffect {
}
return false;
}
}
}

View file

@ -29,6 +29,7 @@ package mage.cards.m;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
@ -39,8 +40,8 @@ import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterNonlandCard;
import mage.game.Game;
@ -54,7 +55,7 @@ import mage.target.TargetCard;
public class MindleechMass extends CardImpl {
public MindleechMass(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{U}{B}{B}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{B}{B}");
this.subtype.add(SubType.HORROR);
this.power = new MageInt(6);
@ -62,7 +63,7 @@ public class MindleechMass extends CardImpl {
// Trample
this.addAbility(TrampleAbility.getInstance());
// Whenever Mindleech Mass deals combat damage to a player, you may look at that player's hand. If you do, you may cast a nonland card in it without paying that card's mana cost.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new MindleechMassEffect(), true, true));
}
@ -96,18 +97,18 @@ class MindleechMassEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source));
Player you = game.getPlayer(source.getControllerId());
if (opponent != null && you != null) {
Player controller = game.getPlayer(source.getControllerId());
if (opponent != null && controller != null) {
Cards cardsInHand = new CardsImpl();
cardsInHand.addAll(opponent.getHand());
opponent.revealCards("Opponents hand", cardsInHand, game);
if (!cardsInHand.isEmpty()
&& !cardsInHand.getCards(new FilterNonlandCard(), game).isEmpty()) {
TargetCard target = new TargetCard(1, Zone.HAND, new FilterNonlandCard());
if (you.chooseTarget(Outcome.PlayForFree, cardsInHand, target, source, game)) {
if (controller.chooseTarget(Outcome.PlayForFree, cardsInHand, target, source, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
you.cast(card.getSpellAbility(), game, true);
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
}

View file

@ -30,6 +30,7 @@ package mage.cards.m;
import java.util.List;
import java.util.UUID;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastOpponentTriggeredAbility;
import mage.abilities.effects.Effect;
@ -55,7 +56,7 @@ import mage.watchers.common.SpellsCastWatcher;
public class MindsDilation extends CardImpl {
public MindsDilation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{5}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{5}{U}{U}");
// Whenever an opponent casts their first spell each turn, that player exiles the top card of their library. If it's a nonland card,
// you may cast it without paying its mana cost.
@ -138,7 +139,7 @@ class MindsDilationEffect extends OneShotEffect {
if (card != null && opponent.moveCards(card, Zone.EXILED, source, game)) {
if (!card.isLand()) {
if (controller.chooseUse(outcome, "Cast " + card.getLogName() + " without paying its mana cost from exile?", source, game)) {
controller.cast(card.getSpellAbility(), game, true);
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
}

View file

@ -29,6 +29,7 @@ package mage.cards.m;
import java.util.Set;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
@ -106,7 +107,7 @@ class MizzixsMasteryEffect extends OneShotEffect {
Card cardCopy = game.copyCard(card, source, source.getControllerId());
if (cardCopy.getSpellAbility().canChooseTarget(game)
&& controller.chooseUse(outcome, "Cast copy of " + card.getName() + " without paying its mana cost?", source, game)) {
controller.cast(cardCopy.getSpellAbility(), game, true);
controller.cast(cardCopy.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
}
@ -150,7 +151,7 @@ class MizzixsMasteryOverloadEffect extends OneShotEffect {
if (controller.choose(outcome, copiedCards, targetCard, game)) {
Card selectedCard = game.getCard(targetCard.getFirstTarget());
if (selectedCard != null && selectedCard.getSpellAbility().canChooseTarget(game)) {
if (controller.cast(selectedCard.getSpellAbility(), game, true)) {
if (controller.cast(selectedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
copiedCards.remove(selectedCard);
}
}

View file

@ -28,6 +28,7 @@
package mage.cards.o;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfDrawTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
@ -126,7 +127,7 @@ class OmenMachineEffect2 extends OneShotEffect {
if (card.isLand()) {
player.moveCards(card, Zone.BATTLEFIELD, source, game);
} else {
player.cast(card.getSpellAbility(), game, true);
player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
return true;

View file

@ -29,6 +29,7 @@ package mage.cards.o;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@ -41,8 +42,8 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.filter.common.FilterInstantOrSorceryCard;
import mage.game.Game;
@ -57,7 +58,7 @@ import mage.target.common.TargetCardInHand;
public class OracleOfBones extends CardImpl {
public OracleOfBones(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{R}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}");
this.subtype.add(SubType.MINOTAUR);
this.subtype.add(SubType.SHAMAN);
@ -107,8 +108,8 @@ class OracleOfBonesCastEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Target target = new TargetCardInHand(filter);
if (target.canChoose(source.getSourceId(), controller.getId(), game) &&
controller.chooseUse(outcome, "Cast an instant or sorcery card from your hand without paying its mana cost?", source, game)) {
if (target.canChoose(source.getSourceId(), controller.getId(), game)
&& controller.chooseUse(outcome, "Cast an instant or sorcery card from your hand without paying its mana cost?", source, game)) {
Card cardToCast = null;
boolean cancel = false;
while (controller.canRespond() && !cancel) {
@ -122,7 +123,7 @@ class OracleOfBonesCastEffect extends OneShotEffect {
}
}
if (cardToCast != null) {
controller.cast(cardToCast.getSpellAbility(), game, true);
controller.cast(cardToCast.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
return true;

View file

@ -28,6 +28,7 @@
package mage.cards.p;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
@ -57,7 +58,7 @@ import mage.util.CardUtil;
public class PanopticMirror extends CardImpl {
public PanopticMirror(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{5}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
// Imprint - {X}, {tap}: You may exile an instant or sorcery card with converted mana cost X from your hand.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PanopticMirrorExileEffect(), new VariableManaCost());
@ -114,7 +115,7 @@ class PanopticMirrorExileEffect extends OneShotEffect {
if (card != null) {
card.moveToExile(CardUtil.getCardExileZoneId(game, source), "Panoptic Mirror", source.getSourceId(), game);
Permanent PanopticMirror = game.getPermanent(source.getSourceId());
if(PanopticMirror != null){
if (PanopticMirror != null) {
PanopticMirror.imprint(card.getId(), game);
}
return true;
@ -149,31 +150,29 @@ class PanopticMirrorCastEffect extends OneShotEffect {
}
if (PanopticMirror != null && PanopticMirror.getImprinted() != null && !PanopticMirror.getImprinted().isEmpty() && controller != null) {
CardsImpl cards = new CardsImpl();
for(UUID uuid : PanopticMirror.getImprinted()){
for (UUID uuid : PanopticMirror.getImprinted()) {
Card card = game.getCard(uuid);
if(card != null){
if(card.isSplitCard()){
cards.add(((SplitCard)card).getLeftHalfCard());
cards.add(((SplitCard)card).getRightHalfCard());
}
else{
if (card != null) {
if (card.isSplitCard()) {
cards.add(((SplitCard) card).getLeftHalfCard());
cards.add(((SplitCard) card).getRightHalfCard());
} else {
cards.add(card);
}
}
}
Card cardToCopy;
if(cards.size() == 1){
if (cards.size() == 1) {
cardToCopy = cards.getCards(game).iterator().next();
}
else{
} else {
TargetCard target = new TargetCard(1, Zone.EXILED, new FilterCard("card to copy"));
controller.choose(Outcome.Copy, cards, target, game);
cardToCopy = cards.get(target.getFirstTarget(), game);
}
if(cardToCopy != null){
if (cardToCopy != null) {
Card copy = game.copyCard(cardToCopy, source, source.getControllerId());
if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) {
return controller.cast(copy.getSpellAbility(), game, true);
return controller.cast(copy.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
return true;

View file

@ -30,6 +30,7 @@ package mage.cards.p;
import java.util.EnumSet;
import java.util.UUID;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
@ -155,7 +156,7 @@ class PossibilityStormEffect extends OneShotEffect {
&& !card.isLand()
&& card.getSpellAbility().canChooseTarget(game)) {
if (spellController.chooseUse(Outcome.PlayForFree, "Cast " + card.getLogName() + " without paying cost?", source, game)) {
spellController.cast(card.getSpellAbility(), game, true);
spellController.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}

View file

@ -29,6 +29,7 @@ package mage.cards.q;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbilityImpl;
import mage.abilities.SpellAbility;
@ -52,7 +53,7 @@ import mage.players.Player;
public class QasaliAmbusher extends CardImpl {
public QasaliAmbusher(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}{W}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{W}");
this.subtype.add(SubType.CAT);
this.subtype.add(SubType.WARRIOR);
@ -102,18 +103,16 @@ class QasaliAmbusherAbility extends ActivatedAbilityImpl {
}
@Override
public boolean canActivate(UUID playerId, Game game) {
if (super.canActivate(playerId, game)) {
if (!game.getBattlefield().getActivePermanents(filterPlains, this.getControllerId(), this.getSourceId(), game).isEmpty()
&& !game.getBattlefield().getActivePermanents(filterForest, this.getControllerId(), this.getSourceId(), game).isEmpty()) {
for (CombatGroup group : game.getCombat().getGroups()) {
if (getControllerId().equals(group.getDefenderId())) {
return true;
}
public ActivationStatus canActivate(UUID playerId, Game game) {
if (!game.getBattlefield().getActivePermanents(filterPlains, this.getControllerId(), this.getSourceId(), game).isEmpty()
&& !game.getBattlefield().getActivePermanents(filterForest, this.getControllerId(), this.getSourceId(), game).isEmpty()) {
for (CombatGroup group : game.getCombat().getGroups()) {
if (getControllerId().equals(group.getDefenderId())) {
return super.canActivate(playerId, game);
}
}
}
return false;
return ActivationStatus.getFalse();
}
@Override
@ -151,7 +150,7 @@ class QasaliAmbusherEffect extends OneShotEffect {
if (controller != null) {
SpellAbility spellAbility = card.getSpellAbility();
spellAbility.clear();
return controller.cast(spellAbility, game, true);
return controller.cast(spellAbility, game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
return false;

View file

@ -30,6 +30,7 @@ package mage.cards.r;
import java.util.List;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.Effect;
@ -39,8 +40,8 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.game.Game;
@ -56,7 +57,7 @@ import mage.watchers.common.SpellsCastWatcher;
public class RashmiEternitiesCrafter extends CardImpl {
public RashmiEternitiesCrafter(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{U}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ELF);
this.subtype.add(SubType.DRUID);
@ -146,7 +147,7 @@ class RashmiEternitiesCrafterEffect extends OneShotEffect {
|| card.isLand()
|| card.getConvertedManaCost() >= (int) cmcObject
|| !controller.chooseUse(Outcome.PlayForFree, "Cast " + card.getName() + " without paying its mana cost?", source, game)
|| !controller.cast(card.getSpellAbility(), game, true)) {
|| !controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
controller.moveCards(card, Zone.HAND, source, game);
}
}

View file

@ -28,6 +28,7 @@
package mage.cards.r;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
@ -51,8 +52,7 @@ import mage.target.common.TargetOpponent;
public class ReversalOfFortune extends CardImpl {
public ReversalOfFortune(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{R}{R}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{R}{R}");
// Target opponent reveals their hand. You may copy an instant or sorcery card in it. If you do, you may cast the copy without paying its mana cost.
this.getSpellAbility().addEffect(new ReversalOfFortuneEffect());
@ -69,7 +69,6 @@ public class ReversalOfFortune extends CardImpl {
}
}
class ReversalOfFortuneEffect extends OneShotEffect {
public ReversalOfFortuneEffect() {
@ -88,28 +87,27 @@ class ReversalOfFortuneEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Player opponent = game.getPlayer(source.getFirstTarget());
if (controller != null && opponent != null) {
// Target opponent reveals their hand
Cards revealedCards = new CardsImpl();
revealedCards.addAll(opponent.getHand());
Cards revealedCards = new CardsImpl();
revealedCards.addAll(opponent.getHand());
opponent.revealCards("Reveal", revealedCards, game);
//You may copy an instant or sorcery card in it
TargetCard target = new TargetCard(1, Zone.HAND, new FilterInstantOrSorceryCard());
TargetCard target = new TargetCard(1, Zone.HAND, new FilterInstantOrSorceryCard());
target.setRequired(false);
if (controller.choose(outcome, revealedCards, target, game)) {
Card card = revealedCards.get((UUID) target.getFirstTarget(), game);
//If you do, you may cast the copy without paying its mana cost
if(card != null){
if (card != null) {
Card copiedCard = game.copyCard(card, source, source.getControllerId());
if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) {
controller.cast(copiedCard.getSpellAbility(), game, true);
controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
else{
} else {
return false;
}
}
@ -117,4 +115,4 @@ class ReversalOfFortuneEffect extends OneShotEffect {
}
return false;
}
}
}

View file

@ -87,12 +87,12 @@ class RhysticCaveManaAbility extends ActivatedManaAbilityImpl {
}
@Override
public boolean canActivate(UUID playerId, Game game) {
public ActivationStatus canActivate(UUID playerId, Game game) {
Player player = game.getPlayer(playerId);
if (player != null && !player.isInPayManaMode()) {
return super.canActivate(playerId, game);
}
return false;
return ActivationStatus.getFalse();
}
@Override

View file

@ -28,6 +28,7 @@
package mage.cards.s;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
@ -157,7 +158,7 @@ class ShellOfTheLastKappaCastEffect extends OneShotEffect {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
game.getExile().removeCard(card, game);
return controller.cast(card.getSpellAbility(), game, true);
return controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
}

View file

@ -29,6 +29,7 @@ package mage.cards.s;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
@ -40,8 +41,8 @@ import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterNonlandCard;
import mage.game.Game;
@ -55,7 +56,7 @@ import mage.target.TargetCard;
public class SilentBladeOni extends CardImpl {
public SilentBladeOni(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{U}{B}{B}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}{B}{B}");
this.subtype.add(SubType.DEMON);
this.subtype.add(SubType.NINJA);
@ -107,7 +108,7 @@ class SilentBladeOniEffect extends OneShotEffect {
if (controller.chooseTarget(outcome, cardsInHand, target, source, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
controller.cast(card.getSpellAbility(), game, true);
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}

View file

@ -31,6 +31,7 @@ import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
@ -42,9 +43,9 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.ComparisonType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.FilterSpell;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.ExileZone;
@ -69,7 +70,7 @@ public class SpellQueller extends CardImpl {
}
public SpellQueller(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{U}");
this.subtype.add(SubType.SPIRIT);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
@ -160,13 +161,13 @@ class SpellQuellerLeavesEffect extends OneShotEffect {
if (exile != null) { // null is valid if source left battlefield before enters the battlefield effect resolved
Card card = null;
Set<Card> exiledCards = exile.getCards(game);
if (exiledCards != null && !exiledCards.isEmpty()) {
card = exiledCards.iterator().next();
if (exiledCards != null && !exiledCards.isEmpty()) {
card = exiledCards.iterator().next();
if (card != null) {
Player cardOwner = game.getPlayer(card.getOwnerId());
if (cardOwner != null) {
if (cardOwner.chooseUse(Outcome.PlayForFree, "Cast " + card.getLogName() + " without paying cost?", source, game)) {
cardOwner.cast(card.getSpellAbility(), game, true);
cardOwner.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
}

View file

@ -28,6 +28,7 @@
package mage.cards.s;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@ -38,8 +39,8 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.CardTypePredicate;
@ -60,12 +61,12 @@ import org.apache.log4j.Logger;
public class Spellbinder extends CardImpl {
public Spellbinder(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
this.subtype.add(SubType.EQUIPMENT);
// Imprint - When Spellbinder enters the battlefield, you may exile an instant card from your hand.
this.addAbility(new EntersBattlefieldTriggeredAbility(new SpellbinderImprintEffect(), true, "<i>Imprint &mdash; </i>"));
// Whenever equipped creature deals combat damage to a player, you may copy the exiled card. If you do, you may cast the copy without paying its mana cost.
this.addAbility(new SpellbinderTriggeredAbility());
@ -197,7 +198,7 @@ class SpellbinderCopyEffect extends OneShotEffect {
game.getState().setZone(copiedCard.getId(), Zone.EXILED);
if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) {
if (copiedCard.getSpellAbility() != null) {
controller.cast(copiedCard.getSpellAbility(), game, true);
controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
} else {
Logger.getLogger(SpellbinderCopyEffect.class).error("Spellbinder: spell ability == null " + copiedCard.getName());
}
@ -210,4 +211,4 @@ class SpellbinderCopyEffect extends OneShotEffect {
}
return false;
}
}
}

View file

@ -28,6 +28,7 @@
package mage.cards.s;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CounterTargetEffect;
@ -103,7 +104,7 @@ class SpellshiftEffect extends OneShotEffect {
}
spellController.revealCards(source, cardsToReveal, game);
if (toCast != null && spellController.chooseUse(outcome, "Cast " + toCast.getLogName() + " without paying its mana cost?", source, game)) {
spellController.cast(toCast.getSpellAbility(), game, true);
spellController.cast(toCast.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
spellController.shuffleLibrary(source, game);
return true;

View file

@ -28,6 +28,7 @@
package mage.cards.s;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileSpellEffect;
@ -65,7 +66,7 @@ public class Spelltwine extends CardImpl {
}
public Spelltwine(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{5}{U}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{U}");
// Exile target instant or sorcery card from your graveyard and target instant or sorcery card from an opponent's graveyard. Copy those cards. Cast the copies if able without paying their mana costs. Exile Spelltwine.
this.getSpellAbility().addEffect(new SpelltwineEffect());
@ -109,18 +110,19 @@ class SpelltwineEffect extends OneShotEffect {
controller.moveCards(cardTwo, Zone.EXILED, source, game);
}
boolean castCardOne = true;
MageObjectReference mor = new MageObjectReference(source.getSourceObject(game), game);
if (cardOne != null && controller.chooseUse(Outcome.Neutral, "Cast the copy of " + cardOne.getName() + " first?", source, game)) {
Card copyOne = game.copyCard(cardOne, source, controller.getId());
controller.cast(copyOne.getSpellAbility(), game, true);
controller.cast(copyOne.getSpellAbility(), game, true, mor);
castCardOne = false;
}
if (cardTwo != null) {
Card copyTwo = game.copyCard(cardTwo, source, controller.getId());
controller.cast(copyTwo.getSpellAbility(), game, true);
controller.cast(copyTwo.getSpellAbility(), game, true, mor);
}
if (cardOne != null && castCardOne) {
Card copyOne = game.copyCard(cardOne, source, controller.getId());
controller.cast(copyOne.getSpellAbility(), game, true);
controller.cast(copyOne.getSpellAbility(), game, true, mor);
}
return true;
}

View file

@ -28,6 +28,7 @@
package mage.cards.s;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@ -55,20 +56,21 @@ import mage.util.CardUtil;
* @author emerald000
*/
public class SpellweaverHelix extends CardImpl {
private static final FilterCard filter = new FilterCard("sorcery cards from a single graveyard");
static {
filter.add(new CardTypePredicate(CardType.SORCERY));
}
public SpellweaverHelix(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
// Imprint - When Spellweaver Helix enters the battlefield, you may exile two target sorcery cards from a single graveyard.
Ability ability = new EntersBattlefieldTriggeredAbility(new SpellweaverHelixImprintEffect(), true, "Imprint &mdash; ");
ability.addTarget(new TargetCardInASingleGraveyard(2, 2, filter));
this.addAbility(ability);
// Whenever a player casts a card, if it has the same name as one of the cards exiled with Spellweaver Helix, you may copy the other. If you do, you may cast the copy without paying its mana cost.
this.addAbility(new SpellweaverHelixTriggeredAbility());
}
@ -84,21 +86,21 @@ public class SpellweaverHelix extends CardImpl {
}
class SpellweaverHelixImprintEffect extends OneShotEffect {
SpellweaverHelixImprintEffect() {
super(Outcome.Exile);
this.staticText = "you may exile two target sorcery cards from a single graveyard";
}
SpellweaverHelixImprintEffect(final SpellweaverHelixImprintEffect effect) {
super(effect);
}
@Override
public SpellweaverHelixImprintEffect copy() {
return new SpellweaverHelixImprintEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
@ -120,20 +122,20 @@ class SpellweaverHelixImprintEffect extends OneShotEffect {
}
class SpellweaverHelixTriggeredAbility extends TriggeredAbilityImpl {
SpellweaverHelixTriggeredAbility() {
super(Zone.BATTLEFIELD, new SpellweaverHelixCastEffect(), false);
}
SpellweaverHelixTriggeredAbility(final SpellweaverHelixTriggeredAbility ability) {
super(ability);
}
@Override
public SpellweaverHelixTriggeredAbility copy() {
return new SpellweaverHelixTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SPELL_CAST;
@ -169,7 +171,7 @@ class SpellweaverHelixTriggeredAbility extends TriggeredAbilityImpl {
}
return false;
}
@Override
public String getRule() {
return "Whenever a player casts a card, if it has the same name as one of the cards exiled with Spellweaver Helix, you may copy the other. If you do, you may cast the copy without paying its mana cost.";
@ -177,28 +179,28 @@ class SpellweaverHelixTriggeredAbility extends TriggeredAbilityImpl {
}
class SpellweaverHelixCastEffect extends OneShotEffect {
private String spellName = "";
SpellweaverHelixCastEffect() {
super(Outcome.Benefit);
this.staticText = "you may copy the other. If you do, you may cast the copy without paying its mana cost";
}
SpellweaverHelixCastEffect(final SpellweaverHelixCastEffect effect) {
super(effect);
this.spellName = effect.spellName;
}
@Override
public SpellweaverHelixCastEffect copy() {
return new SpellweaverHelixCastEffect(this);
}
public void setSpellName(String spellName) {
this.spellName = spellName;
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
@ -211,12 +213,11 @@ class SpellweaverHelixCastEffect extends OneShotEffect {
if (card != null) {
if (!foundSpellWithSameName && card.getName().equals(spellName)) {
foundSpellWithSameName = true;
}
else {
} else {
if (controller.chooseUse(Outcome.Copy, "Copy " + card.getIdName(), source, game)) {
Card copy = game.copyCard(card, source, source.getControllerId());
if (controller.chooseUse(Outcome.PlayForFree, "Cast " + copy.getIdName() + " without paying its mana cost?", source, game)) {
controller.cast(copy.getSpellAbility(), game, true);
controller.cast(copy.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
}

View file

@ -28,6 +28,7 @@
package mage.cards.s;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
@ -119,7 +120,7 @@ class SpellweaverVoluteEffect extends OneShotEffect {
game.getState().setZone(copiedCard.getId(), Zone.GRAVEYARD);
if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) {
if (copiedCard.getSpellAbility() != null) {
controller.cast(copiedCard.getSpellAbility(), game, true);
controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
if (controller.moveCards(enchantedCard, Zone.EXILED, source, game)) {
FilterCard filter = new FilterCard("instant card in a graveyard");

View file

@ -29,6 +29,7 @@ package mage.cards.s;
import java.util.UUID;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.Effect;
@ -156,7 +157,7 @@ class SunbirdsInvocationEffect extends OneShotEffect {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
if (controller.chooseUse(Outcome.Benefit, "Cast " + card.getLogName() + " without paying its mana cost?", source, game)) {
controller.cast(card.getSpellAbility(), game, true);
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
cards.remove(card);
}
}

View file

@ -28,6 +28,7 @@
package mage.cards.s;
import java.util.UUID;
import mage.MageObjectReference;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
@ -44,10 +45,10 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.ComparisonType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicate;
@ -133,7 +134,7 @@ class SunforgerEffect extends OneShotEffect {
UUID targetId = target.getFirstTarget();
Card card = game.getCard(targetId);
if (card != null) {
controller.cast(card.getSpellAbility(), game, true);
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
}

View file

@ -30,6 +30,7 @@ package mage.cards.t;
import java.util.Set;
import java.util.UUID;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.condition.common.SpellMasteryCondition;
import mage.abilities.effects.OneShotEffect;
@ -55,7 +56,7 @@ import mage.target.common.TargetOpponent;
public class TalentOfTheTelepath extends CardImpl {
public TalentOfTheTelepath(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}{U}");
// Target opponent reveals the top seven cards of their library. You may cast an instant or sorcery card from among them without paying its mana cost. Then that player puts the rest into their graveyard.
// <i>Spell mastery</i> &mdash; If there are two or more instant and/or sorcery cards in your graveyard, you may cast up to two revealed instant and/or sorcery cards instead of one.
@ -127,7 +128,7 @@ class TalentOfTheTelepathEffect extends OneShotEffect {
&& controller.choose(outcome, cardsToCast, target, game)) {
Card card = cardsToCast.get(target.getFirstTarget(), game);
if (card != null) {
controller.cast(card.getSpellAbility(), game, true);
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
numberOfSpells--;
cardsToCast.remove(card);
allCards.remove(card);

View file

@ -28,6 +28,7 @@
package mage.cards.t;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.ControlledCreaturesDealCombatDamagePlayerTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
@ -96,7 +97,7 @@ class ThunderbladeChargeCastEffect extends OneShotEffect {
if (controller != null
&& sourceCard != null
&& Zone.GRAVEYARD == game.getState().getZone(sourceCard.getId())) {
controller.cast(sourceCard.getSpellAbility(), game, true);
controller.cast(sourceCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
return true;
}
return false;

View file

@ -29,6 +29,7 @@ package mage.cards.t;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.ContinuousEffect;
@ -39,9 +40,9 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.CardTypePredicate;
@ -115,7 +116,7 @@ class TorrentialGearhulkEffect extends OneShotEffect {
Card card = game.getCard(this.getTargetPointer().getFirst(game, source));
if (card != null && card.getSpellAbility() != null) {
if (controller.chooseUse(outcome, "Cast " + card.getLogName() + '?', source, game)) {
if (controller.cast(card.getSpellAbility(), game, true)) {
if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
ContinuousEffect effect = new TorrentialGearhulkReplacementEffect(card.getId());
effect.setTargetPointer(new FixedTarget(card.getId(), game.getState().getZoneChangeCounter(card.getId())));
game.addEffect(effect, source);

View file

@ -29,6 +29,7 @@ package mage.cards.t;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.DiesCreatureTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
@ -115,7 +116,7 @@ class ToshiroUmezawaEffect extends OneShotEffect {
if (controller != null) {
Card card = game.getCard(getTargetPointer().getFirst(game, source));
if (card != null) {
controller.cast(card.getSpellAbility(), game, false);
controller.cast(card.getSpellAbility(), game, false, new MageObjectReference(source.getSourceObject(game), game));
game.addEffect(new ToshiroUmezawaReplacementEffect(card.getId()), source);
}
}

View file

@ -29,6 +29,7 @@ package mage.cards.t;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.DiesTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
@ -97,7 +98,7 @@ class TreasureKeeperEffect extends OneShotEffect {
}
controller.revealCards(source, toReveal, game);
if (nonLandCard != null && controller.chooseUse(outcome, "Cast " + nonLandCard.getLogName() + "without paying its mana cost?", source, game)) {
controller.cast(nonLandCard.getSpellAbility(), game, true);
controller.cast(nonLandCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
toReveal.remove(nonLandCard);
}
controller.putCardsOnBottomOfLibrary(toReveal, game, source, false);

View file

@ -29,6 +29,7 @@ package mage.cards.t;
import java.util.List;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
@ -121,7 +122,7 @@ class TwinningGlassEffect extends OneShotEffect {
Card chosenCard = game.getCard(target.getFirstTarget());
if (chosenCard != null) {
if (controller.chooseUse(outcome, "Cast the card without paying mana cost?", source, game)) {
return controller.cast(chosenCard.getSpellAbility(), game, true);
return controller.cast(chosenCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
}

View file

@ -28,6 +28,7 @@
package mage.cards.u;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
@ -126,7 +127,7 @@ class UnexpectedResultEffect extends OneShotEffect {
}
} else {
if (controller.chooseUse(outcome, new StringBuilder("Cast ").append(card.getName()).append(" without paying its mana cost?").toString(), source, game)) {
return controller.cast(card.getSpellAbility(), game, true);
return controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
return true;

View file

@ -29,6 +29,7 @@ package mage.cards.v;
import java.util.UUID;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.*;
@ -110,7 +111,7 @@ class VillainousWealthEffect extends OneShotEffect {
while (cardsToExile.count(filter, game) > 0 && controller.choose(Outcome.PlayForFree, cardsToExile, target, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
controller.cast(card.getSpellAbility(), game, true);
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
cardsToExile.remove(card);
} else {
break OuterLoop;

View file

@ -89,14 +89,14 @@ class WellOfKnowledgeConditionalActivatedAbility extends ActivatedAbilityImpl {
}
@Override
public boolean canActivate(UUID playerId, Game game) {
public ActivationStatus canActivate(UUID playerId, Game game) {
if (condition.apply(game, this)
&& costs.canPay(this, sourceId, playerId, game)
&& game.getActivePlayerId().equals(playerId)) {
this.activatorId = playerId;
return true;
return ActivationStatus.getTrue();
}
return false;
return ActivationStatus.getFalse();
}

View file

@ -29,6 +29,7 @@ package mage.cards.w;
import java.util.UUID;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
@ -96,7 +97,7 @@ class WildEvocationEffect extends OneShotEffect {
player.moveCards(card, Zone.BATTLEFIELD, source, game);
} else if (card.getSpellAbility() != null
&& card.getSpellAbility().getTargets().canChoose(player.getId(), game)) {
player.cast(card.getSpellAbility(), game, true);
player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
} else {
game.informPlayers(GameLog.getColoredObjectName(card) + " can't be cast now by " + player.getLogName());
}

View file

@ -29,6 +29,7 @@ package mage.cards.w;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.AttacksAndIsNotBlockedTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
@ -37,8 +38,8 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.filter.common.FilterInstantOrSorceryCard;
import mage.game.Game;
@ -104,7 +105,7 @@ class WildfireEternalCastEffect extends OneShotEffect {
controller.chooseTarget(outcome, target, source, game);
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
controller.cast(card.getSpellAbility(), game, true);
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
return true;

View file

@ -29,6 +29,7 @@ package mage.cards.w;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
@ -119,7 +120,7 @@ class WrexialEffect extends OneShotEffect {
if (controller.chooseTarget(Outcome.PlayForFree, target, source, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
controller.cast(card.getSpellAbility(), game, true);
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
game.addEffect(new WrexialReplacementEffect(card.getId()), source);
}
}

View file

@ -39,6 +39,8 @@ public class FiendOfTheShadowsTest extends CardTestPlayerBase {
@Test
public void testCardExile1() {
// Whenever Fiend of the Shadows deals combat damage to a player, that player exiles a card from their hand. You may play that card for as long as it remains exiled.
// Sacrifice a Human: Regenerate Fiend of the Shadows.
addCard(Zone.BATTLEFIELD, playerA, "Fiend of the Shadows");
removeAllCardsFromHand(playerB);
addCard(Zone.HAND, playerB, "Swamp");

View file

@ -495,7 +495,7 @@ public class TestPlayer implements Player {
List<Permanent> manaPermsWithCost = computerPlayer.getAvailableManaProducersWithCost(game);
for (Permanent perm : manaPermsWithCost) {
for (ActivatedManaAbilityImpl manaAbility : perm.getAbilities().getAvailableActivatedManaAbilities(Zone.BATTLEFIELD, game)) {
if (manaAbility.toString().startsWith(groups[0]) && manaAbility.canActivate(computerPlayer.getId(), game)) {
if (manaAbility.toString().startsWith(groups[0]) && manaAbility.canActivate(computerPlayer.getId(), game).canActivate()) {
Ability newManaAbility = manaAbility.copy();
computerPlayer.activateAbility((ActivatedAbility) newManaAbility, game);
actions.remove(action);
@ -1598,13 +1598,13 @@ public class TestPlayer implements Player {
}
@Override
public boolean cast(SpellAbility ability, Game game, boolean noMana) {
return computerPlayer.cast(ability, game, noMana);
public boolean cast(SpellAbility ability, Game game, boolean noMana, MageObjectReference reference) {
return computerPlayer.cast(ability, game, noMana, reference);
}
@Override
public boolean playCard(Card card, Game game, boolean noMana, boolean ignoreTiming) {
return computerPlayer.playCard(card, game, noMana, ignoreTiming);
public boolean playCard(Card card, Game game, boolean noMana, boolean ignoreTiming, MageObjectReference reference) {
return computerPlayer.playCard(card, game, noMana, ignoreTiming, reference);
}
@Override

View file

@ -30,6 +30,7 @@ package org.mage.test.stub;
import java.io.Serializable;
import java.util.*;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.*;
import mage.abilities.costs.AlternativeSourceCosts;
import mage.abilities.costs.Cost;
@ -564,7 +565,7 @@ public class PlayerStub implements Player {
}
@Override
public boolean cast(SpellAbility ability, Game game, boolean noMana) {
public boolean cast(SpellAbility ability, Game game, boolean noMana, MageObjectReference reference) {
return false;
}
@ -619,7 +620,7 @@ public class PlayerStub implements Player {
}
@Override
public boolean playCard(Card card, Game game, boolean noMana, boolean checkTiming) {
public boolean playCard(Card card, Game game, boolean noMana, boolean checkTiming, MageObjectReference reference) {
return false;
}

View file

@ -157,7 +157,7 @@ public class AbilitiesImpl<T extends Ability> extends ArrayList<T> implements Ab
return stream()
.filter(ability -> ability instanceof ActivatedManaAbilityImpl)
.filter(ability -> ability.getZone().match(zone))
.filter(ability -> (((ActivatedManaAbilityImpl) ability).canActivate(ability.getControllerId(), game)))
.filter(ability -> (((ActivatedManaAbilityImpl) ability).canActivate(ability.getControllerId(), game).canActivate()))
.map(ability -> (ActivatedManaAbilityImpl) ability)
.collect(Collectors.toCollection(AbilitiesImpl::new));

View file

@ -28,6 +28,7 @@
package mage.abilities;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.mana.ManaOptions;
import mage.constants.TargetController;
import mage.game.Game;
@ -38,9 +39,36 @@ import mage.game.Game;
*/
public interface ActivatedAbility extends Ability {
boolean canActivate(UUID playerId, Game game);
final public class ActivationStatus {
public void setMayActivate(TargetController mayActivate);
private final boolean canActivate;
private final MageObjectReference permittingObject;
public ActivationStatus(boolean canActivate, MageObjectReference permittingObject) {
this.canActivate = canActivate;
this.permittingObject = permittingObject;
}
public boolean canActivate() {
return canActivate;
}
public MageObjectReference getPermittingObject() {
return permittingObject;
}
public static ActivationStatus getFalse() {
return new ActivationStatus(false, null);
}
public static ActivationStatus getTrue() {
return new ActivationStatus(true, null);
}
}
ActivationStatus canActivate(UUID playerId, Game game); // has to return a reference to the permitting ability/source
void setMayActivate(TargetController mayActivate);
/**
* Returns the minimal possible cost for what the ability can be activated

View file

@ -29,6 +29,7 @@ package mage.abilities;
import java.util.UUID;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.condition.Condition;
import mage.abilities.costs.Cost;
import mage.abilities.costs.Costs;
@ -177,38 +178,39 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa
public abstract ActivatedAbilityImpl copy();
@Override
public boolean canActivate(UUID playerId, Game game) {
public ActivationStatus canActivate(UUID playerId, Game game) {
//20091005 - 602.2
if (!(hasMoreActivationsThisTurn(game) && (condition == null || condition.apply(game, this)))) {
return false;
return ActivationStatus.getFalse();
}
switch (mayActivate) {
case ANY:
break;
case NOT_YOU:
if (controlsAbility(playerId, game)) {
return false;
return ActivationStatus.getFalse();
}
break;
case TEAM:
if (game.getPlayer(controllerId).hasOpponent(playerId, game)) {
return false;
return ActivationStatus.getFalse();
}
break;
case OPPONENT:
if (!game.getPlayer(controllerId).hasOpponent(playerId, game)) {
return false;
return ActivationStatus.getFalse();
}
break;
case OWNER:
Permanent permanent = game.getPermanent(getSourceId());
if (!permanent.getOwnerId().equals(playerId)) {
return false;
return ActivationStatus.getFalse();
}
break;
case YOU:
if (!controlsAbility(playerId, game)) {
return false;
return ActivationStatus.getFalse();
}
break;
case CONTROLLER_ATTACHED_TO:
@ -219,17 +221,17 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa
break;
}
}
return false;
return ActivationStatus.getFalse();
}
//20091005 - 602.5d/602.5e
if (timing == TimingRule.INSTANT || game.canPlaySorcery(playerId)
|| null != game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.ACTIVATE_AS_INSTANT, this, controllerId, game)) {
MageObjectReference permittingObject = game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.ACTIVATE_AS_INSTANT, this, controllerId, game);
if (timing == TimingRule.INSTANT || game.canPlaySorcery(playerId) || null != permittingObject) {
if (costs.canPay(this, sourceId, playerId, game) && canChooseTarget(game)) {
this.activatorId = playerId;
return true;
return new ActivationStatus(true, permittingObject);
}
}
return false;
return ActivationStatus.getFalse();
}
@Override
@ -310,10 +312,12 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa
return false;
}
@Override
public void setMaxActivationsPerTurn(int maxActivationsPerTurn) {
this.maxActivationsPerTurn = maxActivationsPerTurn;
}
@Override
public int getMaxActivationsPerTurn(Game game) {
return maxActivationsPerTurn;
}

View file

@ -28,6 +28,7 @@
package mage.abilities;
import java.util.UUID;
import mage.MageObjectReference;
import mage.constants.AbilityType;
import mage.constants.AsThoughEffectType;
import mage.constants.Zone;
@ -50,13 +51,13 @@ public class PlayLandAbility extends ActivatedAbilityImpl {
}
@Override
public boolean canActivate(UUID playerId, Game game) {
if (!controlsAbility(playerId, game)
&& null == game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, playerId, game)) {
return false;
public ActivationStatus canActivate(UUID playerId, Game game) {
MageObjectReference permittingObject = game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, null, playerId, game);
if (!controlsAbility(playerId, game) && null == permittingObject) {
return ActivationStatus.getFalse();
}
//20091005 - 114.2a
return game.getActivePlayerId().equals(playerId) && game.getPlayer(playerId).canPlayLand() && game.canPlaySorcery(playerId);
return new ActivationStatus(game.getActivePlayerId().equals(playerId) && game.getPlayer(playerId).canPlayLand() && game.canPlaySorcery(playerId), permittingObject);
}
@Override

View file

@ -29,6 +29,7 @@ package mage.abilities;
import java.util.UUID;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.costs.Cost;
import mage.abilities.costs.VariableCost;
import mage.abilities.costs.mana.ManaCost;
@ -91,48 +92,49 @@ public class SpellAbility extends ActivatedAbilityImpl {
}
@Override
public boolean canActivate(UUID playerId, Game game) {
public ActivationStatus canActivate(UUID playerId, Game game) {
if (null != game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.CAST_AS_INSTANT, this, playerId, game) // check this first to allow Offering in main phase
|| this.spellCanBeActivatedRegularlyNow(playerId, game)) {
if (spellAbilityType == SpellAbilityType.SPLIT || spellAbilityType == SpellAbilityType.SPLIT_AFTERMATH) {
return false;
return ActivationStatus.getFalse();
}
// fix for Gitaxian Probe and casting opponent's spells
if (null == game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, playerId, game)) {
MageObjectReference permittingSource = game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, null, playerId, game);
if (permittingSource == null) {
Card card = game.getCard(sourceId);
if (!(card != null && card.getOwnerId().equals(playerId))) {
return false;
return ActivationStatus.getFalse();
}
}
// Check if rule modifying events prevent to cast the spell in check playable mode
if (this.isCheckPlayableMode()) {
if (game.getContinuousEffects().preventedByRuleModification(
GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, this.getId(), this.getSourceId(), playerId), this, game, true)) {
return false;
return ActivationStatus.getFalse();
}
}
// Alternate spell abilities (Flashback, Overload) can't be cast with no mana to pay option
if (getSpellAbilityType() == SpellAbilityType.BASE_ALTERNATE) {
Player player = game.getPlayer(playerId);
if (player != null && getSourceId().equals(player.getCastSourceIdWithAlternateMana())) {
return false;
return ActivationStatus.getFalse();
}
}
if (costs.canPay(this, sourceId, controllerId, game)) {
if (getSpellAbilityType() == SpellAbilityType.SPLIT_FUSED) {
SplitCard splitCard = (SplitCard) game.getCard(getSourceId());
if (splitCard != null) {
return (splitCard.getLeftHalfCard().getSpellAbility().canChooseTarget(game)
&& splitCard.getRightHalfCard().getSpellAbility().canChooseTarget(game));
return new ActivationStatus(splitCard.getLeftHalfCard().getSpellAbility().canChooseTarget(game)
&& splitCard.getRightHalfCard().getSpellAbility().canChooseTarget(game), null);
}
return false;
return ActivationStatus.getFalse();
} else {
return canChooseTarget(game);
return new ActivationStatus(canChooseTarget(game), permittingSource);
}
}
}
return false;
return ActivationStatus.getFalse();
}
@Override

View file

@ -1,16 +1,16 @@
/*
* 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
@ -20,18 +20,17 @@
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities.common;
import java.util.UUID;
import mage.constants.Zone;
import mage.abilities.ActivatedAbilityImpl;
import mage.abilities.effects.common.PassEffect;
import mage.constants.Zone;
import mage.game.Game;
/**
@ -55,8 +54,8 @@ public class PassAbility extends ActivatedAbilityImpl {
}
@Override
public boolean canActivate(UUID playerId, Game game) {
return true;
public ActivationStatus canActivate(UUID playerId, Game game) {
return ActivationStatus.getTrue();
}
@Override

View file

@ -63,7 +63,7 @@ public class TapSourceCost extends CostImpl {
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null) {
return !permanent.isTapped()
&& (permanent.canTap() || null != game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.ACTIVATE_HASTE, controllerId, game));
&& (permanent.canTap() || null != game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.ACTIVATE_HASTE, ability, controllerId, game));
}
return false;
}

View file

@ -62,7 +62,7 @@ public class UntapSourceCost extends CostImpl {
public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null) {
return permanent.isTapped() && (permanent.canTap() || null != game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.ACTIVATE_HASTE, controllerId, game));
return permanent.isTapped() && (permanent.canTap() || null != game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.ACTIVATE_HASTE, ability, controllerId, game));
}
return false;
}

View file

@ -82,9 +82,9 @@ public class ConditionalGainActivatedAbility extends ActivatedAbilityImpl {
}
@Override
public boolean canActivate(UUID playerId, Game game) {
public ActivationStatus canActivate(UUID playerId, Game game) {
if (!condition.apply(game, this)) {
return false;
return ActivationStatus.getFalse();
}
return super.canActivate(playerId, game);
}

View file

@ -32,6 +32,7 @@ import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.*;
import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect;
import mage.abilities.effects.common.continuous.CommanderReplacementEffect;
@ -502,19 +503,6 @@ public class ContinuousEffects implements Serializable {
return spliceEffects;
}
/**
*
* @param objectId
* @param type
* @param controllerId
* @param game
* @return sourceId of the permitting effect if any exists otherwise returns
* null
*/
public UUID asThough(UUID objectId, AsThoughEffectType type, UUID controllerId, Game game) {
return asThough(objectId, type, null, controllerId, game);
}
/**
*
* @param objectId
@ -525,17 +513,17 @@ public class ContinuousEffects implements Serializable {
* @return sourceId of the permitting effect if any exists otherwise returns
* null
*/
public UUID asThough(UUID objectId, AsThoughEffectType type, Ability affectedAbility, UUID controllerId, Game game) {
public MageObjectReference asThough(UUID objectId, AsThoughEffectType type, Ability affectedAbility, UUID controllerId, Game game) {
List<AsThoughEffect> asThoughEffectsList = getApplicableAsThoughEffects(type, game);
for (AsThoughEffect effect : asThoughEffectsList) {
Set<Ability> abilities = asThoughEffectsMap.get(type).getAbility(effect.getId());
for (Ability ability : abilities) {
if (affectedAbility == null) {
if (effect.applies(objectId, ability, controllerId, game)) {
return ability.getSourceId();
return new MageObjectReference(ability.getSourceObject(game), game);
}
} else if (effect.applies(objectId, affectedAbility, ability, game)) {
return ability.getSourceId();
return new MageObjectReference(ability.getSourceObject(game), game);
}
}
}

View file

@ -28,6 +28,7 @@
package mage.abilities.effects.common;
import java.util.Set;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
@ -88,7 +89,7 @@ public class CastCardFromOutsideTheGameEffect extends OneShotEffect {
}
return false;
}
Cards filteredCards = new CardsImpl();
for (Card card : filtered) {
filteredCards.add(card.getId());
@ -98,7 +99,7 @@ public class CastCardFromOutsideTheGameEffect extends OneShotEffect {
if (player.choose(Outcome.Benefit, filteredCards, target, game)) {
Card card = player.getSideboard().get(target.getFirstTarget(), game);
if (card != null) {
player.cast(card.getSpellAbility(), game, true);
player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
}
@ -106,4 +107,4 @@ public class CastCardFromOutsideTheGameEffect extends OneShotEffect {
return true;
}
}
}

View file

@ -28,6 +28,7 @@
package mage.abilities.effects.common;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
@ -151,7 +152,7 @@ class CipherStoreEffect extends OneShotEffect {
}
ability.getEffects().remove(cipherEffect);
if (ability instanceof SpellAbility) {
controller.cast(ability, game, true);
controller.cast(ability, game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}

View file

@ -27,6 +27,8 @@
*/
package mage.abilities.effects.common;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
@ -36,8 +38,6 @@ import mage.game.Game;
import mage.players.Player;
import mage.util.CardUtil;
import java.util.UUID;
/**
* @author LevelX2
*
@ -82,7 +82,7 @@ public class HideawayPlayEffect extends OneShotEffect {
}
}
if (!controller.playCard(card, game, true, true)) {
if (!controller.playCard(card, game, true, true, new MageObjectReference(source.getSourceObject(game), game))) {
if (card.getZoneChangeCounter(game) == zcc) {
card.setFaceDown(true, game);
}

View file

@ -24,16 +24,16 @@
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
*/
package mage.abilities.effects.common;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import mage.target.Target;
@ -62,7 +62,7 @@ public class PlayTargetWithoutPayingManaEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Card target = (Card) game.getObject(source.getFirstTarget());
if (controller != null && target != null) {
return controller.cast(target.getSpellAbility(), game, true);
return controller.cast(target.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
return false;
}
@ -74,8 +74,7 @@ public class PlayTargetWithoutPayingManaEffect extends OneShotEffect {
Target target = mode.getTargets().get(0);
if (mode.getTargets().get(0).getZone() == Zone.HAND) {
sb.append("you may put ").append(target.getTargetName()).append(" from your hand onto the battlefield");
}
else {
} else {
sb.append("you may cast target ").append(target.getTargetName()).append(" without paying its mana cost");
}
}

View file

@ -27,6 +27,7 @@
*/
package mage.abilities.effects.common.cost;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
@ -101,7 +102,7 @@ public class CastWithoutPayingManaCostEffect extends OneShotEffect {
}
}
if (cardToCast != null) {
controller.cast(cardToCast.getSpellAbility(), game, true);
controller.cast(cardToCast.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
return true;

View file

@ -38,12 +38,15 @@ import mage.choices.ChoiceColor;
import mage.game.Game;
import mage.players.Player;
import mage.util.CardUtil;
import org.apache.log4j.Logger;
/**
* @author noxx
*/
public class AddConditionalManaOfAnyColorEffect extends ManaEffect {
private static final Logger logger = Logger.getLogger(AddConditionalManaOfAnyColorEffect.class);
private final DynamicValue amount;
private final ConditionalManaBuilder manaBuilder;
private final boolean oneChoice;
@ -87,8 +90,13 @@ public class AddConditionalManaOfAnyColorEffect extends ManaEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
checkToFirePossibleEvents(getMana(game, source), game, source);
controller.getManaPool().addMana(getMana(game, source), game, source);
Mana mana = getMana(game, source);
if (mana != null) {
checkToFirePossibleEvents(mana, game, source);
controller.getManaPool().addMana(mana, game, source);
} else {
logger.error("There was no mana created: " + source.getSourceObject(game).getName() + " - Ability: " + source.getRule());
}
return true;
}
return false;

Some files were not shown because too many files have changed in this diff Show more