mirror of
https://github.com/magefree/mage.git
synced 2025-12-25 04:52:07 -08:00
commit
fbde510bac
935 changed files with 13628 additions and 12155 deletions
|
|
@ -1083,7 +1083,7 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
&& this.red >= mana.red
|
||||
&& this.colorless >= mana.colorless
|
||||
&& (this.generic >= mana.generic
|
||||
|| this.countColored() >= mana.countColored() + mana.generic);
|
||||
|| this.countColored() + this.colorless >= mana.count());
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -126,6 +126,8 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
|
|||
newColor.black = black && other.black;
|
||||
newColor.red = red && other.red;
|
||||
newColor.green = green && other.green;
|
||||
|
||||
newColor.gold = gold && other.gold;
|
||||
return newColor;
|
||||
}
|
||||
|
||||
|
|
@ -157,6 +159,7 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
|
|||
List<ObjectColor> colors = new ArrayList<>();
|
||||
int firstColor = 5000;
|
||||
int secondColor = -1;
|
||||
|
||||
if (this.isWhite()) {
|
||||
firstColor = 1;
|
||||
secondColor = 1;
|
||||
|
|
@ -177,6 +180,7 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
|
|||
firstColor = Math.min(firstColor, 5);
|
||||
secondColor = Math.max(secondColor, 5);
|
||||
}
|
||||
|
||||
if (this.isWhite()) {
|
||||
colors.add(ObjectColor.WHITE);
|
||||
}
|
||||
|
|
@ -192,6 +196,7 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
|
|||
if (this.isGreen()) {
|
||||
colors.add(ObjectColor.GREEN);
|
||||
}
|
||||
|
||||
if (colors.size() >= 2 && secondColor - firstColor >= 3) {
|
||||
Collections.swap(colors, 0, 1);
|
||||
}
|
||||
|
|
@ -391,7 +396,11 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
|
|||
if (test.green != this.green) {
|
||||
return false;
|
||||
}
|
||||
return test.gold == this.gold;
|
||||
if (test.gold != this.gold) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -465,10 +474,10 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
|
|||
o1 = 4;
|
||||
} else if (this.isWhite()) {
|
||||
o1 = 5;
|
||||
|
||||
} else if (this.isGold()) {
|
||||
o1 = 6;
|
||||
}
|
||||
|
||||
if (o.isMulticolored()) {
|
||||
o2 = 7;
|
||||
} else if (o.isColorless()) {
|
||||
|
|
@ -483,10 +492,10 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
|
|||
o2 = 4;
|
||||
} else if (o.isWhite()) {
|
||||
o2 = 5;
|
||||
|
||||
} else if (o.isGold()) {
|
||||
o2 = 6;
|
||||
}
|
||||
|
||||
return o1 - o2;
|
||||
}
|
||||
|
||||
|
|
@ -496,7 +505,12 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
|
|||
*
|
||||
* @return null or
|
||||
*/
|
||||
public ColoredManaSymbol getColoredManaSymbol() {
|
||||
public ColoredManaSymbol getOneColoredManaSymbol() {
|
||||
|
||||
if (isMulticolored()) {
|
||||
throw new IllegalStateException("Founded multicolored object, but it's must call with single mana color.");
|
||||
}
|
||||
|
||||
if (isBlack()) {
|
||||
return ColoredManaSymbol.B;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ import mage.abilities.effects.ContinuousEffect;
|
|||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.Effects;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.DynamicManaEffect;
|
||||
import mage.abilities.effects.mana.DynamicManaEffect;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.abilities.mana.ActivatedManaAbilityImpl;
|
||||
import mage.cards.Card;
|
||||
|
|
@ -157,6 +157,8 @@ public abstract class AbilityImpl implements Ability {
|
|||
public void newId() {
|
||||
if (!(this instanceof MageSingleton)) {
|
||||
this.id = UUID.randomUUID();
|
||||
// this.sourceObject = null;
|
||||
// this.sourceObjectZoneChangeCounter = -1;
|
||||
}
|
||||
getEffects().newId();
|
||||
}
|
||||
|
|
@ -1211,7 +1213,7 @@ public abstract class AbilityImpl implements Ability {
|
|||
|
||||
@Override
|
||||
public Permanent getSourcePermanentIfItStillExists(Game game) {
|
||||
if (sourceObject == null) {
|
||||
if (sourceObject == null || !sourceObject.getId().equals(getSourceId())) {
|
||||
setSourceObject(game.getObject(getSourceId()), game);
|
||||
}
|
||||
if (sourceObject instanceof Permanent) {
|
||||
|
|
|
|||
|
|
@ -250,6 +250,7 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMayActivate(TargetController mayActivate) {
|
||||
this.mayActivate = mayActivate;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,6 +79,6 @@ public class ConstellationAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return new StringBuilder("<i>Constellation</i> - Whenever {this} or another enchantment enters the battlefield under your control, ").append(super.getRule()).toString();
|
||||
return new StringBuilder("<i>Constellation</i> — Whenever {this} or another enchantment enters the battlefield under your control, ").append(super.getRule()).toString();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ public class KinshipAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return new StringBuilder("<i>Kinship</i> - At the beginning of your upkeep, ").append(super.getRule()).toString();
|
||||
return new StringBuilder("<i>Kinship</i> — At the beginning of your upkeep, ").append(super.getRule()).toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,12 +46,12 @@ import mage.constants.Zone;
|
|||
public class LieutenantAbility extends SimpleStaticAbility {
|
||||
|
||||
public LieutenantAbility(ContinuousEffect effect) {
|
||||
super(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield), CommanderInPlayCondition.instance, "<i>Lieutenant</i> - As long as you control your commander, {this} gets +2/+2"));
|
||||
super(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield), CommanderInPlayCondition.instance, "<i>Lieutenant</i> — As long as you control your commander, {this} gets +2/+2"));
|
||||
this.addEffect(new ConditionalContinuousEffect(effect, CommanderInPlayCondition.instance, effect.getText(null)));
|
||||
}
|
||||
|
||||
public LieutenantAbility(Effects effects) {
|
||||
super(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield), CommanderInPlayCondition.instance, "<i>Lieutenant</i> - As long as you control your commander, {this} gets +2/+2"));
|
||||
super(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield), CommanderInPlayCondition.instance, "<i>Lieutenant</i> — As long as you control your commander, {this} gets +2/+2"));
|
||||
for (Effect effect : effects) {
|
||||
this.addEffect(new ConditionalContinuousEffect((ContinuousEffect) effect, CommanderInPlayCondition.instance, effect.getText(null)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public class StriveAbility extends SimpleStaticAbility {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return new StringBuilder("<i>Strive</i> - {this} costs ").append(striveCost).append(" more to cast for each target beyond the first.").toString();
|
||||
return new StringBuilder("<i>Strive</i> — {this} costs ").append(striveCost).append(" more to cast for each target beyond the first.").toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,27 @@
|
|||
package mage.abilities.common;
|
||||
|
||||
import mage.abilities.condition.common.LegendaryCondition;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.CardTypePredicate;
|
||||
import mage.filter.predicate.mageobject.SupertypePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
|
||||
/**
|
||||
* @author JRHerlehy
|
||||
* Created on 4/8/18.
|
||||
* @author JRHerlehy Created on 4/8/18.
|
||||
*/
|
||||
public class LegendarySpellAbility extends SimpleStaticAbility {
|
||||
|
||||
public LegendarySpellAbility() {
|
||||
super(Zone.ALL, new CastOnlyIfConditionIsTrueEffect(LegendaryCondition.instance));
|
||||
super(Zone.ALL, new LegendarySpellAbilityCheckEffect());
|
||||
this.setRuleAtTheTop(true);
|
||||
this.getEffects().get(0).setText("<i>(You may cast a legendary sorcery only if you control a legendary creature or planeswalker.)</i>");
|
||||
}
|
||||
|
||||
private LegendarySpellAbility(final LegendarySpellAbility ability) {
|
||||
|
|
@ -24,3 +33,46 @@ public class LegendarySpellAbility extends SimpleStaticAbility {
|
|||
return new LegendarySpellAbility(this);
|
||||
}
|
||||
}
|
||||
|
||||
class LegendarySpellAbilityCheckEffect extends ContinuousRuleModifyingEffectImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterPermanent("legendary creature or planeswalker");
|
||||
|
||||
static {
|
||||
filter.add(
|
||||
Predicates.and(
|
||||
new SupertypePredicate(SuperType.LEGENDARY),
|
||||
Predicates.or(
|
||||
new CardTypePredicate(CardType.CREATURE),
|
||||
new CardTypePredicate(CardType.PLANESWALKER)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public LegendarySpellAbilityCheckEffect() {
|
||||
super(Duration.EndOfGame, Outcome.Detriment);
|
||||
staticText = "<i>(You may cast a legendary sorcery only if you control a legendary creature or planeswalker.)</i>";
|
||||
}
|
||||
|
||||
private LegendarySpellAbilityCheckEffect(final LegendarySpellAbilityCheckEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checksEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.CAST_SPELL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
return event.getSourceId().equals(source.getSourceId())
|
||||
&& !game.getBattlefield().contains(filter, event.getPlayerId(), 1, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LegendarySpellAbilityCheckEffect copy() {
|
||||
return new LegendarySpellAbilityCheckEffect(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,46 +0,0 @@
|
|||
package mage.abilities.condition.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.CardTypePredicate;
|
||||
import mage.filter.predicate.mageobject.SupertypePredicate;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
* @author JRHerlehy
|
||||
* Created on 4/7/18.
|
||||
*/
|
||||
public enum LegendaryCondition implements Condition {
|
||||
|
||||
instance;
|
||||
|
||||
private static final FilterPermanent filter = new FilterPermanent("legendary creature or planeswalker");
|
||||
|
||||
static {
|
||||
filter.add(
|
||||
Predicates.and(
|
||||
new SupertypePredicate(SuperType.LEGENDARY),
|
||||
Predicates.or(
|
||||
new CardTypePredicate(CardType.CREATURE),
|
||||
new CardTypePredicate(CardType.PLANESWALKER)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return game.getBattlefield().contains(filter, source.getControllerId(), 1, game);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -63,7 +63,7 @@ public class ExileFromStackCost extends CostImpl {
|
|||
}
|
||||
String spellName = spellToExile.getName();
|
||||
if (spellToExile.isCopy()) {
|
||||
game.getStack().remove(spellToExile);
|
||||
game.getStack().remove(spellToExile, game);
|
||||
} else {
|
||||
spellToExile.moveToExile(null, "", ability.getSourceId(), game);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ package mage.abilities.decorator;
|
|||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.effects.common.BasicManaEffect;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.abilities.effects.mana.BasicManaEffect;
|
||||
import mage.choices.ChoiceColor;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
|
@ -73,31 +73,7 @@ public class ConditionalManaEffect extends ManaEffect {
|
|||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
if (condition.apply(game, source)) {
|
||||
effect.setTargetPointer(this.targetPointer);
|
||||
} else if (otherwiseEffect != null) {
|
||||
otherwiseEffect.setTargetPointer(this.targetPointer);
|
||||
}
|
||||
Mana mana = getMana(game, source);
|
||||
if (mana == null) {
|
||||
return false;
|
||||
}
|
||||
if (mana.getAny() > 0) {
|
||||
int amount = mana.getAny();
|
||||
|
||||
ChoiceColor choice = new ChoiceColor(true);
|
||||
Mana createdMana = null;
|
||||
if (controller.choose(outcome, choice, game)) {
|
||||
createdMana = choice.getMana(amount);
|
||||
}
|
||||
if (createdMana == null) {
|
||||
return false;
|
||||
}
|
||||
mana = createdMana;
|
||||
// because the mana type is now choosen, fire the event with the mana information
|
||||
checkToFirePossibleEvents(mana, game, source);
|
||||
}
|
||||
controller.getManaPool().addMana(mana, game, source);
|
||||
controller.getManaPool().addMana(getMana(game, source), game, source);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -107,12 +83,25 @@ public class ConditionalManaEffect extends ManaEffect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Mana getMana(Game game, Ability source) {
|
||||
Mana mana = null;
|
||||
public Mana produceMana(boolean netMana, Game game, Ability source) {
|
||||
Mana mana = new Mana();
|
||||
if (condition.apply(game, source)) {
|
||||
mana = effect.getMana();
|
||||
mana = effect.getManaTemplate().copy();
|
||||
} else if (otherwiseEffect != null) {
|
||||
mana = otherwiseEffect.getMana();
|
||||
mana = otherwiseEffect.getManaTemplate().copy();
|
||||
}
|
||||
if (mana.getAny() > 0) {
|
||||
int amount = mana.getAny();
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller == null) {
|
||||
return mana;
|
||||
}
|
||||
ChoiceColor choice = new ChoiceColor(true);
|
||||
if (controller.choose(outcome, choice, game)) {
|
||||
mana.setAny(0);
|
||||
mana.add(choice.getMana(amount));
|
||||
}
|
||||
checkToFirePossibleEvents(mana, game, source);
|
||||
}
|
||||
return mana;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public class OpponentsLostLifeCount implements DynamicValue {
|
|||
public int calculate(Game game, UUID controllerId) {
|
||||
PlayerLostLifeWatcher watcher = (PlayerLostLifeWatcher) game.getState().getWatchers().get(PlayerLostLifeWatcher.class.getSimpleName());
|
||||
if (watcher != null) {
|
||||
return watcher.getAllOppLifeLost(controllerId);
|
||||
return watcher.getAllOppLifeLost(controllerId, game);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,18 +8,30 @@ import mage.game.Game;
|
|||
public class SignInversionDynamicValue implements DynamicValue {
|
||||
|
||||
private final DynamicValue value;
|
||||
private final boolean canBePositive;
|
||||
|
||||
public SignInversionDynamicValue(DynamicValue value) {
|
||||
this(value, true);
|
||||
}
|
||||
|
||||
public SignInversionDynamicValue(DynamicValue value, boolean canBePositive) {
|
||||
this.value = value.copy();
|
||||
this.canBePositive = canBePositive;
|
||||
}
|
||||
|
||||
SignInversionDynamicValue(final SignInversionDynamicValue dynamicValue) {
|
||||
this.value = dynamicValue.value.copy();
|
||||
this.canBePositive = dynamicValue.canBePositive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
return -1 * value.calculate(game, sourceAbility, effect);
|
||||
int amount = value.calculate(game, sourceAbility, effect);
|
||||
if (amount >= 0 || canBePositive) {
|
||||
return -1 * amount;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -926,6 +926,14 @@ public class ContinuousEffects implements Serializable {
|
|||
while (!done) { // loop needed if a added effect adds again an effect (e.g. Level 5- of Joraga Treespeaker)
|
||||
done = true;
|
||||
layer = filterLayeredEffects(activeLayerEffects, Layer.AbilityAddingRemovingEffects_6);
|
||||
|
||||
// debug
|
||||
/*
|
||||
System.out.println(game.getTurn() + ", " + game.getPhase() + ": " + "need apply " + layer.stream()
|
||||
.map((eff) -> {return eff.getClass().getName().replaceAll(".+\\.(.+)", "$1");})
|
||||
.collect(Collectors.joining(", ")));
|
||||
*/
|
||||
|
||||
for (ContinuousEffect effect : layer) {
|
||||
if (activeLayerEffects.contains(effect) && !appliedEffects.contains(effect.getId())) { // Effect does still exist and was not applied yet
|
||||
Set<UUID> dependentTo = effect.isDependentTo(layer);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
package mage.abilities.effects;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.EffectType;
|
||||
|
|
@ -44,26 +45,34 @@ import mage.target.Target;
|
|||
*/
|
||||
public abstract class RedirectionEffect extends ReplacementEffectImpl {
|
||||
|
||||
protected Target redirectTarget;
|
||||
protected int amountToRedirect;
|
||||
protected boolean oneUsage;
|
||||
|
||||
public RedirectionEffect(Duration duration) {
|
||||
this(duration, Integer.MAX_VALUE, false);
|
||||
public enum UsageType {
|
||||
ACCORDING_DURATION,
|
||||
ONE_USAGE_ABSOLUTE,
|
||||
ONE_USAGE_AT_THE_SAME_TIME; // all damage dealt at the same time
|
||||
}
|
||||
|
||||
public RedirectionEffect(Duration duration, int amountToRedirect, boolean oneUsage) {
|
||||
protected Target redirectTarget;
|
||||
protected int amountToRedirect;
|
||||
protected UsageType usageType;
|
||||
protected int applyEffectsCounter;
|
||||
|
||||
public RedirectionEffect(Duration duration) {
|
||||
this(duration, Integer.MAX_VALUE, UsageType.ACCORDING_DURATION);
|
||||
applyEffectsCounter = -1;
|
||||
}
|
||||
|
||||
public RedirectionEffect(Duration duration, int amountToRedirect, UsageType usageType) {
|
||||
super(duration, Outcome.RedirectDamage);
|
||||
this.effectType = EffectType.REDIRECTION;
|
||||
this.amountToRedirect = amountToRedirect;
|
||||
this.oneUsage = oneUsage;
|
||||
this.usageType = usageType;
|
||||
}
|
||||
|
||||
public RedirectionEffect(final RedirectionEffect effect) {
|
||||
super(effect);
|
||||
this.redirectTarget = effect.redirectTarget;
|
||||
this.amountToRedirect = effect.amountToRedirect;
|
||||
this.oneUsage = effect.oneUsage;
|
||||
this.usageType = effect.usageType;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -79,26 +88,38 @@ public abstract class RedirectionEffect extends ReplacementEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
int damageToRedirect = event.getAmount();
|
||||
if (damageToRedirect < 1) { // if multiple replacement effect apply, the rest damage can be 0, so the effect is not applied/replaced
|
||||
return false;
|
||||
}
|
||||
String sourceLogName = source != null ? game.getObject(source.getSourceId()).getLogName() + ": " : "";
|
||||
DamageEvent damageEvent = (DamageEvent) event;
|
||||
int restDamage = 0;
|
||||
int damageToRedirect = event.getAmount();
|
||||
if (damageEvent.getAmount() > amountToRedirect) {
|
||||
restDamage = damageEvent.getAmount() - amountToRedirect;
|
||||
damageToRedirect = amountToRedirect;
|
||||
}
|
||||
if (damageToRedirect > 0 && oneUsage) {
|
||||
this.discard();
|
||||
if (damageToRedirect > 0 && usageType != UsageType.ACCORDING_DURATION) {
|
||||
if (UsageType.ONE_USAGE_ABSOLUTE == usageType) {
|
||||
this.discard();
|
||||
}
|
||||
if (applyEffectsCounter > 0) {
|
||||
if (applyEffectsCounter < game.getState().getApplyEffectsCounter()) {
|
||||
this.discard();
|
||||
}
|
||||
} else {
|
||||
applyEffectsCounter = game.getState().getApplyEffectsCounter();
|
||||
}
|
||||
}
|
||||
Permanent permanent = game.getPermanent(redirectTarget.getFirstTarget());
|
||||
if (permanent != null) {
|
||||
permanent.damage(damageToRedirect, event.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), event.getAppliedEffects());
|
||||
game.informPlayers(sourceLogName + "Redirected " + damageToRedirect + " damage to " + permanent.getLogName());
|
||||
game.informPlayers(sourceLogName + "Redirected " + damageToRedirect + " damage" + getRedirectedFromText(event, game) + " to " + permanent.getLogName());
|
||||
} else {
|
||||
Player player = game.getPlayer(redirectTarget.getFirstTarget());
|
||||
if (player != null) {
|
||||
player.damage(damageToRedirect, event.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), event.getAppliedEffects());
|
||||
game.informPlayers(sourceLogName + "Redirected " + damageToRedirect + " damage to " + player.getLogName());
|
||||
game.informPlayers(sourceLogName + "Redirected " + damageToRedirect + " damage" + getRedirectedFromText(event, game) + " to " + player.getLogName());
|
||||
}
|
||||
}
|
||||
if (restDamage > 0) {
|
||||
|
|
@ -108,4 +129,16 @@ public abstract class RedirectionEffect extends ReplacementEffectImpl {
|
|||
return true;
|
||||
}
|
||||
|
||||
private String getRedirectedFromText(GameEvent event, Game game) {
|
||||
Player player = game.getPlayer(event.getTargetId());
|
||||
if (player != null) {
|
||||
return " from " + player.getLogName();
|
||||
}
|
||||
MageObject mageObject = game.getObject(event.getTargetId());
|
||||
if (mageObject != null) {
|
||||
return " from " + mageObject.getLogName();
|
||||
}
|
||||
return "";
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.mana.builder.ConditionalManaBuilder;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class AddConditionalColorlessManaEffect extends ManaEffect {
|
||||
|
||||
private final int amount;
|
||||
private final ConditionalManaBuilder manaBuilder;
|
||||
|
||||
public AddConditionalColorlessManaEffect(int amount, ConditionalManaBuilder manaBuilder) {
|
||||
super();
|
||||
this.amount = amount;
|
||||
this.manaBuilder = manaBuilder;
|
||||
|
||||
staticText = "Add " + String.format(String.format("%%%ds", amount), " ").replace(" ", "{C}")
|
||||
+ ". " + manaBuilder.getRule();
|
||||
}
|
||||
|
||||
public AddConditionalColorlessManaEffect(final AddConditionalColorlessManaEffect effect) {
|
||||
super(effect);
|
||||
this.amount = effect.amount;
|
||||
this.manaBuilder = effect.manaBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AddConditionalColorlessManaEffect copy() {
|
||||
return new AddConditionalColorlessManaEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null) {
|
||||
player.getManaPool().addMana(getMana(game, source), game, source);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana getMana(Game game, Ability source) {
|
||||
return manaBuilder.setMana(Mana.ColorlessMana(amount), source, game).build();
|
||||
}
|
||||
|
||||
public Mana getMana() {
|
||||
return Mana.ColorlessMana(amount);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
package mage.abilities.effects.common;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.choices.ChoiceColor;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* Created by Galatolol
|
||||
*/
|
||||
public class AddManaOfAnyColorToManaPoolTargetPlayerEffect extends ManaEffect {
|
||||
|
||||
public AddManaOfAnyColorToManaPoolTargetPlayerEffect(String textManaPoolOwner) {
|
||||
super();
|
||||
this.staticText = (textManaPoolOwner.equals("their") ? "that player adds " : "add ") + "one mana of any color" + " to " + textManaPoolOwner + " mana pool";
|
||||
}
|
||||
|
||||
public AddManaOfAnyColorToManaPoolTargetPlayerEffect(final AddManaOfAnyColorToManaPoolTargetPlayerEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
UUID playerId = (UUID) game.getState().getValue(source.getSourceId() + "_player");
|
||||
Player player = game.getPlayer(playerId);
|
||||
ChoiceColor choice = new ChoiceColor();
|
||||
if (player != null && player.choose(outcome, choice, game)) {
|
||||
Mana mana = choice.getMana(1);
|
||||
checkToFirePossibleEvents(mana, game, source);
|
||||
player.getManaPool().addMana(mana, game, source);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AddManaOfAnyColorToManaPoolTargetPlayerEffect copy() {
|
||||
return new AddManaOfAnyColorToManaPoolTargetPlayerEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana getMana(Game game, Ability source) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import java.util.Objects;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
|
||||
|
|
@ -36,8 +37,6 @@ import mage.game.Game;
|
|||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
|
|
@ -67,6 +66,17 @@ public class CantBeRegeneratedSourceEffect extends ContinuousRuleModifyingEffect
|
|||
return event.getType() == EventType.REGENERATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game); //To change body of generated methods, choose Tools | Templates.
|
||||
if (duration.isOnlyValidIfNoZoneChange()) {
|
||||
// If source permanent is no longer onto battlefield discard the effect
|
||||
if (source.getSourcePermanentIfItStillExists(game) == null) {
|
||||
discard();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
return Objects.equals(source.getSourceId(), event.getTargetId());
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public class DestroySourceEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
|
||||
if (permanent != null) {
|
||||
permanent.destroy(source.getSourceId(), game, noRegen);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ public class DoIfCostPaid extends OneShotEffect {
|
|||
}
|
||||
message = getCostText() + " and " + effectText + '?';
|
||||
message = Character.toUpperCase(message.charAt(0)) + message.substring(1);
|
||||
CardUtil.replaceSourceName(message, mageObject.getName());
|
||||
} else {
|
||||
message = chooseUseText;
|
||||
}
|
||||
|
|
@ -79,6 +80,7 @@ public class DoIfCostPaid extends OneShotEffect {
|
|||
if (cost.canPay(source, source.getSourceId(), player.getId(), game)
|
||||
&& executingEffects.size() > 0 && (!optional || player.chooseUse(executingEffects.get(0).getOutcome(), message, source, game))) {
|
||||
cost.clearPaid();
|
||||
int bookmark = game.bookmarkState();
|
||||
if (cost.pay(source, game, source.getSourceId(), player.getId(), false)) {
|
||||
for (Effect effect : executingEffects) {
|
||||
effect.setTargetPointer(this.targetPointer);
|
||||
|
|
@ -89,13 +91,17 @@ public class DoIfCostPaid extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
player.resetStoredBookmark(game); // otherwise you can e.g. undo card drawn with Mentor of the Meek
|
||||
} else if (!otherwiseEffects.isEmpty()) {
|
||||
for (Effect effect : otherwiseEffects) {
|
||||
effect.setTargetPointer(this.targetPointer);
|
||||
if (effect instanceof OneShotEffect) {
|
||||
result &= effect.apply(game, source);
|
||||
} else {
|
||||
game.addEffect((ContinuousEffect) effect, source);
|
||||
} else {
|
||||
// Paying cost was cancels so try to undo payment so far
|
||||
game.restoreState(bookmark, DoIfCostPaid.class.getName());
|
||||
if (!otherwiseEffects.isEmpty()) {
|
||||
for (Effect effect : otherwiseEffects) {
|
||||
effect.setTargetPointer(this.targetPointer);
|
||||
if (effect instanceof OneShotEffect) {
|
||||
result &= effect.apply(game, source);
|
||||
} else {
|
||||
game.addEffect((ContinuousEffect) effect, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
|
|
@ -50,21 +51,19 @@ public class FightTargetSourceEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent originalPermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
|
||||
if (originalPermanent != null) {
|
||||
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
||||
// only if target is legal the effect will be applied
|
||||
if (source.getTargets().get(0).isLegal(source, game)) {
|
||||
Permanent creature1 = game.getPermanent(source.getTargets().get(0).getFirstTarget());
|
||||
// 20110930 - 701.10
|
||||
if (creature1 != null && sourcePermanent != null) {
|
||||
if (creature1.isCreature() && sourcePermanent.isCreature()) {
|
||||
return sourcePermanent.fight(creature1, source, game);
|
||||
}
|
||||
MageObject sourceObject = source.getSourceObject(game);
|
||||
if (sourceObject != null) {
|
||||
Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game);
|
||||
Permanent creature1 = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
// 20110930 - 701.10
|
||||
if (creature1 != null && sourcePermanent != null) {
|
||||
if (creature1.isCreature() && sourcePermanent.isCreature()) {
|
||||
return sourcePermanent.fight(creature1, source, game);
|
||||
}
|
||||
}
|
||||
if (!game.isSimulation())
|
||||
game.informPlayers(originalPermanent.getLogName() + ": Fighting effect has been fizzled.");
|
||||
if (!game.isSimulation()) {
|
||||
game.informPlayers(sourceObject.getLogName() + ": Fighting effect has been fizzled.");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -83,4 +82,3 @@ public class FightTargetSourceEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,11 +8,9 @@ import mage.abilities.effects.OneShotEffect;
|
|||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.TokenImpl;
|
||||
import mage.game.permanent.token.Token;
|
||||
import mage.players.Player;
|
||||
|
||||
|
||||
/**
|
||||
* @author Loki
|
||||
*/
|
||||
|
|
@ -33,14 +31,15 @@ public class FlipSourceEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (permanent != null && controller != null) {
|
||||
if (permanent.flip(game)) {
|
||||
ContinuousEffect effect = new ConditionalContinuousEffect(new CopyTokenEffect(flipToken), FlippedCondition.instance, "");
|
||||
game.addEffect(effect, source);
|
||||
if (!game.isSimulation())
|
||||
if (!game.isSimulation()) {
|
||||
game.informPlayers(new StringBuilder(controller.getLogName()).append(" flips ").append(permanent.getName()).toString());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.Mode;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.Outcome;
|
||||
|
|
@ -150,6 +149,7 @@ public class LookLibraryAndPickControllerEffect extends LookLibraryControllerEff
|
|||
FilterCard pickFilter, Zone targetZoneLookedCards, boolean putOnTop,
|
||||
boolean reveal, boolean upTo, Zone targetZonePickedCards,
|
||||
boolean optional) {
|
||||
|
||||
this(numberOfCards, mayShuffleAfter, numberToPick, pickFilter,
|
||||
targetZoneLookedCards, putOnTop, reveal, upTo,
|
||||
targetZonePickedCards, optional, true, true);
|
||||
|
|
@ -207,16 +207,10 @@ public class LookLibraryAndPickControllerEffect extends LookLibraryControllerEff
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void cardLooked(Card card, Game game, Ability source) {
|
||||
if (numberToPick.calculate(game, source, this) > 0 && filter.match(card, game)) {
|
||||
++foundCardsToPick;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void actionWithSelectedCards(Cards cards, Game game, Ability source, String windowName) {
|
||||
protected void actionWithSelectedCards(Cards cards, Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null && foundCardsToPick > 0) {
|
||||
if (player != null && numberToPick.calculate(game, source, this) > 0
|
||||
&& cards.count(filter, source.getSourceId(), source.getControllerId(), game) > 0) {
|
||||
if (!optional || player.chooseUse(Outcome.DrawCard, getMayText(), source, game)) {
|
||||
FilterCard pickFilter = filter.copy();
|
||||
pickFilter.setMessage(getPickText());
|
||||
|
|
@ -231,7 +225,7 @@ public class LookLibraryAndPickControllerEffect extends LookLibraryControllerEff
|
|||
player.moveCards(pickedCards.getCards(game), targetPickedCards, source, game);
|
||||
}
|
||||
if (revealPickedCards) {
|
||||
player.revealCards(windowName, pickedCards, game);
|
||||
player.revealCards(source, pickedCards, game);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -346,7 +340,14 @@ public class LookLibraryAndPickControllerEffect extends LookLibraryControllerEff
|
|||
}
|
||||
sb.append(" order");
|
||||
} else if (targetZoneLookedCards == Zone.GRAVEYARD) {
|
||||
sb.append(" and the other into your graveyard");
|
||||
sb.append(" and the");
|
||||
if (numberOfCards instanceof StaticValue && numberToPick instanceof StaticValue
|
||||
&& ((StaticValue) numberToPick).getValue() + 1 == ((StaticValue) numberOfCards).getValue()) {
|
||||
sb.append(" other");
|
||||
} else {
|
||||
sb.append(" rest");
|
||||
}
|
||||
sb.append(" into your graveyard");
|
||||
}
|
||||
}
|
||||
// get text frame from super class and inject action text
|
||||
|
|
|
|||
|
|
@ -29,18 +29,15 @@ package mage.abilities.effects.common;
|
|||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
|
|
@ -105,46 +102,25 @@ public class LookLibraryControllerEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
String windowName = "Reveal";
|
||||
|
||||
if (source instanceof SpellAbility) {
|
||||
Card sourceCard = game.getCard(source.getSourceId());
|
||||
if (sourceCard != null) {
|
||||
windowName = sourceCard.getIdName();
|
||||
}
|
||||
} else {
|
||||
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
||||
if (sourcePermanent != null) {
|
||||
windowName = sourcePermanent.getIdName();
|
||||
}
|
||||
}
|
||||
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player == null) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// take cards from library and look at them
|
||||
boolean topCardRevealed = player.isTopCardRevealed();
|
||||
player.setTopCardRevealed(false);
|
||||
Cards cards = new CardsImpl();
|
||||
int count = Math.min(player.getLibrary().size(), this.numberOfCards.calculate(game, source, this));
|
||||
for (int i = 0; i < count; i++) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
cards.add(card);
|
||||
this.cardLooked(card, game, source);
|
||||
}
|
||||
}
|
||||
player.lookAtCards(windowName, cards, game);
|
||||
boolean topCardRevealed = controller.isTopCardRevealed();
|
||||
controller.setTopCardRevealed(false);
|
||||
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, this.numberOfCards.calculate(game, source, this)));
|
||||
|
||||
this.actionWithSelectedCards(cards, game, source, windowName);
|
||||
controller.lookAtCards(source, null, cards, game);
|
||||
|
||||
this.putCardsBack(source, player, cards, game);
|
||||
this.actionWithSelectedCards(cards, game, source);
|
||||
|
||||
player.setTopCardRevealed(topCardRevealed);
|
||||
this.putCardsBack(source, controller, cards, game);
|
||||
|
||||
this.mayShuffle(player, source, game);
|
||||
controller.setTopCardRevealed(topCardRevealed);
|
||||
|
||||
this.mayShuffle(controller, source, game);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -158,10 +134,7 @@ public class LookLibraryControllerEffect extends OneShotEffect {
|
|||
return this;
|
||||
}
|
||||
|
||||
protected void cardLooked(Card card, Game game, Ability source) {
|
||||
}
|
||||
|
||||
protected void actionWithSelectedCards(Cards cards, Game game, Ability source, String windowName) {
|
||||
protected void actionWithSelectedCards(Cards cards, Game game, Ability source) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -47,11 +47,13 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect {
|
|||
|
||||
protected int amount;
|
||||
protected boolean putToGraveyard;
|
||||
protected boolean mayShuffleAfter; // for Visions
|
||||
|
||||
public LookLibraryTopCardTargetPlayerEffect(int amount) {
|
||||
super(Outcome.Benefit);
|
||||
this.amount = amount;
|
||||
this.putToGraveyard = false;
|
||||
this.mayShuffleAfter = false;
|
||||
setText();
|
||||
}
|
||||
|
||||
|
|
@ -59,6 +61,15 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect {
|
|||
super(Outcome.Benefit);
|
||||
this.amount = amount;
|
||||
this.putToGraveyard = putToGraveyard;
|
||||
this.mayShuffleAfter = false;
|
||||
setText();
|
||||
}
|
||||
|
||||
public LookLibraryTopCardTargetPlayerEffect(int amount, boolean putToGraveyard, boolean mayShuffleAfter) {
|
||||
super(Outcome.Benefit);
|
||||
this.amount = amount;
|
||||
this.putToGraveyard = putToGraveyard;
|
||||
this.mayShuffleAfter = mayShuffleAfter;
|
||||
setText();
|
||||
}
|
||||
|
||||
|
|
@ -70,6 +81,7 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect {
|
|||
super(effect);
|
||||
amount = effect.amount;
|
||||
putToGraveyard = effect.putToGraveyard;
|
||||
mayShuffleAfter = effect.mayShuffleAfter;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -95,6 +107,11 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (mayShuffleAfter) {
|
||||
if (player.chooseUse(Outcome.Benefit, (player == targetPlayer ? "Shuffle your library?" : "Do you want the chosen player to shuffle his or her library?"), source, game)) {
|
||||
targetPlayer.shuffleLibrary(source, game);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -118,6 +135,9 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect {
|
|||
}
|
||||
sb.append(" into that player's graveyard");
|
||||
}
|
||||
if (mayShuffleAfter) {
|
||||
sb.append(". You may then have that player shuffle that library");
|
||||
}
|
||||
this.staticText = sb.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,10 +24,11 @@
|
|||
* 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 java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.Cost;
|
||||
|
|
@ -45,26 +46,72 @@ import mage.game.events.ManaEvent;
|
|||
*/
|
||||
public abstract class ManaEffect extends OneShotEffect {
|
||||
|
||||
protected Mana createdMana;
|
||||
|
||||
public ManaEffect() {
|
||||
super(Outcome.PutManaInPool);
|
||||
createdMana = null;
|
||||
}
|
||||
|
||||
public ManaEffect(final ManaEffect effect) {
|
||||
super(effect);
|
||||
this.createdMana = effect.createdMana == null ? null : effect.createdMana.copy();
|
||||
}
|
||||
|
||||
public abstract Mana getMana(Game game, Ability source);
|
||||
/**
|
||||
* Creates the mana the effect can produce or if that already has happened
|
||||
* returns the mana the effect has created during its process of resolving
|
||||
*
|
||||
* @param game
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
public Mana getMana(Game game, Ability source) {
|
||||
if (createdMana == null) {
|
||||
return createdMana = produceMana(false, game, source);
|
||||
}
|
||||
return createdMana;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only used for mana effects that decide which kind of mana is produced during resolution of the effect.
|
||||
*
|
||||
* Returns the currently available max mana variations the effect can
|
||||
* produce
|
||||
*
|
||||
* @param game
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
public List<Mana> getNetMana(Game game, Ability source) {
|
||||
List<Mana> netMana = new ArrayList<>();
|
||||
Mana mana = produceMana(true, game, source);
|
||||
if (mana != null) {
|
||||
netMana.add(mana);
|
||||
}
|
||||
return netMana;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produced the mana the effect can produce
|
||||
*
|
||||
* @param netMana true - produce the hypotetical possible mana for check of
|
||||
* possible castable spells
|
||||
* @param game
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
public abstract Mana produceMana(boolean netMana, Game game, Ability source);
|
||||
|
||||
/**
|
||||
* Only used for mana effects that decide which kind of mana is produced
|
||||
* during resolution of the effect.
|
||||
*
|
||||
* @param mana
|
||||
* @param game
|
||||
* @param source
|
||||
*/
|
||||
public void checkToFirePossibleEvents(Mana mana, Game game, Ability source) {
|
||||
if (source.getAbilityType()==AbilityType.MANA) {
|
||||
for (Cost cost: source.getCosts()) {
|
||||
if (source.getAbilityType() == AbilityType.MANA) {
|
||||
for (Cost cost : source.getCosts()) {
|
||||
if (cost instanceof TapSourceCost) {
|
||||
ManaEvent event = new ManaEvent(GameEvent.EventType.TAPPED_FOR_MANA, source.getSourceId(), source.getSourceId(), source.getControllerId(), mana);
|
||||
if (!game.replaceEvent(event)) {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.Outcome;
|
||||
|
|
@ -34,9 +33,8 @@ public class PhaseOutSourceEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
MageObject sourceObject = source.getSourceObjectIfItStillExists(game);
|
||||
if (sourceObject instanceof Permanent) {
|
||||
Permanent permanent = (Permanent) sourceObject;
|
||||
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
|
||||
if (permanent != null) {
|
||||
return permanent.phaseOut(game);
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -54,6 +54,17 @@ public class PreventDamageToSourceEffect extends PreventionEffectImpl {
|
|||
return new PreventDamageToSourceEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game); //To change body of generated methods, choose Tools | Templates.
|
||||
if (duration.isOnlyValidIfNoZoneChange()) {
|
||||
// If source permanent is no longer onto battlefield discard the effect
|
||||
if (source.getSourcePermanentIfItStillExists(game) == null) {
|
||||
discard();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ import mage.game.permanent.Permanent;
|
|||
*/
|
||||
public class RedirectDamageFromSourceToTargetEffect extends RedirectionEffect {
|
||||
|
||||
public RedirectDamageFromSourceToTargetEffect(Duration duration, int amountToRedirect, boolean oneUsage) {
|
||||
super(duration, amountToRedirect, oneUsage);
|
||||
public RedirectDamageFromSourceToTargetEffect(Duration duration, int amountToRedirect, UsageType usageType) {
|
||||
super(duration, amountToRedirect, usageType);
|
||||
staticText = "The next " + amountToRedirect + " damage that would be dealt to {this} this turn is dealt to target creature you control instead.";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,12 +28,18 @@
|
|||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
||||
import mage.abilities.keyword.HasteAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -43,21 +49,25 @@ public class ReturnSourceFromGraveyardToBattlefieldEffect extends OneShotEffect
|
|||
|
||||
private boolean tapped;
|
||||
private boolean ownerControl;
|
||||
private boolean haste;
|
||||
|
||||
public ReturnSourceFromGraveyardToBattlefieldEffect() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
public ReturnSourceFromGraveyardToBattlefieldEffect(boolean tapped) {
|
||||
super(Outcome.PutCreatureInPlay);
|
||||
this.tapped = tapped;
|
||||
setText();
|
||||
this(tapped, true);
|
||||
}
|
||||
|
||||
public ReturnSourceFromGraveyardToBattlefieldEffect(boolean tapped, boolean ownerControl) {
|
||||
this(tapped, ownerControl, false);
|
||||
}
|
||||
|
||||
public ReturnSourceFromGraveyardToBattlefieldEffect(boolean tapped, boolean ownerControl, boolean haste) {
|
||||
super(Outcome.PutCreatureInPlay);
|
||||
this.tapped = tapped;
|
||||
this.ownerControl = ownerControl;
|
||||
this.haste = haste;
|
||||
setText();
|
||||
}
|
||||
|
||||
|
|
@ -65,6 +75,7 @@ public class ReturnSourceFromGraveyardToBattlefieldEffect extends OneShotEffect
|
|||
super(effect);
|
||||
this.tapped = effect.tapped;
|
||||
this.ownerControl = effect.ownerControl;
|
||||
this.haste = effect.haste;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -89,6 +100,14 @@ public class ReturnSourceFromGraveyardToBattlefieldEffect extends OneShotEffect
|
|||
}
|
||||
if (game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) {
|
||||
player.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, true, null);
|
||||
if (haste) {
|
||||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent != null) {
|
||||
ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom);
|
||||
effect.setTargetPointer(new FixedTarget(permanent, game));
|
||||
game.addEffect(effect, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import mage.cards.Card;
|
|||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -81,16 +82,17 @@ public class ReturnToBattlefieldUnderOwnerControlSourceEffect extends OneShotEff
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Card card = game.getCard(source.getSourceId());
|
||||
if (card != null) {
|
||||
if (controller != null && card != null) {
|
||||
// return only from public zones
|
||||
switch (game.getState().getZone(card.getId())) {
|
||||
case EXILED:
|
||||
case COMMAND:
|
||||
case GRAVEYARD:
|
||||
if (zoneChangeCounter < 0 || game.getState().getZoneChangeCounter(card.getId()) == zoneChangeCounter) {
|
||||
Zone currentZone = game.getState().getZone(card.getId());
|
||||
if (card.putOntoBattlefield(game, currentZone, source.getSourceId(), card.getOwnerId(), tapped)) {
|
||||
|
||||
if (controller.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, true, null)) {
|
||||
if (attacking) {
|
||||
game.getCombat().addAttackingCreature(card.getId(), game);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ public class ReturnToHandTargetEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
for (UUID copyId : copyIds) {
|
||||
game.getStack().remove(game.getSpell(copyId));
|
||||
game.getStack().remove(game.getSpell(copyId), game);
|
||||
}
|
||||
return controller.moveCards(cards, Zone.HAND, source, game);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,10 +63,7 @@ public class TapSourceEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent == null) {
|
||||
permanent = game.getPermanentEntering(source.getSourceId());
|
||||
}
|
||||
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
|
||||
if (permanent != null) {
|
||||
if (withoutTrigger) {
|
||||
permanent.setTapped(true);
|
||||
|
|
|
|||
|
|
@ -31,8 +31,6 @@ import java.util.UUID;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterLandPermanent;
|
||||
import mage.filter.predicate.permanent.TappedPredicate;
|
||||
import mage.game.Game;
|
||||
|
|
@ -46,6 +44,11 @@ import mage.util.CardUtil;
|
|||
*/
|
||||
public class UntapLandsEffect extends OneShotEffect {
|
||||
|
||||
private static final FilterLandPermanent filter = new FilterLandPermanent("untapped lands");
|
||||
|
||||
static {
|
||||
filter.add(new TappedPredicate());
|
||||
}
|
||||
private final int amount;
|
||||
private final boolean upTo;
|
||||
|
||||
|
|
@ -70,15 +73,12 @@ public class UntapLandsEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
TargetLandPermanent target = new TargetLandPermanent(upTo ? 0 : amount, amount, StaticFilters.FILTER_LAND, true);
|
||||
int tappedLands = game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game).size();
|
||||
TargetLandPermanent target = new TargetLandPermanent(upTo ? 0 : Math.min(tappedLands, amount), amount, filter, true);
|
||||
if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) {
|
||||
|
||||
// UI Shortcut: Check if any lands are already tapped. If there are equal/fewer than amount, give the option to add those in to be untapped now.
|
||||
FilterPermanent filter = new FilterLandPermanent();
|
||||
filter.add(new TappedPredicate());
|
||||
int tappedLands = game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game).size();
|
||||
|
||||
if (tappedLands <= amount) {
|
||||
if (tappedLands <= amount && upTo) {
|
||||
if (controller.chooseUse(outcome, "Include your tapped lands to untap?", source, game)) {
|
||||
for (Permanent land : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) {
|
||||
target.addTarget(land.getId(), source, game);
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ public class CantBeBlockedByAllSourceEffect extends RestrictionEffect {
|
|||
|
||||
@Override
|
||||
public boolean applies(Permanent permanent, Ability source, Game game) {
|
||||
return source.getSourceId().equals(permanent.getId());
|
||||
return permanent.equals(source.getSourcePermanentIfItStillExists(game));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -38,13 +38,33 @@ import mage.game.permanent.Permanent;
|
|||
*/
|
||||
public class BecomesBlackZombieAdditionEffect extends ContinuousEffectImpl {
|
||||
|
||||
private boolean giveBlackColor = true;
|
||||
|
||||
public BecomesBlackZombieAdditionEffect() {
|
||||
super(Duration.Custom, Outcome.Neutral);
|
||||
staticText = "That creature is a black Zombie in addition to its other colors and types";
|
||||
this.giveBlackColor = true;
|
||||
updateText();
|
||||
}
|
||||
|
||||
public BecomesBlackZombieAdditionEffect(boolean giveBlackColor) {
|
||||
this();
|
||||
this.giveBlackColor = giveBlackColor;
|
||||
updateText();
|
||||
}
|
||||
|
||||
|
||||
public BecomesBlackZombieAdditionEffect(final BecomesBlackZombieAdditionEffect effect) {
|
||||
super(effect);
|
||||
this.giveBlackColor = effect.giveBlackColor;
|
||||
updateText();
|
||||
}
|
||||
|
||||
private void updateText() {
|
||||
if (this.giveBlackColor) {
|
||||
this.staticText = "That creature is a black Zombie in addition to its other colors and types";
|
||||
} else {
|
||||
this.staticText = "That creature is a Zombie in addition to its other types";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -73,7 +93,7 @@ public class BecomesBlackZombieAdditionEffect extends ContinuousEffectImpl {
|
|||
}
|
||||
break;
|
||||
case ColorChangingEffects_5:
|
||||
if (sublayer == SubLayer.NA) {
|
||||
if (sublayer == SubLayer.NA && this.giveBlackColor) {
|
||||
creature.getColor(game).setBlack(true);
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -52,21 +52,24 @@ import java.util.Set;
|
|||
public class BecomesCreatureAllEffect extends ContinuousEffectImpl {
|
||||
|
||||
protected Token token;
|
||||
protected String type;
|
||||
protected String theyAreStillType;
|
||||
private final FilterPermanent filter;
|
||||
private boolean loseColor = true;
|
||||
|
||||
public BecomesCreatureAllEffect(Token token, String type, FilterPermanent filter, Duration duration) {
|
||||
public BecomesCreatureAllEffect(Token token, String theyAreStillType, FilterPermanent filter, Duration duration, boolean loseColor) {
|
||||
super(duration, Outcome.BecomeCreature);
|
||||
this.token = token;
|
||||
this.type = type;
|
||||
this.theyAreStillType = theyAreStillType;
|
||||
this.filter = filter;
|
||||
this.loseColor = loseColor;
|
||||
}
|
||||
|
||||
public BecomesCreatureAllEffect(final BecomesCreatureAllEffect effect) {
|
||||
super(effect);
|
||||
token = effect.token.copy();
|
||||
type = effect.type;
|
||||
this.token = effect.token.copy();
|
||||
this.theyAreStillType = effect.theyAreStillType;
|
||||
this.filter = effect.filter.copy();
|
||||
this.loseColor = effect.loseColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -94,6 +97,7 @@ public class BecomesCreatureAllEffect extends ContinuousEffectImpl {
|
|||
} else {
|
||||
affectedPermanents = new HashSet<>(game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game));
|
||||
}
|
||||
|
||||
for(Permanent permanent : affectedPermanents) {
|
||||
if (permanent != null) {
|
||||
switch (layer) {
|
||||
|
|
@ -106,7 +110,7 @@ public class BecomesCreatureAllEffect extends ContinuousEffectImpl {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (type == null) {
|
||||
if (theyAreStillType == null) {
|
||||
permanent.getSubtype(game).clear();
|
||||
}
|
||||
if (!token.getSubtype(game).isEmpty()) {
|
||||
|
|
@ -114,13 +118,22 @@ public class BecomesCreatureAllEffect extends ContinuousEffectImpl {
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ColorChangingEffects_5:
|
||||
if (sublayer == SubLayer.NA) {
|
||||
if (this.loseColor) {
|
||||
permanent.getColor(game).setBlack(false);
|
||||
permanent.getColor(game).setGreen(false);
|
||||
permanent.getColor(game).setBlue(false);
|
||||
permanent.getColor(game).setWhite(false);
|
||||
permanent.getColor(game).setRed(false);
|
||||
}
|
||||
if (token.getColor(game).hasColor()) {
|
||||
permanent.getColor(game).setColor(token.getColor(game));
|
||||
permanent.getColor(game).addColor(token.getColor(game));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AbilityAddingRemovingEffects_6:
|
||||
if (sublayer == SubLayer.NA) {
|
||||
if (!token.getAbilities().isEmpty()) {
|
||||
|
|
@ -130,6 +143,7 @@ public class BecomesCreatureAllEffect extends ContinuousEffectImpl {
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PTChangingEffects_7:
|
||||
if (sublayer == SubLayer.SetPT_7b) {
|
||||
int power = token.getPower().getValue();
|
||||
|
|
@ -139,6 +153,7 @@ public class BecomesCreatureAllEffect extends ContinuousEffectImpl {
|
|||
permanent.getToughness().setValue(toughness);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -168,8 +183,8 @@ public class BecomesCreatureAllEffect extends ContinuousEffectImpl {
|
|||
sb.append(" become ");
|
||||
}
|
||||
sb.append(token.getDescription());
|
||||
if (type != null && !type.isEmpty()) {
|
||||
sb.append(". They're still ").append(type);
|
||||
if (theyAreStillType != null && !theyAreStillType.isEmpty()) {
|
||||
sb.append(". They're still ").append(theyAreStillType);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ import mage.game.permanent.token.Token;
|
|||
public class BecomesCreatureAttachedEffect extends ContinuousEffectImpl {
|
||||
|
||||
public enum LoseType {
|
||||
NONE, ALL, ALL_BUT_COLOR, ABILITIES, ABILITIES_SUBTYPE_AND_PT, ABILITIES_AND_PT
|
||||
NONE, ALL, ALL_BUT_COLOR, ABILITIES, ABILITIES_SUBTYPE, COLOR
|
||||
}
|
||||
|
||||
protected Token token;
|
||||
|
|
@ -98,7 +98,7 @@ public class BecomesCreatureAttachedEffect extends ContinuousEffectImpl {
|
|||
switch (loseType) {
|
||||
case ALL:
|
||||
case ALL_BUT_COLOR:
|
||||
case ABILITIES_SUBTYPE_AND_PT:
|
||||
case ABILITIES_SUBTYPE:
|
||||
permanent.getSubtype(game).retainAll(SubType.getLandTypes(false));
|
||||
break;
|
||||
}
|
||||
|
|
@ -107,12 +107,12 @@ public class BecomesCreatureAttachedEffect extends ContinuousEffectImpl {
|
|||
permanent.getSubtype(game).add(t);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case ColorChangingEffects_5:
|
||||
if (sublayer == SubLayer.NA) {
|
||||
if (loseType == LoseType.ALL) {
|
||||
if (loseType == LoseType.ALL || loseType == LoseType.COLOR) {
|
||||
permanent.getColor(game).setBlack(false);
|
||||
permanent.getColor(game).setGreen(false);
|
||||
permanent.getColor(game).setBlue(false);
|
||||
|
|
@ -124,29 +124,29 @@ public class BecomesCreatureAttachedEffect extends ContinuousEffectImpl {
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AbilityAddingRemovingEffects_6:
|
||||
if (sublayer == SubLayer.NA) {
|
||||
switch (loseType) {
|
||||
case ALL:
|
||||
case ALL_BUT_COLOR:
|
||||
case ABILITIES:
|
||||
case ABILITIES_AND_PT:
|
||||
case ABILITIES_SUBTYPE_AND_PT:
|
||||
case ABILITIES_SUBTYPE:
|
||||
permanent.removeAllAbilities(source.getSourceId(), game);
|
||||
break;
|
||||
}
|
||||
for (Ability ability : token.getAbilities()) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case PTChangingEffects_7:
|
||||
if (sublayer == SubLayer.SetPT_7b) {
|
||||
permanent.getPower().setValue(token.getPower().getValue());
|
||||
permanent.getToughness().setValue(token.getToughness().getValue());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -31,10 +31,10 @@ import mage.MageObjectReference;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.TokenImpl;
|
||||
import mage.game.permanent.token.Token;
|
||||
|
||||
/**
|
||||
|
|
@ -43,34 +43,36 @@ import mage.game.permanent.token.Token;
|
|||
public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements SourceEffect {
|
||||
|
||||
protected Token token;
|
||||
protected String type;
|
||||
protected String theyAreStillType;
|
||||
protected boolean losePreviousTypes;
|
||||
protected DynamicValue power = null;
|
||||
protected DynamicValue toughness = null;
|
||||
|
||||
public BecomesCreatureSourceEffect(Token token, String type, Duration duration) {
|
||||
this(token, type, duration, false, false);
|
||||
public BecomesCreatureSourceEffect(Token token, String theyAreStillType, Duration duration) {
|
||||
this(token, theyAreStillType, duration, false, false);
|
||||
}
|
||||
|
||||
public BecomesCreatureSourceEffect(Token token, String type, Duration duration, boolean losePreviousTypes, boolean characterDefining) {
|
||||
this(token, type, duration, losePreviousTypes, characterDefining, null, null);
|
||||
public BecomesCreatureSourceEffect(Token token, String theyAreStillType, Duration duration, boolean losePreviousTypes, boolean characterDefining) {
|
||||
this(token, theyAreStillType, duration, losePreviousTypes, characterDefining, null, null);
|
||||
}
|
||||
|
||||
public BecomesCreatureSourceEffect(Token token, String type, Duration duration, boolean losePreviousTypes, boolean characterDefining, DynamicValue power, DynamicValue toughness) {
|
||||
public BecomesCreatureSourceEffect(Token token, String theyAreStillType, Duration duration, boolean losePreviousTypes, boolean characterDefining, DynamicValue power, DynamicValue toughness) {
|
||||
super(duration, Outcome.BecomeCreature);
|
||||
this.characterDefining = characterDefining;
|
||||
this.token = token;
|
||||
this.type = type;
|
||||
this.theyAreStillType = theyAreStillType;
|
||||
this.losePreviousTypes = losePreviousTypes;
|
||||
this.power = power;
|
||||
this.toughness = toughness;
|
||||
setText();
|
||||
|
||||
this.addDependencyType(DependencyType.BecomeCreature);
|
||||
}
|
||||
|
||||
public BecomesCreatureSourceEffect(final BecomesCreatureSourceEffect effect) {
|
||||
super(effect);
|
||||
this.token = effect.token.copy();
|
||||
this.type = effect.type;
|
||||
this.theyAreStillType = effect.theyAreStillType;
|
||||
this.losePreviousTypes = effect.losePreviousTypes;
|
||||
if (effect.power != null) {
|
||||
this.power = effect.power.copy();
|
||||
|
|
@ -108,10 +110,11 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements
|
|||
if (losePreviousTypes) {
|
||||
permanent.getCardType().clear();
|
||||
}
|
||||
for (CardType t : token.getCardType()) {
|
||||
permanent.addCardType(t);
|
||||
for (CardType cardType : token.getCardType()) {
|
||||
permanent.addCardType(cardType);
|
||||
}
|
||||
if (type != null && type.isEmpty() || type == null && permanent.isLand()) {
|
||||
|
||||
if (theyAreStillType != null && theyAreStillType.isEmpty() || theyAreStillType == null && permanent.isLand()) {
|
||||
permanent.getSubtype(game).retainAll(SubType.getLandTypes(false));
|
||||
}
|
||||
if (!token.getSubtype(game).isEmpty()) {
|
||||
|
|
@ -120,6 +123,7 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements
|
|||
permanent.setIsAllCreatureTypes(token.isAllCreatureTypes());
|
||||
}
|
||||
break;
|
||||
|
||||
case ColorChangingEffects_5:
|
||||
if (sublayer == SubLayer.NA) {
|
||||
if (token.getColor(game).hasColor()) {
|
||||
|
|
@ -127,19 +131,20 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AbilityAddingRemovingEffects_6:
|
||||
if (sublayer == SubLayer.NA) {
|
||||
for (Ability ability : token.getAbilities()) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case PTChangingEffects_7:
|
||||
if ((sublayer == SubLayer.CharacteristicDefining_7a && isCharacterDefining())
|
||||
|| (sublayer == SubLayer.SetPT_7b && !isCharacterDefining())) {
|
||||
if (power != null) {
|
||||
permanent.getPower().setValue(power.calculate(game, source, this));
|
||||
permanent.getPower().setValue(power.calculate(game, source, this)); // check all other becomes to use calculate?
|
||||
} else if (token.getPower() != null) {
|
||||
permanent.getPower().setValue(token.getPower().getValue());
|
||||
}
|
||||
|
|
@ -149,11 +154,15 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements
|
|||
permanent.getToughness().setValue(token.getToughness().getValue());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
} else if (duration == Duration.Custom) {
|
||||
this.discard();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -163,8 +172,8 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements
|
|||
}
|
||||
|
||||
private void setText() {
|
||||
if (type != null && !type.isEmpty()) {
|
||||
staticText = duration.toString() + " {this} becomes a " + token.getDescription() + " that's still a " + this.type;
|
||||
if (theyAreStillType != null && !theyAreStillType.isEmpty()) {
|
||||
staticText = duration.toString() + " {this} becomes a " + token.getDescription() + " that's still a " + this.theyAreStillType;
|
||||
} else {
|
||||
staticText = duration.toString() + " {this} becomes a " + token.getDescription();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ import mage.constants.Duration;
|
|||
import mage.constants.Layer;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubLayer;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.predicate.mageobject.SubtypePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
|
|
@ -50,6 +53,7 @@ public class ExchangeControlTargetEffect extends ContinuousEffectImpl {
|
|||
private String rule;
|
||||
private boolean withSource;
|
||||
private boolean withSecondTarget;
|
||||
private boolean destroyAttachedAuras;
|
||||
private Map<UUID, Integer> zoneChangeCounter = new HashMap<>();
|
||||
private Map<UUID, UUID> lockedControllers = new HashMap<>();
|
||||
|
||||
|
|
@ -62,9 +66,14 @@ public class ExchangeControlTargetEffect extends ContinuousEffectImpl {
|
|||
}
|
||||
|
||||
public ExchangeControlTargetEffect(Duration duration, String rule, boolean withSource, boolean withSecondTarget) {
|
||||
this(duration, rule, withSource, withSecondTarget, false);
|
||||
}
|
||||
|
||||
public ExchangeControlTargetEffect(Duration duration, String rule, boolean withSource, boolean withSecondTarget, boolean destroyAttachedAuras) {
|
||||
super(duration, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
|
||||
this.withSource = withSource;
|
||||
this.withSecondTarget = withSecondTarget;
|
||||
this.destroyAttachedAuras = destroyAttachedAuras;
|
||||
this.rule = rule;
|
||||
}
|
||||
|
||||
|
|
@ -73,6 +82,7 @@ public class ExchangeControlTargetEffect extends ContinuousEffectImpl {
|
|||
this.rule = effect.rule;
|
||||
this.withSource = effect.withSource;
|
||||
this.withSecondTarget = effect.withSecondTarget;
|
||||
this.destroyAttachedAuras = effect.destroyAttachedAuras;
|
||||
this.lockedControllers = new HashMap<>(effect.lockedControllers);
|
||||
this.zoneChangeCounter = new HashMap<>(effect.zoneChangeCounter);
|
||||
}
|
||||
|
|
@ -141,6 +151,16 @@ public class ExchangeControlTargetEffect extends ContinuousEffectImpl {
|
|||
}
|
||||
permanent.changeControllerId(lockedControllers.get(permanent.getId()), game);
|
||||
permanent.getAbilities().setControllerId(lockedControllers.get(permanent.getId()));
|
||||
if (destroyAttachedAuras) {
|
||||
FilterPermanent filter = new FilterPermanent();
|
||||
filter.add(new SubtypePredicate(SubType.AURA));
|
||||
for (UUID attachmentId : new HashSet<>(permanent.getAttachments())) {
|
||||
Permanent attachment = game.getPermanent(attachmentId);
|
||||
if (attachment != null && filter.match(attachment, game)) {
|
||||
attachment.destroy(source.getSourceId(), game, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!toDelete.isEmpty()) {
|
||||
for (UUID uuid : toDelete) {
|
||||
|
|
|
|||
|
|
@ -92,6 +92,13 @@ public class GainAbilitySourceEffect extends ContinuousEffectImpl implements Sou
|
|||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game);
|
||||
if (!onCard && Duration.WhileOnBattlefield != duration) {
|
||||
// If source permanent is no longer onto battlefield discard the effect
|
||||
if (source.getSourcePermanentIfItStillExists(game) == null) {
|
||||
discard();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (affectedObjectsSet) {
|
||||
Permanent permanent = game.getPermanentEntering(source.getSourceId());
|
||||
if (permanent != null) {
|
||||
|
|
|
|||
|
|
@ -12,38 +12,50 @@ import mage.constants.Outcome;
|
|||
import mage.constants.SubLayer;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Noahsark
|
||||
*/
|
||||
public class LoseAbilitySourceEffect extends ContinuousEffectImpl{
|
||||
public class LoseAbilitySourceEffect extends ContinuousEffectImpl {
|
||||
|
||||
protected Ability ability;
|
||||
|
||||
public LoseAbilitySourceEffect(Ability ability){
|
||||
public LoseAbilitySourceEffect(Ability ability) {
|
||||
this(ability, Duration.WhileOnBattlefield);
|
||||
}
|
||||
|
||||
public LoseAbilitySourceEffect(Ability ability, Duration duration){
|
||||
public LoseAbilitySourceEffect(Ability ability, Duration duration) {
|
||||
super(duration, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.LoseAbility);
|
||||
this.ability = ability;
|
||||
staticText = "{this} loses " + ability.getRule() + ' ' + duration.toString();
|
||||
}
|
||||
|
||||
public LoseAbilitySourceEffect(final LoseAbilitySourceEffect effect){
|
||||
public LoseAbilitySourceEffect(final LoseAbilitySourceEffect effect) {
|
||||
super(effect);
|
||||
this.ability = effect.ability.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoseAbilitySourceEffect copy(){
|
||||
public LoseAbilitySourceEffect copy() {
|
||||
return new LoseAbilitySourceEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source){
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game); //To change body of generated methods, choose Tools | Templates.
|
||||
if (duration.isOnlyValidIfNoZoneChange()) {
|
||||
// If source permanent is no longer onto battlefield discard the effect
|
||||
if (source.getSourcePermanentIfItStillExists(game) == null) {
|
||||
discard();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent != null){
|
||||
if (permanent != null) {
|
||||
// 112.10
|
||||
while (permanent.getAbilities().remove(ability)) {
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,17 @@ public class LoseCreatureTypeSourceEffect extends ContinuousEffectImpl implement
|
|||
return new LoseCreatureTypeSourceEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game); //To change body of generated methods, choose Tools | Templates.
|
||||
if (duration.isOnlyValidIfNoZoneChange()) {
|
||||
// If source permanent is no longer onto battlefield discard the effect
|
||||
if (source.getSourcePermanentIfItStillExists(game) == null) {
|
||||
discard();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
|
||||
if (dynamicValue.calculate(game, source, this) >= lessThan) {
|
||||
|
|
|
|||
|
|
@ -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,19 +20,19 @@
|
|||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.abilities.effects.common.continuous;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Layer;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubLayer;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
|
|
@ -55,14 +55,29 @@ public class SwitchPowerToughnessSourceEffect extends ContinuousEffectImpl {
|
|||
return new SwitchPowerToughnessSourceEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game); //To change body of generated methods, choose Tools | Templates.
|
||||
if (duration.isOnlyValidIfNoZoneChange()) {
|
||||
// If source permanent is no longer onto battlefield discard the effect
|
||||
if (source.getSourcePermanentIfItStillExists(game) == null) {
|
||||
discard();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent target = game.getPermanent(source.getSourceId());
|
||||
if (target != null) {
|
||||
int power = target.getPower().getValue();
|
||||
target.getPower().setValue(target.getToughness().getValue());
|
||||
target.getToughness().setValue(power);
|
||||
Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game);
|
||||
if (sourcePermanent != null) {
|
||||
int power = sourcePermanent.getPower().getValue();
|
||||
sourcePermanent.getPower().setValue(sourcePermanent.getToughness().getValue());
|
||||
sourcePermanent.getToughness().setValue(power);
|
||||
return true;
|
||||
} else {
|
||||
if (duration.isOnlyValidIfNoZoneChange()) {
|
||||
discard();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ public class SpellsCostReductionAllEffect extends CostModificationEffectImpl {
|
|||
private FilterCard filter;
|
||||
private int amount;
|
||||
private final boolean upTo;
|
||||
private boolean onlyControlled;
|
||||
|
||||
public SpellsCostReductionAllEffect(int amount) {
|
||||
this(new FilterCard("Spells"), amount);
|
||||
|
|
@ -63,19 +64,24 @@ public class SpellsCostReductionAllEffect extends CostModificationEffectImpl {
|
|||
}
|
||||
|
||||
public SpellsCostReductionAllEffect(FilterCard filter, int amount, boolean upTo) {
|
||||
this(filter, amount, upTo, false);
|
||||
}
|
||||
|
||||
public SpellsCostReductionAllEffect(FilterCard filter, int amount, boolean upTo, boolean onlyControlled) {
|
||||
super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST);
|
||||
this.filter = filter;
|
||||
this.amount = amount;
|
||||
this.upTo = upTo;
|
||||
|
||||
this.onlyControlled = onlyControlled;
|
||||
this.staticText = filter.getMessage() + " cost " + (upTo ? "up to " : "") + '{' + amount + "} less to cast";
|
||||
}
|
||||
|
||||
protected SpellsCostReductionAllEffect(SpellsCostReductionAllEffect effect) {
|
||||
protected SpellsCostReductionAllEffect(final SpellsCostReductionAllEffect effect) {
|
||||
super(effect);
|
||||
this.filter = effect.filter;
|
||||
this.amount = effect.amount;
|
||||
this.upTo = effect.upTo;
|
||||
this.onlyControlled = effect.onlyControlled;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -136,6 +142,9 @@ public class SpellsCostReductionAllEffect extends CostModificationEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean applies(Ability abilityToModify, Ability source, Game game) {
|
||||
if (onlyControlled && abilityToModify.getControllerId().equals(source.getControllerId())) {
|
||||
return false;
|
||||
}
|
||||
if (abilityToModify instanceof SpellAbility) {
|
||||
Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId());
|
||||
if (spell != null) {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,11 @@ import mage.game.Game;
|
|||
public class SpellsCostReductionAllOfChosenSubtypeEffect extends SpellsCostReductionAllEffect {
|
||||
|
||||
public SpellsCostReductionAllOfChosenSubtypeEffect(FilterCard filter, int amount) {
|
||||
super(filter, amount);
|
||||
this(filter, amount, false);
|
||||
}
|
||||
|
||||
public SpellsCostReductionAllOfChosenSubtypeEffect(FilterCard filter, int amount, boolean onlyControlled) {
|
||||
super(filter, amount, false, onlyControlled);
|
||||
}
|
||||
|
||||
public SpellsCostReductionAllOfChosenSubtypeEffect(final SpellsCostReductionAllOfChosenSubtypeEffect effect) {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ import mage.game.permanent.Permanent;
|
|||
* @author TheElk801
|
||||
*/
|
||||
public class RemoveAllCountersSourceEffect extends OneShotEffect {
|
||||
|
||||
|
||||
private final CounterType counterType;
|
||||
|
||||
public RemoveAllCountersSourceEffect(CounterType counterType) {
|
||||
|
|
@ -55,13 +55,13 @@ public class RemoveAllCountersSourceEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if(permanent != null) {
|
||||
int count = permanent.getCounters(game).getCount(counterType);
|
||||
permanent.removeCounters(counterType.getName(), count, game);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
|
||||
if (permanent != null) {
|
||||
int count = permanent.getCounters(game).getCount(counterType);
|
||||
permanent.removeCounters(counterType.getName(), count, game);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public class RemoveCounterSourceEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
|
||||
if (permanent != null) {
|
||||
int toRemove = Math.min(counter.getCount(), permanent.getCounters(game).getCount(counter.getName()));
|
||||
if (toRemove > 0) {
|
||||
|
|
@ -67,18 +67,20 @@ public class RemoveCounterSourceEffect extends OneShotEffect {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
Card card = game.getCard(source.getSourceId());
|
||||
if (card != null) {
|
||||
int toRemove = Math.min(counter.getCount(), card.getCounters(game).getCount(counter.getName()));
|
||||
if (toRemove > 0) {
|
||||
card.removeCounters(counter.getName(), toRemove, game);
|
||||
if (!game.isSimulation()) {
|
||||
game.informPlayers("Removed " + toRemove + ' ' + counter.getName()
|
||||
+ " counter from " + card.getLogName()
|
||||
+ " (" + card.getCounters(game).getCount(counter.getName()) + " left)");
|
||||
if (!(source.getSourceObject(game) instanceof Permanent)) {
|
||||
Card card = game.getCard(source.getSourceId());
|
||||
if (card != null) {
|
||||
int toRemove = Math.min(counter.getCount(), card.getCounters(game).getCount(counter.getName()));
|
||||
if (toRemove > 0) {
|
||||
card.removeCounters(counter.getName(), toRemove, game);
|
||||
if (!game.isSimulation()) {
|
||||
game.informPlayers("Removed " + toRemove + ' ' + counter.getName()
|
||||
+ " counter from " + card.getLogName()
|
||||
+ " (" + card.getCounters(game).getCount(counter.getName()) + " left)");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ public class SweepEffect extends OneShotEffect {
|
|||
public SweepEffect(SubType sweepSubtype) {
|
||||
super(Outcome.Benefit);
|
||||
this.sweepSubtype = sweepSubtype;
|
||||
this.staticText = "<i>Sweep</i> - Return any number of " + sweepSubtype + (sweepSubtype.getDescription().endsWith("s") ? "" : "s") + " you control to their owner's hand";
|
||||
this.staticText = "<i>Sweep</i> — Return any number of " + sweepSubtype + (sweepSubtype.getDescription().endsWith("s") ? "" : "s") + " you control to their owner's hand";
|
||||
}
|
||||
|
||||
public SweepEffect(final SweepEffect effect) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package mage.abilities.effects.mana;
|
||||
|
||||
import mage.Mana;
|
||||
import mage.abilities.mana.builder.ConditionalManaBuilder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class AddConditionalColorlessManaEffect extends AddConditionalManaEffect {
|
||||
|
||||
public AddConditionalColorlessManaEffect(int amount, ConditionalManaBuilder manaBuilder) {
|
||||
super(Mana.ColorlessMana(amount), manaBuilder);
|
||||
}
|
||||
|
||||
public AddConditionalColorlessManaEffect(final AddConditionalColorlessManaEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AddConditionalColorlessManaEffect copy() {
|
||||
return new AddConditionalColorlessManaEffect(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,10 +3,11 @@
|
|||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package mage.abilities.effects.common;
|
||||
package mage.abilities.effects.mana;
|
||||
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.abilities.mana.builder.ConditionalManaBuilder;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
|
@ -49,7 +50,11 @@ public class AddConditionalManaEffect extends ManaEffect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Mana getMana(Game game, Ability source) {
|
||||
public Mana produceMana(boolean netMana, Game game, Ability source) {
|
||||
return manaBuilder.setMana(mana, source, game).build();
|
||||
}
|
||||
|
||||
public Mana getMana() {
|
||||
return mana;
|
||||
}
|
||||
}
|
||||
|
|
@ -25,12 +25,14 @@
|
|||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.abilities.effects.common;
|
||||
package mage.abilities.effects.mana;
|
||||
|
||||
import mage.ConditionalMana;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.abilities.mana.builder.ConditionalManaBuilder;
|
||||
import mage.choices.ChoiceColor;
|
||||
import mage.game.Game;
|
||||
|
|
@ -63,9 +65,9 @@ public class AddConditionalManaOfAnyColorEffect extends ManaEffect {
|
|||
staticText = "Add "
|
||||
+ (amount instanceof StaticValue ? (CardUtil.numberToText(((StaticValue) amount).toString())) : "")
|
||||
+ " mana "
|
||||
+ (oneChoice ? "of any"
|
||||
+ (amount instanceof StaticValue && (((StaticValue) amount).toString()).equals("1") ? "" : " one")
|
||||
+ " color" : "in any combination of colors")
|
||||
+ (oneChoice || (amount instanceof StaticValue && (((StaticValue) amount).toString()).equals("1"))
|
||||
? "of any" + (amount instanceof StaticValue && (((StaticValue) amount).toString()).equals("1") ? "" : " one") + " color"
|
||||
: "in any combination of colors")
|
||||
+ ". " + manaBuilder.getRule();
|
||||
}
|
||||
|
||||
|
|
@ -84,39 +86,44 @@ public class AddConditionalManaOfAnyColorEffect extends ManaEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller == null) {
|
||||
return false;
|
||||
if (controller != null) {
|
||||
checkToFirePossibleEvents(getMana(game, source), game, source);
|
||||
controller.getManaPool().addMana(getMana(game, source), game, source);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana produceMana(boolean netMana, Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller == null) {
|
||||
return null;
|
||||
}
|
||||
ConditionalMana mana = null;
|
||||
int value = amount.calculate(game, source, this);
|
||||
boolean result = false;
|
||||
ChoiceColor choice = new ChoiceColor(true);
|
||||
|
||||
for (int i = 0; i < value; i++) {
|
||||
controller.choose(outcome, choice, game);
|
||||
if (choice.getChoice() == null) {
|
||||
return false;
|
||||
controller.choose(outcome, choice, game);
|
||||
}
|
||||
Mana mana = choice.getMana(1);
|
||||
if (mana != null) {
|
||||
mana = manaBuilder.setMana(mana, source, game).build();
|
||||
if (choice.getChoice() == null) {
|
||||
return null;
|
||||
}
|
||||
if (mana != null) {
|
||||
checkToFirePossibleEvents(mana, game, source);
|
||||
controller.getManaPool().addMana(mana, game, source);
|
||||
result = true;
|
||||
}
|
||||
if (!oneChoice) {
|
||||
if (oneChoice) {
|
||||
mana = new ConditionalMana(manaBuilder.setMana(choice.getMana(value), source, game).build());
|
||||
break;
|
||||
} else {
|
||||
if (mana == null) {
|
||||
mana = new ConditionalMana(manaBuilder.setMana(choice.getMana(1), source, game).build());
|
||||
} else {
|
||||
mana.add(choice.getMana(1));
|
||||
}
|
||||
choice.clearChoice();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
return mana;
|
||||
|
||||
@Override
|
||||
public Mana getMana(Game game, Ability source) {
|
||||
//TODO: TAP_FOR_MANA Event does not support currently to get an amount > 1 of conditional mana
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -25,10 +25,13 @@
|
|||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.abilities.effects.common;
|
||||
package mage.abilities.effects.mana;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.choices.ChoiceColor;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
|
@ -53,14 +56,12 @@ public class AddManaAnyColorAttachedControllerEffect extends ManaEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Permanent enchantment = game.getPermanent(source.getSourceId());
|
||||
if (enchantment != null) {
|
||||
Permanent land = game.getPermanent(enchantment.getAttachedTo());
|
||||
if (land != null) {
|
||||
Player player = game.getPlayer(land.getControllerId());
|
||||
ChoiceColor choice = new ChoiceColor();
|
||||
if (player != null && player.choose(outcome, choice, game)) {
|
||||
Mana mana = choice.getMana(1);
|
||||
checkToFirePossibleEvents(mana, game, source);
|
||||
player.getManaPool().addMana(mana, game, source);
|
||||
Permanent permanentattachedTo = game.getPermanent(enchantment.getAttachedTo());
|
||||
if (permanentattachedTo != null) {
|
||||
Player player = game.getPlayer(permanentattachedTo.getControllerId());
|
||||
if (player != null) {
|
||||
checkToFirePossibleEvents(getMana(game, source), game, source);
|
||||
player.getManaPool().addMana(getMana(game, source), game, source);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -74,8 +75,30 @@ public class AddManaAnyColorAttachedControllerEffect extends ManaEffect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Mana getMana(Game game, Ability source) {
|
||||
return null;
|
||||
public Mana produceMana(boolean netMana, Game game, Ability source) {
|
||||
Permanent enchantment = game.getPermanent(source.getSourceId());
|
||||
if (enchantment != null) {
|
||||
Permanent land = game.getPermanent(enchantment.getAttachedTo());
|
||||
if (land != null) {
|
||||
Player player = game.getPlayer(land.getControllerId());
|
||||
ChoiceColor choice = new ChoiceColor();
|
||||
if (player != null && player.choose(outcome, choice, game)) {
|
||||
return choice.getMana(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Mana();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Mana> getNetMana(Game game, Ability source) {
|
||||
ArrayList<Mana> netMana = new ArrayList<>();
|
||||
netMana.add(Mana.GreenMana(1));
|
||||
netMana.add(Mana.WhiteMana(1));
|
||||
netMana.add(Mana.BlueMana(1));
|
||||
netMana.add(Mana.RedMana(1));
|
||||
netMana.add(Mana.BlackMana(1));
|
||||
return netMana;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package mage.abilities.effects.mana;
|
||||
|
||||
import mage.Mana;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.constants.ColoredManaSymbol;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class AddManaChosenColorEffect extends ManaEffect {
|
||||
|
||||
public AddManaChosenColorEffect() {
|
||||
super();
|
||||
staticText = "Add one mana of the chosen color";
|
||||
}
|
||||
|
||||
public AddManaChosenColorEffect(final AddManaChosenColorEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null) {
|
||||
player.getManaPool().addMana(getMana(game, source), game, source);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana produceMana(boolean netMana, Game game, Ability source) {
|
||||
ObjectColor color = (ObjectColor) game.getState().getValue(source.getSourceId() + "_color");
|
||||
if (color != null) {
|
||||
return new Mana(ColoredManaSymbol.lookup(color.toString().charAt(0)));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AddManaChosenColorEffect copy() {
|
||||
return new AddManaChosenColorEffect(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -25,14 +25,16 @@
|
|||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.abilities.effects.common;
|
||||
package mage.abilities.effects.mana;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.constants.ColoredManaSymbol;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
|
@ -90,6 +92,17 @@ public class AddManaInAnyCombinationEffect extends ManaEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null) {
|
||||
checkToFirePossibleEvents(getMana(game, source), game, source);
|
||||
player.getManaPool().addMana(getMana(game, source), game, source);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana produceMana(boolean netMana, Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null) {
|
||||
Mana mana = new Mana();
|
||||
|
|
@ -111,16 +124,17 @@ public class AddManaInAnyCombinationEffect extends ManaEffect {
|
|||
}
|
||||
}
|
||||
}
|
||||
checkToFirePossibleEvents(mana, game, source);
|
||||
player.getManaPool().addMana(mana, game, source);
|
||||
return true;
|
||||
|
||||
return mana;
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana getMana(Game game, Ability source) {
|
||||
return null;
|
||||
public List<Mana> getNetMana(Game game, Ability source) {
|
||||
ArrayList<Mana> netMana = new ArrayList<>();
|
||||
netMana.add(new Mana(0, 0, 0, 0, 0, 0, amount.calculate(game, source, this), 0));
|
||||
return netMana;
|
||||
}
|
||||
|
||||
private String setText() {
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.abilities.effects.common;
|
||||
package mage.abilities.effects.mana;
|
||||
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
|
|
@ -91,7 +91,7 @@ public class AddManaOfAnyColorEffect extends BasicManaEffect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Mana getMana() {
|
||||
public Mana getManaTemplate() {
|
||||
return new Mana(0, 0, 0, 0, 0, 0, amount, 0);
|
||||
}
|
||||
|
||||
|
|
@ -25,10 +25,11 @@
|
|||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.abilities.effects.common;
|
||||
package mage.abilities.effects.mana;
|
||||
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.choices.Choice;
|
||||
import mage.choices.ChoiceColor;
|
||||
import mage.game.Game;
|
||||
|
|
@ -58,6 +59,24 @@ public class AddManaOfAnyTypeProducedEffect extends ManaEffect {
|
|||
if (targetController == null) {
|
||||
return false;
|
||||
}
|
||||
checkToFirePossibleEvents(getMana(game, source), game, source);
|
||||
targetController.getManaPool().addMana(getMana(game, source), game, source);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana produceMana(boolean netMana, Game game, Ability source) {
|
||||
if (netMana) {
|
||||
return null;
|
||||
}
|
||||
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
if (permanent != null) {
|
||||
Player targetController = game.getPlayer(permanent.getControllerId());
|
||||
if (targetController == null) {
|
||||
return null;
|
||||
}
|
||||
Mana types = (Mana) this.getValue("mana");
|
||||
Choice choice = new ChoiceColor(true);
|
||||
choice.getChoices().clear();
|
||||
|
|
@ -80,15 +99,16 @@ public class AddManaOfAnyTypeProducedEffect extends ManaEffect {
|
|||
if (types.getColorless() > 0) {
|
||||
choice.getChoices().add("Colorless");
|
||||
}
|
||||
Mana newMana = new Mana();
|
||||
if (!choice.getChoices().isEmpty()) {
|
||||
if (choice.getChoices().size() == 1) {
|
||||
choice.setChoice(choice.getChoices().iterator().next());
|
||||
} else {
|
||||
if (!targetController.choose(outcome, choice, game)) {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Mana newMana = new Mana();
|
||||
|
||||
switch (choice.getChoice()) {
|
||||
case "Black":
|
||||
newMana.setBlack(1);
|
||||
|
|
@ -109,13 +129,10 @@ public class AddManaOfAnyTypeProducedEffect extends ManaEffect {
|
|||
newMana.setColorless(1);
|
||||
break;
|
||||
}
|
||||
checkToFirePossibleEvents(newMana, game, source);
|
||||
targetController.getManaPool().addMana(newMana, game, source);
|
||||
|
||||
}
|
||||
return true;
|
||||
return newMana;
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -123,8 +140,4 @@ public class AddManaOfAnyTypeProducedEffect extends ManaEffect {
|
|||
return new AddManaOfAnyTypeProducedEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana getMana(Game game, Ability source) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package mage.abilities.effects.common;
|
||||
package mage.abilities.effects.mana;
|
||||
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
|
|
@ -3,11 +3,11 @@
|
|||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package mage.abilities.effects.common;
|
||||
package mage.abilities.effects.mana;
|
||||
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
|
|
@ -15,28 +15,30 @@ import mage.players.Player;
|
|||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class AddManaToManaPoolTargetControllerEffect extends ManaEffect {
|
||||
|
||||
protected Mana mana;
|
||||
protected boolean emptyOnlyOnTurnsEnd;
|
||||
|
||||
|
||||
public AddManaToManaPoolTargetControllerEffect(Mana mana, String textManaPoolOwner) {
|
||||
this(mana, textManaPoolOwner, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds mana to the mana pool of target pointer player
|
||||
*
|
||||
*
|
||||
* @param mana mana that will be added to the pool
|
||||
* @param textManaPoolOwner text that references to the mana pool owner (e.g. "damaged player's")
|
||||
* @param emptyOnTurnsEnd if set, the mana will empty only on end of turnstep
|
||||
*
|
||||
*/
|
||||
* @param textManaPoolOwner text that references to the mana pool owner
|
||||
* (e.g. "damaged player's")
|
||||
* @param emptyOnTurnsEnd if set, the mana will empty only on end of
|
||||
* turnstep
|
||||
*
|
||||
*/
|
||||
public AddManaToManaPoolTargetControllerEffect(Mana mana, String textManaPoolOwner, boolean emptyOnTurnsEnd) {
|
||||
super();
|
||||
this.mana = mana;
|
||||
this.emptyOnlyOnTurnsEnd = emptyOnTurnsEnd;
|
||||
this.staticText = (textManaPoolOwner.equals("their")?"that player adds ":"add ") + mana.toString() + " to " + textManaPoolOwner + " mana pool";
|
||||
this.staticText = (textManaPoolOwner.equals("their") ? "that player adds " : "add ") + mana.toString() + " to " + textManaPoolOwner + " mana pool";
|
||||
}
|
||||
|
||||
public AddManaToManaPoolTargetControllerEffect(final AddManaToManaPoolTargetControllerEffect effect) {
|
||||
|
|
@ -54,15 +56,17 @@ public class AddManaToManaPoolTargetControllerEffect extends ManaEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||
if (player != null) {
|
||||
player.getManaPool().addMana(mana, game, source, emptyOnlyOnTurnsEnd);
|
||||
player.getManaPool().addMana(getMana(game, source), game, source, emptyOnlyOnTurnsEnd);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana getMana(Game game, Ability source) {
|
||||
return mana;
|
||||
public Mana produceMana(boolean netMana, Game game, Ability source) {
|
||||
if (netMana) {
|
||||
return null;
|
||||
}
|
||||
return mana.copy();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,29 +1,31 @@
|
|||
package mage.abilities.effects.common;
|
||||
package mage.abilities.effects.mana;
|
||||
|
||||
import mage.ConditionalMana;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.game.Game;
|
||||
|
||||
public class BasicManaEffect extends ManaEffect {
|
||||
|
||||
protected Mana mana;
|
||||
protected Mana manaTemplate;
|
||||
|
||||
public BasicManaEffect(Mana mana) {
|
||||
super();
|
||||
this.mana = mana;
|
||||
this.manaTemplate = mana;
|
||||
staticText = "add " + mana.toString();
|
||||
}
|
||||
|
||||
public BasicManaEffect(ConditionalMana conditionalMana) {
|
||||
super();
|
||||
this.mana = conditionalMana;
|
||||
staticText = "add " + mana.toString() + " " + conditionalMana.getDescription();
|
||||
this.manaTemplate = conditionalMana;
|
||||
staticText = "add " + manaTemplate.toString() + " " + conditionalMana.getDescription();
|
||||
}
|
||||
|
||||
public BasicManaEffect(final BasicManaEffect effect) {
|
||||
super(effect);
|
||||
this.mana = effect.mana.copy();
|
||||
this.manaTemplate = effect.manaTemplate.copy();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -33,16 +35,17 @@ public class BasicManaEffect extends ManaEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
game.getPlayer(source.getControllerId()).getManaPool().addMana(mana, game, source);
|
||||
game.getPlayer(source.getControllerId()).getManaPool().addMana(getMana(game, source), game, source);
|
||||
return true;
|
||||
}
|
||||
|
||||
public Mana getMana() {
|
||||
return mana;
|
||||
public Mana getManaTemplate() {
|
||||
return manaTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana getMana(Game game, Ability source) {
|
||||
return mana;
|
||||
public Mana produceMana(boolean netMana, Game game, Ability source) {
|
||||
return manaTemplate.copy();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -3,14 +3,17 @@
|
|||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package mage.abilities.effects.common;
|
||||
package mage.abilities.effects.mana;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
|
@ -69,6 +72,24 @@ public class DoUnlessAnyPlayerPaysManaEffect extends ManaEffect {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Mana> getNetMana(Game game, Ability source) {
|
||||
if (cost.canPay(source, source.getSourceId(), source.getControllerId(), game)) {
|
||||
return manaEffect.getNetMana(game, source);
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana getMana(Game game, Ability source) {
|
||||
return manaEffect.getMana(game, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana produceMana(boolean netMana, Game game, Ability source) {
|
||||
return manaEffect.produceMana(netMana, game, source);
|
||||
}
|
||||
|
||||
protected Player getPayingPlayer(Game game, Ability source) {
|
||||
return game.getPlayer(source.getControllerId());
|
||||
}
|
||||
|
|
@ -81,11 +102,6 @@ public class DoUnlessAnyPlayerPaysManaEffect extends ManaEffect {
|
|||
return manaEffect.getText(mode) + " unless any player pays " + cost.getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana getMana(Game game, Ability source) {
|
||||
return manaEffect.getMana(game, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManaEffect copy() {
|
||||
return new DoUnlessAnyPlayerPaysManaEffect(this);
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.abilities.effects.common;
|
||||
package mage.abilities.effects.mana;
|
||||
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
|
|
@ -64,10 +64,10 @@ public class DynamicManaEffect extends BasicManaEffect {
|
|||
* @param mana
|
||||
* @param amount
|
||||
* @param text
|
||||
* @param oneChoice is all mana from the same colour or if false the player
|
||||
* can choose different colours
|
||||
* @param oneChoice is all manaTemplate from the same colour or if false the
|
||||
* player can choose different colours
|
||||
* @param netAmount a dynamic value that calculates the possible available
|
||||
* mana (e.g. if you have to pay by removing counters from source)
|
||||
* manaTemplate (e.g. if you have to pay by removing counters from source)
|
||||
*/
|
||||
public DynamicManaEffect(Mana mana, DynamicValue amount, String text, boolean oneChoice, DynamicValue netAmount) {
|
||||
super(mana);
|
||||
|
|
@ -96,9 +96,8 @@ public class DynamicManaEffect extends BasicManaEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Mana computedMana = computeMana(false, game, source);
|
||||
checkToFirePossibleEvents(computedMana, game, source);
|
||||
game.getPlayer(source.getControllerId()).getManaPool().addMana(computedMana, game, source);
|
||||
checkToFirePossibleEvents(getMana(game, source), game, source);
|
||||
game.getPlayer(source.getControllerId()).getManaPool().addMana(getMana(game, source), game, source);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -111,33 +110,29 @@ public class DynamicManaEffect extends BasicManaEffect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Mana getMana(Game game, Ability source) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Mana computeMana(boolean netMana, Game game, Ability source) {
|
||||
public Mana produceMana(boolean netMana, Game game, Ability source) {
|
||||
Mana computedMana = new Mana();
|
||||
int count;
|
||||
if (netMana && netAmount != null) {
|
||||
// calculate the maximum available mana
|
||||
// calculate the maximum available manaTemplate
|
||||
count = netAmount.calculate(game, source, this);
|
||||
} else {
|
||||
count = amount.calculate(game, source, this);
|
||||
}
|
||||
|
||||
if (mana.getBlack() > 0) {
|
||||
if (manaTemplate.getBlack() > 0) {
|
||||
computedMana.setBlack(count);
|
||||
} else if (mana.getBlue() > 0) {
|
||||
} else if (manaTemplate.getBlue() > 0) {
|
||||
computedMana.setBlue(count);
|
||||
} else if (mana.getGreen() > 0) {
|
||||
} else if (manaTemplate.getGreen() > 0) {
|
||||
computedMana.setGreen(count);
|
||||
} else if (mana.getRed() > 0) {
|
||||
} else if (manaTemplate.getRed() > 0) {
|
||||
computedMana.setRed(count);
|
||||
} else if (mana.getWhite() > 0) {
|
||||
} else if (manaTemplate.getWhite() > 0) {
|
||||
computedMana.setWhite(count);
|
||||
} else if (mana.getColorless() > 0) {
|
||||
} else if (manaTemplate.getColorless() > 0) {
|
||||
computedMana.setColorless(count);
|
||||
} else if (mana.getAny() > 0) {
|
||||
} else if (manaTemplate.getAny() > 0) {
|
||||
if (netMana) {
|
||||
computedMana.setAny(count);
|
||||
} else {
|
||||
|
|
@ -72,7 +72,7 @@ public class BattalionAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return new StringBuilder("<i>Battalion</i> - Whenever {this} and at least two other creatures attack, ").append(super.getRule()).toString() ;
|
||||
return new StringBuilder("<i>Battalion</i> — Whenever {this} and at least two other creatures attack, ").append(super.getRule()).toString() ;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ public class BloodrushAbility extends ActivatedAbilityImpl {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
StringBuilder sb = new StringBuilder("<i>Bloodrush</i> - ");
|
||||
StringBuilder sb = new StringBuilder("<i>Bloodrush</i> — ");
|
||||
sb.append(super.getRule());
|
||||
return sb.toString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ public class ChannelAbility extends ActivatedAbilityImpl {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
StringBuilder sb = new StringBuilder("<i>Channel</i> - ");
|
||||
StringBuilder sb = new StringBuilder("<i>Channel</i> — ");
|
||||
sb.append(super.getRule());
|
||||
if(this.timing == TimingRule.SORCERY) {
|
||||
sb.append(" Activate this ability only any time you could cast a sorcery.");
|
||||
|
|
|
|||
|
|
@ -103,6 +103,6 @@ public class HeroicAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return new StringBuilder("<i>Heroic</i> - Whenever you cast a spell that targets {this}, ").append(super.getRule()).toString();
|
||||
return new StringBuilder("<i>Heroic</i> — Whenever you cast a spell that targets {this}, ").append(super.getRule()).toString();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,6 +71,6 @@ public class InspiredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "<i>Inspired</i> - Whenever {this} becomes untapped, " + super.getRule();
|
||||
return "<i>Inspired</i> — Whenever {this} becomes untapped, " + super.getRule();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
*/
|
||||
package mage.abilities.keyword;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.ObjectColor;
|
||||
|
|
@ -53,6 +55,7 @@ public class ProtectionAbility extends StaticAbility {
|
|||
|
||||
protected Filter filter;
|
||||
protected boolean removeAuras;
|
||||
protected static List<ObjectColor> colors = new ArrayList<>();
|
||||
protected UUID auraIdNotToBeRemoved; // defines an Aura objectId that will not be removed from this protection ability
|
||||
|
||||
public ProtectionAbility(Filter filter) {
|
||||
|
|
@ -72,12 +75,15 @@ public class ProtectionAbility extends StaticAbility {
|
|||
public static ProtectionAbility from(ObjectColor color) {
|
||||
FilterObject filter = new FilterObject(color.getDescription());
|
||||
filter.add(new ColorPredicate(color));
|
||||
colors.add(color);
|
||||
return new ProtectionAbility(filter);
|
||||
}
|
||||
|
||||
public static ProtectionAbility from(ObjectColor color1, ObjectColor color2) {
|
||||
FilterObject filter = new FilterObject(color1.getDescription() + " and from " + color2.getDescription());
|
||||
filter.add(Predicates.or(new ColorPredicate(color1), new ColorPredicate(color2)));
|
||||
colors.add(color1);
|
||||
colors.add(color2);
|
||||
return new ProtectionAbility(filter);
|
||||
}
|
||||
|
||||
|
|
@ -140,6 +146,8 @@ public class ProtectionAbility extends StaticAbility {
|
|||
return removeAuras;
|
||||
}
|
||||
|
||||
public List<ObjectColor> getColors() { return colors; }
|
||||
|
||||
public UUID getAuraIdNotToBeRemoved() {
|
||||
return auraIdNotToBeRemoved;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ import mage.abilities.effects.ReplacementEffectImpl;
|
|||
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||
import mage.abilities.effects.common.ExileSourceEffect;
|
||||
import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.TimingRule;
|
||||
|
|
@ -63,9 +62,8 @@ import mage.game.events.ZoneChangeEvent;
|
|||
public class UnearthAbility extends ActivatedAbilityImpl {
|
||||
|
||||
public UnearthAbility(ManaCosts costs) {
|
||||
super(Zone.GRAVEYARD, new ReturnSourceFromGraveyardToBattlefieldEffect(), costs);
|
||||
super(Zone.GRAVEYARD, new ReturnSourceFromGraveyardToBattlefieldEffect(false, true, true), costs);
|
||||
this.timing = TimingRule.SORCERY;
|
||||
this.addEffect(new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.Custom));
|
||||
this.addEffect(new CreateDelayedTriggeredAbilityEffect(new UnearthDelayedTriggeredAbility()));
|
||||
this.addEffect(new UnearthLeavesBattlefieldEffect());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ package mage.abilities.mana;
|
|||
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.effects.common.AddConditionalColorlessManaEffect;
|
||||
import mage.abilities.effects.common.BasicManaEffect;
|
||||
import mage.abilities.effects.mana.AddConditionalColorlessManaEffect;
|
||||
import mage.abilities.effects.mana.BasicManaEffect;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ public class ActivateIfConditionManaAbility extends ActivatedManaAbilityImpl {
|
|||
|
||||
public ActivateIfConditionManaAbility(Zone zone, BasicManaEffect effect, Cost cost, Condition condition) {
|
||||
super(zone, effect, cost);
|
||||
this.netMana.add(effect.getMana());
|
||||
this.netMana.add(effect.getManaTemplate());
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ package mage.abilities.mana;
|
|||
|
||||
import mage.Mana;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.effects.common.AddManaOfAnyColorEffect;
|
||||
import mage.abilities.effects.common.BasicManaEffect;
|
||||
import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
|
||||
import mage.abilities.effects.mana.BasicManaEffect;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ public class ActivateOncePerTurnManaAbility extends ActivatedManaAbilityImpl {
|
|||
|
||||
public ActivateOncePerTurnManaAbility(Zone zone, BasicManaEffect effect, Cost cost) {
|
||||
super(zone, effect, cost);
|
||||
this.netMana.add(effect.getMana());
|
||||
this.netMana.add(effect.getManaTemplate());
|
||||
this.maxActivationsPerTurn = 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import java.util.UUID;
|
|||
import mage.Mana;
|
||||
import mage.abilities.ActivatedAbilityImpl;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.constants.AbilityType;
|
||||
import mage.constants.AsThoughEffectType;
|
||||
|
|
@ -95,6 +96,13 @@ public abstract class ActivatedManaAbilityImpl extends ActivatedAbilityImpl impl
|
|||
*/
|
||||
@Override
|
||||
public List<Mana> getNetMana(Game game) {
|
||||
if (netMana.isEmpty()) {
|
||||
for (Effect effect : getEffects()) {
|
||||
if (effect instanceof ManaEffect) {
|
||||
netMana.addAll(((ManaEffect) effect).getNetMana(game, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
return netMana;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,6 +105,18 @@ class AnyColorLandsProduceManaEffect extends ManaEffect {
|
|||
|
||||
@Override
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana produceMana(boolean netMana, Game game, Ability source) {
|
||||
Mana mana = new Mana();
|
||||
Mana types = getManaTypes(game, source);
|
||||
Choice choice = new ChoiceColor(true);
|
||||
choice.getChoices().clear();
|
||||
|
|
@ -143,12 +155,11 @@ class AnyColorLandsProduceManaEffect extends ManaEffect {
|
|||
if (choice.getChoices().size() == 1) {
|
||||
choice.setChoice(choice.getChoices().iterator().next());
|
||||
} else {
|
||||
if (!player.choose(outcome, choice, game)) {
|
||||
return false;
|
||||
if (player == null || !player.choose(outcome, choice, game)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (choice.getChoice() != null) {
|
||||
Mana mana = new Mana();
|
||||
switch (choice.getChoice()) {
|
||||
case "Black":
|
||||
mana.setBlack(1);
|
||||
|
|
@ -169,16 +180,9 @@ class AnyColorLandsProduceManaEffect extends ManaEffect {
|
|||
mana.setColorless(1);
|
||||
break;
|
||||
}
|
||||
checkToFirePossibleEvents(mana, game, source);
|
||||
player.getManaPool().addMana(mana, game, source);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana getMana(Game game, Ability source) {
|
||||
return null;
|
||||
return mana;
|
||||
}
|
||||
|
||||
private Mana getManaTypes(Game game, Ability source) {
|
||||
|
|
@ -205,6 +209,7 @@ class AnyColorLandsProduceManaEffect extends ManaEffect {
|
|||
return types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Mana> getNetMana(Game game, Ability source) {
|
||||
List<Mana> netManas = new ArrayList<>();
|
||||
Mana types = getManaTypes(game, source);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ package mage.abilities.mana;
|
|||
import mage.Mana;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.effects.common.AddManaOfAnyColorEffect;
|
||||
import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
|
||||
import mage.constants.Zone;
|
||||
|
||||
public class AnyColorManaAbility extends ActivatedManaAbilityImpl {
|
||||
|
|
|
|||
|
|
@ -82,6 +82,18 @@ class AnyColorPermanentTypesManaEffect extends ManaEffect {
|
|||
|
||||
@Override
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana produceMana(boolean netMana, Game game, Ability source) {
|
||||
Mana mana = new Mana();
|
||||
Mana types = getManaTypes(game, source);
|
||||
Choice choice = new ChoiceColor(true);
|
||||
choice.getChoices().clear();
|
||||
|
|
@ -121,11 +133,11 @@ class AnyColorPermanentTypesManaEffect extends ManaEffect {
|
|||
choice.setChoice(choice.getChoices().iterator().next());
|
||||
} else {
|
||||
if (!player.choose(outcome, choice, game)) {
|
||||
return false;
|
||||
return mana;
|
||||
}
|
||||
}
|
||||
if (choice.getChoice() != null) {
|
||||
Mana mana = new Mana();
|
||||
|
||||
switch (choice.getChoice()) {
|
||||
case "Black":
|
||||
mana.setBlack(1);
|
||||
|
|
@ -146,16 +158,9 @@ class AnyColorPermanentTypesManaEffect extends ManaEffect {
|
|||
mana.setColorless(1);
|
||||
break;
|
||||
}
|
||||
checkToFirePossibleEvents(mana, game, source);
|
||||
player.getManaPool().addMana(mana, game, source);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana getMana(Game game, Ability source) {
|
||||
return null;
|
||||
return mana;
|
||||
}
|
||||
|
||||
private Mana getManaTypes(Game game, Ability source) {
|
||||
|
|
@ -167,19 +172,19 @@ class AnyColorPermanentTypesManaEffect extends ManaEffect {
|
|||
return types;
|
||||
}
|
||||
inManaTypeCalculation = true;
|
||||
|
||||
|
||||
ObjectColor permanentColor;
|
||||
|
||||
|
||||
List<Permanent> permanents = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game);
|
||||
|
||||
|
||||
for (Permanent permanent : permanents) {
|
||||
permanentColor = permanent.getColor(game);
|
||||
if(permanentColor.isColorless())
|
||||
if (permanentColor.isColorless()) {
|
||||
types.add(Mana.ColorlessMana(1));
|
||||
else{
|
||||
} else {
|
||||
List<ObjectColor> permanentColors = permanent.getColor(game).getColors();
|
||||
for (ObjectColor color : permanentColors){
|
||||
types.add(new Mana(color.getColoredManaSymbol()));
|
||||
for (ObjectColor color : permanentColors) {
|
||||
types.add(new Mana(color.getOneColoredManaSymbol()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -187,6 +192,7 @@ class AnyColorPermanentTypesManaEffect extends ManaEffect {
|
|||
return types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Mana> getNetMana(Game game, Ability source) {
|
||||
List<Mana> netManas = new ArrayList<>();
|
||||
Mana types = getManaTypes(game, source);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
package mage.abilities.mana;
|
||||
|
||||
import mage.Mana;
|
||||
import mage.abilities.effects.common.BasicManaEffect;
|
||||
import mage.abilities.effects.mana.BasicManaEffect;
|
||||
import mage.constants.ColoredManaSymbol;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
package mage.abilities.mana;
|
||||
|
||||
import mage.Mana;
|
||||
import mage.abilities.effects.common.BasicManaEffect;
|
||||
import mage.abilities.effects.mana.BasicManaEffect;
|
||||
import mage.constants.ColoredManaSymbol;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
package mage.abilities.mana;
|
||||
|
||||
import mage.Mana;
|
||||
import mage.abilities.effects.common.BasicManaEffect;
|
||||
import mage.abilities.effects.mana.BasicManaEffect;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
|||
|
|
@ -122,6 +122,18 @@ class CommanderIdentityManaEffect extends ManaEffect {
|
|||
|
||||
@Override
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana produceMana(boolean netMana, Game game, Ability source) {
|
||||
Mana mana = new Mana();
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
Choice choice = new ChoiceImpl();
|
||||
|
|
@ -152,10 +164,10 @@ class CommanderIdentityManaEffect extends ManaEffect {
|
|||
choice.setChoice(choice.getChoices().iterator().next());
|
||||
} else {
|
||||
if (!controller.choose(outcome, choice, game)) {
|
||||
return false;
|
||||
return mana;
|
||||
}
|
||||
}
|
||||
Mana mana = new Mana();
|
||||
|
||||
switch (choice.getChoice()) {
|
||||
case "Black":
|
||||
mana.setBlack(1);
|
||||
|
|
@ -173,16 +185,10 @@ class CommanderIdentityManaEffect extends ManaEffect {
|
|||
mana.setWhite(1);
|
||||
break;
|
||||
}
|
||||
checkToFirePossibleEvents(mana, game, source);
|
||||
controller.getManaPool().addMana(mana, game, source);
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return mana;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana getMana(Game game, Ability source) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import mage.abilities.costs.Cost;
|
|||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.abilities.effects.common.AddConditionalManaOfAnyColorEffect;
|
||||
import mage.abilities.effects.mana.AddConditionalManaOfAnyColorEffect;
|
||||
import mage.abilities.mana.builder.ConditionalManaBuilder;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ package mage.abilities.mana;
|
|||
import mage.Mana;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.effects.common.AddConditionalManaEffect;
|
||||
import mage.abilities.effects.mana.AddConditionalManaEffect;
|
||||
import mage.abilities.mana.builder.ConditionalManaBuilder;
|
||||
import mage.constants.Zone;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ package mage.abilities.mana;
|
|||
import mage.Mana;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.effects.common.AddConditionalColorlessManaEffect;
|
||||
import mage.abilities.effects.mana.AddConditionalColorlessManaEffect;
|
||||
import mage.abilities.mana.builder.ConditionalManaBuilder;
|
||||
import mage.constants.Zone;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import mage.Mana;
|
|||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.effects.common.DynamicManaEffect;
|
||||
import mage.abilities.effects.mana.DynamicManaEffect;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ public class DynamicManaAbility extends ActivatedManaAbilityImpl {
|
|||
if (game != null) {
|
||||
// TODO: effects from replacement effects like Mana Reflection are not considered yet
|
||||
// TODO: effects that need a X payment (e.g. Mage-Ring Network) return always 0
|
||||
newNetMana.add(manaEffect.computeMana(true, game, this));
|
||||
newNetMana.addAll(manaEffect.getNetMana(game, this));
|
||||
}
|
||||
return newNetMana;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
package mage.abilities.mana;
|
||||
|
||||
import mage.Mana;
|
||||
import mage.abilities.effects.common.BasicManaEffect;
|
||||
import mage.abilities.effects.mana.BasicManaEffect;
|
||||
import mage.constants.ColoredManaSymbol;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
package mage.abilities.mana;
|
||||
|
||||
import mage.Mana;
|
||||
import mage.abilities.effects.common.BasicManaEffect;
|
||||
import mage.abilities.effects.mana.BasicManaEffect;
|
||||
import mage.constants.ColoredManaSymbol;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -30,9 +30,8 @@ package mage.abilities.mana;
|
|||
import java.util.List;
|
||||
import mage.Mana;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.BasicManaEffect;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.abilities.effects.mana.BasicManaEffect;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
|
||||
|
|
@ -79,15 +78,8 @@ public class SimpleManaAbility extends ActivatedManaAbilityImpl {
|
|||
|
||||
@Override
|
||||
public List<Mana> getNetMana(Game game) {
|
||||
if (netMana.isEmpty() && predictable) {
|
||||
for (Effect effect : getEffects()) {
|
||||
if (effect instanceof ManaEffect) {
|
||||
Mana effectMana = ((ManaEffect) effect).getMana(game, this);
|
||||
if (effectMana != null) {
|
||||
netMana.add(effectMana);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (predictable) {
|
||||
return super.getNetMana(game);
|
||||
}
|
||||
return netMana;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ import java.util.List;
|
|||
import mage.Mana;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.DynamicManaEffect;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.constants.AbilityType;
|
||||
import mage.constants.Zone;
|
||||
|
|
@ -72,20 +71,14 @@ public abstract class TriggeredManaAbility extends TriggeredAbilityImpl implemen
|
|||
*/
|
||||
@Override
|
||||
public List<Mana> getNetMana(Game game) {
|
||||
if (!getEffects().isEmpty()) {
|
||||
Effect effect = getEffects().get(0);
|
||||
if (effect != null && game != null) {
|
||||
ArrayList<Mana> newNetMana = new ArrayList<>();
|
||||
if (effect instanceof DynamicManaEffect) {
|
||||
|
||||
// TODO: effects from replacement effects like Mana Reflection are not considered yet
|
||||
// TODO: effects that need a X payment (e.g. Mage-Ring Network) return always 0
|
||||
newNetMana.add(((DynamicManaEffect) effect).computeMana(true, game, this));
|
||||
} else if (effect instanceof Effect) {
|
||||
newNetMana.add(((ManaEffect) effect).getMana(game, this));
|
||||
if (game != null) {
|
||||
ArrayList<Mana> newNetMana = new ArrayList<>();
|
||||
for (Effect effect : getEffects()) {
|
||||
if (effect instanceof ManaEffect) {
|
||||
newNetMana.addAll(((ManaEffect) effect).getNetMana(game, this));
|
||||
}
|
||||
return newNetMana;
|
||||
}
|
||||
return newNetMana;
|
||||
}
|
||||
return netMana;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
package mage.abilities.mana;
|
||||
|
||||
import mage.Mana;
|
||||
import mage.abilities.effects.common.BasicManaEffect;
|
||||
import mage.abilities.effects.mana.BasicManaEffect;
|
||||
import mage.constants.ColoredManaSymbol;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
|
|||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.filter.predicate.mageobject.PowerPredicate;
|
||||
import mage.game.*;
|
||||
import mage.game.command.CommandObject;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
|
@ -618,14 +619,18 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
stackObject = game.getStack().getSpell(getId());
|
||||
}
|
||||
if (stackObject != null) {
|
||||
removed = game.getStack().remove(stackObject);
|
||||
removed = game.getStack().remove(stackObject, game);
|
||||
lkiObject = stackObject;
|
||||
}
|
||||
break;
|
||||
case COMMAND:
|
||||
lkiObject = game.getObject(objectId);
|
||||
for (CommandObject commandObject : game.getState().getCommand()) {
|
||||
if (commandObject.getId().equals(objectId)) {
|
||||
lkiObject = commandObject;
|
||||
}
|
||||
}
|
||||
if (lkiObject != null) {
|
||||
removed = game.getState().getCommand().remove(game.getObject(objectId));
|
||||
removed = game.getState().getCommand().remove((CommandObject) lkiObject);
|
||||
}
|
||||
break;
|
||||
case OUTSIDE:
|
||||
|
|
|
|||
|
|
@ -54,6 +54,12 @@ public class CardsImpl extends LinkedHashSet<UUID> implements Cards, Serializabl
|
|||
}
|
||||
}
|
||||
|
||||
public CardsImpl(Set<Card> cards) {
|
||||
for (Card card : cards) {
|
||||
this.add(card.getId());
|
||||
}
|
||||
}
|
||||
|
||||
public CardsImpl(Collection<UUID> cardIds) {
|
||||
if (cardIds != null) {
|
||||
this.addAll(cardIds);
|
||||
|
|
|
|||
|
|
@ -110,7 +110,15 @@ public class TxtDeckImporter extends DeckImporter {
|
|||
}
|
||||
String lineNum = line.substring(0, delim).trim();
|
||||
String lineName = line.substring(delim).replace("’", "\'").trim();
|
||||
lineName = lineName.replace("&", "//").replace("Æ", "Ae").replace("ö", "ö").replace("û", "u").replace("\"", "'");
|
||||
lineName = lineName
|
||||
.replace("&", "//")
|
||||
.replace("Æ", "Ae")
|
||||
.replace("ö", "o")
|
||||
.replace("û", "u")
|
||||
.replace("í", "i")
|
||||
.replace("â", "a")
|
||||
.replace("á", "a")
|
||||
.replace("\"", "'");
|
||||
if (lineName.contains("//") && !lineName.contains(" // ")) {
|
||||
lineName = lineName.replace("//", " // ");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ public enum CardRepository {
|
|||
// raise this if db structure was changed
|
||||
private static final long CARD_DB_VERSION = 51;
|
||||
// raise this if new cards were added to the server
|
||||
private static final long CARD_CONTENT_VERSION = 108;
|
||||
private static final long CARD_CONTENT_VERSION = 109;
|
||||
private Dao<CardInfo, Object> cardDao;
|
||||
private Set<String> classNames;
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ package mage.constants;
|
|||
* @author LevelX2
|
||||
*/
|
||||
public enum DependencyType {
|
||||
|
||||
AuraAddingRemoving,
|
||||
ArtifactAddingRemoving,
|
||||
AddingAbility,
|
||||
|
|
@ -48,6 +47,7 @@ public enum DependencyType {
|
|||
BecomeMountain,
|
||||
BecomePlains,
|
||||
BecomeSwamp,
|
||||
BecomeCreature,
|
||||
EnchantmentAddingRemoving,
|
||||
LooseDefenderEffect
|
||||
}
|
||||
}
|
||||
|
|
@ -5,21 +5,23 @@ package mage.constants;
|
|||
* @author North
|
||||
*/
|
||||
public enum Duration {
|
||||
OneUse(""),
|
||||
EndOfGame("for the rest of the game"),
|
||||
WhileOnBattlefield(""),
|
||||
WhileOnStack(""),
|
||||
WhileInGraveyard(""),
|
||||
EndOfTurn("until end of turn"),
|
||||
UntilYourNextTurn("until your next turn"),
|
||||
EndOfCombat("until end of combat"),
|
||||
EndOfStep("until end of phase step"),
|
||||
Custom("");
|
||||
OneUse("", true),
|
||||
EndOfGame("for the rest of the game", false),
|
||||
WhileOnBattlefield("", false),
|
||||
WhileOnStack("", false),
|
||||
WhileInGraveyard("", false),
|
||||
EndOfTurn("until end of turn", true),
|
||||
UntilYourNextTurn("until your next turn", true),
|
||||
EndOfCombat("until end of combat", true),
|
||||
EndOfStep("until end of phase step", true),
|
||||
Custom("", true);
|
||||
|
||||
private final String text;
|
||||
private final boolean onlyValidIfNoZoneChange; // defines if an effect lasts only if the source has not chnaged zone since init of the effect
|
||||
|
||||
Duration(String text) {
|
||||
Duration(String text, boolean onlyValidIfNoZoneChange) {
|
||||
this.text = text;
|
||||
this.onlyValidIfNoZoneChange = onlyValidIfNoZoneChange;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -27,4 +29,8 @@ public enum Duration {
|
|||
return text;
|
||||
}
|
||||
|
||||
public boolean isOnlyValidIfNoZoneChange() {
|
||||
return onlyValidIfNoZoneChange;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import java.util.Arrays;
|
|||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import mage.util.SubTypeList;
|
||||
|
||||
public enum SubType {
|
||||
|
|
@ -328,17 +329,16 @@ public enum SubType {
|
|||
TROOPER("Trooper", SubTypeSet.CreatureType, true), // Star Wars
|
||||
TRILOBITE("Trilobite", SubTypeSet.CreatureType),
|
||||
TWILEK("Twi'lek", SubTypeSet.CreatureType, true), // Star Wars
|
||||
|
||||
// U
|
||||
UGNAUGHT("Ugnaught", SubTypeSet.CreatureType, true),
|
||||
UNICORN("Unicorn", SubTypeSet.CreatureType),
|
||||
//V
|
||||
// V
|
||||
VAMPIRE("Vampire", SubTypeSet.CreatureType),
|
||||
VEDALKEN("Vedalken", SubTypeSet.CreatureType),
|
||||
VIASHINO("Viashino", SubTypeSet.CreatureType),
|
||||
VILLAIN("Villain", SubTypeSet.CreatureType, true), // Unstable
|
||||
VOLVER("Volver", SubTypeSet.CreatureType),
|
||||
//W
|
||||
// W
|
||||
WALL("Wall", SubTypeSet.CreatureType),
|
||||
WARRIOR("Warrior", SubTypeSet.CreatureType),
|
||||
WEEQUAY("Weequay", SubTypeSet.CreatureType, true),
|
||||
|
|
@ -429,6 +429,16 @@ public enum SubType {
|
|||
return description;
|
||||
}
|
||||
|
||||
public static SubType fromString(String value) {
|
||||
for (SubType st : SubType.values()) {
|
||||
if (st.toString().equals(value)) {
|
||||
return st;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Can''t find subtype enum value: " + value);
|
||||
}
|
||||
|
||||
public static SubType byDescription(String subType) {
|
||||
for (SubType s : values()) {
|
||||
if (s.getDescription().equals(subType)) {
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public enum CounterType {
|
|||
ARROWHEAD("arrowhead"),
|
||||
AWAKENING("awakening"),
|
||||
BLAZE("blaze"),
|
||||
BLOOD("blood"),
|
||||
BOUNTY("bounty"),
|
||||
BRIBERY("bribery"),
|
||||
BRICK("brick"),
|
||||
|
|
@ -67,10 +68,12 @@ public enum CounterType {
|
|||
FADE("fade"),
|
||||
FATE("fate"),
|
||||
FEATHER("feather"),
|
||||
FILIBUSTER("filibuster"),
|
||||
FLOOD("flood"),
|
||||
FURY("fury"),
|
||||
FUNGUS("fungus"),
|
||||
FUSE("fuse"),
|
||||
GEM("gem"),
|
||||
GLOBE("globe"),
|
||||
GOLD("gold"),
|
||||
GROWTH("growth"),
|
||||
|
|
@ -83,6 +86,7 @@ public enum CounterType {
|
|||
ICE("ice"),
|
||||
INFECTION("infection"),
|
||||
INTERVENTION("intervention"),
|
||||
ISOLATION("isolation"),
|
||||
JAVELIN("javelin"),
|
||||
KI("ki"),
|
||||
LANDMARK("landmark"),
|
||||
|
|
@ -90,6 +94,7 @@ public enum CounterType {
|
|||
LORE("lore"),
|
||||
LUCK("luck"),
|
||||
LOYALTY("loyalty"),
|
||||
MANIFESTATION("manifestation"),
|
||||
MANNEQUIN("mannequin"),
|
||||
M1M1(new BoostCounter(-1, -1).name),
|
||||
M2M1(new BoostCounter(-2, -1).name),
|
||||
|
|
@ -99,6 +104,7 @@ public enum CounterType {
|
|||
MIRE("mire"),
|
||||
MUSTER("muster"),
|
||||
NET("net"),
|
||||
OMEN("omen"),
|
||||
P0P1(new BoostCounter(0, 1).name),
|
||||
P1P0(new BoostCounter(1, 0).name),
|
||||
P1P1(new BoostCounter(1, 1).name),
|
||||
|
|
@ -108,6 +114,7 @@ public enum CounterType {
|
|||
PAIN("pain"),
|
||||
PETAL("petal"),
|
||||
PETRIFICATION("petrification"),
|
||||
PHYLACTERY("phylactery"),
|
||||
PLAGUE("plague"),
|
||||
PLOT("plot"),
|
||||
POLYP("polyp"),
|
||||
|
|
@ -123,6 +130,7 @@ public enum CounterType {
|
|||
SHIELD("shield"),
|
||||
SHRED("shred"),
|
||||
SLIME("slime"),
|
||||
SOOT("soot"),
|
||||
SPITE("spite"),
|
||||
SPORE("spore"),
|
||||
STORAGE("storage"),
|
||||
|
|
@ -132,6 +140,7 @@ public enum CounterType {
|
|||
TIDE("tide"),
|
||||
TIME("time"),
|
||||
TOWER("tower"),
|
||||
TRAINING("training"),
|
||||
TRAP("trap"),
|
||||
TREASURE("treasure"),
|
||||
UNITY("unity"),
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import mage.constants.TargetController;
|
|||
import mage.filter.common.*;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.CardTypePredicate;
|
||||
import mage.filter.predicate.mageobject.MulticoloredPredicate;
|
||||
import mage.filter.predicate.mageobject.SubtypePredicate;
|
||||
import mage.filter.predicate.mageobject.SupertypePredicate;
|
||||
import mage.filter.predicate.permanent.AnotherPredicate;
|
||||
|
|
@ -75,6 +76,13 @@ public final class StaticFilters {
|
|||
static {
|
||||
FILTER_CARD_CREATURE_YOUR_GRAVEYARD.setLockedFilter(true);
|
||||
}
|
||||
|
||||
public static final FilterCard FILTER_CARD_FROM_YOUR_GRAVEYARD = new FilterCard("card from your graveyard");
|
||||
|
||||
static {
|
||||
FILTER_CARD_FROM_YOUR_GRAVEYARD.setLockedFilter(true);
|
||||
}
|
||||
|
||||
public static final FilterLandCard FILTER_CARD_LAND = new FilterLandCard();
|
||||
|
||||
static {
|
||||
|
|
@ -102,6 +110,13 @@ public final class StaticFilters {
|
|||
static {
|
||||
FILTER_PERMANENT.setLockedFilter(true);
|
||||
}
|
||||
|
||||
public static final FilterPermanent FILTER_PERMANENT_ARTIFACT_AN = new FilterArtifactPermanent("an artifact");
|
||||
|
||||
static {
|
||||
FILTER_PERMANENT_ARTIFACT_AN.setLockedFilter(true);
|
||||
}
|
||||
|
||||
public static final FilterArtifactOrEnchantmentPermanent FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT = new FilterArtifactOrEnchantmentPermanent();
|
||||
|
||||
static {
|
||||
|
|
@ -363,10 +378,18 @@ public final class StaticFilters {
|
|||
static {
|
||||
FILTER_SPELL.setLockedFilter(true);
|
||||
}
|
||||
public static final FilterSpell FILTER_A_SPELL = new FilterSpell("a spell");
|
||||
|
||||
public static final FilterSpell FILTER_SPELL_A = new FilterSpell("a spell");
|
||||
|
||||
static {
|
||||
FILTER_A_SPELL.setLockedFilter(true);
|
||||
FILTER_SPELL_A.setLockedFilter(true);
|
||||
}
|
||||
|
||||
public static final FilterSpell FILTER_SPELL_A_MULTICOLORED = new FilterSpell("a multicolored spell");
|
||||
|
||||
static {
|
||||
FILTER_SPELL_A_MULTICOLORED.add(new MulticoloredPredicate());
|
||||
FILTER_SPELL_A_MULTICOLORED.setLockedFilter(true);
|
||||
}
|
||||
|
||||
public static final FilterSpell FILTER_INSTANT_OR_SORCERY_SPELL = new FilterSpell("instant or sorcery spell");
|
||||
|
|
|
|||
|
|
@ -328,12 +328,15 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
MageObject object;
|
||||
if (state.getBattlefield().containsPermanent(objectId)) {
|
||||
object = state.getBattlefield().getPermanent(objectId);
|
||||
state.setZone(objectId, Zone.BATTLEFIELD); // why is this neccessary?
|
||||
// state.setZone(objectId, Zone.BATTLEFIELD); // why is this neccessary?
|
||||
return object;
|
||||
}
|
||||
if (getPermanentsEntering().containsKey(objectId)) {
|
||||
return getPermanentEntering(objectId);
|
||||
}
|
||||
for (StackObject item : state.getStack()) {
|
||||
if (item.getId().equals(objectId)) {
|
||||
state.setZone(objectId, Zone.STACK); // why is this neccessary?
|
||||
// state.setZone(objectId, Zone.STACK); // why is this neccessary?
|
||||
return item;
|
||||
}
|
||||
if (item.getSourceId().equals(objectId) && item instanceof Spell) {
|
||||
|
|
@ -1383,7 +1386,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
} catch (Exception ex) {
|
||||
logger.fatal("Game exception gameId: " + getId(), ex);
|
||||
if ((ex instanceof NullPointerException)
|
||||
&& errorContinueCounter == 1 && ex.getStackTrace() != null) {
|
||||
&& errorContinueCounter == 0 && ex.getStackTrace() != null) {
|
||||
logger.fatal(ex.getStackTrace());
|
||||
}
|
||||
this.fireErrorEvent("Game exception occurred: ", ex);
|
||||
|
|
@ -1421,7 +1424,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
top.resolve(this);
|
||||
} finally {
|
||||
if (top != null) {
|
||||
state.getStack().remove(top); // seems partly redundant because move card from stack to grave is already done and the stack removed
|
||||
state.getStack().remove(top, this); // seems partly redundant because move card from stack to grave is already done and the stack removed
|
||||
rememberLKI(top.getSourceId(), Zone.STACK, top);
|
||||
checkInfiniteLoop(top.getSourceId());
|
||||
if (!getTurn().isEndTurnRequested()) {
|
||||
|
|
@ -2581,10 +2584,10 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (addPlaneAgain) {
|
||||
boolean addedAgain = false;
|
||||
for (Player aplayer : state.getPlayers().values()) {
|
||||
for (Player aplayer : state.getPlayers().values()) {
|
||||
if (!aplayer.hasLeft() && !addedAgain) {
|
||||
addedAgain = true;
|
||||
Plane plane = Plane.getRandomPlane();
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ package mage.game;
|
|||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.*;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
|
|
@ -121,6 +120,8 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
private Map<UUID, Card> copiedCards = new HashMap<>();
|
||||
private int permanentOrderNumber;
|
||||
|
||||
private int applyEffectsCounter; // Upcounting number of each applyEffects execution
|
||||
|
||||
public GameState() {
|
||||
players = new Players();
|
||||
playerList = new PlayerList();
|
||||
|
|
@ -137,6 +138,7 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
combat = new Combat();
|
||||
turnMods = new TurnMods();
|
||||
watchers = new Watchers();
|
||||
applyEffectsCounter = 0;
|
||||
}
|
||||
|
||||
public GameState(final GameState state) {
|
||||
|
|
@ -193,6 +195,7 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
this.zoneChangeCounter.putAll(state.zoneChangeCounter);
|
||||
this.copiedCards.putAll(state.copiedCards);
|
||||
this.permanentOrderNumber = state.permanentOrderNumber;
|
||||
this.applyEffectsCounter = state.applyEffectsCounter;
|
||||
}
|
||||
|
||||
public void restoreForRollBack(GameState state) {
|
||||
|
|
@ -210,7 +213,7 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
this.command = state.command;
|
||||
this.isPlaneChase = state.isPlaneChase;
|
||||
this.seenPlanes = state.seenPlanes;
|
||||
this.designations = state.designations;
|
||||
this.designations = state.designations;
|
||||
this.exile = state.exile;
|
||||
this.battlefield = state.battlefield;
|
||||
this.turnNum = state.turnNum;
|
||||
|
|
@ -237,6 +240,7 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
this.zoneChangeCounter = state.zoneChangeCounter;
|
||||
this.copiedCards = state.copiedCards;
|
||||
this.permanentOrderNumber = state.permanentOrderNumber;
|
||||
this.applyEffectsCounter = state.applyEffectsCounter;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -466,12 +470,12 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<String> getSeenPlanes() {
|
||||
return seenPlanes;
|
||||
}
|
||||
|
||||
|
||||
public boolean isPlaneChase() {
|
||||
return isPlaneChase;
|
||||
}
|
||||
|
|
@ -574,6 +578,7 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
}
|
||||
|
||||
public void applyEffects(Game game) {
|
||||
applyEffectsCounter++;
|
||||
for (Player player : players.values()) {
|
||||
player.reset();
|
||||
}
|
||||
|
|
@ -680,7 +685,11 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
}
|
||||
|
||||
public void setZone(UUID id, Zone zone) {
|
||||
zones.put(id, zone);
|
||||
if (zone == null) {
|
||||
zones.remove(id);
|
||||
} else {
|
||||
zones.put(id, zone);
|
||||
}
|
||||
}
|
||||
|
||||
public void addSimultaneousEvent(GameEvent event, Game game) {
|
||||
|
|
@ -752,8 +761,8 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
ZoneChangeData data = (ZoneChangeData) obj;
|
||||
return this.fromZone == data.fromZone
|
||||
&& this.toZone == data.toZone
|
||||
&& this.sourceId == data.sourceId
|
||||
&& this.playerId == data.playerId;
|
||||
&& Objects.equals(this.sourceId, data.sourceId)
|
||||
&& Objects.equals(this.playerId, data.playerId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -881,13 +890,13 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
addAbility(ability, designation.getId(), null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void addSeenPlane(Plane plane, Game game, UUID controllerId) {
|
||||
if (plane != null) {
|
||||
getSeenPlanes().add(plane.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void resetSeenPlanes() {
|
||||
getSeenPlanes().clear();
|
||||
}
|
||||
|
|
@ -1169,4 +1178,9 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
public int getNextPermanentOrderNumber() {
|
||||
return permanentOrderNumber++;
|
||||
}
|
||||
|
||||
public int getApplyEffectsCounter() {
|
||||
return applyEffectsCounter;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue