mirror of
https://github.com/magefree/mage.git
synced 2025-12-26 21:42:07 -08:00
Refactoring subtypes to make Maskwood Nexus work (ready for review) (#7432)
* removed and renamed SubTypeList * updated subtype test * refactored Changeling to be an ability that actually does something * moved isAllCreatureTypes into SubTypes class * renamed copyTo method to copyFrom * added removeAllCreatureTypes where usable * replaced some subtype methods * replaced some more subtype methods * replaced subtype mass add/remove methods * updated more subtype methods * fixed some errors * made common shared creature type predicate * refactored another card involving subtypes * Added usage of object attribute in subTypes's write operations; * Refactor: use same param styles in subtype methods * Refactor: simplified usage of copy appliers; * Refactor: fixed code usage in CopyApplier Co-authored-by: Oleg Agafonov <jaydi85@gmail.com>
This commit is contained in:
parent
6f42b90305
commit
dacf30f4b9
259 changed files with 1857 additions and 1922 deletions
|
|
@ -13,10 +13,11 @@ import mage.constants.SubTypeSet;
|
|||
import mage.constants.SuperType;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.util.SubTypeList;
|
||||
import mage.util.SubTypes;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
|
|
@ -34,7 +35,20 @@ public interface MageObject extends MageItem, Serializable {
|
|||
|
||||
ArrayList<CardType> getCardType();
|
||||
|
||||
SubTypeList getSubtype(Game game);
|
||||
/**
|
||||
* Return original object's subtypes
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
SubTypes getSubtype();
|
||||
|
||||
/**
|
||||
* Return full subtypes list (from object, from effects)
|
||||
*
|
||||
* @param game
|
||||
* @return
|
||||
*/
|
||||
SubTypes getSubtype(Game game);
|
||||
|
||||
boolean hasSubtype(SubType subtype, Game game);
|
||||
|
||||
|
|
@ -50,6 +64,8 @@ public interface MageObject extends MageItem, Serializable {
|
|||
|
||||
boolean hasAbility(Ability ability, Game game);
|
||||
|
||||
ObjectColor getColor();
|
||||
|
||||
ObjectColor getColor(Game game);
|
||||
|
||||
ObjectColor getFrameColor(Game game);
|
||||
|
|
@ -91,7 +107,7 @@ public interface MageObject extends MageItem, Serializable {
|
|||
default boolean isHistoric() {
|
||||
return getCardType().contains(CardType.ARTIFACT)
|
||||
|| getSuperType().contains(SuperType.LEGENDARY)
|
||||
|| hasSubtype(SubType.SAGA, null);
|
||||
|| getSubtype().contains(SubType.SAGA);
|
||||
}
|
||||
|
||||
default boolean isCreature() {
|
||||
|
|
@ -164,23 +180,104 @@ public interface MageObject extends MageItem, Serializable {
|
|||
getCardType().add(cardType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add subtype temporary, for continuous effects only
|
||||
*
|
||||
* @param game
|
||||
* @param subTypes
|
||||
*/
|
||||
default void addSubType(Game game, Collection<SubType> subTypes) {
|
||||
for (SubType subType : subTypes) {
|
||||
addSubType(game, subType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add subtype permanently, for one shot effects and tokens setup
|
||||
*
|
||||
* @param subTypes
|
||||
*/
|
||||
default void addSubType(SubType... subTypes) {
|
||||
for (SubType subType : subTypes) {
|
||||
if (subType.canGain(this)
|
||||
&& !getSubtype().contains(subType)) {
|
||||
getSubtype().add(subType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add subtype temporary, for continuous effects only
|
||||
*
|
||||
* @param game
|
||||
* @param subTypes
|
||||
*/
|
||||
default void addSubType(Game game, SubType... subTypes) {
|
||||
for (SubType subType : subTypes) {
|
||||
if (subType.canGain(this)
|
||||
&& !hasSubtype(subType, game)) {
|
||||
getSubtype(game).add(subType);
|
||||
game.getState().getCreateMageObjectAttribute(this, game).getSubtype().add(subType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default void copySubTypesFrom(Game game, MageObject mageObject) {
|
||||
copySubTypesFrom(game, mageObject, null);
|
||||
}
|
||||
|
||||
default void copySubTypesFrom(Game game, MageObject mageObject, SubTypeSet subTypeSet) {
|
||||
if (subTypeSet == SubTypeSet.CreatureType || subTypeSet == null) {
|
||||
this.setIsAllCreatureTypes(game, mageObject.isAllCreatureTypes(game));
|
||||
}
|
||||
for (SubType subType : mageObject.getSubtype(game)) {
|
||||
if (subType.getSubTypeSet() == subTypeSet || subTypeSet == null) {
|
||||
this.addSubType(game, subType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default void removeAllSubTypes(Game game) {
|
||||
getSubtype(game).clear();
|
||||
setIsAllCreatureTypes(false);
|
||||
removeAllSubTypes(game, null);
|
||||
}
|
||||
|
||||
default void removeAllCreatureTypes(Game game) {
|
||||
getSubtype(game).removeAll(SubType.getCreatureTypes());
|
||||
default void removeAllSubTypes(Game game, SubTypeSet subTypeSet) {
|
||||
if (subTypeSet == null) {
|
||||
setIsAllCreatureTypes(game, false);
|
||||
game.getState().getCreateMageObjectAttribute(this, game).getSubtype().clear();
|
||||
} else if (subTypeSet == SubTypeSet.CreatureType) {
|
||||
removeAllCreatureTypes(game);
|
||||
} else if (subTypeSet == SubTypeSet.NonBasicLandType) {
|
||||
game.getState().getCreateMageObjectAttribute(this, game).getSubtype().removeAll(SubType.getLandTypes());
|
||||
} else {
|
||||
game.getState().getCreateMageObjectAttribute(this, game).getSubtype().removeAll(SubType.getBySubTypeSet(subTypeSet));
|
||||
}
|
||||
}
|
||||
|
||||
default void retainAllEnchantmentSubTypes(Game game) {
|
||||
setIsAllCreatureTypes(game, false);
|
||||
game.getState().getCreateMageObjectAttribute(this, game).getSubtype().retainAll(SubType.getEnchantmentTypes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove object's own creature types forever (for copy effects usage)
|
||||
*/
|
||||
default void removeAllCreatureTypes() {
|
||||
setIsAllCreatureTypes(false);
|
||||
getSubtype().removeAll(SubType.getCreatureTypes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove object attribute's creature types temporary (for continuous effects usage)
|
||||
*
|
||||
* @param game
|
||||
*/
|
||||
default void removeAllCreatureTypes(Game game) {
|
||||
setIsAllCreatureTypes(game, false);
|
||||
game.getState().getCreateMageObjectAttribute(this, game).getSubtype().removeAll(SubType.getCreatureTypes());
|
||||
}
|
||||
|
||||
default void removeSubType(Game game, SubType subType) {
|
||||
game.getState().getCreateMageObjectAttribute(this, game).getSubtype().remove(subType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -209,19 +306,19 @@ public interface MageObject extends MageItem, Serializable {
|
|||
return false;
|
||||
}
|
||||
|
||||
default boolean shareCreatureTypes(Card otherCard, Game game) {
|
||||
default boolean shareCreatureTypes(Game game, MageObject otherCard) {
|
||||
if (!isCreature() && !isTribal()) {
|
||||
return false;
|
||||
}
|
||||
if (!otherCard.isCreature() && !otherCard.isTribal()) {
|
||||
return false;
|
||||
}
|
||||
boolean isAllA = this.isAllCreatureTypes();
|
||||
boolean isAllA = this.isAllCreatureTypes(game);
|
||||
boolean isAnyA = isAllA || this.getSubtype(game)
|
||||
.stream()
|
||||
.map(SubType::getSubTypeSet)
|
||||
.anyMatch(SubTypeSet.CreatureType::equals);
|
||||
boolean isAllB = otherCard.isAllCreatureTypes();
|
||||
boolean isAllB = otherCard.isAllCreatureTypes(game);
|
||||
boolean isAnyB = isAllB || otherCard
|
||||
.getSubtype(game)
|
||||
.stream()
|
||||
|
|
@ -241,10 +338,18 @@ public interface MageObject extends MageItem, Serializable {
|
|||
.anyMatch(subType -> otherCard.hasSubtype(subType, game)));
|
||||
}
|
||||
|
||||
boolean isAllCreatureTypes();
|
||||
boolean isAllCreatureTypes(Game game);
|
||||
|
||||
void setIsAllCreatureTypes(boolean value);
|
||||
|
||||
/**
|
||||
* Change all creature type mark temporary, for continuous effects only
|
||||
*
|
||||
* @param game
|
||||
* @param value
|
||||
*/
|
||||
void setIsAllCreatureTypes(Game game, boolean value);
|
||||
|
||||
default void addCardTypes(ArrayList<CardType> cardType) {
|
||||
getCardType().addAll(cardType);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package mage;
|
||||
|
||||
import java.util.*;
|
||||
import mage.abilities.Abilities;
|
||||
import mage.abilities.AbilitiesImpl;
|
||||
import mage.abilities.Ability;
|
||||
|
|
@ -20,7 +19,9 @@ import mage.game.Game;
|
|||
import mage.game.MageObjectAttribute;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.util.GameLog;
|
||||
import mage.util.SubTypeList;
|
||||
import mage.util.SubTypes;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public abstract class MageObjectImpl implements MageObject {
|
||||
|
||||
|
|
@ -32,8 +33,7 @@ public abstract class MageObjectImpl implements MageObject {
|
|||
protected ObjectColor frameColor;
|
||||
protected FrameStyle frameStyle;
|
||||
protected ArrayList<CardType> cardType = new ArrayList<>();
|
||||
protected SubTypeList subtype = new SubTypeList();
|
||||
protected boolean isAllCreatureTypes;
|
||||
protected SubTypes subtype = new SubTypes();
|
||||
protected Set<SuperType> supertype = EnumSet.noneOf(SuperType.class);
|
||||
protected Abilities<Ability> abilities;
|
||||
protected String text;
|
||||
|
|
@ -71,8 +71,7 @@ public abstract class MageObjectImpl implements MageObject {
|
|||
toughness = object.toughness.copy();
|
||||
abilities = object.abilities.copy();
|
||||
this.cardType.addAll(object.cardType);
|
||||
this.subtype.addAll(object.subtype);
|
||||
isAllCreatureTypes = object.isAllCreatureTypes;
|
||||
this.subtype.copyFrom(object.subtype);
|
||||
supertype.addAll(object.supertype);
|
||||
this.copy = object.copy;
|
||||
this.copyFrom = (object.copyFrom != null ? object.copyFrom.copy() : null);
|
||||
|
|
@ -116,13 +115,18 @@ public abstract class MageObjectImpl implements MageObject {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SubTypeList getSubtype(Game game) {
|
||||
public SubTypes getSubtype() {
|
||||
return subtype;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubTypes getSubtype(Game game) {
|
||||
if (game != null) {
|
||||
MageObjectAttribute mageObjectAttribute = game.getState().getMageObjectAttribute(getId());
|
||||
if (mageObjectAttribute != null) {
|
||||
return mageObjectAttribute.getSubtype();
|
||||
}
|
||||
}
|
||||
}
|
||||
return subtype;
|
||||
}
|
||||
|
||||
|
|
@ -174,6 +178,11 @@ public abstract class MageObjectImpl implements MageObject {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectColor getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectColor getColor(Game game) {
|
||||
if (game != null) {
|
||||
|
|
@ -181,7 +190,7 @@ public abstract class MageObjectImpl implements MageObject {
|
|||
if (mageObjectAttribute != null) {
|
||||
return mageObjectAttribute.getColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
|
|
@ -240,7 +249,7 @@ public abstract class MageObjectImpl implements MageObject {
|
|||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
if (value.getSubTypeSet() == SubTypeSet.CreatureType && isAllCreatureTypes()) {
|
||||
if (value.getSubTypeSet() == SubTypeSet.CreatureType && isAllCreatureTypes(game)) {
|
||||
return true;
|
||||
}
|
||||
return getSubtype(game).contains(value);
|
||||
|
|
@ -278,13 +287,18 @@ public abstract class MageObjectImpl implements MageObject {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllCreatureTypes() {
|
||||
return isAllCreatureTypes;
|
||||
public boolean isAllCreatureTypes(Game game) {
|
||||
return this.getSubtype(game).isAllCreatureTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsAllCreatureTypes(boolean value) {
|
||||
isAllCreatureTypes = value && (this.isTribal() || this.isCreature());
|
||||
this.getSubtype().setIsAllCreatureTypes(value && (this.isTribal() || this.isCreature()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsAllCreatureTypes(Game game, boolean value) {
|
||||
this.getSubtype(game).setIsAllCreatureTypes(value && (this.isTribal() || this.isCreature()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ class KinshipBaseEffect extends OneShotEffect {
|
|||
if (card != null) {
|
||||
Cards cards = new CardsImpl(card);
|
||||
controller.lookAtCards(sourcePermanent.getName(), cards, game);
|
||||
if (sourcePermanent.shareCreatureTypes(card, game)) {
|
||||
if (sourcePermanent.shareCreatureTypes(game, card)) {
|
||||
if (controller.chooseUse(outcome, new StringBuilder("Kinship - Reveal ").append(card.getLogName()).append('?').toString(), source, game)) {
|
||||
controller.revealCards(sourcePermanent.getName(), cards, game);
|
||||
for (Effect effect : kinshipEffects) {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ import mage.constants.SubType;
|
|||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.util.SubTypeList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Describes condition when equipped permanent has subType
|
||||
|
|
@ -16,35 +18,31 @@ import mage.util.SubTypeList;
|
|||
*/
|
||||
public class EquippedHasSubtypeCondition implements Condition {
|
||||
|
||||
private SubTypeList subTypes; // scope = Any
|
||||
private final List<SubType> subTypes = new ArrayList<>(); // scope = Any
|
||||
|
||||
public EquippedHasSubtypeCondition(SubTypeList subType) {
|
||||
this.subTypes = subType;
|
||||
}
|
||||
|
||||
|
||||
public EquippedHasSubtypeCondition(SubType subType){
|
||||
subTypes = new SubTypeList();
|
||||
subTypes.add(subType);
|
||||
public EquippedHasSubtypeCondition(SubType... subTypes) {
|
||||
for (SubType subType : subTypes) {
|
||||
this.subTypes.add(subType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId());
|
||||
if (permanent != null && permanent.getAttachedTo() != null) {
|
||||
Permanent attachedTo = game.getBattlefield().getPermanent(permanent.getAttachedTo());
|
||||
if (attachedTo == null) {
|
||||
attachedTo = (Permanent) game.getLastKnownInformation(permanent.getAttachedTo(), Zone.BATTLEFIELD);
|
||||
}
|
||||
if (attachedTo != null) {
|
||||
|
||||
for (SubType s : subTypes) {
|
||||
if (attachedTo.hasSubtype(s, game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (permanent == null || permanent.getAttachedTo() == null) {
|
||||
return false;
|
||||
}
|
||||
Permanent attachedTo = game.getBattlefield().getPermanent(permanent.getAttachedTo());
|
||||
if (attachedTo == null) {
|
||||
attachedTo = (Permanent) game.getLastKnownInformation(permanent.getAttachedTo(), Zone.BATTLEFIELD);
|
||||
}
|
||||
if (attachedTo == null) {
|
||||
return false;
|
||||
}
|
||||
for (SubType s : subTypes) {
|
||||
if (attachedTo.hasSubtype(s, game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package mage.abilities.condition.common;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.SubType;
|
||||
import mage.game.Game;
|
||||
import mage.watchers.common.ProwlWatcher;
|
||||
|
||||
|
|
@ -20,13 +19,8 @@ public enum ProwlCondition implements Condition {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
ProwlWatcher watcher = game.getState().getWatcher(ProwlWatcher.class);
|
||||
Card card = game.getCard(source.getSourceId());
|
||||
if (watcher != null && card != null) {
|
||||
for (SubType subtype : card.getSubtype(game)) {
|
||||
if (watcher.hasSubtypeMadeCombatDamage(source.getControllerId(), subtype)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return watcher != null
|
||||
&& card != null
|
||||
&& watcher.hasSubtypeMadeCombatDamage(source.getControllerId(), card, game);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,33 +5,31 @@ import mage.abilities.condition.Condition;
|
|||
import mage.constants.SubType;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.util.SubTypeList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Quercitron
|
||||
*/
|
||||
public class SourceHasSubtypeCondition implements Condition {
|
||||
|
||||
private final SubTypeList subtypes;
|
||||
private final List<SubType> subtypes = new ArrayList<>();
|
||||
|
||||
public SourceHasSubtypeCondition(SubTypeList subtypes) {
|
||||
this.subtypes = subtypes;
|
||||
}
|
||||
|
||||
public SourceHasSubtypeCondition(SubType subType){
|
||||
subtypes = new SubTypeList();
|
||||
subtypes.add(subType);
|
||||
public SourceHasSubtypeCondition(SubType... subTypes) {
|
||||
this.subtypes.addAll(Arrays.asList(subTypes));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent != null) {
|
||||
for (SubType subtype : subtypes) {
|
||||
if (permanent.hasSubtype(subtype, game)) {
|
||||
return true;
|
||||
}
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
for (SubType subtype : subtypes) {
|
||||
if (permanent.hasSubtype(subtype, game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package mage.abilities.dynamicvalue.common;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
|
|
@ -34,10 +33,10 @@ public enum GreatestSharedCreatureTypeCount implements DynamicValue {
|
|||
int changelings = permanentList
|
||||
.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.filter(MageObject::isAllCreatureTypes)
|
||||
.filter(permanent1 -> permanent1.isAllCreatureTypes(game))
|
||||
.mapToInt(x -> 1)
|
||||
.sum();
|
||||
permanentList.removeIf(MageObject::isAllCreatureTypes);
|
||||
permanentList.removeIf(permanent1 -> permanent1.isAllCreatureTypes(game));
|
||||
Map<SubType, Integer> typeMap = new HashMap<>();
|
||||
permanentList
|
||||
.stream()
|
||||
|
|
|
|||
|
|
@ -8,13 +8,14 @@ package mage.abilities.effects.common;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.common.FilterCreatureCard;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.CardIdPredicate;
|
||||
import mage.game.Game;
|
||||
|
|
@ -24,9 +25,6 @@ import mage.game.permanent.Permanent;
|
|||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Effect for the AmplifyAbility
|
||||
* <p>
|
||||
|
|
@ -74,6 +72,19 @@ public class AmplifyEffect extends ReplacementEffectImpl {
|
|||
}
|
||||
}
|
||||
|
||||
private static class AmplifyPredicate implements Predicate<Card> {
|
||||
private final Card card;
|
||||
|
||||
private AmplifyPredicate(Card card) {
|
||||
this.card = card;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Card input, Game game) {
|
||||
return input.shareCreatureTypes(game, card);
|
||||
}
|
||||
}
|
||||
|
||||
public AmplifyEffect(AmplifyFactor amplifyFactor) {
|
||||
super(Duration.EndOfGame, Outcome.BoostCreature);
|
||||
this.amplifyFactor = amplifyFactor;
|
||||
|
|
@ -98,36 +109,31 @@ public class AmplifyEffect extends ReplacementEffectImpl {
|
|||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
Permanent sourceCreature = ((EntersTheBattlefieldEvent) event).getTarget();
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null && sourceCreature != null) {
|
||||
FilterCreatureCard filter = new FilterCreatureCard("creatures cards to reveal");
|
||||
List<SubType.SubTypePredicate> filterSubtypes = new ArrayList<>();
|
||||
for (SubType subtype : sourceCreature.getSubtype(game)) {
|
||||
filterSubtypes.add(subtype.getPredicate());
|
||||
}
|
||||
if (filterSubtypes.size() > 1) {
|
||||
filter.add(Predicates.or(filterSubtypes));
|
||||
} else if (filterSubtypes.size() == 1) {
|
||||
filter.add(filterSubtypes.get(0));
|
||||
}
|
||||
if (controller == null || sourceCreature == null) {
|
||||
return false;
|
||||
}
|
||||
FilterCreatureCard filter = new FilterCreatureCard("creatures cards to reveal");
|
||||
filter.add(new AmplifyPredicate(sourceCreature));
|
||||
|
||||
// You can’t reveal this card or any other cards that are entering the battlefield at the same time as this card.
|
||||
filter.add(Predicates.not(new CardIdPredicate(source.getSourceId())));
|
||||
for (Permanent enteringPermanent : game.getPermanentsEntering().values()) {
|
||||
filter.add(Predicates.not(new CardIdPredicate(enteringPermanent.getId())));
|
||||
}
|
||||
// You can’t reveal this card or any other cards that are entering the battlefield at the same time as this card.
|
||||
filter.add(Predicates.not(new CardIdPredicate(source.getSourceId())));
|
||||
for (Permanent enteringPermanent : game.getPermanentsEntering().values()) {
|
||||
filter.add(Predicates.not(new CardIdPredicate(enteringPermanent.getId())));
|
||||
}
|
||||
|
||||
if (controller.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) > 0) {
|
||||
if (controller.chooseUse(outcome, "Reveal cards to Amplify?", source, game)) {
|
||||
TargetCardInHand target = new TargetCardInHand(0, Integer.MAX_VALUE, filter);
|
||||
if (controller.chooseTarget(outcome, target, source, game) && !target.getTargets().isEmpty()) {
|
||||
Cards cards = new CardsImpl();
|
||||
cards.addAll(target.getTargets());
|
||||
int amountCounters = cards.size() * amplifyFactor.getFactor();
|
||||
sourceCreature.addCounters(CounterType.P1P1.createInstance(amountCounters), source, game);
|
||||
controller.revealCards(sourceCreature.getIdName(), cards, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (controller.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) <= 0) {
|
||||
return false;
|
||||
}
|
||||
if (!controller.chooseUse(outcome, "Reveal cards to Amplify?", source, game)) {
|
||||
return false;
|
||||
}
|
||||
TargetCardInHand target = new TargetCardInHand(0, Integer.MAX_VALUE, filter);
|
||||
if (controller.chooseTarget(outcome, target, source, game) && !target.getTargets().isEmpty()) {
|
||||
Cards cards = new CardsImpl();
|
||||
cards.addAll(target.getTargets());
|
||||
int amountCounters = cards.size() * amplifyFactor.getFactor();
|
||||
sourceCreature.addCounters(CounterType.P1P1.createInstance(amountCounters), source, game);
|
||||
controller.revealCards(sourceCreature.getIdName(), cards, game);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import mage.game.Game;
|
|||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.PermanentCard;
|
||||
import mage.game.permanent.PermanentToken;
|
||||
import mage.util.functions.ApplyToPermanent;
|
||||
import mage.util.functions.CopyApplier;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ public class CopyEffect extends ContinuousEffectImpl {
|
|||
protected MageObject copyFromObject;
|
||||
|
||||
protected UUID copyToObjectId;
|
||||
protected ApplyToPermanent applier;
|
||||
protected CopyApplier applier;
|
||||
|
||||
public CopyEffect(MageObject copyFromObject, UUID copyToObjectId) {
|
||||
this(Duration.Custom, copyFromObject, copyToObjectId);
|
||||
|
|
@ -105,8 +105,7 @@ public class CopyEffect extends ContinuousEffectImpl {
|
|||
}
|
||||
|
||||
permanent.removeAllSubTypes(game);
|
||||
permanent.getSubtype(game).addAll(copyFromObject.getSubtype(game));
|
||||
permanent.setIsAllCreatureTypes(copyFromObject.isAllCreatureTypes());
|
||||
permanent.copySubTypesFrom(game, copyFromObject);
|
||||
|
||||
permanent.getSuperType().clear();
|
||||
for (SuperType type : copyFromObject.getSuperType()) {
|
||||
|
|
@ -165,11 +164,11 @@ public class CopyEffect extends ContinuousEffectImpl {
|
|||
return copyToObjectId;
|
||||
}
|
||||
|
||||
public ApplyToPermanent getApplier() {
|
||||
public CopyApplier getApplier() {
|
||||
return applier;
|
||||
}
|
||||
|
||||
public void setApplier(ApplyToPermanent applier) {
|
||||
public void setApplier(CopyApplier applier) {
|
||||
this.applier = applier;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ import mage.game.permanent.Permanent;
|
|||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.util.functions.ApplyToPermanent;
|
||||
import mage.util.functions.EmptyApplyToPermanent;
|
||||
import mage.util.functions.CopyApplier;
|
||||
import mage.util.functions.EmptyCopyApplier;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ import java.util.UUID;
|
|||
public class CopyPermanentEffect extends OneShotEffect {
|
||||
|
||||
private final FilterPermanent filter;
|
||||
private final ApplyToPermanent applier;
|
||||
private final CopyApplier applier;
|
||||
private final boolean useTargetOfAbility;
|
||||
private Permanent bluePrintPermanent;
|
||||
private Duration duration = Duration.Custom;
|
||||
|
|
@ -36,19 +36,19 @@ public class CopyPermanentEffect extends OneShotEffect {
|
|||
this(StaticFilters.FILTER_PERMANENT_CREATURE);
|
||||
}
|
||||
|
||||
public CopyPermanentEffect(ApplyToPermanent applier) {
|
||||
public CopyPermanentEffect(CopyApplier applier) {
|
||||
this(StaticFilters.FILTER_PERMANENT_CREATURE, applier);
|
||||
}
|
||||
|
||||
public CopyPermanentEffect(FilterPermanent filter) {
|
||||
this(filter, new EmptyApplyToPermanent());
|
||||
this(filter, new EmptyCopyApplier());
|
||||
}
|
||||
|
||||
public CopyPermanentEffect(FilterPermanent filter, ApplyToPermanent applier) {
|
||||
public CopyPermanentEffect(FilterPermanent filter, CopyApplier applier) {
|
||||
this(filter, applier, false);
|
||||
}
|
||||
|
||||
public CopyPermanentEffect(FilterPermanent filter, ApplyToPermanent applier, boolean useTarget) {
|
||||
public CopyPermanentEffect(FilterPermanent filter, CopyApplier applier, boolean useTarget) {
|
||||
super(Outcome.Copy);
|
||||
this.applier = applier;
|
||||
this.filter = filter;
|
||||
|
|
|
|||
|
|
@ -32,10 +32,7 @@ public class CopyTokenEffect extends ContinuousEffectImpl {
|
|||
permanent.addCardType(type);
|
||||
}
|
||||
permanent.removeAllSubTypes(game);
|
||||
for (SubType type : token.getSubtype(game)) {
|
||||
permanent.addSubType(game, type);
|
||||
}
|
||||
permanent.setIsAllCreatureTypes(token.isAllCreatureTypes());
|
||||
permanent.copySubTypesFrom(game, token);
|
||||
permanent.getSuperType().clear();
|
||||
for (SuperType type : token.getSuperType()) {
|
||||
permanent.addSuperType(type);
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ import mage.game.permanent.Permanent;
|
|||
import mage.game.permanent.token.EmptyToken;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
import mage.util.CardUtil;
|
||||
import mage.util.functions.ApplyToPermanent;
|
||||
import mage.util.functions.EmptyApplyToPermanent;
|
||||
import mage.util.functions.CopyApplier;
|
||||
import mage.util.functions.EmptyCopyApplier;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
|
@ -141,7 +141,7 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect {
|
|||
|
||||
// can target card or permanent
|
||||
Card copyFrom;
|
||||
ApplyToPermanent applier = new EmptyApplyToPermanent();
|
||||
CopyApplier applier = new EmptyCopyApplier();
|
||||
if (permanent != null) {
|
||||
// handle copies of copies
|
||||
Permanent copyFromPermanent = permanent;
|
||||
|
|
@ -169,6 +169,7 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect {
|
|||
return false;
|
||||
}
|
||||
|
||||
// create token and modify all attributes permanently (without game usage)
|
||||
EmptyToken token = new EmptyToken();
|
||||
CardUtil.copyTo(token).from(copyFrom, game); // needed so that entersBattlefied triggered abilities see the attributes (e.g. Master Biomancer)
|
||||
applier.apply(game, token, source, targetId);
|
||||
|
|
@ -200,14 +201,14 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect {
|
|||
token.getToughness().modifyBaseValue(tokenToughness);
|
||||
}
|
||||
if (onlySubType != null) {
|
||||
token.removeAllCreatureTypes(game);
|
||||
token.addSubType(game, onlySubType);
|
||||
token.removeAllCreatureTypes();
|
||||
token.addSubType(onlySubType);
|
||||
}
|
||||
if (additionalSubType != null && !token.hasSubtype(additionalSubType, game)) {
|
||||
token.addSubType(game, additionalSubType);
|
||||
if (additionalSubType != null) {
|
||||
token.addSubType(additionalSubType);
|
||||
}
|
||||
if (color != null) {
|
||||
token.getColor(game).setColor(color);
|
||||
token.getColor().setColor(color);
|
||||
}
|
||||
additionalAbilities.stream().forEach(token::addAbility);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import mage.game.permanent.Permanent;
|
|||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
import mage.util.SubTypeList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
|
@ -87,12 +86,12 @@ public class DevourEffect extends ReplacementEffectImpl {
|
|||
if (controller.chooseUse(Outcome.Detriment, "Devour creatures?", source, game)) {
|
||||
controller.chooseTarget(Outcome.Detriment, target, source, game);
|
||||
if (!target.getTargets().isEmpty()) {
|
||||
List<SubTypeList> cardSubtypes = new ArrayList<>();
|
||||
List<Permanent> creaturesDevoured = new ArrayList<>();
|
||||
int devouredCreatures = 0;
|
||||
for (UUID targetId : target.getTargets()) {
|
||||
Permanent targetCreature = game.getPermanent(targetId);
|
||||
if (targetCreature != null && targetCreature.sacrifice(source, game)) {
|
||||
cardSubtypes.add(targetCreature.getSubtype(game));
|
||||
creaturesDevoured.add(targetCreature);
|
||||
devouredCreatures++;
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +107,7 @@ public class DevourEffect extends ReplacementEffectImpl {
|
|||
amountCounters = devouredCreatures * devourFactor.getFactor();
|
||||
}
|
||||
creature.addCounters(CounterType.P1P1.createInstance(amountCounters), source, game);
|
||||
game.getState().setValue(creature.getId().toString() + "devoured", cardSubtypes);
|
||||
game.getState().setValue(creature.getId().toString() + "devoured", creaturesDevoured);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -124,10 +123,10 @@ public class DevourEffect extends ReplacementEffectImpl {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
public List<SubTypeList> getSubtypes(Game game, UUID permanentId) {
|
||||
public List<Permanent> getDevouredCreatures(Game game, UUID permanentId) {
|
||||
Object object = game.getState().getValue(permanentId.toString() + "devoured");
|
||||
if (object != null) {
|
||||
return (List<SubTypeList>) object;
|
||||
return (List<Permanent>) object;
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
|
@ -135,7 +134,7 @@ public class DevourEffect extends ReplacementEffectImpl {
|
|||
public int getDevouredCreaturesAmount(Game game, UUID permanentId) {
|
||||
Object object = game.getState().getValue(permanentId.toString() + "devoured");
|
||||
if (object != null) {
|
||||
return ((List<SubTypeList>) object).size();
|
||||
return ((List<Permanent>) object).size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ public class BecomesBasicLandEnchantedEffect extends ContinuousEffectImpl {
|
|||
return false;
|
||||
}
|
||||
// lands intrictically have the mana ability associated with their type, so added here in layer 4
|
||||
permanent.getSubtype(game).removeAll(SubType.getLandTypes());
|
||||
permanent.getSubtype(game).addAll(landTypes);
|
||||
permanent.removeAllSubTypes(game, SubTypeSet.NonBasicLandType);
|
||||
permanent.addSubType(game, landTypes);
|
||||
permanent.removeAllAbilities(source.getSourceId(), game);
|
||||
for (SubType landType : landTypes) {
|
||||
switch (landType) {
|
||||
|
|
|
|||
|
|
@ -117,8 +117,8 @@ public class BecomesBasicLandTargetEffect extends ContinuousEffectImpl {
|
|||
// So the ability removing has to be done before Layer 6
|
||||
land.removeAllAbilities(source.getSourceId(), game);
|
||||
// 305.7
|
||||
land.getSubtype(game).removeAll(SubType.getLandTypes());
|
||||
land.getSubtype(game).addAll(landTypes);
|
||||
land.removeAllSubTypes(game, SubTypeSet.NonBasicLandType);
|
||||
land.addSubType(game, landTypes);
|
||||
} else {
|
||||
landTypesToAdd.clear();
|
||||
for (SubType subtype : landTypes) {
|
||||
|
|
|
|||
|
|
@ -104,10 +104,7 @@ public class BecomesCreatureAllEffect extends ContinuousEffectImpl {
|
|||
if (theyAreStillType != null || loseTypes) {
|
||||
permanent.removeAllCreatureTypes(game);
|
||||
}
|
||||
for (SubType t : token.getSubtype(game)) {
|
||||
permanent.addSubType(game, t);
|
||||
}
|
||||
permanent.setIsAllCreatureTypes(token.isAllCreatureTypes());
|
||||
permanent.copySubTypesFrom(game, token);
|
||||
|
||||
for (SuperType t : token.getSuperType()) {
|
||||
if (!permanent.getSuperType().contains(t)) {
|
||||
|
|
|
|||
|
|
@ -53,85 +53,78 @@ public class BecomesCreatureAttachedEffect extends ContinuousEffectImpl {
|
|||
@Override
|
||||
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
|
||||
Permanent enchantment = game.getPermanent(source.getSourceId());
|
||||
if (enchantment != null) {
|
||||
Permanent permanent = game.getPermanent(enchantment.getAttachedTo());
|
||||
if (permanent != null) {
|
||||
switch (layer) {
|
||||
case TypeChangingEffects_4:
|
||||
if (sublayer == SubLayer.NA) {
|
||||
for (SuperType t : token.getSuperType()) {
|
||||
permanent.addSuperType(t);
|
||||
|
||||
}
|
||||
// card type
|
||||
switch (loseType) {
|
||||
case ALL:
|
||||
case ALL_BUT_COLOR:
|
||||
permanent.getCardType().clear();
|
||||
break;
|
||||
}
|
||||
for (CardType t : token.getCardType()) {
|
||||
permanent.addCardType(t);
|
||||
}
|
||||
|
||||
// sub type
|
||||
switch (loseType) {
|
||||
case ALL:
|
||||
case ALL_BUT_COLOR:
|
||||
permanent.removeAllSubTypes(game);
|
||||
break;
|
||||
case ABILITIES_SUBTYPE:
|
||||
permanent.removeAllCreatureTypes(game);
|
||||
break;
|
||||
}
|
||||
for (SubType t : token.getSubtype(game)) {
|
||||
permanent.addSubType(game, t);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ColorChangingEffects_5:
|
||||
if (sublayer == SubLayer.NA) {
|
||||
if (loseType == LoseType.ALL || loseType == LoseType.COLOR) {
|
||||
permanent.getColor(game).setWhite(false);
|
||||
permanent.getColor(game).setBlue(false);
|
||||
permanent.getColor(game).setBlack(false);
|
||||
permanent.getColor(game).setRed(false);
|
||||
permanent.getColor(game).setGreen(false);
|
||||
}
|
||||
if (token.getColor(game).hasColor()) {
|
||||
permanent.getColor(game).addColor(token.getColor(game));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AbilityAddingRemovingEffects_6:
|
||||
if (sublayer == SubLayer.NA) {
|
||||
switch (loseType) {
|
||||
case ALL:
|
||||
case ALL_BUT_COLOR:
|
||||
case ABILITIES:
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (enchantment == null) {
|
||||
return false;
|
||||
}
|
||||
Permanent permanent = game.getPermanent(enchantment.getAttachedTo());
|
||||
if (permanent == null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
switch (layer) {
|
||||
case TypeChangingEffects_4:
|
||||
for (SuperType t : token.getSuperType()) {
|
||||
permanent.addSuperType(t);
|
||||
|
||||
}
|
||||
// card type
|
||||
switch (loseType) {
|
||||
case ALL:
|
||||
case ALL_BUT_COLOR:
|
||||
permanent.getCardType().clear();
|
||||
break;
|
||||
}
|
||||
for (CardType t : token.getCardType()) {
|
||||
permanent.addCardType(t);
|
||||
}
|
||||
|
||||
// sub type
|
||||
switch (loseType) {
|
||||
case ALL:
|
||||
case ALL_BUT_COLOR:
|
||||
permanent.removeAllSubTypes(game);
|
||||
break;
|
||||
case ABILITIES_SUBTYPE:
|
||||
permanent.removeAllCreatureTypes(game);
|
||||
break;
|
||||
}
|
||||
permanent.copySubTypesFrom(game, token);
|
||||
break;
|
||||
|
||||
case ColorChangingEffects_5:
|
||||
if (loseType == LoseType.ALL || loseType == LoseType.COLOR) {
|
||||
permanent.getColor(game).setWhite(false);
|
||||
permanent.getColor(game).setBlue(false);
|
||||
permanent.getColor(game).setBlack(false);
|
||||
permanent.getColor(game).setRed(false);
|
||||
permanent.getColor(game).setGreen(false);
|
||||
}
|
||||
if (token.getColor(game).hasColor()) {
|
||||
permanent.getColor(game).addColor(token.getColor(game));
|
||||
}
|
||||
break;
|
||||
|
||||
case AbilityAddingRemovingEffects_6:
|
||||
switch (loseType) {
|
||||
case ALL:
|
||||
case ALL_BUT_COLOR:
|
||||
case ABILITIES:
|
||||
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;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -101,12 +101,7 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements
|
|||
|| theyAreStillType == null && permanent.isLand()) {
|
||||
permanent.removeAllCreatureTypes(game);
|
||||
}
|
||||
if (!token.getSubtype(game).isEmpty()) {
|
||||
for (SubType subType : token.getSubtype(game)) {
|
||||
permanent.addSubType(game, subType);
|
||||
}
|
||||
}
|
||||
permanent.setIsAllCreatureTypes(token.isAllCreatureTypes());
|
||||
permanent.copySubTypesFrom(game, token);
|
||||
break;
|
||||
|
||||
case ColorChangingEffects_5:
|
||||
|
|
|
|||
|
|
@ -87,9 +87,7 @@ public class BecomesCreatureTargetEffect extends ContinuousEffectImpl {
|
|||
if (loseAllAbilities || removeSubtypes) {
|
||||
permanent.removeAllCreatureTypes(game);
|
||||
}
|
||||
for (SubType t : token.getSubtype(game)) {
|
||||
permanent.addSubType(game, t);
|
||||
}
|
||||
permanent.copySubTypesFrom(game, token);
|
||||
|
||||
for (SuperType t : token.getSuperType()) {
|
||||
if (!permanent.getSuperType().contains(t)) {
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@ import mage.abilities.effects.ContinuousEffectImpl;
|
|||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.util.SubTypeList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
|
|
@ -14,22 +16,22 @@ import java.util.UUID;
|
|||
*/
|
||||
public class BecomesCreatureTypeTargetEffect extends ContinuousEffectImpl {
|
||||
|
||||
private final SubTypeList subtypes = new SubTypeList();
|
||||
private final List<SubType> subtypes = new ArrayList<>();
|
||||
private final boolean loseOther; // loses other creature types
|
||||
|
||||
public BecomesCreatureTypeTargetEffect(Duration duration, SubType subtype) {
|
||||
this(duration, new SubTypeList(subtype));
|
||||
this(duration, Arrays.asList(subtype));
|
||||
}
|
||||
|
||||
public BecomesCreatureTypeTargetEffect(Duration duration, SubType subtype, boolean loseOther) {
|
||||
this(duration, new SubTypeList(subtype), loseOther);
|
||||
this(duration, Arrays.asList(subtype), loseOther);
|
||||
}
|
||||
|
||||
public BecomesCreatureTypeTargetEffect(Duration duration, SubTypeList subtypes) {
|
||||
public BecomesCreatureTypeTargetEffect(Duration duration, List<SubType> subtypes) {
|
||||
this(duration, subtypes, true);
|
||||
}
|
||||
|
||||
public BecomesCreatureTypeTargetEffect(Duration duration, SubTypeList subtypes, boolean loseOther) {
|
||||
public BecomesCreatureTypeTargetEffect(Duration duration, List<SubType> subtypes, boolean loseOther) {
|
||||
super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Detriment);
|
||||
this.subtypes.addAll(subtypes);
|
||||
this.staticText = setText();
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ public class BecomesEnchantmentSourceEffect extends ContinuousEffectImpl impleme
|
|||
}
|
||||
permanent.getCardType().clear();
|
||||
permanent.getCardType().add(CardType.ENCHANTMENT);
|
||||
permanent.getSubtype(game).retainAll(SubType.getEnchantmentTypes());
|
||||
permanent.setIsAllCreatureTypes(false);
|
||||
permanent.retainAllEnchantmentSubTypes(game);
|
||||
permanent.setIsAllCreatureTypes(game, false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,26 +12,29 @@ import mage.filter.StaticFilters;
|
|||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.util.SubTypeList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class BecomesSubtypeAllEffect extends ContinuousEffectImpl {
|
||||
|
||||
private final SubTypeList subtypes = new SubTypeList();
|
||||
private final List<SubType> subtypes = new ArrayList<>();
|
||||
private final boolean loseOther; // loses other subtypes
|
||||
private final FilterCreaturePermanent filter;
|
||||
|
||||
public BecomesSubtypeAllEffect(Duration duration, SubType subtype) {
|
||||
this(duration, new SubTypeList(subtype));
|
||||
this(duration, Arrays.asList(subtype));
|
||||
}
|
||||
|
||||
public BecomesSubtypeAllEffect(Duration duration, SubTypeList subtypes) {
|
||||
public BecomesSubtypeAllEffect(Duration duration, List<SubType> subtypes) {
|
||||
this(duration, subtypes, StaticFilters.FILTER_PERMANENT_CREATURE, true);
|
||||
}
|
||||
|
||||
public BecomesSubtypeAllEffect(Duration duration, SubTypeList subtypes, FilterCreaturePermanent filter, boolean loseOther) {
|
||||
public BecomesSubtypeAllEffect(Duration duration, List<SubType> subtypes, FilterCreaturePermanent filter, boolean loseOther) {
|
||||
super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Detriment);
|
||||
this.subtypes.addAll(subtypes);
|
||||
this.staticText = setText();
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ public class GainAllCreatureTypesAttachedEffect extends ContinuousEffectImpl {
|
|||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
permanent.setIsAllCreatureTypes(true);
|
||||
permanent.setIsAllCreatureTypes(game, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ public class GainAllCreatureTypesTargetEffect extends ContinuousEffectImpl {
|
|||
for (UUID permanentId : targetPointer.getTargets(game, source)) {
|
||||
Permanent target = game.getPermanent(permanentId);
|
||||
if (target != null) {
|
||||
target.setIsAllCreatureTypes(true);
|
||||
target.setIsAllCreatureTypes(game, true);
|
||||
affectedTargets++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,18 +5,21 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.util.SubTypeList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public class HasSubtypesSourceEffect extends ContinuousEffectImpl {
|
||||
|
||||
private final SubTypeList subtypes = new SubTypeList();
|
||||
private final List<SubType> subtypes = new ArrayList<>();
|
||||
|
||||
public HasSubtypesSourceEffect(SubType... subTypes) {
|
||||
super(Duration.EndOfGame, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
|
||||
subtypes.add(subTypes);
|
||||
subtypes.addAll(Arrays.asList(subTypes));
|
||||
this.staticText = setText();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
package mage.abilities.effects.common.continuous;
|
||||
|
||||
import mage.MageObject;
|
||||
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.game.Game;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public class IsAllCreatureTypesSourceEffect extends ContinuousEffectImpl {
|
||||
|
||||
public IsAllCreatureTypesSourceEffect() {
|
||||
super(Duration.Custom, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
|
||||
this.staticText = "{this} is every creature type <i>(even if this card isn't on the battlefield)</i>.";
|
||||
}
|
||||
|
||||
private IsAllCreatureTypesSourceEffect(final IsAllCreatureTypesSourceEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsAllCreatureTypesSourceEffect copy() {
|
||||
return new IsAllCreatureTypesSourceEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
if (sourceObject == null) {
|
||||
return false;
|
||||
}
|
||||
sourceObject.setIsAllCreatureTypes(game, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -40,34 +40,19 @@ public class LoseArtifactTypeTargetEffect extends ContinuousEffectImpl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
|
||||
public boolean apply(Game game, Ability source) {
|
||||
for (UUID targetId : targetPointer.getTargets(game, source)) {
|
||||
if (targetId != null) {
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
if (permanent != null) {
|
||||
switch (layer) {
|
||||
case TypeChangingEffects_4:
|
||||
if (sublayer == SubLayer.NA) {
|
||||
permanent.getCardType().remove(CardType.ARTIFACT);
|
||||
permanent.getSubtype(game).removeAll(SubType.getArtifactTypes());
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (targetId == null) {
|
||||
continue;
|
||||
}
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
if (permanent == null) {
|
||||
continue;
|
||||
}
|
||||
permanent.getCardType().remove(CardType.ARTIFACT);
|
||||
permanent.removeAllSubTypes(game, SubTypeSet.ArtifactType);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLayer(Layer layer) {
|
||||
return layer == Layer.TypeChangingEffects_4;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,19 +5,22 @@ import mage.abilities.effects.ContinuousEffectImpl;
|
|||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.util.SubTypeList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author nantuko
|
||||
*/
|
||||
public class SetCardSubtypeAttachedEffect extends ContinuousEffectImpl {
|
||||
|
||||
private SubTypeList setSubtypes = new SubTypeList();
|
||||
private List<SubType> setSubtypes = new ArrayList<>();
|
||||
private final AttachmentType attachmentType;
|
||||
|
||||
public SetCardSubtypeAttachedEffect(Duration duration, AttachmentType attachmentType, SubType... setSubtype) {
|
||||
super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
|
||||
this.setSubtypes.add(setSubtype);
|
||||
this.setSubtypes.addAll(Arrays.asList(setSubtype));
|
||||
this.attachmentType = attachmentType;
|
||||
this.setText();
|
||||
}
|
||||
|
|
@ -39,7 +42,7 @@ public class SetCardSubtypeAttachedEffect extends ContinuousEffectImpl {
|
|||
return true;
|
||||
}
|
||||
target.removeAllCreatureTypes(game);
|
||||
target.getSubtype(game).addAll(setSubtypes);
|
||||
target.addSubType(game, setSubtypes);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -122,15 +122,16 @@ public class BestowAbility extends SpellAbility {
|
|||
}
|
||||
|
||||
static public void becomeCreature(Permanent permanent, Game game) {
|
||||
// permanently changes to the object
|
||||
if (permanent != null) {
|
||||
MageObject basicObject = permanent.getBasicMageObject(game);
|
||||
if (basicObject != null) {
|
||||
basicObject.getSubtype(null).remove(SubType.AURA);
|
||||
basicObject.getSubtype().remove(SubType.AURA);
|
||||
if (!basicObject.isCreature()) {
|
||||
basicObject.addCardType(CardType.CREATURE);
|
||||
}
|
||||
}
|
||||
permanent.getSubtype(null).remove(SubType.AURA);
|
||||
permanent.getSubtype().remove(SubType.AURA);
|
||||
if (!permanent.isCreature()) {
|
||||
permanent.addCardType(CardType.CREATURE);
|
||||
}
|
||||
|
|
@ -139,8 +140,9 @@ public class BestowAbility extends SpellAbility {
|
|||
}
|
||||
|
||||
static public void becomeAura(Card card) {
|
||||
// permanently changes to the object
|
||||
if (card != null) {
|
||||
card.getSubtype(null).add(SubType.AURA);
|
||||
card.addSubType(SubType.AURA);
|
||||
card.getCardType().remove(CardType.CREATURE);
|
||||
card.getCardType().add(CardType.ENCHANTMENT);
|
||||
}
|
||||
|
|
@ -173,7 +175,7 @@ class BestowEntersBattlefieldEffect extends ReplacementEffectImpl {
|
|||
if (bestowPermanent != null) {
|
||||
if (bestowPermanent.hasSubtype(SubType.AURA, game)) {
|
||||
MageObject basicObject = bestowPermanent.getBasicMageObject(game);
|
||||
if (basicObject != null && !basicObject.getSubtype(null).contains(SubType.AURA)) {
|
||||
if (basicObject != null && !basicObject.getSubtype().contains(SubType.AURA)) {
|
||||
basicObject.getSubtype(null).add(SubType.AURA);
|
||||
basicObject.getCardType().remove(CardType.CREATURE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,36 +1,27 @@
|
|||
|
||||
|
||||
package mage.abilities.keyword;
|
||||
|
||||
import mage.abilities.MageSingleton;
|
||||
import mage.abilities.StaticAbility;
|
||||
import mage.abilities.effects.common.continuous.IsAllCreatureTypesSourceEffect;
|
||||
import mage.constants.Zone;
|
||||
|
||||
import java.io.ObjectStreamException;
|
||||
|
||||
|
||||
/**
|
||||
* October 1, 2012
|
||||
* 702.71. Changeling
|
||||
* 702.71a Changeling is a characteristic-defining ability. "Changeling" means "This object
|
||||
* is every creature type." This ability works everywhere, even outside the game. See rule 604.3.
|
||||
* 702.71b Multiple instances of changeling on the same object are redundant.
|
||||
* 702.71a Changeling is a characteristic-defining ability. "Changeling" means "This object
|
||||
* is every creature type." This ability works everywhere, even outside the game. See rule 604.3.
|
||||
* 702.71b Multiple instances of changeling on the same object are redundant.
|
||||
*
|
||||
* @author nantuko
|
||||
*/
|
||||
public class ChangelingAbility extends StaticAbility implements MageSingleton {
|
||||
private static final ChangelingAbility instance = new ChangelingAbility();
|
||||
public class ChangelingAbility extends StaticAbility {
|
||||
|
||||
private Object readResolve() throws ObjectStreamException {
|
||||
return instance;
|
||||
public ChangelingAbility() {
|
||||
super(Zone.ALL, new IsAllCreatureTypesSourceEffect());
|
||||
}
|
||||
|
||||
public static ChangelingAbility getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private ChangelingAbility() {
|
||||
super(Zone.ALL, null);
|
||||
private ChangelingAbility(final ChangelingAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -40,6 +31,6 @@ public class ChangelingAbility extends StaticAbility implements MageSingleton {
|
|||
|
||||
@Override
|
||||
public ChangelingAbility copy() {
|
||||
return instance;
|
||||
return new ChangelingAbility(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ public class EmbalmAbility extends ActivatedAbilityImpl {
|
|||
StringBuilder sb = new StringBuilder("Embalm ").append(cost.getText());
|
||||
sb.append(" <i>(").append(cost.getText());
|
||||
sb.append(", Exile this card from your graveyard: Create a token that's a copy of it, except it's a white Zombie ");
|
||||
for (SubType subtype : card.getSubtype(null)) {
|
||||
for (SubType subtype : card.getSubtype()) {
|
||||
sb.append(subtype).append(" ");
|
||||
}
|
||||
sb.append(" with no mana cost. Embalm only as a sorcery.)</i>");
|
||||
|
|
@ -84,10 +84,12 @@ class EmbalmEffect extends OneShotEffect {
|
|||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// create token and modify all attributes permanently (without game usage)
|
||||
EmptyToken token = new EmptyToken();
|
||||
CardUtil.copyTo(token).from(card, game); // needed so that entersBattlefied triggered abilities see the attributes (e.g. Master Biomancer)
|
||||
token.getColor(game).setColor(ObjectColor.WHITE);
|
||||
token.addSubType(game, SubType.ZOMBIE);
|
||||
token.getColor().setColor(ObjectColor.WHITE);
|
||||
token.addSubType(SubType.ZOMBIE);
|
||||
token.getManaCost().clear();
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.EMBALMED_CREATURE, token.getId(), source, controller.getId()));
|
||||
token.putOntoBattlefield(1, game, source, controller.getId(), false, false, null);
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public class EternalizeAbility extends ActivatedAbilityImpl {
|
|||
StringBuilder sb = new StringBuilder("Eternalize ").append(cost.getText());
|
||||
sb.append(" <i>(").append(cost.getText());
|
||||
sb.append(", Exile this card from your graveyard: Create a token that's a copy of it, except it's a 4/4 black Zombie ");
|
||||
for (SubType subtype : card.getSubtype(null)) {
|
||||
for (SubType subtype : card.getSubtype()) {
|
||||
sb.append(subtype).append(" ");
|
||||
}
|
||||
sb.append(" with no mana cost. Eternalize only as a sorcery.)</i>");
|
||||
|
|
@ -89,10 +89,12 @@ class EternalizeEffect extends OneShotEffect {
|
|||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// create token and modify all attributes permanently (without game usage)
|
||||
EmptyToken token = new EmptyToken();
|
||||
CardUtil.copyTo(token).from(card, game); // needed so that entersBattlefied triggered abilities see the attributes (e.g. Master Biomancer)
|
||||
token.getColor(game).setColor(ObjectColor.BLACK);
|
||||
token.addSubType(game, SubType.ZOMBIE);
|
||||
token.getColor().setColor(ObjectColor.BLACK);
|
||||
token.addSubType(SubType.ZOMBIE);
|
||||
token.getManaCost().clear();
|
||||
token.removePTCDA();
|
||||
token.getPower().modifyBaseValue(4);
|
||||
|
|
|
|||
|
|
@ -285,11 +285,11 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
|
|||
mageObject.getPower().modifyBaseValue(2);
|
||||
mageObject.getToughness().modifyBaseValue(2);
|
||||
mageObject.getAbilities().clear();
|
||||
mageObject.getColor(null).setColor(new ObjectColor());
|
||||
mageObject.getColor().setColor(new ObjectColor());
|
||||
mageObject.setName("");
|
||||
mageObject.getCardType().clear();
|
||||
mageObject.addCardType(CardType.CREATURE);
|
||||
mageObject.getSubtype(null).clear();
|
||||
mageObject.getSubtype().clear();
|
||||
mageObject.getSuperType().clear();
|
||||
mageObject.getManaCost().clear();
|
||||
if (mageObject instanceof Permanent) {
|
||||
|
|
|
|||
|
|
@ -53,10 +53,7 @@ public class TransformAbility extends SimpleStaticAbility {
|
|||
permanent.addCardType(type);
|
||||
}
|
||||
permanent.removeAllSubTypes(game);
|
||||
permanent.setIsAllCreatureTypes(sourceCard.isAllCreatureTypes());
|
||||
for (SubType type : sourceCard.getSubtype(game)) {
|
||||
permanent.addSubType(game, type);
|
||||
}
|
||||
permanent.copySubTypesFrom(game, sourceCard);
|
||||
permanent.getSuperType().clear();
|
||||
for (SuperType type : sourceCard.getSuperType()) {
|
||||
permanent.addSuperType(type);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import mage.constants.*;
|
|||
import mage.game.Game;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.util.CardUtil;
|
||||
import mage.util.SubTypeList;
|
||||
import mage.util.SubTypes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
|
|
@ -136,9 +136,15 @@ public abstract class ModalDoubleFacesCard extends CardImpl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SubTypeList getSubtype(Game game) {
|
||||
public SubTypes getSubtype() {
|
||||
// rules: While a double-faced card isn’t on the stack or battlefield, consider only the characteristics of its front face.
|
||||
// CardImpl's constructor can call some code on init, so you must check left/right before
|
||||
return leftHalfCard != null ? leftHalfCard.getSubtype() : subtype;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubTypes getSubtype(Game game) {
|
||||
// rules: While a double-faced card isn’t on the stack or battlefield, consider only the characteristics of its front face.
|
||||
// CardImpl's constructor can call some code on init, so you must check left/right before
|
||||
return leftHalfCard != null ? leftHalfCard.getSubtype(game) : subtype;
|
||||
}
|
||||
|
|
@ -240,6 +246,11 @@ public abstract class ModalDoubleFacesCard extends CardImpl {
|
|||
return super.hasAbility(ability, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectColor getColor() {
|
||||
return leftHalfCard.getColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectColor getColor(Game game) {
|
||||
return leftHalfCard.getColor(game);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import mage.cards.mock.MockCard;
|
|||
import mage.cards.mock.MockSplitCard;
|
||||
import mage.constants.*;
|
||||
import mage.util.CardUtil;
|
||||
import mage.util.SubTypeList;
|
||||
import mage.util.SubTypes;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.*;
|
||||
|
|
@ -162,7 +162,7 @@ public class CardInfo {
|
|||
this.white = card.getColor(null).isWhite();
|
||||
|
||||
this.setTypes(card.getCardType());
|
||||
this.setSubtypes(card.getSubtype(null).stream().map(SubType::toString).collect(Collectors.toList()));
|
||||
this.setSubtypes(card.getSubtype().stream().map(SubType::toString).collect(Collectors.toList()));
|
||||
this.setSuperTypes(card.getSuperType());
|
||||
|
||||
// mana cost can contains multiple cards (split left/right, modal double faces, card/adventure)
|
||||
|
|
@ -367,8 +367,8 @@ public class CardInfo {
|
|||
this.rules = joinList(rules);
|
||||
}
|
||||
|
||||
public final SubTypeList getSubTypes() {
|
||||
SubTypeList sl = new SubTypeList();
|
||||
public final SubTypes getSubTypes() {
|
||||
SubTypes sl = new SubTypes();
|
||||
if (subtypes.trim().isEmpty()) {
|
||||
return sl;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -594,4 +594,8 @@ public enum SubType {
|
|||
public static Set<SubType> getLandTypes() {
|
||||
return landTypes;
|
||||
}
|
||||
|
||||
public static Set<SubType> getBySubTypeSet(SubTypeSet subTypeSet) {
|
||||
return subTypeSetMap.get(subTypeSet);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import mage.game.Game;
|
|||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.util.Copyable;
|
||||
import mage.util.GameLog;
|
||||
import mage.util.SubTypeList;
|
||||
import mage.util.SubTypes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
|
|
@ -156,8 +156,13 @@ public abstract class Designation implements MageObject, Copyable<Designation> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SubTypeList getSubtype(Game game) {
|
||||
return new SubTypeList();
|
||||
public SubTypes getSubtype() {
|
||||
return new SubTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubTypes getSubtype(Game game) {
|
||||
return new SubTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -175,6 +180,11 @@ public abstract class Designation implements MageObject, Copyable<Designation> {
|
|||
return this.getAbilities().contains(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectColor getColor() {
|
||||
return emptyColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectColor getColor(Game game) {
|
||||
return emptyColor;
|
||||
|
|
@ -245,13 +255,16 @@ public abstract class Designation implements MageObject, Copyable<Designation> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllCreatureTypes() {
|
||||
public boolean isAllCreatureTypes(Game game) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsAllCreatureTypes(boolean value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsAllCreatureTypes(Game game, boolean value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,44 +0,0 @@
|
|||
|
||||
package mage.filter.common;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SubTypeSet;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.permanent.PermanentIdPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tschroeder
|
||||
*/
|
||||
|
||||
public class FilterOtherCreatureSharingCreatureSubtype extends FilterCreaturePermanent {
|
||||
|
||||
public FilterOtherCreatureSharingCreatureSubtype(Permanent creature, Game game) {
|
||||
super("creature sharing a creature type with " + creature.toString());
|
||||
|
||||
List<SubType.SubTypePredicate> subtypePredicates = new ArrayList<>();
|
||||
for (SubType subtype : creature.getSubtype(game)) {
|
||||
if (subtype.getSubTypeSet() == SubTypeSet.CreatureType) {
|
||||
subtypePredicates.add(subtype.getPredicate());
|
||||
}
|
||||
}
|
||||
this.add(Predicates.and(
|
||||
Predicates.or(subtypePredicates),
|
||||
Predicates.not(new PermanentIdPredicate(creature.getId()))
|
||||
));
|
||||
}
|
||||
|
||||
public FilterOtherCreatureSharingCreatureSubtype(final FilterOtherCreatureSharingCreatureSubtype filter) {
|
||||
super(filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FilterOtherCreatureSharingCreatureSubtype copy() {
|
||||
return new FilterOtherCreatureSharingCreatureSubtype(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package mage.filter.predicate.permanent;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public class SharesCreatureTypePredicate implements Predicate<MageObject> {
|
||||
|
||||
private final MageObject mageObject;
|
||||
|
||||
public SharesCreatureTypePredicate(Permanent permanent) {
|
||||
this.mageObject = permanent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(MageObject input, Game game) {
|
||||
return mageObject != null && mageObject.shareCreatureTypes(game, input);
|
||||
}
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ import mage.players.Player;
|
|||
import mage.players.PlayerList;
|
||||
import mage.players.Players;
|
||||
import mage.util.MessageToClient;
|
||||
import mage.util.functions.ApplyToPermanent;
|
||||
import mage.util.functions.CopyApplier;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
|
@ -411,9 +411,9 @@ public interface Game extends MageItem, Serializable {
|
|||
* @param applier
|
||||
* @return
|
||||
*/
|
||||
Permanent copyPermanent(Permanent copyFromPermanent, UUID copyToPermanentId, Ability source, ApplyToPermanent applier);
|
||||
Permanent copyPermanent(Permanent copyFromPermanent, UUID copyToPermanentId, Ability source, CopyApplier applier);
|
||||
|
||||
Permanent copyPermanent(Duration duration, Permanent copyFromPermanent, UUID copyToPermanentId, Ability source, ApplyToPermanent applier);
|
||||
Permanent copyPermanent(Duration duration, Permanent copyFromPermanent, UUID copyToPermanentId, Ability source, CopyApplier applier);
|
||||
|
||||
Card copyCard(Card cardToCopy, Ability source, UUID newController);
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ import mage.util.CardUtil;
|
|||
import mage.util.GameLog;
|
||||
import mage.util.MessageToClient;
|
||||
import mage.util.RandomUtil;
|
||||
import mage.util.functions.ApplyToPermanent;
|
||||
import mage.util.functions.CopyApplier;
|
||||
import mage.watchers.common.*;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
|
|
@ -1651,12 +1651,12 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Permanent copyPermanent(Permanent copyFromPermanent, UUID copyToPermanentId, Ability source, ApplyToPermanent applier) {
|
||||
public Permanent copyPermanent(Permanent copyFromPermanent, UUID copyToPermanentId, Ability source, CopyApplier applier) {
|
||||
return copyPermanent(Duration.Custom, copyFromPermanent, copyToPermanentId, source, applier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Permanent copyPermanent(Duration duration, Permanent copyFromPermanent, UUID copyToPermanentId, Ability source, ApplyToPermanent applier) {
|
||||
public Permanent copyPermanent(Duration duration, Permanent copyFromPermanent, UUID copyToPermanentId, Ability source, CopyApplier applier) {
|
||||
Permanent newBluePrint = null;
|
||||
// handle copies of copies
|
||||
for (Effect effect : getState().getContinuousEffects().getLayeredEffects(this)) {
|
||||
|
|
@ -2231,9 +2231,9 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
Permanent attachment = getPermanent(attachmentId);
|
||||
if (attachment != null
|
||||
&& (attachment.isCreature()
|
||||
|| !(attachment.getSubtype(this).contains(SubType.AURA)
|
||||
|| attachment.getSubtype(this).contains(SubType.EQUIPMENT)
|
||||
|| attachment.getSubtype(this).contains(SubType.FORTIFICATION)))) {
|
||||
|| !(attachment.hasSubtype(SubType.AURA, this)
|
||||
|| attachment.hasSubtype(SubType.EQUIPMENT, this)
|
||||
|| attachment.hasSubtype(SubType.FORTIFICATION, this)))) {
|
||||
if (perm.removeAttachment(attachment.getId(), null, this)) {
|
||||
somethingHappened = true;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,10 @@
|
|||
/*
|
||||
* 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.game;
|
||||
|
||||
import java.io.Serializable;
|
||||
import mage.MageObject;
|
||||
import mage.ObjectColor;
|
||||
import mage.util.SubTypeList;
|
||||
import mage.util.SubTypes;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* This class saves changed attributes of mage objects (e.g. in command zone, graveyard, exile or
|
||||
|
|
@ -19,12 +15,11 @@ import mage.util.SubTypeList;
|
|||
public class MageObjectAttribute implements Serializable {
|
||||
|
||||
protected ObjectColor color;
|
||||
protected SubTypeList subtype;
|
||||
protected SubTypes subtype;
|
||||
|
||||
public MageObjectAttribute(MageObject mageObject, Game game) {
|
||||
color = mageObject.getColor(null).copy();
|
||||
subtype = new SubTypeList();
|
||||
subtype.addAll(mageObject.getSubtype(game));
|
||||
color = mageObject.getColor().copy();
|
||||
subtype = new SubTypes(mageObject.getSubtype(game));
|
||||
}
|
||||
|
||||
public MageObjectAttribute(MageObjectAttribute mageObjectAttribute) {
|
||||
|
|
@ -40,7 +35,7 @@ public class MageObjectAttribute implements Serializable {
|
|||
return color;
|
||||
}
|
||||
|
||||
public SubTypeList getSubtype() {
|
||||
public SubTypes getSubtype() {
|
||||
return subtype;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import mage.constants.SuperType;
|
|||
import mage.game.Game;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.util.GameLog;
|
||||
import mage.util.SubTypeList;
|
||||
import mage.util.SubTypes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
|
@ -130,7 +130,6 @@ public class Commander implements CommandObject {
|
|||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -139,7 +138,12 @@ public class Commander implements CommandObject {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SubTypeList getSubtype(Game game) {
|
||||
public SubTypes getSubtype() {
|
||||
return sourceObject.getSubtype();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubTypes getSubtype(Game game) {
|
||||
return sourceObject.getSubtype(game);
|
||||
}
|
||||
|
||||
|
|
@ -167,6 +171,11 @@ public class Commander implements CommandObject {
|
|||
return otherAbilities != null && otherAbilities.contains(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectColor getColor() {
|
||||
return sourceObject.getColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectColor getColor(Game game) {
|
||||
return sourceObject.getColor(game);
|
||||
|
|
@ -245,7 +254,7 @@ public class Commander implements CommandObject {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllCreatureTypes() {
|
||||
public boolean isAllCreatureTypes(Game game) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -253,6 +262,10 @@ public class Commander implements CommandObject {
|
|||
public void setIsAllCreatureTypes(boolean value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsAllCreatureTypes(Game game, boolean value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TextPart> getTextParts() {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import mage.constants.SuperType;
|
|||
import mage.game.Game;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.util.GameLog;
|
||||
import mage.util.SubTypeList;
|
||||
import mage.util.SubTypes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
|
|
@ -76,7 +76,7 @@ public class Emblem implements CommandObject {
|
|||
this.sourceObject = sourceObject;
|
||||
if (sourceObject instanceof Card) {
|
||||
if (name.isEmpty()) {
|
||||
name = sourceObject.getSubtype(null).toString();
|
||||
name = sourceObject.getSubtype().toString();
|
||||
}
|
||||
if (expansionSetCodeForImage.isEmpty()) {
|
||||
expansionSetCodeForImage = ((Card) sourceObject).getExpansionSetCode();
|
||||
|
|
@ -154,8 +154,13 @@ public class Emblem implements CommandObject {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SubTypeList getSubtype(Game game) {
|
||||
return new SubTypeList();
|
||||
public SubTypes getSubtype() {
|
||||
return new SubTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubTypes getSubtype(Game game) {
|
||||
return new SubTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -178,6 +183,11 @@ public class Emblem implements CommandObject {
|
|||
return getAbilities().contains(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectColor getColor() {
|
||||
return emptyColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectColor getColor(Game game) {
|
||||
return emptyColor;
|
||||
|
|
@ -258,13 +268,19 @@ public class Emblem implements CommandObject {
|
|||
throw new UnsupportedOperationException("Unsupported operation");
|
||||
}
|
||||
|
||||
public boolean isAllCreatureTypes() {
|
||||
@Override
|
||||
public boolean isAllCreatureTypes(Game game) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsAllCreatureTypes(boolean value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsAllCreatureTypes(Game game, boolean value) {
|
||||
}
|
||||
|
||||
public void discardEffects() {
|
||||
for (Ability ability : abilites) {
|
||||
for (Effect effect : ability.getEffects()) {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import mage.game.Game;
|
|||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.util.GameLog;
|
||||
import mage.util.RandomUtil;
|
||||
import mage.util.SubTypeList;
|
||||
import mage.util.SubTypes;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -163,8 +163,13 @@ public class Plane implements CommandObject {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SubTypeList getSubtype(Game game) {
|
||||
return new SubTypeList();
|
||||
public SubTypes getSubtype() {
|
||||
return new SubTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubTypes getSubtype(Game game) {
|
||||
return new SubTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -187,6 +192,11 @@ public class Plane implements CommandObject {
|
|||
return getAbilities().contains(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectColor getColor() {
|
||||
return emptyColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectColor getColor(Game game) {
|
||||
return emptyColor;
|
||||
|
|
@ -267,13 +277,19 @@ public class Plane implements CommandObject {
|
|||
throw new UnsupportedOperationException("Unsupported operation");
|
||||
}
|
||||
|
||||
public boolean isAllCreatureTypes() {
|
||||
@Override
|
||||
public boolean isAllCreatureTypes(Game game) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsAllCreatureTypes(boolean value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsAllCreatureTypes(Game game, boolean value) {
|
||||
}
|
||||
|
||||
public void discardEffects() {
|
||||
for (Ability ability : abilites) {
|
||||
for (Effect effect : ability.getEffects()) {
|
||||
|
|
|
|||
|
|
@ -91,9 +91,9 @@ public final class RateCard {
|
|||
type = 15;
|
||||
} else if (card.isCreature()) {
|
||||
type = 10;
|
||||
} else if (card.getSubtype(null).contains(SubType.EQUIPMENT)) {
|
||||
} else if (card.getSubtype().contains(SubType.EQUIPMENT)) {
|
||||
type = 8;
|
||||
} else if (card.getSubtype(null).contains(SubType.AURA)) {
|
||||
} else if (card.getSubtype().contains(SubType.AURA)) {
|
||||
type = 5;
|
||||
} else if (card.isInstant()) {
|
||||
type = 7;
|
||||
|
|
|
|||
|
|
@ -1,21 +1,20 @@
|
|||
package mage.game.permanent;
|
||||
|
||||
import java.util.UUID;
|
||||
import javax.annotation.processing.SupportedSourceVersion;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Abilities;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.abilities.costs.mana.ManaCosts;
|
||||
import mage.abilities.keyword.EnchantAbility;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.LevelerCard;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
|
||||
import javax.annotation.processing.SupportedSourceVersion;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
|
|
@ -105,9 +104,7 @@ public class PermanentCard extends PermanentImpl {
|
|||
if (card instanceof PermanentCard) {
|
||||
this.maxLevelCounters = ((PermanentCard) card).maxLevelCounters;
|
||||
}
|
||||
this.subtype.clear();
|
||||
this.subtype.addAll(card.getSubtype(game));
|
||||
this.isAllCreatureTypes = card.isAllCreatureTypes();
|
||||
this.subtype.copyFrom(card.getSubtype(game));
|
||||
this.supertype.clear();
|
||||
supertype.addAll(card.getSuperType());
|
||||
this.expansionSetCode = card.getExpansionSetCode();
|
||||
|
|
|
|||
|
|
@ -1634,6 +1634,11 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
|
|||
this.createOrder = createOrder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectColor getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectColor getColor(Game game) {
|
||||
return color;
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ public class PermanentToken extends PermanentImpl {
|
|||
}
|
||||
|
||||
private void copyFromToken(Token token, Game game, boolean reset) {
|
||||
// modify all attributes permanently (without game usage)
|
||||
this.name = token.getName();
|
||||
this.abilities.clear();
|
||||
if (reset) {
|
||||
|
|
@ -81,9 +82,7 @@ public class PermanentToken extends PermanentImpl {
|
|||
this.frameStyle = token.getFrameStyle();
|
||||
this.supertype.clear();
|
||||
this.supertype.addAll(token.getSuperType());
|
||||
this.subtype.clear();
|
||||
this.subtype.addAll(token.getSubtype(game));
|
||||
this.isAllCreatureTypes = token.isAllCreatureTypes();
|
||||
this.subtype.copyFrom(token.getSubtype(game));
|
||||
this.tokenDescriptor = token.getTokenDescriptor();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ public final class CamaridToken extends TokenImpl {
|
|||
this.getPower().modifyBaseValue(1);
|
||||
this.getToughness().modifyBaseValue(1);
|
||||
this.color.setBlue(true);
|
||||
this.getSubtype(null).add(SubType.CAMARID);
|
||||
this.addCardType(CardType.CREATURE);
|
||||
this.subtype.add(SubType.CAMARID);
|
||||
this.cardType.add(CardType.CREATURE);
|
||||
}
|
||||
|
||||
public CamaridToken(final CamaridToken token) {
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ public final class CatWarriorToken extends TokenImpl {
|
|||
this.getPower().modifyBaseValue(2);
|
||||
this.getToughness().modifyBaseValue(2);
|
||||
this.color.setGreen(true);
|
||||
this.getSubtype(null).add(SubType.CAT);
|
||||
this.getSubtype(null).add(SubType.WARRIOR);
|
||||
this.addCardType(CardType.CREATURE);
|
||||
this.subtype.add(SubType.CAT);
|
||||
this.subtype.add(SubType.WARRIOR);
|
||||
this.cardType.add(CardType.CREATURE);
|
||||
this.addAbility(new ForestwalkAbility());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@ public final class CribSwapShapeshifterWhiteToken extends TokenImpl {
|
|||
subtype.add(SubType.SHAPESHIFTER);
|
||||
power = new MageInt(1);
|
||||
toughness = new MageInt(1);
|
||||
setIsAllCreatureTypes(true);
|
||||
addAbility(ChangelingAbility.getInstance());
|
||||
addAbility(new ChangelingAbility());
|
||||
}
|
||||
|
||||
public CribSwapShapeshifterWhiteToken(final CribSwapShapeshifterWhiteToken token) {
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ public final class NissaSageAnimistToken extends TokenImpl {
|
|||
public NissaSageAnimistToken() {
|
||||
super("Ashaya, the Awoken World", "legendary 4/4 green Elemental creature token named Ashaya, the Awoken World");
|
||||
this.setOriginalExpansionSetCode("ORI");
|
||||
this.addSuperType(SuperType.LEGENDARY);
|
||||
this.supertype.add(SuperType.LEGENDARY);
|
||||
this.getPower().modifyBaseValue(4);
|
||||
this.getToughness().modifyBaseValue(4);
|
||||
this.color.setGreen(true);
|
||||
this.getSubtype(null).add(SubType.ELEMENTAL);
|
||||
this.addCardType(CardType.CREATURE);
|
||||
this.subtype.add(SubType.ELEMENTAL);
|
||||
this.cardType.add(CardType.CREATURE);
|
||||
}
|
||||
|
||||
public NissaSageAnimistToken(final NissaSageAnimistToken token) {
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ public final class RagavanToken extends TokenImpl {
|
|||
public RagavanToken() {
|
||||
super("Ragavan", "legendary 2/1 red Monkey creature token named Ragavan");
|
||||
this.setOriginalExpansionSetCode("AER");
|
||||
this.addSuperType(SuperType.LEGENDARY);
|
||||
this.supertype.add(SuperType.LEGENDARY);
|
||||
this.getPower().modifyBaseValue(2);
|
||||
this.getToughness().modifyBaseValue(1);
|
||||
this.color.setRed(true);
|
||||
this.getSubtype(null).add(SubType.MONKEY);
|
||||
this.addCardType(CardType.CREATURE);
|
||||
this.subtype.add(SubType.MONKEY);
|
||||
this.cardType.add(CardType.CREATURE);
|
||||
}
|
||||
|
||||
public RagavanToken(final RagavanToken token) {
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@ public final class ShapeshifterBlueToken extends TokenImpl {
|
|||
color.setBlue(true);
|
||||
power = new MageInt(2);
|
||||
toughness = new MageInt(2);
|
||||
setIsAllCreatureTypes(true);
|
||||
addAbility(ChangelingAbility.getInstance());
|
||||
addAbility(new ChangelingAbility());
|
||||
}
|
||||
|
||||
private ShapeshifterBlueToken(final ShapeshifterBlueToken token) {
|
||||
|
|
|
|||
|
|
@ -27,8 +27,7 @@ public final class ShapeshifterToken extends TokenImpl {
|
|||
subtype.add(SubType.SHAPESHIFTER);
|
||||
power = new MageInt(2);
|
||||
toughness = new MageInt(2);
|
||||
setIsAllCreatureTypes(true);
|
||||
addAbility(ChangelingAbility.getInstance());
|
||||
addAbility(new ChangelingAbility());
|
||||
}
|
||||
|
||||
public ShapeshifterToken(final ShapeshifterToken token) {
|
||||
|
|
|
|||
|
|
@ -75,7 +75,6 @@ public abstract class TokenImpl extends MageObjectImpl implements Token {
|
|||
this.expansionSetCodeChecked = token.expansionSetCodeChecked;
|
||||
this.copySourceCard = token.copySourceCard; // will never be changed
|
||||
this.availableImageSetCodes = token.availableImageSetCodes;
|
||||
this.isAllCreatureTypes = token.isAllCreatureTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ public final class WireflyToken extends TokenImpl {
|
|||
this.setOriginalExpansionSetCode("DST");
|
||||
this.getPower().modifyBaseValue(2);
|
||||
this.getToughness().modifyBaseValue(2);
|
||||
this.getSubtype(null).add(SubType.INSECT);
|
||||
this.addCardType(CardType.ARTIFACT);
|
||||
this.addCardType(CardType.CREATURE);
|
||||
this.subtype.add(SubType.INSECT);
|
||||
this.cardType.add(CardType.ARTIFACT);
|
||||
this.cardType.add(CardType.CREATURE);
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ import mage.abilities.Ability;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.game.permanent.token.TokenImpl;
|
||||
import mage.util.SubTypeList;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
public final class CreatureToken extends TokenImpl {
|
||||
|
|
@ -23,21 +23,17 @@ public final class CreatureToken extends TokenImpl {
|
|||
}
|
||||
|
||||
public CreatureToken(int power, int toughness, String description) {
|
||||
this(power, toughness, description, (SubTypeList) null);
|
||||
this(power, toughness, description, null);
|
||||
}
|
||||
|
||||
public CreatureToken(int power, int toughness, String description, SubType extraSubType) {
|
||||
this(power, toughness, description, new SubTypeList(extraSubType));
|
||||
}
|
||||
|
||||
public CreatureToken(int power, int toughness, String description, SubTypeList extraSubTypes) {
|
||||
public CreatureToken(int power, int toughness, String description, SubType... extraSubTypes) {
|
||||
super("", description);
|
||||
this.cardType.add(CardType.CREATURE);
|
||||
this.power = new MageInt(power);
|
||||
this.toughness = new MageInt(toughness);
|
||||
|
||||
if (extraSubTypes != null) {
|
||||
this.subtype.addAll(extraSubTypes);
|
||||
this.subtype.addAll(Arrays.asList(extraSubTypes));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import mage.game.permanent.token.EmptyToken;
|
|||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
import mage.util.GameLog;
|
||||
import mage.util.SubTypeList;
|
||||
import mage.util.SubTypes;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
|
|
@ -253,10 +253,11 @@ public class Spell extends StackObjImpl implements Card {
|
|||
if (ability.getTargets().stillLegal(ability, game)) {
|
||||
boolean bestow = SpellAbilityCastMode.BESTOW.equals(ability.getSpellAbilityCastMode());
|
||||
if (bestow) {
|
||||
// before put to play:
|
||||
// Must be removed first time, after that will be removed by continous effect
|
||||
// Otherwise effects like evolve trigger from creature comes into play event
|
||||
card.getCardType().remove(CardType.CREATURE);
|
||||
if (!card.getSubtype(game).contains(SubType.AURA)) {
|
||||
if (!card.hasSubtype(SubType.AURA, game)) {
|
||||
card.addSubType(game, SubType.AURA);
|
||||
}
|
||||
}
|
||||
|
|
@ -280,9 +281,11 @@ public class Spell extends StackObjImpl implements Card {
|
|||
// TODO: Find a better way to prevent bestow creatures from being effected by creature affecting abilities
|
||||
Permanent permanent = game.getPermanent(permId);
|
||||
if (permanent instanceof PermanentCard) {
|
||||
// after put to play:
|
||||
// restore removed stats (see "before put to play" above)
|
||||
permanent.setSpellAbility(ability); // otherwise spell ability without bestow will be set
|
||||
card.addCardType(CardType.CREATURE);
|
||||
card.getSubtype(game).remove(SubType.AURA);
|
||||
card.removeSubType(game, SubType.AURA);
|
||||
}
|
||||
}
|
||||
if (isCopy()) {
|
||||
|
|
@ -312,7 +315,7 @@ public class Spell extends StackObjImpl implements Card {
|
|||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent instanceof PermanentCard) {
|
||||
((PermanentCard) permanent).getCard().addCardType(CardType.CREATURE);
|
||||
((PermanentCard) permanent).getCard().getSubtype(game).remove(SubType.AURA);
|
||||
((PermanentCard) permanent).getCard().removeSubType(game, SubType.AURA);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -524,9 +527,14 @@ public class Spell extends StackObjImpl implements Card {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SubTypeList getSubtype(Game game) {
|
||||
public SubTypes getSubtype() {
|
||||
return card.getSubtype();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubTypes getSubtype(Game game) {
|
||||
if (SpellAbilityCastMode.BESTOW.equals(this.getSpellAbility().getSpellAbilityCastMode())) {
|
||||
SubTypeList subtypes = card.getSubtype(game);
|
||||
SubTypes subtypes = card.getSubtype(game);
|
||||
if (!subtypes.contains(SubType.AURA)) { // do it only once
|
||||
subtypes.add(SubType.AURA);
|
||||
}
|
||||
|
|
@ -538,7 +546,7 @@ public class Spell extends StackObjImpl implements Card {
|
|||
@Override
|
||||
public boolean hasSubtype(SubType subtype, Game game) {
|
||||
if (SpellAbilityCastMode.BESTOW.equals(this.getSpellAbility().getSpellAbilityCastMode())) { // workaround for Bestow (don't like it)
|
||||
SubTypeList subtypes = card.getSubtype(game);
|
||||
SubTypes subtypes = card.getSubtype(game);
|
||||
if (!subtypes.contains(SubType.AURA)) { // do it only once
|
||||
subtypes.add(SubType.AURA);
|
||||
}
|
||||
|
|
@ -573,6 +581,11 @@ public class Spell extends StackObjImpl implements Card {
|
|||
return card.hasAbility(ability, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectColor getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectColor getColor(Game game) {
|
||||
if (game != null) {
|
||||
|
|
@ -1090,7 +1103,7 @@ public class Spell extends StackObjImpl implements Card {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllCreatureTypes() {
|
||||
public boolean isAllCreatureTypes(Game game) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1098,6 +1111,10 @@ public class Spell extends StackObjImpl implements Card {
|
|||
public void setIsAllCreatureTypes(boolean value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsAllCreatureTypes(Game game, boolean value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TextPart> getTextParts() {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import mage.target.Target;
|
|||
import mage.target.Targets;
|
||||
import mage.target.targetadjustment.TargetAdjuster;
|
||||
import mage.util.GameLog;
|
||||
import mage.util.SubTypeList;
|
||||
import mage.util.SubTypes;
|
||||
import mage.watchers.Watcher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -161,8 +161,13 @@ public class StackAbility extends StackObjImpl implements Ability {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SubTypeList getSubtype(Game game) {
|
||||
return new SubTypeList();
|
||||
public SubTypes getSubtype() {
|
||||
return new SubTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubTypes getSubtype(Game game) {
|
||||
return new SubTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -185,6 +190,11 @@ public class StackAbility extends StackObjImpl implements Ability {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectColor getColor() {
|
||||
return emptyColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectColor getColor(Game game) {
|
||||
return emptyColor;
|
||||
|
|
@ -604,7 +614,7 @@ public class StackAbility extends StackObjImpl implements Ability {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllCreatureTypes() {
|
||||
public boolean isAllCreatureTypes(Game game) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -612,6 +622,10 @@ public class StackAbility extends StackObjImpl implements Ability {
|
|||
public void setIsAllCreatureTypes(boolean value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsAllCreatureTypes(Game game, boolean value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TextPart> getTextParts() {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public class TargetCreaturePermanentWithDifferentTypes extends TargetCreaturePer
|
|||
Permanent selectedCreature = game.getPermanent(targetId);
|
||||
if (selectedCreature != null
|
||||
&& !creature.getId().equals(selectedCreature.getId())) {
|
||||
if (creature.shareCreatureTypes(selectedCreature, game)) {
|
||||
if (creature.shareCreatureTypes(game, selectedCreature)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
package mage.util;
|
||||
|
||||
import mage.constants.SubType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SubTypeList extends ArrayList<SubType> {
|
||||
|
||||
public SubTypeList(SubType firstSubType) {
|
||||
super();
|
||||
this.add(firstSubType);
|
||||
}
|
||||
|
||||
public SubTypeList(SubType... subTypesList) {
|
||||
super();
|
||||
Collections.addAll(this, subTypesList);
|
||||
}
|
||||
|
||||
public SubTypeList(final SubTypeList list) {
|
||||
this.addAll(list);
|
||||
}
|
||||
|
||||
public boolean add(SubType... subTypes) {
|
||||
return Collections.addAll(this, subTypes);
|
||||
}
|
||||
|
||||
public boolean removeAll(SubType... subTypes) {
|
||||
return super.removeAll(Arrays.stream(subTypes)
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
44
Mage/src/main/java/mage/util/SubTypes.java
Normal file
44
Mage/src/main/java/mage/util/SubTypes.java
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
package mage.util;
|
||||
|
||||
import mage.constants.SubType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
public class SubTypes extends ArrayList<SubType> {
|
||||
|
||||
private boolean isAllCreatureTypes = false;
|
||||
|
||||
public SubTypes(SubType... subTypes) {
|
||||
super();
|
||||
Collections.addAll(this, subTypes);
|
||||
}
|
||||
|
||||
public SubTypes(final SubTypes list) {
|
||||
this.addAll(list);
|
||||
this.isAllCreatureTypes = list.isAllCreatureTypes;
|
||||
}
|
||||
|
||||
public boolean add(SubType... subTypes) {
|
||||
return Collections.addAll(this, subTypes);
|
||||
}
|
||||
|
||||
public void copyFrom(SubTypes subtypes) {
|
||||
this.clear();
|
||||
this.addAll(subtypes);
|
||||
this.isAllCreatureTypes = subtypes.isAllCreatureTypes;
|
||||
}
|
||||
|
||||
public boolean removeAll(SubType... subTypes) {
|
||||
return super.removeAll(Arrays.asList(subTypes));
|
||||
}
|
||||
|
||||
public void setIsAllCreatureTypes(boolean allCreatureTypes) {
|
||||
isAllCreatureTypes = allCreatureTypes;
|
||||
}
|
||||
|
||||
public boolean isAllCreatureTypes() {
|
||||
return isAllCreatureTypes;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
|
||||
package mage.util.functions;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class AbilityApplier extends ApplyToPermanent {
|
||||
|
||||
private final Ability ability;
|
||||
|
||||
public AbilityApplier(Ability ability) {
|
||||
this.ability = ability;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
|
||||
mageObject.getAbilities().add(ability);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package mage.util.functions;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class AbilityCopyApplier extends CopyApplier {
|
||||
|
||||
private final Ability ability;
|
||||
|
||||
public AbilityCopyApplier(Ability ability) {
|
||||
this.ability = ability;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) {
|
||||
blueprint.getAbilities().add(ability);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,44 +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.util.functions;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.constants.SubType;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class AddSubtypeApplier extends ApplyToPermanent {
|
||||
|
||||
private final SubType subtype;
|
||||
|
||||
public AddSubtypeApplier(SubType subtype) {
|
||||
this.subtype = subtype;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) {
|
||||
if (!permanent.hasSubtype(subtype, game)) {
|
||||
permanent.addSubType(game, subtype);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
|
||||
if (!mageObject.hasSubtype(subtype, game)) {
|
||||
mageObject.addSubType(game, subtype);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package mage.util.functions;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.constants.SubType;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class AddSubtypeCopyApplier extends CopyApplier {
|
||||
|
||||
private final SubType subtype;
|
||||
|
||||
public AddSubtypeCopyApplier(SubType subtype) {
|
||||
this.subtype = subtype;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) {
|
||||
if (!blueprint.getSubtype().contains(subtype)) {
|
||||
blueprint.getSubtype().add(subtype);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
package mage.util.functions;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author noxx
|
||||
*/
|
||||
public abstract class ApplyToPermanent extends ApplyToMageObject implements Serializable {
|
||||
|
||||
// WARNING: see comments in ApplyToMageObject
|
||||
public abstract boolean apply(Game game, Permanent permanent, Ability source, UUID targetObjectId);
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
|
||||
package mage.util.functions;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.constants.CardType;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class CardTypeApplier extends ApplyToPermanent {
|
||||
|
||||
private final CardType cardType;
|
||||
|
||||
public CardTypeApplier(CardType cardType) {
|
||||
this.cardType = cardType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) {
|
||||
permanent.addCardType(cardType);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
|
||||
mageObject.addCardType(cardType);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
package mage.util.functions;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.constants.CardType;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class CardTypeCopyApplier extends CopyApplier {
|
||||
|
||||
private final CardType cardType;
|
||||
|
||||
public CardTypeCopyApplier(CardType cardType) {
|
||||
this.cardType = cardType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) {
|
||||
blueprint.addCardType(cardType);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,13 +3,17 @@ package mage.util.functions;
|
|||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.game.Game;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Apply additional modifications for blueprint of the copy permanent
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public abstract class ApplyToMageObject {
|
||||
public abstract class CopyApplier implements Serializable {
|
||||
|
||||
// WARNING:
|
||||
// 1. Applier uses for copy effects only;
|
||||
|
|
@ -17,8 +21,7 @@ public abstract class ApplyToMageObject {
|
|||
// 3. "source" is the current copy ability and can be different from the original copy ability (copy of copy);
|
||||
// 4. Don't use "source" param at all;
|
||||
// 5. Use isCopyOfCopy() to detect it (some effects can apply to copy of copy, but others can't -- see Spark Double as an example).
|
||||
// TODO: check all applier implementations - remove source uses, add isCopyOfCopy processing
|
||||
public abstract boolean apply(Game game, MageObject mageObject, Ability source, UUID targetObjectId);
|
||||
public abstract boolean apply(Game game, MageObject blueprint, Ability source, UUID targetObjectId);
|
||||
|
||||
public boolean isCopyOfCopy(Ability source, UUID targetObjectId) {
|
||||
return !Objects.equals(targetObjectId, source.getSourceId());
|
||||
|
|
@ -63,18 +63,16 @@ public class CopyTokenFunction implements Function<Token, Card> {
|
|||
target.setCopySourceCard(source);
|
||||
}
|
||||
|
||||
// modify all attributes permanently (without game usage)
|
||||
target.setName(sourceObj.getName());
|
||||
target.getColor(null).setColor(sourceObj.getColor(null));
|
||||
target.getColor().setColor(sourceObj.getColor());
|
||||
target.getManaCost().clear();
|
||||
target.getManaCost().add(sourceObj.getManaCost());
|
||||
target.getCardType().clear();
|
||||
for (CardType type : sourceObj.getCardType()) {
|
||||
target.addCardType(type);
|
||||
}
|
||||
target.getSubtype(null).clear();
|
||||
for (SubType type : sourceObj.getSubtype(null)) {
|
||||
target.getSubtype(null).add(type);
|
||||
}
|
||||
target.getSubtype().copyFrom(sourceObj.getSubtype());
|
||||
target.getSuperType().clear();
|
||||
for (SuperType type : sourceObj.getSuperType()) {
|
||||
target.addSuperType(type);
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
package mage.util.functions;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
* @author noxx
|
||||
*/
|
||||
public class EmptyApplyToPermanent extends ApplyToPermanent {
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) {
|
||||
// do nothing
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
19
Mage/src/main/java/mage/util/functions/EmptyCopyApplier.java
Normal file
19
Mage/src/main/java/mage/util/functions/EmptyCopyApplier.java
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
package mage.util.functions;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
* @author noxx
|
||||
*/
|
||||
public class EmptyCopyApplier extends CopyApplier {
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
package mage.watchers.common;
|
||||
|
||||
import mage.cards.Card;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SubTypeSet;
|
||||
import mage.constants.WatcherScope;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.DamagedPlayerEvent;
|
||||
|
|
@ -39,7 +41,7 @@ public class ProwlWatcher extends Watcher {
|
|||
if (creature == null || allSubtypes.contains(creature.getControllerId())) {
|
||||
return;
|
||||
}
|
||||
if (creature.isAllCreatureTypes()) {
|
||||
if (creature.isAllCreatureTypes(game)) {
|
||||
allSubtypes.add(creature.getControllerId());
|
||||
return;
|
||||
}
|
||||
|
|
@ -55,12 +57,16 @@ public class ProwlWatcher extends Watcher {
|
|||
allSubtypes.clear();
|
||||
}
|
||||
|
||||
public boolean hasSubtypeMadeCombatDamage(UUID playerId, SubType subtype) {
|
||||
public boolean hasSubtypeMadeCombatDamage(UUID playerId, Card card, Game game) {
|
||||
if (allSubtypes.contains(playerId)) {
|
||||
return true;
|
||||
}
|
||||
Set<SubType> subtypes = damagingSubtypes.get(playerId);
|
||||
return subtypes != null && subtypes.contains(subtype);
|
||||
return subtypes != null
|
||||
&& subtypes
|
||||
.stream()
|
||||
.filter(subType -> subType.getSubTypeSet() == SubTypeSet.CreatureType)
|
||||
.anyMatch(subType -> card.hasSubtype(subType, game));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue