mirror of
https://github.com/correl/mage.git
synced 2024-11-25 03:00:11 +00:00
Game: fixed rare bugs in some cards after rollback or cancel actions:
* Cumulative upkeep cost - fixed that it can lost payed state (cards: Aboroth, Karplusan Minotaur, Psychic Vortex, Sheltering Ancient); * Effects - fixed that it can lost selected targets or other settings (cards: Citadel of Pain, Crimson Honor Guard, Curfew, Leveler, Mana Cache, Monsoon, Paradigm Shift, Saprazzan Bailiff); * Exile all cards from graveyard ability - fixed that it can lost targets (example: Agent of Erebos); * Melee ability - fixed that it can lost targets (example: Adriana, Captain of the Guard).
This commit is contained in:
parent
82cc789534
commit
07ddad6e48
60 changed files with 163 additions and 224 deletions
|
@ -48,6 +48,10 @@ class AborothCost extends CostImpl {
|
|||
this.text = "Put a -1/-1 counter on Aboroth";
|
||||
}
|
||||
|
||||
private AborothCost(final AborothCost cost) {
|
||||
super(cost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
|
@ -66,6 +70,6 @@ class AborothCost extends CostImpl {
|
|||
|
||||
@Override
|
||||
public AborothCost copy() {
|
||||
return new AborothCost();
|
||||
return new AborothCost(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ public final class AdamaroFirstToDesire extends CardImpl {
|
|||
}
|
||||
|
||||
class MostCardsInOpponentsHandCount implements DynamicValue {
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
int maxCards = 0;
|
||||
|
@ -59,7 +60,7 @@ class MostCardsInOpponentsHandCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public MostCardsInOpponentsHandCount copy() {
|
||||
return new MostCardsInOpponentsHandCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ class AlphaStatusDynamicValue implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public AlphaStatusDynamicValue copy() {
|
||||
return new AlphaStatusDynamicValue();
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ class AnathemancerCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public AnathemancerCount copy() {
|
||||
return new AnathemancerCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ class AncientOozePowerToughnessValue implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public AncientOozePowerToughnessValue copy() {
|
||||
return new AncientOozePowerToughnessValue();
|
||||
}
|
||||
|
||||
|
|
|
@ -59,12 +59,11 @@ class HalfForestsDownCount implements DynamicValue {
|
|||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
int amount = game.getBattlefield().countAll(filter, sourceAbility.getControllerId(), game) / 2;
|
||||
return amount;
|
||||
return game.getBattlefield().countAll(filter, sourceAbility.getControllerId(), game) / 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public HalfForestsDownCount copy() {
|
||||
return new HalfForestsDownCount();
|
||||
}
|
||||
|
||||
|
@ -94,7 +93,7 @@ class HalfForestsUpCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public HalfForestsUpCount copy() {
|
||||
return new HalfForestsUpCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ class BurdenOfGreedCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public BurdenOfGreedCount copy() {
|
||||
return new BurdenOfGreedCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ class SourceControllerLostLifeCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public SourceControllerLostLifeCount copy() {
|
||||
return new SourceControllerLostLifeCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -27,10 +27,10 @@ public final class CitadelOfPain extends CardImpl {
|
|||
public CitadelOfPain(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
|
||||
|
||||
// At the beginning of each player's end step, Citadel of Pain deals X damage to that player, where X is the number of untapped lands they control.
|
||||
TriggeredAbility triggered = new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE,
|
||||
"beginning of the end step", true,
|
||||
new CitadelOfPainEffect());
|
||||
// At the beginning of each player's end step, Citadel of Pain deals X damage to that player, where X is the number of untapped lands they control.
|
||||
this.addAbility(triggered);
|
||||
}
|
||||
|
||||
|
@ -48,11 +48,6 @@ class CitadelOfPainEffect extends OneShotEffect {
|
|||
|
||||
private static final FilterPermanent filter = new FilterControlledLandPermanent();
|
||||
|
||||
@Override
|
||||
public String getText(Mode mode) {
|
||||
return "{this} deals X damage to that player, where X is the number of untapped lands they control.";
|
||||
}
|
||||
|
||||
static {
|
||||
filter.add(TappedPredicate.UNTAPPED);
|
||||
}
|
||||
|
@ -61,8 +56,8 @@ class CitadelOfPainEffect extends OneShotEffect {
|
|||
super(Outcome.Damage);
|
||||
}
|
||||
|
||||
public CitadelOfPainEffect(Outcome outcome) {
|
||||
super(outcome);
|
||||
private CitadelOfPainEffect(final CitadelOfPainEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -77,7 +72,12 @@ class CitadelOfPainEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Effect copy() {
|
||||
return new CitadelOfPainEffect();
|
||||
public CitadelOfPainEffect copy() {
|
||||
return new CitadelOfPainEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Mode mode) {
|
||||
return "{this} deals X damage to that player, where X is the number of untapped lands they control.";
|
||||
}
|
||||
}
|
|
@ -56,12 +56,6 @@ public final class ConquerorsFlail extends CardImpl {
|
|||
|
||||
class ConquerorsFlailColorCount implements DynamicValue {
|
||||
|
||||
public ConquerorsFlailColorCount() {
|
||||
}
|
||||
|
||||
public ConquerorsFlailColorCount(final ConquerorsFlailColorCount dynamicValue) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
Player controller = game.getPlayer(sourceAbility.getControllerId());
|
||||
|
@ -105,7 +99,7 @@ class ConquerorsFlailColorCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public ConquerorsFlailColorCount copy() {
|
||||
return new ConquerorsFlailColorCount();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,9 +62,8 @@ class CrimsonHonorGuardEffect extends OneShotEffect {
|
|||
super(Outcome.Damage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Effect copy() {
|
||||
return new CrimsonHonorGuardEffect();
|
||||
private CrimsonHonorGuardEffect(final CrimsonHonorGuardEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -84,4 +83,9 @@ class CrimsonHonorGuardEffect extends OneShotEffect {
|
|||
public String getText(Mode mode) {
|
||||
return "{this} deals 4 damage to that player unless they control a commander";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CrimsonHonorGuardEffect copy() {
|
||||
return new CrimsonHonorGuardEffect(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,10 @@ class CurfewEffect extends OneShotEffect {
|
|||
staticText = "Each player returns a creature they control to its owner's hand";
|
||||
}
|
||||
|
||||
private CurfewEffect(final CurfewEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
game.informPlayers("Each player returns a creature they control to its owner's hand");
|
||||
|
@ -64,7 +68,7 @@ class CurfewEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Effect copy() {
|
||||
return new CurfewEffect();
|
||||
public CurfewEffect copy() {
|
||||
return new CurfewEffect(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,17 +51,3 @@ public final class DemonicAppetite extends CardImpl {
|
|||
return new DemonicAppetite(this);
|
||||
}
|
||||
}
|
||||
|
||||
class DemonicAppetiteEffect extends SacrificeTargetEffect {
|
||||
|
||||
DemonicAppetiteEffect() {
|
||||
super();
|
||||
staticText = "sacrifice a creature";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DemonicAppetiteEffect copy() {
|
||||
return new DemonicAppetiteEffect();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ class DyingWishAttachedPermanentPowerCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public DyingWishAttachedPermanentPowerCount copy() {
|
||||
return new DyingWishAttachedPermanentPowerCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ class CurrentHourCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public CurrentHourCount copy() {
|
||||
return new CurrentHourCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ class EmissaryOfDespairCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public EmissaryOfDespairCount copy() {
|
||||
return new EmissaryOfDespairCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ class HalfZombiesCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public HalfZombiesCount copy() {
|
||||
return new HalfZombiesCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ class CardsInControllerLibraryCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public CardsInControllerLibraryCount copy() {
|
||||
return new CardsInControllerLibraryCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -134,6 +134,10 @@ class KarplusanMinotaurCost extends CostImpl {
|
|||
this.text = "Flip a coin";
|
||||
}
|
||||
|
||||
private KarplusanMinotaurCost(final KarplusanMinotaurCost cost) {
|
||||
super(cost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
|
@ -158,7 +162,7 @@ class KarplusanMinotaurCost extends CostImpl {
|
|||
|
||||
@Override
|
||||
public KarplusanMinotaurCost copy() {
|
||||
return new KarplusanMinotaurCost();
|
||||
return new KarplusanMinotaurCost(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ class AllCountersCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public AllCountersCount copy() {
|
||||
return new AllCountersCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -50,9 +50,8 @@ class LevelerExileLibraryEffect extends OneShotEffect {
|
|||
staticText = "exile all cards from your library";
|
||||
}
|
||||
|
||||
@Override
|
||||
public LevelerExileLibraryEffect copy() {
|
||||
return new LevelerExileLibraryEffect();
|
||||
private LevelerExileLibraryEffect(final LevelerExileLibraryEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,4 +65,9 @@ class LevelerExileLibraryEffect extends OneShotEffect {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LevelerExileLibraryEffect copy() {
|
||||
return new LevelerExileLibraryEffect(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ class LordOfExtinctionDynamicCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public LordOfExtinctionDynamicCount copy() {
|
||||
return new LordOfExtinctionDynamicCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ class CreaturesControlledByChosenPlayer implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public CreaturesControlledByChosenPlayer copy() {
|
||||
return new CreaturesControlledByChosenPlayer();
|
||||
}
|
||||
|
||||
|
|
|
@ -66,9 +66,13 @@ class ManaCacheEffect extends OneShotEffect {
|
|||
this.staticText = "put a charge counter on {this} for each untapped land that player controls";
|
||||
}
|
||||
|
||||
private ManaCacheEffect(final ManaCacheEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Effect copy() {
|
||||
return new ManaCacheEffect();
|
||||
public ManaCacheEffect copy() {
|
||||
return new ManaCacheEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -44,12 +44,11 @@ public final class MercadiasDownfall extends CardImpl {
|
|||
return new MercadiasDownfall(this);
|
||||
}
|
||||
|
||||
class DefendersNonBasicLandCount implements DynamicValue {
|
||||
|
||||
UUID defenderId;
|
||||
static class DefendersNonBasicLandCount implements DynamicValue {
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
UUID defenderId;
|
||||
for (CombatGroup group : game.getCombat().getGroups()) {
|
||||
defenderId = group.getDefenderId();
|
||||
if (group.isDefenderIsPlaneswalker()) {
|
||||
|
@ -67,7 +66,7 @@ public final class MercadiasDownfall extends CardImpl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public DefendersNonBasicLandCount copy() {
|
||||
return new DefendersNonBasicLandCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -56,8 +56,8 @@ class MonsoonEffect extends OneShotEffect {
|
|||
this.staticText = "tap all untapped Islands that player controls and {this} deals X damage to the player, where X is the number of Islands tapped this way";
|
||||
}
|
||||
|
||||
public MonsoonEffect(Outcome outcome) {
|
||||
super(outcome);
|
||||
private MonsoonEffect(final MonsoonEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -76,7 +76,7 @@ class MonsoonEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Effect copy() {
|
||||
return new MonsoonEffect();
|
||||
public MonsoonEffect copy() {
|
||||
return new MonsoonEffect(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ class AttachedPermanentPowerCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public AttachedPermanentPowerCount copy() {
|
||||
return new AttachedPermanentPowerCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ class CardsInChosenPlayerHandCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public CardsInChosenPlayerHandCount copy() {
|
||||
return new CardsInChosenPlayerHandCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ class AnathemancerCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public AnathemancerCount copy() {
|
||||
return new AnathemancerCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ public final class ParadigmShift extends CardImpl {
|
|||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{U}");
|
||||
|
||||
// Exile all cards from your library. Then shuffle your graveyard into your library.
|
||||
this.getSpellAbility().addEffect(new ExileLibraryEffect());
|
||||
this.getSpellAbility().addEffect(new ParadigmShiftExileLibraryEffect());
|
||||
}
|
||||
|
||||
private ParadigmShift(final ParadigmShift card) {
|
||||
|
@ -38,16 +38,20 @@ public final class ParadigmShift extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class ExileLibraryEffect extends OneShotEffect {
|
||||
class ParadigmShiftExileLibraryEffect extends OneShotEffect {
|
||||
|
||||
public ExileLibraryEffect() {
|
||||
public ParadigmShiftExileLibraryEffect() {
|
||||
super(Outcome.Exile);
|
||||
staticText = "Exile all cards from your library. Then shuffle your graveyard into your library";
|
||||
}
|
||||
|
||||
private ParadigmShiftExileLibraryEffect(final ParadigmShiftExileLibraryEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExileLibraryEffect copy() {
|
||||
return new ExileLibraryEffect();
|
||||
public ParadigmShiftExileLibraryEffect copy() {
|
||||
return new ParadigmShiftExileLibraryEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -53,7 +53,7 @@ class TargetPermanentPowerPlusToughnessCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public TargetPermanentPowerPlusToughnessCount copy() {
|
||||
return new TargetPermanentPowerPlusToughnessCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ class GreatestPowerCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public GreatestPowerCount copy() {
|
||||
return new GreatestPowerCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.p;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -58,6 +57,10 @@ class PsychicVortexCost extends CostImpl {
|
|||
this.text = "Draw a card";
|
||||
}
|
||||
|
||||
private PsychicVortexCost(final PsychicVortexCost cost) {
|
||||
super(cost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
|
@ -77,6 +80,6 @@ class PsychicVortexCost extends CostImpl {
|
|||
|
||||
@Override
|
||||
public PsychicVortexCost copy() {
|
||||
return new PsychicVortexCost();
|
||||
return new PsychicVortexCost(this);
|
||||
}
|
||||
}
|
|
@ -59,6 +59,7 @@ public final class RighteousAuthority extends CardImpl {
|
|||
|
||||
|
||||
class CardsInEnchantedControllerHandCount implements DynamicValue {
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
if (sourceAbility != null) {
|
||||
|
@ -77,7 +78,7 @@ class CardsInEnchantedControllerHandCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public CardsInEnchantedControllerHandCount copy() {
|
||||
return new CardsInEnchantedControllerHandCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ class TargetPlayerCardsInHandCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public TargetPlayerCardsInHandCount copy() {
|
||||
return new TargetPlayerCardsInHandCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -64,9 +64,13 @@ class SaprazzanBailiffEffect extends OneShotEffect {
|
|||
staticText = "exile all artifact and enchantment cards from all graveyards";
|
||||
}
|
||||
|
||||
private SaprazzanBailiffEffect(final SaprazzanBailiffEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SaprazzanBailiffEffect copy() {
|
||||
return new SaprazzanBailiffEffect();
|
||||
return new SaprazzanBailiffEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -72,7 +72,7 @@ class CardsInTargetOpponentsGraveyardCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public CardsInTargetOpponentsGraveyardCount copy() {
|
||||
return new CardsInTargetOpponentsGraveyardCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,10 @@ class ShelteringAncientCost extends CostImpl {
|
|||
this.text = "Put a +1/+1 counter on a creature an opponent controls";
|
||||
}
|
||||
|
||||
private ShelteringAncientCost(final ShelteringAncientCost cost) {
|
||||
super(cost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
|
@ -86,6 +90,6 @@ class ShelteringAncientCost extends CostImpl {
|
|||
|
||||
@Override
|
||||
public ShelteringAncientCost copy() {
|
||||
return new ShelteringAncientCost();
|
||||
return new ShelteringAncientCost(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ class SoullessOneDynamicCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public SoullessOneDynamicCount copy() {
|
||||
return new SoullessOneDynamicCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ class GreatestPowerCountCreatureYouControl implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public GreatestPowerCountCreatureYouControl copy() {
|
||||
return new GreatestPowerCountCreatureYouControl();
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ class OtherSpellsCastThisTurnCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public OtherSpellsCastThisTurnCount copy() {
|
||||
return new OtherSpellsCastThisTurnCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ class OpponentNoncombatLostLifeCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public OpponentNoncombatLostLifeCount copy() {
|
||||
return new OpponentNoncombatLostLifeCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ class TappedCreaturesControlledByTargetCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public TappedCreaturesControlledByTargetCount copy() {
|
||||
return new TappedCreaturesControlledByTargetCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ class TerraRavagerLandCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public TerraRavagerLandCount copy() {
|
||||
return new TerraRavagerLandCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ class ChromaUmbraStalkerCount implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
public ChromaUmbraStalkerCount copy() {
|
||||
return new ChromaUmbraStalkerCount();
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,15 @@ public final class UrborgJustice extends CardImpl {
|
|||
|
||||
class UrborgJusticeDynamicValue implements DynamicValue {
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
CreaturesDiedWatcher watcher = game.getState().getWatcher(CreaturesDiedWatcher.class);
|
||||
if (watcher != null) {
|
||||
return watcher.getAmountOfCreaturesDiedThisTurnByOwner(sourceAbility.getControllerId());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UrborgJusticeDynamicValue copy() {
|
||||
return new UrborgJusticeDynamicValue();
|
||||
|
@ -58,13 +67,4 @@ class UrborgJusticeDynamicValue implements DynamicValue {
|
|||
public String getMessage() {
|
||||
return "creature put into your graveyard from the battlefield this turn";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
CreaturesDiedWatcher watcher = game.getState().getWatcher(CreaturesDiedWatcher.class);
|
||||
if (watcher != null) {
|
||||
return watcher.getAmountOfCreaturesDiedThisTurnByOwner(sourceAbility.getControllerId());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.w;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -40,7 +39,7 @@ public final class WolfOfDevilsBreach extends CardImpl {
|
|||
Costs toPay = new CostsImpl<>();
|
||||
toPay.add(new ManaCostsImpl<>("{1}{R}"));
|
||||
toPay.add(new DiscardCardCost());
|
||||
Ability ability = new AttacksTriggeredAbility(new DoIfCostPaid(new DamageTargetEffect(new WolfOfDevilsBreachDiscardCostCardConvertedMana()), toPay,
|
||||
Ability ability = new AttacksTriggeredAbility(new DoIfCostPaid(new DamageTargetEffect(new WolfOfDevilsBreachDiscardCostCardConvertedManaCount()), toPay,
|
||||
"Pay {1}{R} and discard a card to let {this} do damage to target creature or planeswalker equal to the discarded card's mana value?", true), false,
|
||||
"Whenever {this} attacks, you may pay {1}{R} and discard a card. If you do, {this} deals damage to target creature or planeswalker "
|
||||
+ "equal to the discarded card's mana value.");
|
||||
|
@ -58,7 +57,7 @@ public final class WolfOfDevilsBreach extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class WolfOfDevilsBreachDiscardCostCardConvertedMana implements DynamicValue {
|
||||
class WolfOfDevilsBreachDiscardCostCardConvertedManaCount implements DynamicValue {
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
|
@ -84,8 +83,8 @@ class WolfOfDevilsBreachDiscardCostCardConvertedMana implements DynamicValue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public WolfOfDevilsBreachDiscardCostCardConvertedMana copy() {
|
||||
return new WolfOfDevilsBreachDiscardCostCardConvertedMana();
|
||||
public WolfOfDevilsBreachDiscardCostCardConvertedManaCount copy() {
|
||||
return new WolfOfDevilsBreachDiscardCostCardConvertedManaCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -687,7 +687,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
CardInfo cardInfo = CardRepository.instance.findCard(cardName);
|
||||
Card card = cardInfo != null ? cardInfo.getCard() : null;
|
||||
if (card == null) {
|
||||
throw new AssertionError("Couldn't find a card: " + cardName);
|
||||
throw new AssertionError("Couldn't find a card in db: " + cardName);
|
||||
}
|
||||
cards.add(card);
|
||||
|
||||
|
|
|
@ -3,11 +3,12 @@ package mage.abilities.costs;
|
|||
import mage.abilities.Ability;
|
||||
import mage.game.Game;
|
||||
import mage.target.Targets;
|
||||
import mage.util.Copyable;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface Cost extends Serializable {
|
||||
public interface Cost extends Serializable, Copyable<Cost> {
|
||||
|
||||
UUID getId();
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.abilities.costs;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -72,5 +71,4 @@ public abstract class CostImpl implements Cost {
|
|||
public UUID getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import mage.util.Copyable;
|
|||
/**
|
||||
* @author LevelX2
|
||||
*/
|
||||
public interface OptionalAdditionalCost extends Cost, Copyable<OptionalAdditionalCost> {
|
||||
public interface OptionalAdditionalCost extends Cost {
|
||||
|
||||
String getName();
|
||||
|
||||
|
@ -77,4 +77,6 @@ public interface OptionalAdditionalCost extends Cost, Copyable<OptionalAdditiona
|
|||
*/
|
||||
int getActivateCount();
|
||||
|
||||
@Override
|
||||
OptionalAdditionalCost copy();
|
||||
}
|
||||
|
|
|
@ -3,11 +3,19 @@ package mage.abilities.dynamicvalue;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.game.Game;
|
||||
import mage.util.Copyable;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public interface DynamicValue extends Serializable {
|
||||
/**
|
||||
* Dynamic value can be called multiple times from different places, so don't use inner/changeable fields. If you
|
||||
* use it then think x100 times and override Copy method with copy constructor.
|
||||
*/
|
||||
public interface DynamicValue extends Serializable, Copyable<DynamicValue> {
|
||||
|
||||
int calculate(Game game, Ability sourceAbility, Effect effect);
|
||||
|
||||
DynamicValue copy();
|
||||
|
||||
String getMessage();
|
||||
}
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
|
||||
|
||||
package mage.abilities.dynamicvalue.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
import java.io.ObjectStreamException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class TargetPermanenToughnessValue implements DynamicValue {
|
||||
|
||||
private static final TargetPermanenToughnessValue instance = new TargetPermanenToughnessValue();
|
||||
|
||||
private Object readResolve() throws ObjectStreamException {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static TargetPermanenToughnessValue getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
Permanent sourcePermanent = game.getPermanent(sourceAbility.getFirstTarget());
|
||||
if (sourcePermanent == null) {
|
||||
sourcePermanent = (Permanent) game.getLastKnownInformation(sourceAbility.getFirstTarget(), Zone.BATTLEFIELD);
|
||||
}
|
||||
if (sourcePermanent != null) {
|
||||
return sourcePermanent.getToughness().getValue();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetPermanenToughnessValue copy() {
|
||||
return new TargetPermanenToughnessValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "X";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "target creature's toughness";
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ import mage.constants.EffectType;
|
|||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.target.targetpointer.TargetPointer;
|
||||
import mage.util.Copyable;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.UUID;
|
||||
|
@ -13,7 +14,7 @@ import java.util.UUID;
|
|||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public interface Effect extends Serializable {
|
||||
public interface Effect extends Serializable, Copyable<Effect> {
|
||||
|
||||
UUID getId();
|
||||
|
||||
|
|
|
@ -19,5 +19,4 @@ public abstract class OneShotEffect extends EffectImpl {
|
|||
public OneShotEffect(final OneShotEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
|
@ -21,9 +19,13 @@ public class ExileGraveyardAllTargetPlayerEffect extends OneShotEffect {
|
|||
staticText = "exile all cards from target player's graveyard";
|
||||
}
|
||||
|
||||
private ExileGraveyardAllTargetPlayerEffect(final ExileGraveyardAllTargetPlayerEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExileGraveyardAllTargetPlayerEffect copy() {
|
||||
return new ExileGraveyardAllTargetPlayerEffect();
|
||||
return new ExileGraveyardAllTargetPlayerEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -24,7 +24,7 @@ public class ExileSpellEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public ExileSpellEffect copy() {
|
||||
return new ExileSpellEffect();
|
||||
return new ExileSpellEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.TurnPhase;
|
||||
import mage.game.Game;
|
||||
import mage.game.turn.TurnMod;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
|
||||
*/
|
||||
public class SkipNextCombatEffect extends OneShotEffect {
|
||||
|
||||
public SkipNextCombatEffect() {
|
||||
super(Outcome.Detriment);
|
||||
staticText = "target opponent skips their next combat phase";
|
||||
}
|
||||
|
||||
public SkipNextCombatEffect(SkipNextCombatEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
if (targetPointer != null) {
|
||||
Player player = game.getPlayer(targetPointer.getFirst(game, source));
|
||||
if (player != null) {
|
||||
game.getState().getTurnMods().add(new TurnMod(player.getId(), TurnPhase.COMBAT, null, true));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SkipNextCombatEffect copy() {
|
||||
return new SkipNextCombatEffect();
|
||||
}
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
|
||||
package mage.abilities.effects.common.turn;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.game.turn.TurnMod;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author nantuko
|
||||
*/
|
||||
|
@ -35,6 +35,6 @@ public class ControlTargetPlayerNextTurnEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public ControlTargetPlayerNextTurnEffect copy() {
|
||||
return new ControlTargetPlayerNextTurnEffect();
|
||||
return new ControlTargetPlayerNextTurnEffect(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.abilities.keyword;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -71,9 +70,19 @@ class MeleeWatcher extends Watcher {
|
|||
|
||||
class MeleeDynamicValue implements DynamicValue {
|
||||
|
||||
private boolean valueChecked = false;
|
||||
private boolean valueChecked;
|
||||
private int lockedInValue;
|
||||
|
||||
public MeleeDynamicValue() {
|
||||
super();
|
||||
}
|
||||
|
||||
protected MeleeDynamicValue(final MeleeDynamicValue dynamicValue) {
|
||||
super();
|
||||
valueChecked = dynamicValue.valueChecked;
|
||||
lockedInValue = dynamicValue.lockedInValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
MeleeWatcher watcher = game.getState().getWatcher(MeleeWatcher.class);
|
||||
|
@ -89,7 +98,7 @@ class MeleeDynamicValue implements DynamicValue {
|
|||
|
||||
@Override
|
||||
public MeleeDynamicValue copy() {
|
||||
return new MeleeDynamicValue();
|
||||
return new MeleeDynamicValue(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in a new issue