mirror of
https://github.com/magefree/mage.git
synced 2025-12-22 03:22:00 -08:00
* Fixed problems of Yixlid Jailer that removed abilities from cards in graveyard permanently (fixes #1147).
This commit is contained in:
parent
893bcbb01f
commit
8854871c15
28 changed files with 248 additions and 180 deletions
|
|
@ -1,6 +1,8 @@
|
||||||
package mage.view;
|
package mage.view;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.ObjectColor;
|
import mage.ObjectColor;
|
||||||
import mage.abilities.Abilities;
|
import mage.abilities.Abilities;
|
||||||
|
|
@ -26,9 +28,6 @@ import mage.target.Target;
|
||||||
import mage.target.Targets;
|
import mage.target.Targets;
|
||||||
import mage.util.SubTypeList;
|
import mage.util.SubTypeList;
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
|
|
@ -211,8 +210,8 @@ public class CardView extends SimpleCardView {
|
||||||
* @param card
|
* @param card
|
||||||
* @param game
|
* @param game
|
||||||
* @param controlled is the card view created for the card controller - used
|
* @param controlled is the card view created for the card controller - used
|
||||||
* for morph / face down cards to know which player may see information for
|
* for morph / face down cards to know which player may see information for
|
||||||
* the card
|
* the card
|
||||||
*/
|
*/
|
||||||
public CardView(Card card, Game game, boolean controlled) {
|
public CardView(Card card, Game game, boolean controlled) {
|
||||||
this(card, game, controlled, false, false);
|
this(card, game, controlled, false, false);
|
||||||
|
|
@ -238,12 +237,12 @@ public class CardView extends SimpleCardView {
|
||||||
/**
|
/**
|
||||||
* @param card
|
* @param card
|
||||||
* @param game
|
* @param game
|
||||||
* @param controlled is the card view created for the card controller - used
|
* @param controlled is the card view created for the card controller - used
|
||||||
* for morph / face down cards to know which player may see information for
|
* for morph / face down cards to know which player may see information for
|
||||||
* the card
|
* the card
|
||||||
* @param showFaceDownCard if true and the card is not on the battlefield,
|
* @param showFaceDownCard if true and the card is not on the battlefield,
|
||||||
* also a face down card is shown in the view, face down cards will be shown
|
* also a face down card is shown in the view, face down cards will be shown
|
||||||
* @param storeZone if true the card zone will be set in the zone attribute.
|
* @param storeZone if true the card zone will be set in the zone attribute.
|
||||||
*/
|
*/
|
||||||
public CardView(Card card, Game game, boolean controlled, boolean showFaceDownCard, boolean storeZone) {
|
public CardView(Card card, Game game, boolean controlled, boolean showFaceDownCard, boolean storeZone) {
|
||||||
super(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.getUsesVariousArt(), card.getTokenSetCode(), game != null, card.getTokenDescriptor());
|
super(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.getUsesVariousArt(), card.getTokenSetCode(), game != null, card.getTokenDescriptor());
|
||||||
|
|
@ -436,7 +435,7 @@ public class CardView extends SimpleCardView {
|
||||||
artRect = ArtRect.SPLIT_FUSED;
|
artRect = ArtRect.SPLIT_FUSED;
|
||||||
} else if (spell.getCard() != null) {
|
} else if (spell.getCard() != null) {
|
||||||
SplitCard wholeCard = ((SplitCardHalf) spell.getCard()).getParentCard();
|
SplitCard wholeCard = ((SplitCardHalf) spell.getCard()).getParentCard();
|
||||||
Abilities<Ability> aftermathHalfAbilities = wholeCard.getRightHalfCard().getAbilities();
|
Abilities<Ability> aftermathHalfAbilities = wholeCard.getRightHalfCard().getAbilities(game);
|
||||||
if (aftermathHalfAbilities.stream().anyMatch(ability -> ability instanceof AftermathAbility)) {
|
if (aftermathHalfAbilities.stream().anyMatch(ability -> ability instanceof AftermathAbility)) {
|
||||||
if (ty == SpellAbilityType.SPLIT_RIGHT) {
|
if (ty == SpellAbilityType.SPLIT_RIGHT) {
|
||||||
artRect = ArtRect.AFTERMATH_BOTTOM;
|
artRect = ArtRect.AFTERMATH_BOTTOM;
|
||||||
|
|
@ -470,7 +469,7 @@ public class CardView extends SimpleCardView {
|
||||||
this.startingLoyalty = "" + card.getStartingLoyalty();
|
this.startingLoyalty = "" + card.getStartingLoyalty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public CardView(MageObject object) {
|
public CardView(MageObject object, Game game) {
|
||||||
super(object.getId(), "", "0", false, "", true, "");
|
super(object.getId(), "", "0", false, "", true, "");
|
||||||
this.originalCard = null;
|
this.originalCard = null;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package mage.view;
|
package mage.view;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
|
|
@ -14,8 +15,6 @@ import mage.game.permanent.PermanentToken;
|
||||||
import mage.target.targetpointer.TargetPointer;
|
import mage.target.targetpointer.TargetPointer;
|
||||||
import mage.util.GameLog;
|
import mage.util.GameLog;
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
|
|
@ -102,7 +101,7 @@ public class CardsView extends LinkedHashMap<UUID, CardView> {
|
||||||
} else if (isCard) {
|
} else if (isCard) {
|
||||||
sourceCardView = new CardView((Card) sourceObject);
|
sourceCardView = new CardView((Card) sourceObject);
|
||||||
} else {
|
} else {
|
||||||
sourceCardView = new CardView(sourceObject);
|
sourceCardView = new CardView(sourceObject, game);
|
||||||
}
|
}
|
||||||
abilityView = new AbilityView(ability, sourceObject.getName(), sourceCardView);
|
abilityView = new AbilityView(ability, sourceObject.getName(), sourceCardView);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,11 @@ package mage.view;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.abilities.costs.Cost;
|
import mage.abilities.costs.Cost;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
|
|
@ -25,12 +30,6 @@ import mage.players.Player;
|
||||||
import mage.watchers.common.CastSpellLastTurnWatcher;
|
import mage.watchers.common.CastSpellLastTurnWatcher;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
|
|
@ -121,7 +120,7 @@ public class GameView implements Serializable {
|
||||||
} else if (object instanceof Designation) {
|
} else if (object instanceof Designation) {
|
||||||
Designation designation = (Designation) game.getObject(object.getId());
|
Designation designation = (Designation) game.getObject(object.getId());
|
||||||
if (designation != null) {
|
if (designation != null) {
|
||||||
stack.put(stackObject.getId(), new StackAbilityView(game, (StackAbility) stackObject, designation.getName(), new CardView(designation)));
|
stack.put(stackObject.getId(), new StackAbilityView(game, (StackAbility) stackObject, designation.getName(), new CardView(designation, game)));
|
||||||
} else {
|
} else {
|
||||||
LOGGER.fatal("Designation object not found: " + object.getName() + ' ' + object.toString() + ' ' + object.getClass().toString());
|
LOGGER.fatal("Designation object not found: " + object.getName() + ' ' + object.toString() + ' ' + object.getClass().toString());
|
||||||
}
|
}
|
||||||
|
|
@ -129,7 +128,7 @@ public class GameView implements Serializable {
|
||||||
} else if (object instanceof StackAbility) {
|
} else if (object instanceof StackAbility) {
|
||||||
StackAbility stackAbility = ((StackAbility) object);
|
StackAbility stackAbility = ((StackAbility) object);
|
||||||
stackAbility.newId();
|
stackAbility.newId();
|
||||||
stack.put(stackObject.getId(), new CardView(stackObject));
|
stack.put(stackObject.getId(), new CardView(stackObject, game));
|
||||||
checkPaid(stackObject.getId(), ((StackAbility) stackObject));
|
checkPaid(stackObject.getId(), ((StackAbility) stackObject));
|
||||||
} else {
|
} else {
|
||||||
LOGGER.fatal("Object can't be cast to StackAbility: " + object.getName() + ' ' + object.toString() + ' ' + object.getClass().toString());
|
LOGGER.fatal("Object can't be cast to StackAbility: " + object.getName() + ' ' + object.toString() + ' ' + object.getClass().toString());
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.effects.ReplacementEffectImpl;
|
import mage.abilities.effects.ReplacementEffectImpl;
|
||||||
|
|
@ -18,11 +21,6 @@ import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.watchers.Watcher;
|
import mage.watchers.Watcher;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author jeffwadsworth
|
* @author jeffwadsworth
|
||||||
*/
|
*/
|
||||||
|
|
@ -114,7 +112,7 @@ class AbandonedSarcophagusReplacementEffect extends ReplacementEffectImpl {
|
||||||
|| !card.isOwnedBy(controller.getId())) {
|
|| !card.isOwnedBy(controller.getId())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (Ability ability : card.getAbilities()) {
|
for (Ability ability : card.getAbilities(game)) {
|
||||||
if (ability instanceof CyclingAbility) {
|
if (ability instanceof CyclingAbility) {
|
||||||
cardHasCycling = true;
|
cardHasCycling = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
package mage.cards.c;
|
package mage.cards.c;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.UUID;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.effects.ContinuousEffectImpl;
|
import mage.abilities.effects.ContinuousEffectImpl;
|
||||||
|
|
@ -18,10 +19,6 @@ import mage.game.stack.Spell;
|
||||||
import mage.game.stack.StackObject;
|
import mage.game.stack.StackObject;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author magenoxx_at_gmail.com
|
* @author magenoxx_at_gmail.com
|
||||||
*/
|
*/
|
||||||
|
|
@ -34,7 +31,7 @@ public final class CastThroughTime extends CardImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CastThroughTime(UUID ownerId, CardSetInfo setInfo) {
|
public CastThroughTime(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{4}{U}{U}{U}");
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{U}{U}{U}");
|
||||||
|
|
||||||
// Instant and sorcery spells you control have rebound.
|
// Instant and sorcery spells you control have rebound.
|
||||||
// (Exile the spell as it resolves if you cast it from your hand. At the beginning of your next upkeep, you may cast that card from exile without paying its mana cost.)
|
// (Exile the spell as it resolves if you cast it from your hand. At the beginning of your next upkeep, you may cast that card from exile without paying its mana cost.)
|
||||||
|
|
@ -73,7 +70,7 @@ class GainReboundEffect extends ContinuousEffectImpl {
|
||||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||||
if (player != null && permanent != null) {
|
if (player != null && permanent != null) {
|
||||||
for (Card card : player.getHand().getCards(CastThroughTime.filter, game)) {
|
for (Card card : player.getHand().getCards(CastThroughTime.filter, game)) {
|
||||||
addReboundAbility(card, source, game);
|
addReboundAbility(card, game);
|
||||||
}
|
}
|
||||||
for (Iterator<StackObject> iterator = game.getStack().iterator(); iterator.hasNext();) {
|
for (Iterator<StackObject> iterator = game.getStack().iterator(); iterator.hasNext();) {
|
||||||
StackObject stackObject = iterator.next();
|
StackObject stackObject = iterator.next();
|
||||||
|
|
@ -81,7 +78,7 @@ class GainReboundEffect extends ContinuousEffectImpl {
|
||||||
Spell spell = (Spell) stackObject;
|
Spell spell = (Spell) stackObject;
|
||||||
Card card = spell.getCard();
|
Card card = spell.getCard();
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
addReboundAbility(card, source, game);
|
addReboundAbility(card, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -91,9 +88,9 @@ class GainReboundEffect extends ContinuousEffectImpl {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addReboundAbility(Card card, Ability source, Game game) {
|
private void addReboundAbility(Card card, Game game) {
|
||||||
if (CastThroughTime.filter.match(card, game)) {
|
if (CastThroughTime.filter.match(card, game)) {
|
||||||
boolean found = card.getAbilities().stream().anyMatch(ability -> ability instanceof ReboundAbility);
|
boolean found = card.getAbilities(game).stream().anyMatch(ability -> ability instanceof ReboundAbility);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
Ability ability = new ReboundAbility();
|
Ability ability = new ReboundAbility();
|
||||||
game.getState().addOtherAbility(card, ability);
|
game.getState().addOtherAbility(card, ability);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.d;
|
package mage.cards.d;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
@ -108,7 +107,7 @@ class DarkImpostorContinuousEffect extends ContinuousEffectImpl {
|
||||||
for (UUID imprintedId : perm.getImprinted()) {
|
for (UUID imprintedId : perm.getImprinted()) {
|
||||||
Card card = game.getCard(imprintedId);
|
Card card = game.getCard(imprintedId);
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
for (Ability ability : card.getAbilities()) {
|
for (Ability ability : card.getAbilities(game)) {
|
||||||
if (ability instanceof ActivatedAbility) {
|
if (ability instanceof ActivatedAbility) {
|
||||||
perm.addAbility(ability.copy(), source.getSourceId(), game);
|
perm.addAbility(ability.copy(), source.getSourceId(), game);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.d;
|
package mage.cards.d;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
@ -28,8 +27,7 @@ import mage.target.TargetSpell;
|
||||||
public final class Delay extends CardImpl {
|
public final class Delay extends CardImpl {
|
||||||
|
|
||||||
public Delay(UUID ownerId, CardSetInfo setInfo) {
|
public Delay(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}");
|
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
|
||||||
|
|
||||||
|
|
||||||
// Counter target spell. If the spell is countered this way, exile it with three time counters on it instead of putting it into its owner's graveyard. If it doesn't have suspend, it gains suspend.
|
// Counter target spell. If the spell is countered this way, exile it with three time counters on it instead of putting it into its owner's graveyard. If it doesn't have suspend, it gains suspend.
|
||||||
this.getSpellAbility().addEffect(new DelayEffect());
|
this.getSpellAbility().addEffect(new DelayEffect());
|
||||||
|
|
@ -71,7 +69,7 @@ class DelayEffect extends OneShotEffect {
|
||||||
effect.setTargetPointer(targetPointer);
|
effect.setTargetPointer(targetPointer);
|
||||||
Card card = game.getCard(spell.getSourceId());
|
Card card = game.getCard(spell.getSourceId());
|
||||||
if (card != null && effect.apply(game, source) && game.getState().getZone(card.getId()) == Zone.EXILED) {
|
if (card != null && effect.apply(game, source) && game.getState().getZone(card.getId()) == Zone.EXILED) {
|
||||||
boolean hasSuspend = card.getAbilities().containsClass(SuspendAbility.class);
|
boolean hasSuspend = card.getAbilities(game).containsClass(SuspendAbility.class);
|
||||||
UUID exileId = SuspendAbility.getSuspendExileId(controller.getId(), game);
|
UUID exileId = SuspendAbility.getSuspendExileId(controller.getId(), game);
|
||||||
if (controller.moveCardToExileWithInfo(card, exileId, "Suspended cards of " + controller.getLogName(), source.getSourceId(), game, Zone.HAND, true)) {
|
if (controller.moveCardToExileWithInfo(card, exileId, "Suspended cards of " + controller.getLogName(), source.getSourceId(), game, Zone.HAND, true)) {
|
||||||
card.addCounters(CounterType.TIME.createInstance(3), source, game);
|
card.addCounters(CounterType.TIME.createInstance(3), source, game);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.f;
|
package mage.cards.f;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
@ -15,8 +14,8 @@ import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
|
import mage.filter.StaticFilters;
|
||||||
import mage.filter.common.FilterControlledPermanent;
|
import mage.filter.common.FilterControlledPermanent;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
|
||||||
import mage.filter.predicate.mageobject.CardTypePredicate;
|
import mage.filter.predicate.mageobject.CardTypePredicate;
|
||||||
import mage.filter.predicate.mageobject.SubtypePredicate;
|
import mage.filter.predicate.mageobject.SubtypePredicate;
|
||||||
|
|
||||||
|
|
@ -36,7 +35,7 @@ public final class Filth extends CardImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Filth(UUID ownerId, CardSetInfo setInfo) {
|
public Filth(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
|
||||||
this.subtype.add(SubType.INCARNATION);
|
this.subtype.add(SubType.INCARNATION);
|
||||||
|
|
||||||
this.power = new MageInt(2);
|
this.power = new MageInt(2);
|
||||||
|
|
@ -47,7 +46,7 @@ public final class Filth extends CardImpl {
|
||||||
|
|
||||||
// As long as Filth is in your graveyard and you control a Swamp, creatures you control have swampwalk.
|
// As long as Filth is in your graveyard and you control a Swamp, creatures you control have swampwalk.
|
||||||
ContinuousEffect effect = new GainAbilityControlledEffect(new SwampwalkAbility(),
|
ContinuousEffect effect = new GainAbilityControlledEffect(new SwampwalkAbility(),
|
||||||
Duration.WhileOnBattlefield, new FilterCreaturePermanent());
|
Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES);
|
||||||
ConditionalContinuousEffect filthEffect = new ConditionalContinuousEffect(effect,
|
ConditionalContinuousEffect filthEffect = new ConditionalContinuousEffect(effect,
|
||||||
new PermanentsOnTheBattlefieldCondition(filter), ruleText);
|
new PermanentsOnTheBattlefieldCondition(filter), ruleText);
|
||||||
this.addAbility(new SimpleStaticAbility(Zone.GRAVEYARD, filthEffect));
|
this.addAbility(new SimpleStaticAbility(Zone.GRAVEYARD, filthEffect));
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.h;
|
package mage.cards.h;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
@ -16,11 +15,11 @@ import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.AsThoughEffectType;
|
import mage.constants.AsThoughEffectType;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.Layer;
|
import mage.constants.Layer;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.constants.SubLayer;
|
import mage.constants.SubLayer;
|
||||||
|
import mage.constants.SubType;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.filter.FilterCard;
|
import mage.filter.FilterCard;
|
||||||
import mage.filter.common.FilterCreatureCard;
|
import mage.filter.common.FilterCreatureCard;
|
||||||
|
|
@ -39,7 +38,7 @@ public final class HavengulLich extends CardImpl {
|
||||||
private static final FilterCard filter = new FilterCreatureCard("creature card in a graveyard");
|
private static final FilterCard filter = new FilterCreatureCard("creature card in a graveyard");
|
||||||
|
|
||||||
public HavengulLich(UUID ownerId, CardSetInfo setInfo) {
|
public HavengulLich(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{B}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{B}");
|
||||||
this.subtype.add(SubType.ZOMBIE);
|
this.subtype.add(SubType.ZOMBIE);
|
||||||
this.subtype.add(SubType.WIZARD);
|
this.subtype.add(SubType.WIZARD);
|
||||||
|
|
||||||
|
|
@ -188,7 +187,7 @@ class HavengulLichEffect extends ContinuousEffectImpl {
|
||||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||||
Card card = game.getCard(cardId);
|
Card card = game.getCard(cardId);
|
||||||
if (permanent != null && card != null) {
|
if (permanent != null && card != null) {
|
||||||
for (ActivatedAbility ability : card.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) {
|
for (ActivatedAbility ability : card.getAbilities(game).getActivatedAbilities(Zone.BATTLEFIELD)) {
|
||||||
permanent.addAbility(ability, source.getSourceId(), game);
|
permanent.addAbility(ability, source.getSourceId(), game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
package mage.cards.j;
|
package mage.cards.j;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.MageObjectReference;
|
import mage.MageObjectReference;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
|
@ -20,10 +23,6 @@ import mage.game.Game;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.common.TargetCardInHand;
|
import mage.target.common.TargetCardInHand;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
|
|
@ -89,7 +88,7 @@ class JhoiraOfTheGhituSuspendEffect extends OneShotEffect {
|
||||||
if (card == null) {
|
if (card == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
boolean hasSuspend = card.getAbilities().containsClass(SuspendAbility.class);
|
boolean hasSuspend = card.getAbilities(game).containsClass(SuspendAbility.class);
|
||||||
|
|
||||||
UUID exileId = SuspendAbility.getSuspendExileId(controller.getId(), game);
|
UUID exileId = SuspendAbility.getSuspendExileId(controller.getId(), game);
|
||||||
if (controller.moveCardToExileWithInfo(card, exileId, "Suspended cards of " + controller.getName(), source.getSourceId(), game, Zone.HAND, true)) {
|
if (controller.moveCardToExileWithInfo(card, exileId, "Suspended cards of " + controller.getName(), source.getSourceId(), game, Zone.HAND, true)) {
|
||||||
|
|
@ -104,4 +103,3 @@ class JhoiraOfTheGhituSuspendEffect extends OneShotEffect {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.m;
|
package mage.cards.m;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -14,11 +13,11 @@ import mage.cards.Card;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.Layer;
|
import mage.constants.Layer;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.constants.SubLayer;
|
import mage.constants.SubLayer;
|
||||||
|
import mage.constants.SubType;
|
||||||
import mage.constants.SuperType;
|
import mage.constants.SuperType;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
|
|
@ -140,7 +139,7 @@ class MairsilThePretenderGainAbilitiesEffect extends ContinuousEffectImpl {
|
||||||
}
|
}
|
||||||
for (Card card : game.getExile().getAllCards(game)) {
|
for (Card card : game.getExile().getAllCards(game)) {
|
||||||
if (filter.match(card, game) && Objects.equals(card.getOwnerId(), perm.getControllerId())) {
|
if (filter.match(card, game) && Objects.equals(card.getOwnerId(), perm.getControllerId())) {
|
||||||
for (Ability ability : card.getAbilities()) {
|
for (Ability ability : card.getAbilities(game)) {
|
||||||
if (ability instanceof ActivatedAbility) {
|
if (ability instanceof ActivatedAbility) {
|
||||||
ActivatedAbility copyAbility = (ActivatedAbility) ability.copy();
|
ActivatedAbility copyAbility = (ActivatedAbility) ability.copy();
|
||||||
copyAbility.setMaxActivationsPerTurn(1);
|
copyAbility.setMaxActivationsPerTurn(1);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.m;
|
package mage.cards.m;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
@ -59,7 +58,7 @@ class MemoryCrystalSpellsCostReductionEffect extends CostModificationEffectImpl
|
||||||
|
|
||||||
Card card = game.getCard(abilityToModify.getSourceId());
|
Card card = game.getCard(abilityToModify.getSourceId());
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
for (Ability ability : card.getAbilities()) {
|
for (Ability ability : card.getAbilities(game)) {
|
||||||
if (ability instanceof BuybackAbility) {
|
if (ability instanceof BuybackAbility) {
|
||||||
if (ability.isActivated()) {
|
if (ability.isActivated()) {
|
||||||
int amountToReduce = ((BuybackAbility) ability).reduceCost(2);
|
int amountToReduce = ((BuybackAbility) ability).reduceCost(2);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
package mage.cards.m;
|
package mage.cards.m;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
@ -15,11 +13,11 @@ import mage.cards.Card;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.Layer;
|
import mage.constants.Layer;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.constants.SubLayer;
|
import mage.constants.SubLayer;
|
||||||
|
import mage.constants.SubType;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.filter.common.FilterArtifactCard;
|
import mage.filter.common.FilterArtifactCard;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
|
@ -33,7 +31,7 @@ import mage.target.common.TargetCardInGraveyard;
|
||||||
public final class MyrWelder extends CardImpl {
|
public final class MyrWelder extends CardImpl {
|
||||||
|
|
||||||
public MyrWelder(UUID ownerId, CardSetInfo setInfo) {
|
public MyrWelder(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{3}");
|
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}");
|
||||||
this.subtype.add(SubType.MYR);
|
this.subtype.add(SubType.MYR);
|
||||||
this.power = new MageInt(1);
|
this.power = new MageInt(1);
|
||||||
this.toughness = new MageInt(4);
|
this.toughness = new MageInt(4);
|
||||||
|
|
@ -104,12 +102,12 @@ class MyrWelderContinuousEffect extends ContinuousEffectImpl {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Permanent perm = game.getPermanent(source.getSourceId());
|
Permanent perm = game.getPermanent(source.getSourceId());
|
||||||
if (perm != null) {
|
if (perm != null) {
|
||||||
for (UUID imprintedId: perm.getImprinted()) {
|
for (UUID imprintedId : perm.getImprinted()) {
|
||||||
Card card = game.getCard(imprintedId);
|
Card card = game.getCard(imprintedId);
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
for (Ability ability: card.getAbilities()) {
|
for (Ability ability : card.getAbilities(game)) {
|
||||||
if (ability instanceof ActivatedAbility) {
|
if (ability instanceof ActivatedAbility) {
|
||||||
perm.addAbility(ability, game);
|
perm.addAbility(ability, source.getId(), game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.n;
|
package mage.cards.n;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
@ -18,11 +17,11 @@ import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.cards.CardsImpl;
|
import mage.cards.CardsImpl;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.Layer;
|
import mage.constants.Layer;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.constants.SubLayer;
|
import mage.constants.SubLayer;
|
||||||
|
import mage.constants.SubType;
|
||||||
import mage.constants.SuperType;
|
import mage.constants.SuperType;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
|
@ -171,7 +170,7 @@ class NarsetTranscendentGainReboundEffect extends ContinuousEffectImpl {
|
||||||
if (spell != null) {
|
if (spell != null) {
|
||||||
Card card = spell.getCard();
|
Card card = spell.getCard();
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
addReboundAbility(card, source, game);
|
addReboundAbility(card, game);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
discard();
|
discard();
|
||||||
|
|
@ -181,9 +180,9 @@ class NarsetTranscendentGainReboundEffect extends ContinuousEffectImpl {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addReboundAbility(Card card, Ability source, Game game) {
|
private void addReboundAbility(Card card, Game game) {
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
for (Ability ability : card.getAbilities()) {
|
for (Ability ability : card.getAbilities(game)) {
|
||||||
if (ability instanceof ReboundAbility) {
|
if (ability instanceof ReboundAbility) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
|
|
||||||
package mage.cards.n;
|
package mage.cards.n;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.ActivatedAbility;
|
import mage.abilities.ActivatedAbility;
|
||||||
|
|
@ -66,9 +64,9 @@ public final class NecroticOoze extends CardImpl {
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
for (Card card : player.getGraveyard().getCards(game)) {
|
for (Card card : player.getGraveyard().getCards(game)) {
|
||||||
if (card.isCreature()) {
|
if (card.isCreature()) {
|
||||||
for (Ability ability : card.getAbilities()) {
|
for (Ability ability : card.getAbilities(game)) {
|
||||||
if (ability instanceof ActivatedAbility) {
|
if (ability instanceof ActivatedAbility) {
|
||||||
perm.addAbility(ability, game);
|
perm.addAbility(ability, source.getSourceId(), game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
package mage.cards.p;
|
package mage.cards.p;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.SpellAbility;
|
import mage.abilities.SpellAbility;
|
||||||
|
|
@ -23,10 +26,6 @@ import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.target.TargetPermanent;
|
import mage.target.TargetPermanent;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
*/
|
*/
|
||||||
|
|
@ -76,6 +75,7 @@ class PolukranosUnchainedEffect extends OneShotEffect {
|
||||||
|
|
||||||
PolukranosUnchainedEffect() {
|
PolukranosUnchainedEffect() {
|
||||||
super(Outcome.BoostCreature);
|
super(Outcome.BoostCreature);
|
||||||
|
staticText = "with six +1/+1 counters on it. It escapes with twelve +1/+1 counters on it instead";
|
||||||
}
|
}
|
||||||
|
|
||||||
private PolukranosUnchainedEffect(final PolukranosUnchainedEffect effect) {
|
private PolukranosUnchainedEffect(final PolukranosUnchainedEffect effect) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.s;
|
package mage.cards.s;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
@ -13,11 +12,11 @@ import mage.cards.Card;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.Layer;
|
import mage.constants.Layer;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.constants.SubLayer;
|
import mage.constants.SubLayer;
|
||||||
|
import mage.constants.SubType;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
|
@ -30,7 +29,7 @@ import mage.players.Player;
|
||||||
public final class SkillBorrower extends CardImpl {
|
public final class SkillBorrower extends CardImpl {
|
||||||
|
|
||||||
public SkillBorrower(UUID ownerId, CardSetInfo setInfo) {
|
public SkillBorrower(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}{U}");
|
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}{U}");
|
||||||
this.subtype.add(SubType.HUMAN);
|
this.subtype.add(SubType.HUMAN);
|
||||||
this.subtype.add(SubType.WIZARD);
|
this.subtype.add(SubType.WIZARD);
|
||||||
|
|
||||||
|
|
@ -53,7 +52,6 @@ public final class SkillBorrower extends CardImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class SkillBorrowerAbility extends StaticAbility {
|
class SkillBorrowerAbility extends StaticAbility {
|
||||||
|
|
||||||
public SkillBorrowerAbility() {
|
public SkillBorrowerAbility() {
|
||||||
|
|
@ -71,7 +69,7 @@ class SkillBorrowerAbility extends StaticAbility {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return "As long as the top card of your library is an artifact or creature card, Skill Borrower has all activated abilities of that card";
|
return "As long as the top card of your library is an artifact or creature card, {this} has all activated abilities of that card";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,14 +77,13 @@ class SkillBorrowerEffect extends ContinuousEffectImpl {
|
||||||
|
|
||||||
public SkillBorrowerEffect() {
|
public SkillBorrowerEffect() {
|
||||||
super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
|
super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
|
||||||
staticText = "As long as the top card of your library is an artifact or creature card, Skill Borrower has all activated abilities of that card";
|
staticText = "As long as the top card of your library is an artifact or creature card, {this} has all activated abilities of that card";
|
||||||
}
|
}
|
||||||
|
|
||||||
public SkillBorrowerEffect(final SkillBorrowerEffect effect) {
|
public SkillBorrowerEffect(final SkillBorrowerEffect effect) {
|
||||||
super(effect);
|
super(effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SkillBorrowerEffect copy() {
|
public SkillBorrowerEffect copy() {
|
||||||
return new SkillBorrowerEffect(this);
|
return new SkillBorrowerEffect(this);
|
||||||
|
|
@ -95,13 +92,13 @@ class SkillBorrowerEffect extends ContinuousEffectImpl {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player player = game.getPlayer(source.getControllerId());
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
if(player != null){
|
if (player != null) {
|
||||||
Card card = player.getLibrary().getFromTop(game);
|
Card card = player.getLibrary().getFromTop(game);
|
||||||
if(card != null && (card.isCreature() || card.isArtifact())){
|
if (card != null && (card.isCreature() || card.isArtifact())) {
|
||||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||||
if(permanent != null){
|
if (permanent != null) {
|
||||||
for(Ability ability : card.getAbilities()){
|
for (Ability ability : card.getAbilities(game)) {
|
||||||
if(ability instanceof ActivatedAbility){
|
if (ability instanceof ActivatedAbility) {
|
||||||
permanent.addAbility(ability, source.getSourceId(), game);
|
permanent.addAbility(ability, source.getSourceId(), game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
package mage.cards.s;
|
package mage.cards.s;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.MageObjectReference;
|
import mage.MageObjectReference;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
|
@ -16,10 +19,6 @@ import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.util.CardUtil;
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
|
|
@ -91,7 +90,7 @@ class SoulflayerEffect extends ContinuousEffectImpl implements SourceEffect {
|
||||||
if (!card.isCreature()) {
|
if (!card.isCreature()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (Ability cardAbility : card.getAbilities()) {
|
for (Ability cardAbility : card.getAbilities(game)) {
|
||||||
if (cardAbility instanceof FlyingAbility) {
|
if (cardAbility instanceof FlyingAbility) {
|
||||||
abilitiesToAdd.add(FlyingAbility.getInstance());
|
abilitiesToAdd.add(FlyingAbility.getInstance());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package mage.cards.t;
|
package mage.cards.t;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.DelayedTriggeredAbility;
|
import mage.abilities.DelayedTriggeredAbility;
|
||||||
|
|
@ -26,8 +27,6 @@ import mage.players.Player;
|
||||||
import mage.target.targetpointer.FixedTarget;
|
import mage.target.targetpointer.FixedTarget;
|
||||||
import mage.watchers.common.AttackedThisTurnWatcher;
|
import mage.watchers.common.AttackedThisTurnWatcher;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author spjspj
|
* @author spjspj
|
||||||
*/
|
*/
|
||||||
|
|
@ -153,7 +152,7 @@ class TaigamOjutaiMasterGainReboundEffect extends ContinuousEffectImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addReboundAbility(Card card, Ability source, Game game) {
|
private void addReboundAbility(Card card, Ability source, Game game) {
|
||||||
boolean found = card.getAbilities().stream().anyMatch(ability -> ability instanceof ReboundAbility);
|
boolean found = card.getAbilities(game).stream().anyMatch(ability -> ability instanceof ReboundAbility);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
Ability ability = new ReboundAbility();
|
Ability ability = new ReboundAbility();
|
||||||
game.getState().addOtherAbility(card, ability);
|
game.getState().addOtherAbility(card, ability);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package mage.cards.v;
|
package mage.cards.v;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
|
@ -14,8 +15,6 @@ import mage.constants.*;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ImperatorPrime
|
* @author ImperatorPrime
|
||||||
*/
|
*/
|
||||||
|
|
@ -98,7 +97,7 @@ class VolrathsShapeshifterEffect extends ContinuousEffectImpl {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Ability ability : card.getAbilities()) {
|
for (Ability ability : card.getAbilities(game)) {
|
||||||
if (!permanent.getAbilities().contains(ability)) {
|
if (!permanent.getAbilities().contains(ability)) {
|
||||||
permanent.addAbility(ability, source.getSourceId(), game);
|
permanent.addAbility(ability, source.getSourceId(), game);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
|
|
||||||
package mage.cards.y;
|
package mage.cards.y;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Abilities;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.effects.ContinuousEffectImpl;
|
import mage.abilities.effects.ContinuousEffectImpl;
|
||||||
|
|
@ -21,7 +19,7 @@ import mage.players.Player;
|
||||||
public final class YixlidJailer extends CardImpl {
|
public final class YixlidJailer extends CardImpl {
|
||||||
|
|
||||||
public YixlidJailer(UUID ownerId, CardSetInfo setInfo) {
|
public YixlidJailer(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
|
||||||
this.subtype.add(SubType.ZOMBIE);
|
this.subtype.add(SubType.ZOMBIE);
|
||||||
this.subtype.add(SubType.WIZARD);
|
this.subtype.add(SubType.WIZARD);
|
||||||
|
|
||||||
|
|
@ -67,14 +65,7 @@ public final class YixlidJailer extends CardImpl {
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
for (Card card : player.getGraveyard().getCards(game)) {
|
for (Card card : player.getGraveyard().getCards(game)) {
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
card.getAbilities(game).clear(); // Will the abilities ever come back????
|
card.looseAllAbilities(game);
|
||||||
// TODO: Fix that (LevelX2)
|
|
||||||
// game.getContinuousEffects().removeGainedEffectsForSource(card.getId());
|
|
||||||
// game.getState().resetTriggersForSourceId(card.getId());
|
|
||||||
Abilities abilities = game.getState().getAllOtherAbilities(card.getId());
|
|
||||||
if (abilities != null) {
|
|
||||||
abilities.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.mage.test.cards.continuous;
|
||||||
|
|
||||||
|
import mage.abilities.keyword.SwampwalkAbility;
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author LevelX2
|
||||||
|
*/
|
||||||
|
public class LoosingAbilitiesTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void GivingSwampwalkFromGraveyard() {
|
||||||
|
|
||||||
|
// Swampwalk
|
||||||
|
// As long as Filth is in your graveyard and you control a Swamp, creatures you control have swampwalk.
|
||||||
|
addCard(Zone.GRAVEYARD, playerB, "Filth"); // Creature
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPermanentCount(playerB, "Silvercoat Lion", 1);
|
||||||
|
assertAbility(playerB, "Silvercoat Lion", new SwampwalkAbility(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Card in the graveyard should have no Swampwalk if Yixlid Jailer
|
||||||
|
* effect was added later
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testYixlidJailerRemovesAbilities() {
|
||||||
|
// Cards in graveyards lose all abilities.
|
||||||
|
addCard(Zone.HAND, playerA, "Yixlid Jailer"); // Creature 2/1 - {1}{B}
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
|
||||||
|
|
||||||
|
// Swampwalk
|
||||||
|
// As long as Filth is in your graveyard and you control a Swamp, creatures you control have swampwalk.
|
||||||
|
addCard(Zone.GRAVEYARD, playerB, "Filth");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Yixlid Jailer");
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPermanentCount(playerB, "Silvercoat Lion", 1);
|
||||||
|
assertAbility(playerB, "Silvercoat Lion", new SwampwalkAbility(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/magefree/mage/issues/1147
|
||||||
|
@Test
|
||||||
|
public void testYixlidJailerAbilitiesComeBack() {
|
||||||
|
// Cards in graveyards lose all abilities.
|
||||||
|
addCard(Zone.HAND, playerA, "Yixlid Jailer"); // Creature 2/1 - {1}{B}
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4);
|
||||||
|
|
||||||
|
// Gravecrawler can’t block.
|
||||||
|
// You may cast Gravecrawler from your graveyard as long as you control a Zombie.
|
||||||
|
addCard(Zone.GRAVEYARD, playerB, "Gravecrawler");
|
||||||
|
addCard(Zone.HAND, playerB, "Lightning Bolt", 2);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Walking Corpse"); // Creature 2/2 - Zombie
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Yixlid Jailer");
|
||||||
|
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", "Yixlid Jailer");
|
||||||
|
|
||||||
|
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Gravecrawler");
|
||||||
|
|
||||||
|
setStopAt(2, PhaseStep.BEGIN_COMBAT);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertGraveyardCount(playerA, "Yixlid Jailer", 1);
|
||||||
|
assertGraveyardCount(playerB, "Lightning Bolt", 1);
|
||||||
|
|
||||||
|
assertPermanentCount(playerB, "Gravecrawler", 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,17 +5,13 @@ import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.Mana;
|
|
||||||
import mage.abilities.costs.*;
|
import mage.abilities.costs.*;
|
||||||
import mage.abilities.costs.common.PayLifeCost;
|
import mage.abilities.costs.common.PayLifeCost;
|
||||||
import mage.abilities.costs.common.TapSourceCost;
|
|
||||||
import mage.abilities.costs.mana.*;
|
import mage.abilities.costs.mana.*;
|
||||||
import mage.abilities.effects.ContinuousEffect;
|
import mage.abilities.effects.ContinuousEffect;
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
import mage.abilities.effects.Effects;
|
import mage.abilities.effects.Effects;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.ManaEffect;
|
|
||||||
import mage.abilities.effects.mana.DynamicManaEffect;
|
|
||||||
import mage.abilities.hint.Hint;
|
import mage.abilities.hint.Hint;
|
||||||
import mage.abilities.mana.ActivatedManaAbilityImpl;
|
import mage.abilities.mana.ActivatedManaAbilityImpl;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
|
|
@ -25,7 +21,6 @@ import mage.game.Game;
|
||||||
import mage.game.command.Emblem;
|
import mage.game.command.Emblem;
|
||||||
import mage.game.command.Plane;
|
import mage.game.command.Plane;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
import mage.game.events.ManaEvent;
|
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.game.stack.Spell;
|
import mage.game.stack.Spell;
|
||||||
import mage.game.stack.StackAbility;
|
import mage.game.stack.StackAbility;
|
||||||
|
|
@ -952,7 +947,12 @@ public abstract class AbilityImpl implements Ability {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return ((Permanent) object).isPhasedIn();
|
return ((Permanent) object).isPhasedIn();
|
||||||
} else if (!object.getAbilities().contains(this)) {
|
} else if (object instanceof Card) {
|
||||||
|
if (!((Card) object).getAbilities(game).contains(this)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else if (!object.getAbilities().contains(this)) { // not sure which object it can still be
|
||||||
// check if it's an ability that is temporary gained to a card
|
// check if it's an ability that is temporary gained to a card
|
||||||
Abilities<Ability> otherAbilities = game.getState().getAllOtherAbilities(this.getSourceId());
|
Abilities<Ability> otherAbilities = game.getState().getAllOtherAbilities(this.getSourceId());
|
||||||
return otherAbilities != null && otherAbilities.contains(this);
|
return otherAbilities != null && otherAbilities.contains(this);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package mage.cards;
|
package mage.cards;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.Mana;
|
import mage.Mana;
|
||||||
import mage.abilities.Abilities;
|
import mage.abilities.Abilities;
|
||||||
|
|
@ -14,9 +16,6 @@ import mage.game.Game;
|
||||||
import mage.game.GameState;
|
import mage.game.GameState;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public interface Card extends MageObject {
|
public interface Card extends MageObject {
|
||||||
|
|
||||||
UUID getOwnerId();
|
UUID getOwnerId();
|
||||||
|
|
@ -77,15 +76,15 @@ public interface Card extends MageObject {
|
||||||
* @param zone
|
* @param zone
|
||||||
* @param sourceId
|
* @param sourceId
|
||||||
* @param game
|
* @param game
|
||||||
* @param flag If zone
|
* @param flag If zone
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>LIBRARY: <ul><li>true - put on top</li><li>false - put on
|
* <li>LIBRARY: <ul><li>true - put on top</li><li>false - put on
|
||||||
* bottom</li></ul></li>
|
* bottom</li></ul></li>
|
||||||
* <li>BATTLEFIELD: <ul><li>true - tapped</li><li>false -
|
* <li>BATTLEFIELD: <ul><li>true - tapped</li><li>false -
|
||||||
* untapped</li></ul></li>
|
* untapped</li></ul></li>
|
||||||
* <li>GRAVEYARD: <ul><li>true - not from Battlefield</li><li>false - from
|
* <li>GRAVEYARD: <ul><li>true - not from Battlefield</li><li>false - from
|
||||||
* Battlefield</li></ul></li>
|
* Battlefield</li></ul></li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* @return true if card was moved to zone
|
* @return true if card was moved to zone
|
||||||
*/
|
*/
|
||||||
boolean moveToZone(Zone zone, UUID sourceId, Game game, boolean flag);
|
boolean moveToZone(Zone zone, UUID sourceId, Game game, boolean flag);
|
||||||
|
|
@ -95,8 +94,8 @@ public interface Card extends MageObject {
|
||||||
/**
|
/**
|
||||||
* Moves the card to an exile zone
|
* Moves the card to an exile zone
|
||||||
*
|
*
|
||||||
* @param exileId set to null for generic exile zone
|
* @param exileId set to null for generic exile zone
|
||||||
* @param name used for exile zone with the specified exileId
|
* @param name used for exile zone with the specified exileId
|
||||||
* @param sourceId
|
* @param sourceId
|
||||||
* @param game
|
* @param game
|
||||||
* @return true if card was moved to zone
|
* @return true if card was moved to zone
|
||||||
|
|
@ -132,6 +131,8 @@ public interface Card extends MageObject {
|
||||||
|
|
||||||
void addAbility(Ability ability);
|
void addAbility(Ability ability);
|
||||||
|
|
||||||
|
void looseAllAbilities(Game game);
|
||||||
|
|
||||||
boolean addCounters(Counter counter, Ability source, Game game);
|
boolean addCounters(Counter counter, Ability source, Game game);
|
||||||
|
|
||||||
boolean addCounters(Counter counter, Ability source, Game game, boolean isEffect);
|
boolean addCounters(Counter counter, Ability source, Game game, boolean isEffect);
|
||||||
|
|
@ -148,8 +149,8 @@ public interface Card extends MageObject {
|
||||||
Card copy();
|
Card copy();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The main card of a split half card or adventure spell card, otherwise the card itself is
|
* @return The main card of a split half card or adventure spell card,
|
||||||
* returned
|
* otherwise the card itself is returned
|
||||||
*/
|
*/
|
||||||
Card getMainCard();
|
Card getMainCard();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,12 @@
|
||||||
package mage.cards;
|
package mage.cards;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.MageObjectImpl;
|
import mage.MageObjectImpl;
|
||||||
import mage.Mana;
|
import mage.Mana;
|
||||||
|
|
@ -26,13 +32,6 @@ import mage.util.SubTypeList;
|
||||||
import mage.watchers.Watcher;
|
import mage.watchers.Watcher;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public abstract class CardImpl extends MageObjectImpl implements Card {
|
public abstract class CardImpl extends MageObjectImpl implements Card {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
@ -240,19 +239,12 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
||||||
@Override
|
@Override
|
||||||
public List<String> getRules(Game game) {
|
public List<String> getRules(Game game) {
|
||||||
try {
|
try {
|
||||||
List<String> rules = getRules();
|
List<String> rules = getAbilities(game).getRules(getName());
|
||||||
if (game != null) {
|
if (game != null) {
|
||||||
// debug state
|
// debug state
|
||||||
CardState cardState = game.getState().getCardState(objectId);
|
for (String data : game.getState().getCardState(objectId).getInfo().values()) {
|
||||||
if (cardState != null) {
|
rules.add(data);
|
||||||
for (String data : cardState.getInfo().values()) {
|
|
||||||
rules.add(data);
|
|
||||||
}
|
|
||||||
for (Ability ability : cardState.getAbilities()) {
|
|
||||||
rules.add(ability.getRule());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ability hints
|
// ability hints
|
||||||
List<String> abilityHints = new ArrayList<>();
|
List<String> abilityHints = new ArrayList<>();
|
||||||
if (HintUtils.ABILITY_HINTS_ENABLE) {
|
if (HintUtils.ABILITY_HINTS_ENABLE) {
|
||||||
|
|
@ -267,7 +259,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
||||||
}
|
}
|
||||||
|
|
||||||
// restrict hints only for permanents, not cards
|
// restrict hints only for permanents, not cards
|
||||||
|
|
||||||
// total hints
|
// total hints
|
||||||
if (!abilityHints.isEmpty()) {
|
if (!abilityHints.isEmpty()) {
|
||||||
rules.add(HintUtils.HINT_START_MARK);
|
rules.add(HintUtils.HINT_START_MARK);
|
||||||
|
|
@ -301,21 +292,31 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Abilities<Ability> getAbilities(Game game) {
|
public Abilities<Ability> getAbilities(Game game) {
|
||||||
Abilities<Ability> otherAbilities = game.getState().getAllOtherAbilities(objectId);
|
CardState cardState = game.getState().getCardState(this.getId());
|
||||||
if (otherAbilities == null || otherAbilities.isEmpty()) {
|
if (!cardState.hasLostAllAbilities() && (cardState.getAbilities() == null || cardState.getAbilities().isEmpty())) {
|
||||||
return abilities;
|
return abilities;
|
||||||
}
|
}
|
||||||
Abilities<Ability> all = new AbilitiesImpl<>();
|
Abilities<Ability> all = new AbilitiesImpl<>();
|
||||||
all.addAll(abilities);
|
if (!cardState.hasLostAllAbilities()) {
|
||||||
all.addAll(otherAbilities);
|
all.addAll(abilities);
|
||||||
|
}
|
||||||
|
all.addAll(cardState.getAbilities());
|
||||||
return all;
|
return all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void looseAllAbilities(Game game) {
|
||||||
|
CardState cardState = game.getState().getCardState(this.getId());
|
||||||
|
cardState.setLostAllAbilities(true);
|
||||||
|
cardState.getAbilities().clear();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public in order to support adding abilities to SplitCardHalf's
|
* Public in order to support adding abilities to SplitCardHalf's
|
||||||
*
|
*
|
||||||
* @param ability
|
* @param ability
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void addAbility(Ability ability) {
|
public void addAbility(Ability ability) {
|
||||||
ability.setSourceId(this.getId());
|
ability.setSourceId(this.getId());
|
||||||
abilities.add(ability);
|
abilities.add(ability);
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ public class CardState implements Serializable {
|
||||||
protected Map<String, String> info;
|
protected Map<String, String> info;
|
||||||
protected Counters counters;
|
protected Counters counters;
|
||||||
protected Abilities<Ability> abilities;
|
protected Abilities<Ability> abilities;
|
||||||
|
protected boolean lostAllAbilities;
|
||||||
|
|
||||||
private static final Map<String, String> emptyInfo = new HashMap<>();
|
private static final Map<String, String> emptyInfo = new HashMap<>();
|
||||||
private static final Abilities<Ability> emptyAbilities = new AbilitiesImpl<>();
|
private static final Abilities<Ability> emptyAbilities = new AbilitiesImpl<>();
|
||||||
|
|
@ -39,6 +40,7 @@ public class CardState implements Serializable {
|
||||||
abilities.add(ability.copy());
|
abilities.add(ability.copy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.lostAllAbilities = state.lostAllAbilities;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CardState copy() {
|
public CardState copy() {
|
||||||
|
|
@ -90,20 +92,29 @@ public class CardState implements Serializable {
|
||||||
abilities.addAll(ability.getSubAbilities());
|
abilities.addAll(ability.getSubAbilities());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called from applyEffects reset, to reset all layered effects
|
||||||
|
*/
|
||||||
public void clearAbilities() {
|
public void clearAbilities() {
|
||||||
if (abilities != null) {
|
if (abilities != null) {
|
||||||
// for (Ability ability: abilities) { // Causes problems if temporary (gained) continuous effects are removed
|
|
||||||
// ability.setSourceId(null);
|
|
||||||
// ability.setControllerId(null);
|
|
||||||
// }
|
|
||||||
abilities = null;
|
abilities = null;
|
||||||
}
|
}
|
||||||
|
setLostAllAbilities(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
counters.clear();
|
counters.clear();
|
||||||
info = null;
|
info = null;
|
||||||
clearAbilities();
|
clearAbilities();
|
||||||
|
lostAllAbilities = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasLostAllAbilities() {
|
||||||
|
return lostAllAbilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLostAllAbilities(boolean lostAllAbilities) {
|
||||||
|
this.lostAllAbilities = lostAllAbilities;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
package mage.game;
|
package mage.game;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.abilities.*;
|
import mage.abilities.*;
|
||||||
import mage.abilities.effects.ContinuousEffect;
|
import mage.abilities.effects.ContinuousEffect;
|
||||||
|
|
@ -34,10 +37,6 @@ import mage.util.ThreadLocalStringBuilder;
|
||||||
import mage.watchers.Watcher;
|
import mage.watchers.Watcher;
|
||||||
import mage.watchers.Watchers;
|
import mage.watchers.Watchers;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -602,7 +601,6 @@ public class GameState implements Serializable, Copyable<GameState> {
|
||||||
// public void addMessage(String message) {
|
// public void addMessage(String message) {
|
||||||
// this.messages.add(message);
|
// this.messages.add(message);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of all players of the game ignoring range or if a player
|
* Returns a list of all players of the game ignoring range or if a player
|
||||||
* has lost or left the game.
|
* has lost or left the game.
|
||||||
|
|
@ -636,8 +634,9 @@ public class GameState implements Serializable, Copyable<GameState> {
|
||||||
* also setting the playerId to the first/current player of the list. Also
|
* also setting the playerId to the first/current player of the list. Also
|
||||||
* returning the other players in turn order.
|
* returning the other players in turn order.
|
||||||
* <p>
|
* <p>
|
||||||
* Not safe for continuous effects, see rule 800.4k (effects must work until end of turn even after player leaves)
|
* Not safe for continuous effects, see rule 800.4k (effects must work until
|
||||||
* Use Player.InRange() to find active players list at the start of the turn
|
* end of turn even after player leaves) Use Player.InRange() to find active
|
||||||
|
* players list at the start of the turn
|
||||||
*
|
*
|
||||||
* @param playerId
|
* @param playerId
|
||||||
* @param game
|
* @param game
|
||||||
|
|
@ -775,7 +774,7 @@ public class GameState implements Serializable, Copyable<GameState> {
|
||||||
for (Map.Entry<ZoneChangeData, List<GameEvent>> entry : eventsByKey.entrySet()) {
|
for (Map.Entry<ZoneChangeData, List<GameEvent>> entry : eventsByKey.entrySet()) {
|
||||||
Set<Card> movedCards = new LinkedHashSet<>();
|
Set<Card> movedCards = new LinkedHashSet<>();
|
||||||
Set<PermanentToken> movedTokens = new LinkedHashSet<>();
|
Set<PermanentToken> movedTokens = new LinkedHashSet<>();
|
||||||
for (Iterator<GameEvent> it = entry.getValue().iterator(); it.hasNext(); ) {
|
for (Iterator<GameEvent> it = entry.getValue().iterator(); it.hasNext();) {
|
||||||
GameEvent event = it.next();
|
GameEvent event = it.next();
|
||||||
ZoneChangeEvent castEvent = (ZoneChangeEvent) event;
|
ZoneChangeEvent castEvent = (ZoneChangeEvent) event;
|
||||||
UUID targetId = castEvent.getTargetId();
|
UUID targetId = castEvent.getTargetId();
|
||||||
|
|
@ -1008,7 +1007,7 @@ public class GameState implements Serializable, Copyable<GameState> {
|
||||||
* @param attachedTo
|
* @param attachedTo
|
||||||
* @param ability
|
* @param ability
|
||||||
* @param copyAbility copies non MageSingleton abilities before adding to
|
* @param copyAbility copies non MageSingleton abilities before adding to
|
||||||
* state
|
* state
|
||||||
*/
|
*/
|
||||||
public void addOtherAbility(Card attachedTo, Ability ability, boolean copyAbility) {
|
public void addOtherAbility(Card attachedTo, Ability ability, boolean copyAbility) {
|
||||||
Ability newAbility;
|
Ability newAbility;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package mage.game.stack;
|
package mage.game.stack;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.Mana;
|
import mage.Mana;
|
||||||
|
|
@ -31,8 +32,6 @@ import mage.players.Player;
|
||||||
import mage.util.GameLog;
|
import mage.util.GameLog;
|
||||||
import mage.util.SubTypeList;
|
import mage.util.SubTypeList;
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
|
|
@ -1045,4 +1044,9 @@ public class Spell extends StackObjImpl implements Card {
|
||||||
return commandedBy;
|
return commandedBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void looseAllAbilities(Game game) {
|
||||||
|
throw new UnsupportedOperationException("Spells should not loose all abilities. Check if this operation is correct.");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue