mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
CardType: fixed seting specific SubTypes
This commit is contained in:
@@ -1573,7 +1573,7 @@ public class ComputerUtilCard {
|
||||
pumped.addNewPT(c.getCurrentPower(), c.getCurrentToughness(), timestamp);
|
||||
pumped.addTempPowerBoost(c.getTempPowerBoost() + power + berserkPower);
|
||||
pumped.addTempToughnessBoost(c.getTempToughnessBoost() + toughness);
|
||||
pumped.addChangedCardKeywords(kws, new ArrayList<String>(), false, timestamp);
|
||||
pumped.addChangedCardKeywords(kws, null, false, false, timestamp);
|
||||
Set<CounterType> types = c.getCounters().keySet();
|
||||
for(CounterType ct : types) {
|
||||
pumped.addCounterFireNoEvents(ct, c.getCounters(ct), c, true);
|
||||
@@ -1596,7 +1596,7 @@ public class ComputerUtilCard {
|
||||
}
|
||||
}
|
||||
final long timestamp2 = c.getGame().getNextTimestamp(); //is this necessary or can the timestamp be re-used?
|
||||
pumped.addChangedCardKeywordsInternal(toCopy, Lists.<KeywordInterface>newArrayList(), false, timestamp2, true);
|
||||
pumped.addChangedCardKeywordsInternal(toCopy, null, false, false, timestamp2, true);
|
||||
ComputerUtilCard.applyStaticContPT(ai.getGame(), pumped, new CardCollection(c));
|
||||
return pumped;
|
||||
}
|
||||
|
||||
@@ -23,12 +23,12 @@ import forge.game.staticability.StaticAbilityLayer;
|
||||
import forge.game.trigger.Trigger;
|
||||
import forge.game.trigger.TriggerHandler;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.collect.FCollectionView;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import forge.game.ability.effects.AnimateEffectBase;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -363,11 +363,11 @@ public class AnimateAi extends SpellAbilityAi {
|
||||
card.setSickness(hasOriginalCardSickness);
|
||||
|
||||
// AF specific sa
|
||||
int power = -1;
|
||||
Integer power = null;
|
||||
if (sa.hasParam("Power")) {
|
||||
power = AbilityUtils.calculateAmount(source, sa.getParam("Power"), sa);
|
||||
}
|
||||
int toughness = -1;
|
||||
Integer toughness = null;
|
||||
if (sa.hasParam("Toughness")) {
|
||||
toughness = AbilityUtils.calculateAmount(source, sa.getParam("Toughness"), sa);
|
||||
}
|
||||
@@ -453,65 +453,7 @@ public class AnimateAi extends SpellAbilityAi {
|
||||
sVars.addAll(Arrays.asList(sa.getParam("sVars").split(",")));
|
||||
}
|
||||
|
||||
// duplicating AnimateEffectBase.doAnimate
|
||||
boolean removeSuperTypes = false;
|
||||
boolean removeCardTypes = false;
|
||||
boolean removeSubTypes = false;
|
||||
boolean removeCreatureTypes = false;
|
||||
boolean removeArtifactTypes = false;
|
||||
|
||||
if (sa.hasParam("OverwriteTypes")) {
|
||||
removeSuperTypes = true;
|
||||
removeCardTypes = true;
|
||||
removeSubTypes = true;
|
||||
removeCreatureTypes = true;
|
||||
removeArtifactTypes = true;
|
||||
}
|
||||
|
||||
if (sa.hasParam("KeepSupertypes")) {
|
||||
removeSuperTypes = false;
|
||||
}
|
||||
|
||||
if (sa.hasParam("KeepCardTypes")) {
|
||||
removeCardTypes = false;
|
||||
}
|
||||
|
||||
if (sa.hasParam("RemoveSuperTypes")) {
|
||||
removeSuperTypes = true;
|
||||
}
|
||||
|
||||
if (sa.hasParam("RemoveCardTypes")) {
|
||||
removeCardTypes = true;
|
||||
}
|
||||
|
||||
if (sa.hasParam("RemoveSubTypes")) {
|
||||
removeSubTypes = true;
|
||||
}
|
||||
|
||||
if (sa.hasParam("RemoveCreatureTypes")) {
|
||||
removeCreatureTypes = true;
|
||||
}
|
||||
|
||||
if (sa.hasParam("RemoveArtifactTypes")) {
|
||||
removeArtifactTypes = true;
|
||||
}
|
||||
|
||||
if ((power != -1) || (toughness != -1)) {
|
||||
card.addNewPT(power, toughness, timestamp);
|
||||
}
|
||||
|
||||
if (!types.isEmpty() || !removeTypes.isEmpty() || removeCreatureTypes) {
|
||||
card.addChangedCardTypes(types, removeTypes, removeSuperTypes, removeCardTypes, removeSubTypes,
|
||||
removeCreatureTypes, removeArtifactTypes, timestamp);
|
||||
}
|
||||
|
||||
card.addChangedCardKeywords(keywords, removeKeywords, sa.hasParam("RemoveAllAbilities"), timestamp);
|
||||
|
||||
for (final String k : hiddenKeywords) {
|
||||
card.addHiddenExtrinsicKeyword(k);
|
||||
}
|
||||
|
||||
card.addColor(finalDesc, !sa.hasParam("OverwriteColors"), timestamp);
|
||||
AnimateEffectBase.doAnimate(card, sa, power, toughness, types, removeTypes, finalDesc, keywords, removeKeywords, hiddenKeywords, timestamp);
|
||||
|
||||
// back to duplicating AnimateEffect.resolve
|
||||
// TODO will all these abilities/triggers/replacements/etc. lead to
|
||||
@@ -521,10 +463,14 @@ public class AnimateAi extends SpellAbilityAi {
|
||||
boolean clearAbilities = sa.hasParam("OverwriteAbilities");
|
||||
boolean clearSpells = sa.hasParam("OverwriteSpells");
|
||||
boolean removeAll = sa.hasParam("RemoveAllAbilities");
|
||||
boolean removeIntrinsic = sa.hasParam("RemoveIntrinsicAbilities");
|
||||
|
||||
if (clearAbilities || clearSpells || removeAll) {
|
||||
for (final SpellAbility ab : card.getSpellAbilities()) {
|
||||
if (removeAll || (ab.isAbility() && clearAbilities) || (ab.isSpell() && clearSpells)) {
|
||||
if (removeAll
|
||||
|| (ab.isIntrinsic() && removeIntrinsic && !ab.isBasicLandAbility())
|
||||
|| (ab.isAbility() && clearAbilities)
|
||||
|| (ab.isSpell() && clearSpells)) {
|
||||
card.removeSpellAbility(ab);
|
||||
removedAbilities.add(ab);
|
||||
}
|
||||
@@ -565,9 +511,11 @@ public class AnimateAi extends SpellAbilityAi {
|
||||
|
||||
// suppress triggers from the animated card
|
||||
final List<Trigger> removedTriggers = Lists.newArrayList();
|
||||
if (sa.hasParam("OverwriteTriggers") || removeAll) {
|
||||
final FCollectionView<Trigger> triggersToRemove = card.getTriggers();
|
||||
for (final Trigger trigger : triggersToRemove) {
|
||||
if (sa.hasParam("OverwriteTriggers") || removeAll || removeIntrinsic) {
|
||||
for (final Trigger trigger : card.getTriggers()) {
|
||||
if (removeIntrinsic && !trigger.isIntrinsic()) {
|
||||
continue;
|
||||
}
|
||||
trigger.setSuppressed(true);
|
||||
removedTriggers.add(trigger);
|
||||
}
|
||||
@@ -603,9 +551,11 @@ public class AnimateAi extends SpellAbilityAi {
|
||||
|
||||
// suppress static abilities from the animated card
|
||||
final List<StaticAbility> removedStatics = Lists.newArrayList();
|
||||
if (sa.hasParam("OverwriteStatics") || removeAll) {
|
||||
final FCollectionView<StaticAbility> staticsToRemove = card.getStaticAbilities();
|
||||
for (final StaticAbility stAb : staticsToRemove) {
|
||||
if (sa.hasParam("OverwriteStatics") || removeAll || removeIntrinsic) {
|
||||
for (final StaticAbility stAb : card.getStaticAbilities()) {
|
||||
if (removeIntrinsic && !stAb.isIntrinsic()) {
|
||||
continue;
|
||||
}
|
||||
stAb.setTemporarilySuppressed(true);
|
||||
removedStatics.add(stAb);
|
||||
}
|
||||
@@ -613,8 +563,11 @@ public class AnimateAi extends SpellAbilityAi {
|
||||
|
||||
// suppress static abilities from the animated card
|
||||
final List<ReplacementEffect> removedReplacements = Lists.newArrayList();
|
||||
if (sa.hasParam("OverwriteReplacements") || removeAll) {
|
||||
if (sa.hasParam("OverwriteReplacements") || removeAll || removeIntrinsic) {
|
||||
for (final ReplacementEffect re : card.getReplacementEffects()) {
|
||||
if (removeIntrinsic && !re.isIntrinsic()) {
|
||||
continue;
|
||||
}
|
||||
re.setTemporarilySuppressed(true);
|
||||
removedReplacements.add(re);
|
||||
}
|
||||
|
||||
@@ -32,19 +32,24 @@ public class CardChangedType {
|
||||
private final boolean removeSuperTypes;
|
||||
private final boolean removeCardTypes;
|
||||
private final boolean removeSubTypes;
|
||||
private final boolean removeLandTypes;
|
||||
private final boolean removeCreatureTypes;
|
||||
private final boolean removeArtifactTypes;
|
||||
private final boolean removeEnchantmentTypes;
|
||||
|
||||
public CardChangedType(final CardType addType0, final CardType removeType0, final boolean removeSuperType0,
|
||||
final boolean removeCardType0, final boolean removeSubType0, final boolean removeCreatureType0,
|
||||
final boolean removeArtifactType0) {
|
||||
final boolean removeCardType0, final boolean removeSubType0, final boolean removeLandType0,
|
||||
final boolean removeCreatureType0, final boolean removeArtifactType0,
|
||||
final boolean removeEnchantmentTypes0) {
|
||||
addType = addType0;
|
||||
removeType = removeType0;
|
||||
removeSuperTypes = removeSuperType0;
|
||||
removeCardTypes = removeCardType0;
|
||||
removeSubTypes = removeSubType0;
|
||||
removeLandTypes = removeLandType0;
|
||||
removeCreatureTypes = removeCreatureType0;
|
||||
removeArtifactTypes = removeArtifactType0;
|
||||
removeEnchantmentTypes = removeEnchantmentTypes0;
|
||||
}
|
||||
|
||||
public final CardType getAddType() {
|
||||
@@ -67,6 +72,10 @@ public class CardChangedType {
|
||||
return removeSubTypes;
|
||||
}
|
||||
|
||||
public final boolean isRemoveLandTypes() {
|
||||
return removeLandTypes;
|
||||
}
|
||||
|
||||
public final boolean isRemoveCreatureTypes() {
|
||||
return removeCreatureTypes;
|
||||
}
|
||||
@@ -74,4 +83,8 @@ public class CardChangedType {
|
||||
public final boolean isRemoveArtifactTypes() {
|
||||
return removeArtifactTypes;
|
||||
}
|
||||
|
||||
public final boolean isRemoveEnchantmentTypes() {
|
||||
return removeEnchantmentTypes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
||||
|
||||
public boolean setCreatureTypes(Collection<String> ctypes) {
|
||||
// if it isn't a creature then this has no effect
|
||||
if (!coreTypes.contains(CoreType.Creature)) {
|
||||
if (!isCreature() && !isTribal()) {
|
||||
return false;
|
||||
}
|
||||
boolean changed = Iterables.removeIf(subtypes, Predicates.IS_CREATURE_TYPE);
|
||||
@@ -236,7 +236,7 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
||||
final Set<String> landTypes = Sets.newHashSet();
|
||||
if (isLand()) {
|
||||
for (final String t : subtypes) {
|
||||
if (isALandType(t) || isABasicLandType(t)) {
|
||||
if (isALandType(t)) {
|
||||
landTypes.add(t);
|
||||
}
|
||||
}
|
||||
@@ -435,6 +435,9 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
||||
@Override
|
||||
public CardTypeView getTypeWithChanges(final Iterable<CardChangedType> changedCardTypes) {
|
||||
CardType newType = null;
|
||||
if (Iterables.isEmpty(changedCardTypes)) {
|
||||
return this;
|
||||
}
|
||||
// we assume that changes are already correctly ordered (taken from TreeMap.values())
|
||||
for (final CardChangedType ct : changedCardTypes) {
|
||||
if(null == newType)
|
||||
@@ -449,7 +452,10 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
||||
if (ct.isRemoveSubTypes()) {
|
||||
newType.subtypes.clear();
|
||||
}
|
||||
else {
|
||||
else if (!newType.subtypes.isEmpty()) {
|
||||
if (ct.isRemoveLandTypes()) {
|
||||
Iterables.removeIf(newType.subtypes, Predicates.IS_LAND_TYPE);
|
||||
}
|
||||
if (ct.isRemoveCreatureTypes()) {
|
||||
Iterables.removeIf(newType.subtypes, Predicates.IS_CREATURE_TYPE);
|
||||
// need to remove AllCreatureTypes too when removing creature Types
|
||||
@@ -458,6 +464,9 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
||||
if (ct.isRemoveArtifactTypes()) {
|
||||
Iterables.removeIf(newType.subtypes, Predicates.IS_ARTIFACT_TYPE);
|
||||
}
|
||||
if (ct.isRemoveEnchantmentTypes()) {
|
||||
Iterables.removeIf(newType.subtypes, Predicates.IS_ENCHANTMENT_TYPE);
|
||||
}
|
||||
}
|
||||
if (ct.getRemoveType() != null) {
|
||||
newType.removeAll(ct.getRemoveType());
|
||||
@@ -466,6 +475,28 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
||||
newType.addAll(ct.getAddType());
|
||||
}
|
||||
}
|
||||
// sanisfy subtypes
|
||||
if (newType != null && !newType.subtypes.isEmpty()) {
|
||||
if (!newType.isCreature() && !newType.isTribal()) {
|
||||
Iterables.removeIf(newType.subtypes, Predicates.IS_CREATURE_TYPE);
|
||||
newType.subtypes.remove("AllCreatureTypes");
|
||||
}
|
||||
if (!newType.isLand()) {
|
||||
Iterables.removeIf(newType.subtypes, Predicates.IS_LAND_TYPE);
|
||||
}
|
||||
if (!newType.isArtifact()) {
|
||||
Iterables.removeIf(newType.subtypes, Predicates.IS_ARTIFACT_TYPE);
|
||||
}
|
||||
if (!newType.isEnchantment()) {
|
||||
Iterables.removeIf(newType.subtypes, Predicates.IS_ENCHANTMENT_TYPE);
|
||||
}
|
||||
if (!newType.isInstant() && !newType.isSorcery()) {
|
||||
Iterables.removeIf(newType.subtypes, Predicates.IS_SPELL_TYPE);
|
||||
}
|
||||
if (!newType.isPlaneswalker() && !newType.isEmblem()) {
|
||||
Iterables.removeIf(newType.subtypes, Predicates.IS_WALKER_TYPE);
|
||||
}
|
||||
}
|
||||
return newType == null ? this : newType;
|
||||
}
|
||||
|
||||
@@ -574,6 +605,13 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
||||
public static final BiMap<String,String> singularTypes = pluralTypes.inverse();
|
||||
}
|
||||
public static class Predicates {
|
||||
public static Predicate<String> IS_LAND_TYPE = new Predicate<String>() {
|
||||
@Override
|
||||
public boolean apply(String input) {
|
||||
return CardType.isALandType(input);
|
||||
}
|
||||
};
|
||||
|
||||
public static Predicate<String> IS_ARTIFACT_TYPE = new Predicate<String>() {
|
||||
@Override
|
||||
public boolean apply(String input) {
|
||||
@@ -587,6 +625,27 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
||||
return CardType.isACreatureType(input);
|
||||
}
|
||||
};
|
||||
|
||||
public static Predicate<String> IS_ENCHANTMENT_TYPE = new Predicate<String>() {
|
||||
@Override
|
||||
public boolean apply(String input) {
|
||||
return CardType.isAnEnchantmentType(input);
|
||||
}
|
||||
};
|
||||
|
||||
public static Predicate<String> IS_SPELL_TYPE = new Predicate<String>() {
|
||||
@Override
|
||||
public boolean apply(String input) {
|
||||
return CardType.isASpellType(input);
|
||||
}
|
||||
};
|
||||
|
||||
public static Predicate<String> IS_WALKER_TYPE = new Predicate<String>() {
|
||||
@Override
|
||||
public boolean apply(String input) {
|
||||
return CardType.isAPlaneswalkerType(input);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -656,7 +715,7 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
||||
}
|
||||
|
||||
public static boolean isALandType(final String cardType) {
|
||||
return (Constant.LAND_TYPES.contains(cardType));
|
||||
return Constant.LAND_TYPES.contains(cardType) || isABasicLandType(cardType);
|
||||
}
|
||||
|
||||
public static boolean isAPlaneswalkerType(final String cardType) {
|
||||
@@ -667,6 +726,13 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
||||
return (Constant.BASIC_TYPES.contains(cardType));
|
||||
}
|
||||
|
||||
public static boolean isAnEnchantmentType(final String cardType) {
|
||||
return (Constant.ENCHANTMENT_TYPES.contains(cardType));
|
||||
}
|
||||
|
||||
public static boolean isASpellType(final String cardType) {
|
||||
return (Constant.SPELL_TYPES.contains(cardType));
|
||||
}
|
||||
|
||||
/**
|
||||
* If the input is a plural type, return the corresponding singular form.
|
||||
|
||||
@@ -1036,7 +1036,7 @@ public class StaticEffect {
|
||||
}
|
||||
|
||||
// remove abilities
|
||||
if (params.containsKey("RemoveAllAbilities")) {
|
||||
if (params.containsKey("RemoveAllAbilities") || params.containsKey("RemoveIntrinsicAbilities")) {
|
||||
affectedCard.unSuppressCardTraits();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
public class AnimateAllEffect extends AnimateEffectBase {
|
||||
|
||||
@Override
|
||||
@@ -144,6 +146,9 @@ public class AnimateAllEffect extends AnimateEffectBase {
|
||||
|
||||
list = CardLists.getValidCards(list, valid.split(","), host.getController(), host, sa);
|
||||
|
||||
boolean removeAll = sa.hasParam("RemoveAllAbilities");
|
||||
boolean removeIntrinsic = sa.hasParam("RemoveIntrinsicAbilities");
|
||||
|
||||
for (final Card c : list) {
|
||||
doAnimate(c, sa, power, toughness, types, removeTypes, finalDesc,
|
||||
keywords, removeKeywords, hiddenKeywords, timestamp);
|
||||
@@ -161,14 +166,17 @@ public class AnimateAllEffect extends AnimateEffectBase {
|
||||
|
||||
// remove abilities
|
||||
final List<SpellAbility> removedAbilities = new ArrayList<SpellAbility>();
|
||||
if (sa.hasParam("OverwriteAbilities") || sa.hasParam("RemoveAllAbilities")) {
|
||||
if (sa.hasParam("OverwriteAbilities") || removeAll || removeIntrinsic) {
|
||||
for (final SpellAbility ab : c.getSpellAbilities()) {
|
||||
if (ab.isAbility()) {
|
||||
c.removeSpellAbility(ab);
|
||||
if (removeAll
|
||||
|| (ab.isIntrinsic() && removeIntrinsic && !ab.isBasicLandAbility())) {
|
||||
ab.setTemporarilySuppressed(true);
|
||||
removedAbilities.add(ab);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// give replacement effects
|
||||
final List<ReplacementEffect> addedReplacements = new ArrayList<ReplacementEffect>();
|
||||
if (replacements.size() > 0) {
|
||||
@@ -190,19 +198,24 @@ public class AnimateAllEffect extends AnimateEffectBase {
|
||||
|
||||
// suppress triggers from the animated card
|
||||
final List<Trigger> removedTriggers = new ArrayList<Trigger>();
|
||||
if (sa.hasParam("OverwriteTriggers") || sa.hasParam("RemoveAllAbilities")) {
|
||||
if (sa.hasParam("OverwriteTriggers") || removeAll || removeIntrinsic) {
|
||||
final FCollectionView<Trigger> triggersToRemove = c.getTriggers();
|
||||
for (final Trigger trigger : triggersToRemove) {
|
||||
trigger.setSuppressed(true);
|
||||
if (removeIntrinsic && !trigger.isIntrinsic()) {
|
||||
continue;
|
||||
}
|
||||
trigger.setSuppressed(true); // why this not TemporarilySuppressed?
|
||||
removedTriggers.add(trigger);
|
||||
}
|
||||
}
|
||||
|
||||
// suppress static abilities from the animated card
|
||||
final List<StaticAbility> removedStatics = new ArrayList<StaticAbility>();
|
||||
if (sa.hasParam("OverwriteStatics") || sa.hasParam("RemoveAllAbilities")) {
|
||||
final FCollectionView<StaticAbility> staticsToRemove = c.getStaticAbilities();
|
||||
for (final StaticAbility stAb : staticsToRemove) {
|
||||
if (sa.hasParam("OverwriteStatics") || removeAll || removeIntrinsic) {
|
||||
for (final StaticAbility stAb : c.getStaticAbilities()) {
|
||||
if (removeIntrinsic && !stAb.isIntrinsic()) {
|
||||
continue;
|
||||
}
|
||||
stAb.setTemporarilySuppressed(true);
|
||||
removedStatics.add(stAb);
|
||||
}
|
||||
@@ -210,9 +223,11 @@ public class AnimateAllEffect extends AnimateEffectBase {
|
||||
|
||||
// suppress static abilities from the animated card
|
||||
final List<ReplacementEffect> removedReplacements = new ArrayList<ReplacementEffect>();
|
||||
if (sa.hasParam("OverwriteReplacements") || sa.hasParam("RemoveAllAbilities")) {
|
||||
final FCollectionView<ReplacementEffect> replacementsToRemove = c.getReplacementEffects();
|
||||
for (final ReplacementEffect re : replacementsToRemove) {
|
||||
if (sa.hasParam("OverwriteReplacements") || removeAll || removeIntrinsic) {
|
||||
for (final ReplacementEffect re : c.getReplacementEffects()) {
|
||||
if (removeIntrinsic && !re.isIntrinsic()) {
|
||||
continue;
|
||||
}
|
||||
re.setTemporarilySuppressed(true);
|
||||
removedReplacements.add(re);
|
||||
}
|
||||
@@ -234,8 +249,11 @@ public class AnimateAllEffect extends AnimateEffectBase {
|
||||
public void run() {
|
||||
doUnanimate(c, sa, finalDesc, hiddenKeywords,
|
||||
addedAbilities, addedTriggers, addedReplacements,
|
||||
false, removedAbilities, timestamp);
|
||||
ImmutableList.of(), timestamp);
|
||||
|
||||
for (final SpellAbility sa : removedAbilities) {
|
||||
sa.setTemporarilySuppressed(false);
|
||||
}
|
||||
// give back suppressed triggers
|
||||
for (final Trigger t : removedTriggers) {
|
||||
t.setSuppressed(false);
|
||||
|
||||
@@ -18,7 +18,6 @@ import forge.game.spellability.SpellAbility;
|
||||
import forge.game.staticability.StaticAbility;
|
||||
import forge.game.trigger.Trigger;
|
||||
import forge.game.trigger.TriggerHandler;
|
||||
import forge.util.collect.FCollectionView;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -162,21 +161,20 @@ public class AnimateEffect extends AnimateEffectBase {
|
||||
boolean clearAbilities = sa.hasParam("OverwriteAbilities");
|
||||
boolean clearSpells = sa.hasParam("OverwriteSpells");
|
||||
boolean removeAll = sa.hasParam("RemoveAllAbilities");
|
||||
boolean removeIntrinsic = sa.hasParam("RemoveIntrinsicAbilities");
|
||||
|
||||
if (clearAbilities || clearSpells || removeAll) {
|
||||
for (final SpellAbility ab : c.getSpellAbilities()) {
|
||||
if (removeAll || (ab.isAbility() && clearAbilities)
|
||||
if (removeAll
|
||||
|| (ab.isIntrinsic() && removeIntrinsic && !ab.isBasicLandAbility())
|
||||
|| (ab.isAbility() && clearAbilities)
|
||||
|| (ab.isSpell() && clearSpells)) {
|
||||
ab.setTemporarilySuppressed(true);
|
||||
removedAbilities.add(ab);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Can't rmeove SAs in foreach loop that finds them
|
||||
for (final SpellAbility ab : removedAbilities) {
|
||||
c.removeSpellAbility(ab);
|
||||
}
|
||||
|
||||
if (sa.hasParam("RemoveThisAbility") && !removedAbilities.contains(sa)) {
|
||||
c.removeSpellAbility(sa);
|
||||
removedAbilities.add(sa);
|
||||
@@ -215,20 +213,23 @@ public class AnimateEffect extends AnimateEffectBase {
|
||||
|
||||
// suppress triggers from the animated card
|
||||
final List<Trigger> removedTriggers = Lists.newArrayList();
|
||||
if (sa.hasParam("OverwriteTriggers") || removeAll) {
|
||||
final FCollectionView<Trigger> triggersToRemove = c.getTriggers();
|
||||
for (final Trigger trigger : triggersToRemove) {
|
||||
trigger.setSuppressed(true);
|
||||
if (sa.hasParam("OverwriteTriggers") || removeAll || removeIntrinsic) {
|
||||
for (final Trigger trigger : c.getTriggers()) {
|
||||
if (removeIntrinsic && !trigger.isIntrinsic()) {
|
||||
continue;
|
||||
}
|
||||
trigger.setSuppressed(true); // why this not TemporarilySuppressed?
|
||||
removedTriggers.add(trigger);
|
||||
}
|
||||
}
|
||||
|
||||
// give static abilities (should only be used by cards to give
|
||||
// itself a static ability)
|
||||
final List<StaticAbility> addedStaticAbilities = Lists.newArrayList();
|
||||
if (stAbs.size() > 0) {
|
||||
for (final String s : stAbs) {
|
||||
final String actualAbility = source.getSVar(s);
|
||||
c.addStaticAbility(actualAbility);
|
||||
addedStaticAbilities.add(c.addStaticAbility(actualAbility));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,9 +249,11 @@ public class AnimateEffect extends AnimateEffectBase {
|
||||
|
||||
// suppress static abilities from the animated card
|
||||
final List<StaticAbility> removedStatics = Lists.newArrayList();
|
||||
if (sa.hasParam("OverwriteStatics") || removeAll) {
|
||||
final FCollectionView<StaticAbility> staticsToRemove = c.getStaticAbilities();
|
||||
for (final StaticAbility stAb : staticsToRemove) {
|
||||
if (sa.hasParam("OverwriteStatics") || removeAll || removeIntrinsic) {
|
||||
for (final StaticAbility stAb : c.getStaticAbilities()) {
|
||||
if (removeIntrinsic && !stAb.isIntrinsic()) {
|
||||
continue;
|
||||
}
|
||||
stAb.setTemporarilySuppressed(true);
|
||||
removedStatics.add(stAb);
|
||||
}
|
||||
@@ -258,8 +261,11 @@ public class AnimateEffect extends AnimateEffectBase {
|
||||
|
||||
// suppress static abilities from the animated card
|
||||
final List<ReplacementEffect> removedReplacements = Lists.newArrayList();
|
||||
if (sa.hasParam("OverwriteReplacements") || removeAll) {
|
||||
if (sa.hasParam("OverwriteReplacements") || removeAll || removeIntrinsic) {
|
||||
for (final ReplacementEffect re : c.getReplacementEffects()) {
|
||||
if (removeIntrinsic && !re.isIntrinsic()) {
|
||||
continue;
|
||||
}
|
||||
re.setTemporarilySuppressed(true);
|
||||
removedReplacements.add(re);
|
||||
}
|
||||
@@ -272,8 +278,6 @@ public class AnimateEffect extends AnimateEffectBase {
|
||||
}
|
||||
}
|
||||
|
||||
final boolean givesStAbs = (stAbs.size() > 0);
|
||||
|
||||
final GameCommand unanimate = new GameCommand() {
|
||||
private static final long serialVersionUID = -5861759814760561373L;
|
||||
|
||||
@@ -281,9 +285,13 @@ public class AnimateEffect extends AnimateEffectBase {
|
||||
public void run() {
|
||||
doUnanimate(c, sa, finalDesc, hiddenKeywords,
|
||||
addedAbilities, addedTriggers, addedReplacements,
|
||||
givesStAbs, removedAbilities, timestamp);
|
||||
addedStaticAbilities, timestamp);
|
||||
|
||||
game.fireEvent(new GameEventCardStatsChanged(c));
|
||||
|
||||
for (final SpellAbility sa : removedAbilities) {
|
||||
sa.setTemporarilySuppressed(false);
|
||||
}
|
||||
// give back suppressed triggers
|
||||
for (final Trigger t : removedTriggers) {
|
||||
t.setSuppressed(false);
|
||||
|
||||
@@ -24,11 +24,10 @@ import forge.game.replacement.ReplacementEffect;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.staticability.StaticAbility;
|
||||
import forge.game.trigger.Trigger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
||||
void doAnimate(final Card c, final SpellAbility sa, final Integer power, final Integer toughness,
|
||||
public static void doAnimate(final Card c, final SpellAbility sa, final Integer power, final Integer toughness,
|
||||
final CardType addType, final CardType removeType, final String colors,
|
||||
final List<String> keywords, final List<String> removeKeywords,
|
||||
final List<String> hiddenKeywords, final long timestamp) {
|
||||
@@ -36,15 +35,19 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
||||
boolean removeSuperTypes = false;
|
||||
boolean removeCardTypes = false;
|
||||
boolean removeSubTypes = false;
|
||||
boolean removeLandTypes = false;
|
||||
boolean removeCreatureTypes = false;
|
||||
boolean removeArtifactTypes = false;
|
||||
boolean removeEnchantmentTypes = false;
|
||||
|
||||
if (sa.hasParam("OverwriteTypes")) {
|
||||
removeSuperTypes = true;
|
||||
removeCardTypes = true;
|
||||
removeSubTypes = true;
|
||||
removeLandTypes = true;
|
||||
removeCreatureTypes = true;
|
||||
removeArtifactTypes = true;
|
||||
removeEnchantmentTypes = true;
|
||||
}
|
||||
|
||||
if (sa.hasParam("KeepSupertypes")) {
|
||||
@@ -57,6 +60,10 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
||||
|
||||
if (sa.hasParam("KeepSubtypes")) {
|
||||
removeSubTypes = false;
|
||||
removeLandTypes = false;
|
||||
removeCreatureTypes = false;
|
||||
removeArtifactTypes = false;
|
||||
removeEnchantmentTypes = false;
|
||||
}
|
||||
|
||||
if (sa.hasParam("RemoveSuperTypes")) {
|
||||
@@ -71,23 +78,30 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
||||
removeSubTypes = true;
|
||||
}
|
||||
|
||||
if (sa.hasParam("RemoveLandTypes")) {
|
||||
removeCreatureTypes = true;
|
||||
}
|
||||
if (sa.hasParam("RemoveCreatureTypes")) {
|
||||
removeCreatureTypes = true;
|
||||
}
|
||||
|
||||
if (sa.hasParam("RemoveArtifactTypes")) {
|
||||
removeArtifactTypes = true;
|
||||
}
|
||||
if (sa.hasParam("RemoveEnchantmentTypes")) {
|
||||
removeEnchantmentTypes = true;
|
||||
}
|
||||
|
||||
if ((power != null) || (toughness != null)) {
|
||||
c.addNewPT(power, toughness, timestamp);
|
||||
}
|
||||
|
||||
if (!addType.isEmpty() || !removeType.isEmpty() || removeCreatureTypes) {
|
||||
c.addChangedCardTypes(addType, removeType, removeSuperTypes, removeCardTypes, removeSubTypes,
|
||||
removeCreatureTypes, removeArtifactTypes, timestamp);
|
||||
removeLandTypes, removeCreatureTypes, removeArtifactTypes, removeEnchantmentTypes, timestamp);
|
||||
}
|
||||
|
||||
c.addChangedCardKeywords(keywords, removeKeywords, sa.hasParam("RemoveAllAbilities"), timestamp);
|
||||
c.addChangedCardKeywords(keywords, removeKeywords,
|
||||
sa.hasParam("RemoveAllAbilities"), sa.hasParam("RemoveIntrinsicAbilities"), timestamp);
|
||||
|
||||
for (final String k : hiddenKeywords) {
|
||||
c.addHiddenExtrinsicKeyword(k);
|
||||
@@ -114,10 +128,10 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
||||
* @param timestamp
|
||||
* a long.
|
||||
*/
|
||||
void doUnanimate(final Card c, SpellAbility sa, final String colorDesc,
|
||||
static void doUnanimate(final Card c, SpellAbility sa, final String colorDesc,
|
||||
final List<String> hiddenKeywords, final List<SpellAbility> addedAbilities,
|
||||
final List<Trigger> addedTriggers, final List<ReplacementEffect> addedReplacements,
|
||||
final boolean givesStAbs, final List<SpellAbility> removedAbilities, final long timestamp) {
|
||||
final List<StaticAbility> addedStaticAbilities, final long timestamp) {
|
||||
|
||||
if (sa.hasParam("LastsIndefinitely")) {
|
||||
return;
|
||||
@@ -127,16 +141,7 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
||||
|
||||
c.removeChangedCardKeywords(timestamp);
|
||||
|
||||
// remove all static abilities
|
||||
if (givesStAbs) {
|
||||
c.setStaticAbilities(new ArrayList<StaticAbility>());
|
||||
}
|
||||
|
||||
if (sa.hasParam("Types") || sa.hasParam("RemoveTypes")
|
||||
|| sa.hasParam("RemoveCreatureTypes") || sa.hasParam("RemoveArtifactTypes")) {
|
||||
c.removeChangedCardTypes(timestamp);
|
||||
}
|
||||
|
||||
c.removeColor(timestamp);
|
||||
|
||||
for (final String k : hiddenKeywords) {
|
||||
@@ -147,10 +152,6 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
||||
c.removeSpellAbility(saAdd);
|
||||
}
|
||||
|
||||
for (final SpellAbility saRem : removedAbilities) {
|
||||
c.addSpellAbility(saRem);
|
||||
}
|
||||
|
||||
for (final Trigger t : addedTriggers) {
|
||||
c.removeTrigger(t);
|
||||
}
|
||||
@@ -159,6 +160,10 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
|
||||
c.removeReplacementEffect(rep);
|
||||
}
|
||||
|
||||
for (final StaticAbility stAb : addedStaticAbilities) {
|
||||
c.removeStaticAbility(stAb);
|
||||
}
|
||||
|
||||
// any other unanimate cleanup
|
||||
if (!c.isCreature()) {
|
||||
c.unEquipAllCards();
|
||||
|
||||
@@ -350,7 +350,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
|
||||
copyInPlay.setCloneOrigin(host);
|
||||
sa.getHostCard().addClone(copyInPlay);
|
||||
if (!pumpKeywords.isEmpty()) {
|
||||
copyInPlay.addChangedCardKeywords(pumpKeywords, Lists.<String>newArrayList(), false, timestamp);
|
||||
copyInPlay.addChangedCardKeywords(pumpKeywords, Lists.<String>newArrayList(), false, false, timestamp);
|
||||
}
|
||||
crds.add(copyInPlay);
|
||||
if (sa.hasParam("RememberCopied")) {
|
||||
|
||||
@@ -137,7 +137,7 @@ public class DebuffEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
removedKW.addAll(kws);
|
||||
tgtC.addChangedCardKeywords(addedKW, removedKW, false, timestamp);
|
||||
tgtC.addChangedCardKeywords(addedKW, removedKW, false, false, timestamp);
|
||||
}
|
||||
if (!sa.hasParam("Permanent")) {
|
||||
game.getEndOfTurn().addUntil(new GameCommand() {
|
||||
|
||||
@@ -90,7 +90,7 @@ public class ProtectAllEffect extends SpellAbilityEffect {
|
||||
|
||||
for (final Card tgtC : list) {
|
||||
if (tgtC.isInPlay()) {
|
||||
tgtC.addChangedCardKeywords(gainsKWList, ImmutableList.<String>of(), false, timestamp, true);
|
||||
tgtC.addChangedCardKeywords(gainsKWList, null, false, false, timestamp, true);
|
||||
|
||||
if (!sa.hasParam("Permanent")) {
|
||||
// If not Permanent, remove protection at EOT
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package forge.game.ability.effects;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
import forge.GameCommand;
|
||||
import forge.card.MagicColor;
|
||||
@@ -153,7 +152,7 @@ public class ProtectEffect extends SpellAbilityEffect {
|
||||
continue;
|
||||
}
|
||||
|
||||
tgtC.addChangedCardKeywords(gainsKWList, ImmutableList.<String>of(), false, timestamp, true);
|
||||
tgtC.addChangedCardKeywords(gainsKWList, null, false, false, timestamp, true);
|
||||
|
||||
if (!sa.hasParam("Permanent")) {
|
||||
// If not Permanent, remove protection at EOT
|
||||
@@ -181,7 +180,7 @@ public class ProtectEffect extends SpellAbilityEffect {
|
||||
continue;
|
||||
}
|
||||
|
||||
unTgtC.addChangedCardKeywords(gainsKWList, ImmutableList.<String>of(), false, timestamp, true);
|
||||
unTgtC.addChangedCardKeywords(gainsKWList, null, false, false, timestamp, true);
|
||||
|
||||
if (!sa.hasParam("Permanent")) {
|
||||
// If not Permanent, remove protection at EOT
|
||||
|
||||
@@ -13,10 +13,11 @@ import forge.game.spellability.SpellAbility;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.TextUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public class PumpAllEffect extends SpellAbilityEffect {
|
||||
private static void applyPumpAll(final SpellAbility sa,
|
||||
final List<Card> list, final int a, final int d,
|
||||
@@ -24,23 +25,18 @@ public class PumpAllEffect extends SpellAbilityEffect {
|
||||
|
||||
final Game game = sa.getActivatingPlayer().getGame();
|
||||
final long timestamp = game.getNextTimestamp();
|
||||
final List<String> kws = new ArrayList<String>();
|
||||
final List<String> hiddenkws = new ArrayList<String>();
|
||||
boolean suspend = false;
|
||||
final List<String> kws = Lists.newArrayList();
|
||||
final List<String> hiddenkws = Lists.newArrayList();
|
||||
|
||||
for (String kw : keywords) {
|
||||
if (kw.startsWith("HIDDEN")) {
|
||||
hiddenkws.add(kw);
|
||||
} else {
|
||||
kws.add(kw);
|
||||
if (kw.equals("Suspend")) {
|
||||
suspend = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (final Card tgtC : list) {
|
||||
|
||||
// only pump things in the affected zones.
|
||||
boolean found = false;
|
||||
for (final ZoneType z : affectedZones) {
|
||||
@@ -55,7 +51,7 @@ public class PumpAllEffect extends SpellAbilityEffect {
|
||||
|
||||
tgtC.addTempPowerBoost(a);
|
||||
tgtC.addTempToughnessBoost(d);
|
||||
tgtC.addChangedCardKeywords(kws, new ArrayList<String>(), false, timestamp);
|
||||
tgtC.addChangedCardKeywords(kws, null, false, false, timestamp);
|
||||
|
||||
for (String kw : hiddenkws) {
|
||||
tgtC.addHiddenExtrinsicKeyword(kw);
|
||||
@@ -118,13 +114,11 @@ public class PumpAllEffect extends SpellAbilityEffect {
|
||||
@Override
|
||||
public void resolve(final SpellAbility sa) {
|
||||
final List<Player> tgtPlayers = getTargetPlayers(sa);
|
||||
final List<ZoneType> affectedZones = new ArrayList<ZoneType>();
|
||||
final List<ZoneType> affectedZones = Lists.newArrayList();
|
||||
final Game game = sa.getActivatingPlayer().getGame();
|
||||
|
||||
if (sa.hasParam("PumpZone")) {
|
||||
for (final String zone : sa.getParam("PumpZone").split(",")) {
|
||||
affectedZones.add(ZoneType.valueOf(zone));
|
||||
}
|
||||
affectedZones.addAll(ZoneType.listValueOf(sa.getParam("PumpZone")));
|
||||
} else {
|
||||
affectedZones.add(ZoneType.Battlefield);
|
||||
}
|
||||
@@ -149,7 +143,10 @@ public class PumpAllEffect extends SpellAbilityEffect {
|
||||
|
||||
list = (CardCollection)AbilityUtils.filterListByType(list, valid, sa);
|
||||
|
||||
List<String> keywords = sa.hasParam("KW") ? Arrays.asList(sa.getParam("KW").split(" & ")) : new ArrayList<String>();
|
||||
List<String> keywords = Lists.newArrayList();
|
||||
if (sa.hasParam("KW")) {
|
||||
keywords.addAll(Arrays.asList(sa.getParam("KW").split(" & ")));
|
||||
}
|
||||
final int a = AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("NumAtt"), sa, true);
|
||||
final int d = AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("NumDef"), sa, true);
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ public class PumpEffect extends SpellAbilityEffect {
|
||||
|
||||
applyTo.addTempPowerBoost(a);
|
||||
applyTo.addTempToughnessBoost(d);
|
||||
applyTo.addChangedCardKeywords(kws, Lists.<String>newArrayList(), false, timestamp);
|
||||
applyTo.addChangedCardKeywords(kws, Lists.<String>newArrayList(), false, false, timestamp);
|
||||
if (redrawPT) { applyTo.updatePowerToughnessForView(); }
|
||||
|
||||
if (sa.hasParam("LeaveBattlefield")) {
|
||||
@@ -251,7 +251,7 @@ public class PumpEffect extends SpellAbilityEffect {
|
||||
final String landtype = sa.getParam("DefinedLandwalk");
|
||||
final Card c = AbilityUtils.getDefinedCards(host, landtype, sa).get(0);
|
||||
for (String type : c.getType()) {
|
||||
if (CardType.isALandType(type) || CardType.isABasicLandType(type)) {
|
||||
if (CardType.isALandType(type)) {
|
||||
keywords.add(type + "walk");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
// changes by AF animate and continuous static effects - timestamp is the key of maps
|
||||
private final Map<Long, CardChangedType> changedCardTypes = Maps.newTreeMap();
|
||||
private final Map<Long, KeywordsChange> changedCardKeywords = Maps.newTreeMap();
|
||||
private final SortedMap<Long, CardColor> changedCardColors = Maps.newTreeMap();
|
||||
private final Map<Long, CardColor> changedCardColors = Maps.newTreeMap();
|
||||
|
||||
// changes that say "replace each instance of one [color,type] by another - timestamp is the key of maps
|
||||
private final CardChangedWords changedTextColors = new CardChangedWords();
|
||||
@@ -2776,17 +2776,22 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
|
||||
public final void addChangedCardTypes(final CardType addType, final CardType removeType,
|
||||
final boolean removeSuperTypes, final boolean removeCardTypes, final boolean removeSubTypes,
|
||||
final boolean removeCreatureTypes, final boolean removeArtifactTypes, final long timestamp) {
|
||||
addChangedCardTypes(addType, removeType, removeSuperTypes, removeCardTypes, removeSubTypes, removeCreatureTypes, removeArtifactTypes, timestamp, true);
|
||||
final boolean removeLandTypes, final boolean removeCreatureTypes, final boolean removeArtifactTypes,
|
||||
final boolean removeEnchantmentTypes,
|
||||
final long timestamp) {
|
||||
addChangedCardTypes(addType, removeType, removeSuperTypes, removeCardTypes, removeSubTypes, removeLandTypes,
|
||||
removeCreatureTypes, removeArtifactTypes, removeEnchantmentTypes, timestamp, true);
|
||||
}
|
||||
|
||||
public final void addChangedCardTypes(final CardType addType, final CardType removeType,
|
||||
final boolean removeSuperTypes, final boolean removeCardTypes, final boolean removeSubTypes,
|
||||
final boolean removeCreatureTypes, final boolean removeArtifactTypes, final long timestamp, final boolean updateView) {
|
||||
final boolean removeLandTypes, final boolean removeCreatureTypes, final boolean removeArtifactTypes,
|
||||
final boolean removeEnchantmentTypes,
|
||||
final long timestamp, final boolean updateView) {
|
||||
|
||||
changedCardTypes.put(timestamp, new CardChangedType(
|
||||
addType, removeType, removeSuperTypes, removeCardTypes, removeSubTypes,
|
||||
removeCreatureTypes, removeArtifactTypes));
|
||||
removeLandTypes, removeCreatureTypes, removeArtifactTypes, removeEnchantmentTypes));
|
||||
if (updateView) {
|
||||
currentState.getView().updateType(currentState);
|
||||
}
|
||||
@@ -2794,13 +2799,19 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
|
||||
public final void addChangedCardTypes(final String[] types, final String[] removeTypes,
|
||||
final boolean removeSuperTypes, final boolean removeCardTypes, final boolean removeSubTypes,
|
||||
final boolean removeCreatureTypes, final boolean removeArtifactTypes, final long timestamp) {
|
||||
addChangedCardTypes(types, removeTypes, removeSuperTypes, removeCardTypes, removeSubTypes, removeCreatureTypes, removeArtifactTypes, timestamp, true);
|
||||
final boolean removeLandTypes, final boolean removeCreatureTypes, final boolean removeArtifactTypes,
|
||||
final boolean removeEnchantmentTypes,
|
||||
final long timestamp) {
|
||||
addChangedCardTypes(types, removeTypes, removeSuperTypes, removeCardTypes, removeSubTypes,
|
||||
removeLandTypes, removeCreatureTypes, removeArtifactTypes, removeEnchantmentTypes,
|
||||
timestamp, true);
|
||||
}
|
||||
|
||||
public final void addChangedCardTypes(final String[] types, final String[] removeTypes,
|
||||
final boolean removeSuperTypes, final boolean removeCardTypes, final boolean removeSubTypes,
|
||||
final boolean removeCreatureTypes, final boolean removeArtifactTypes, final long timestamp, final boolean updateView) {
|
||||
final boolean removeLandTypes, final boolean removeCreatureTypes, final boolean removeArtifactTypes,
|
||||
final boolean removeEnchantmentTypes,
|
||||
final long timestamp, final boolean updateView) {
|
||||
CardType addType = null;
|
||||
CardType removeType = null;
|
||||
if (types != null) {
|
||||
@@ -2812,7 +2823,8 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
}
|
||||
|
||||
addChangedCardTypes(addType, removeType, removeSuperTypes, removeCardTypes, removeSubTypes,
|
||||
removeCreatureTypes, removeArtifactTypes, timestamp, updateView);
|
||||
removeLandTypes, removeCreatureTypes, removeArtifactTypes, removeEnchantmentTypes,
|
||||
timestamp, updateView);
|
||||
}
|
||||
|
||||
public final void removeChangedCardTypes(final long timestamp) {
|
||||
@@ -3272,23 +3284,25 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
}
|
||||
|
||||
public final void addChangedCardKeywords(final List<String> keywords, final List<String> removeKeywords,
|
||||
final boolean removeAllKeywords, final long timestamp) {
|
||||
addChangedCardKeywords(keywords, removeKeywords, removeAllKeywords, timestamp, true);
|
||||
final boolean removeAllKeywords, final boolean removeIntrinsicKeywords, final long timestamp) {
|
||||
addChangedCardKeywords(keywords, removeKeywords, removeAllKeywords, removeIntrinsicKeywords, timestamp, true);
|
||||
}
|
||||
|
||||
|
||||
public final void addChangedCardKeywords(final List<String> keywords, final List<String> removeKeywords,
|
||||
final boolean removeAllKeywords, final long timestamp, final boolean updateView) {
|
||||
final boolean removeAllKeywords, final boolean removeIntrinsicKeywords, final long timestamp, final boolean updateView) {
|
||||
keywords.removeAll(getCantHaveOrGainKeyword());
|
||||
// if the key already exists - merge entries
|
||||
final KeywordsChange cks = changedCardKeywords.get(timestamp);
|
||||
if (cks != null) {
|
||||
final KeywordsChange newCks = cks.merge(keywords, removeKeywords, removeAllKeywords);
|
||||
final KeywordsChange newCks = cks.merge(keywords, removeKeywords,
|
||||
removeAllKeywords, removeIntrinsicKeywords);
|
||||
newCks.addKeywordsToCard(this);
|
||||
changedCardKeywords.put(timestamp, newCks);
|
||||
}
|
||||
else {
|
||||
final KeywordsChange newCks = new KeywordsChange(keywords, removeKeywords, removeAllKeywords);
|
||||
final KeywordsChange newCks = new KeywordsChange(keywords, removeKeywords,
|
||||
removeAllKeywords, removeIntrinsicKeywords);
|
||||
newCks.addKeywordsToCard(this);
|
||||
changedCardKeywords.put(timestamp, newCks);
|
||||
}
|
||||
@@ -3298,20 +3312,24 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
}
|
||||
}
|
||||
|
||||
public final void addChangedCardKeywordsInternal(final List<KeywordInterface> keywords, final List<KeywordInterface> removeKeywords,
|
||||
final boolean removeAllKeywords, final long timestamp, final boolean updateView) {
|
||||
public final void addChangedCardKeywordsInternal(
|
||||
final List<KeywordInterface> keywords, final List<KeywordInterface> removeKeywords,
|
||||
final boolean removeAllKeywords, final boolean removeIntrinsicKeywords,
|
||||
final long timestamp, final boolean updateView) {
|
||||
KeywordCollection list = new KeywordCollection();
|
||||
list.insertAll(keywords);
|
||||
list.removeAll(getCantHaveOrGainKeyword());
|
||||
// if the key already exists - merge entries
|
||||
final KeywordsChange cks = changedCardKeywords.get(timestamp);
|
||||
if (cks != null) {
|
||||
final KeywordsChange newCks = cks.merge(keywords, removeKeywords, removeAllKeywords);
|
||||
final KeywordsChange newCks = cks.merge(keywords, removeKeywords,
|
||||
removeAllKeywords, removeIntrinsicKeywords);
|
||||
newCks.addKeywordsToCard(this);
|
||||
changedCardKeywords.put(timestamp, newCks);
|
||||
}
|
||||
else {
|
||||
final KeywordsChange newCks = new KeywordsChange(keywords, removeKeywords, removeAllKeywords);
|
||||
final KeywordsChange newCks = new KeywordsChange(keywords, removeKeywords,
|
||||
removeAllKeywords, removeIntrinsicKeywords);
|
||||
newCks.addKeywordsToCard(this);
|
||||
changedCardKeywords.put(timestamp, newCks);
|
||||
}
|
||||
@@ -3322,7 +3340,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
}
|
||||
|
||||
public final void addChangedCardKeywords(final String[] keywords, final String[] removeKeywords,
|
||||
final boolean removeAllKeywords, final long timestamp) {
|
||||
final boolean removeAllKeywords, final boolean removeIntrinsicKeywords, final long timestamp) {
|
||||
List<String> keywordsList = Lists.newArrayList();
|
||||
List<String> removeKeywordsList = Lists.newArrayList();
|
||||
if (keywords != null) {
|
||||
@@ -3333,7 +3351,8 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
removeKeywordsList = Lists.newArrayList(Arrays.asList(removeKeywords));
|
||||
}
|
||||
|
||||
addChangedCardKeywords(keywordsList, removeKeywordsList, removeAllKeywords, timestamp);
|
||||
addChangedCardKeywords(keywordsList, removeKeywordsList,
|
||||
removeAllKeywords, removeIntrinsicKeywords, timestamp);
|
||||
}
|
||||
|
||||
public final KeywordsChange removeChangedCardKeywords(final long timestamp) {
|
||||
@@ -3360,8 +3379,17 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
KeywordCollection keywords = new KeywordCollection();
|
||||
|
||||
//final List<KeywordInterface> keywords = Lists.newArrayList();
|
||||
boolean removeIntrinsic = false;
|
||||
for (final KeywordsChange ck : changedCardKeywords.values()) {
|
||||
if (ck.isRemoveIntrinsicKeywords()) {
|
||||
removeIntrinsic = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!removeIntrinsic) {
|
||||
keywords.insertAll(state.getIntrinsicKeywords());
|
||||
}
|
||||
keywords.insertAll(extrinsicKeyword.getValues());
|
||||
|
||||
// see if keyword changes are in effect
|
||||
@@ -3435,7 +3463,8 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
public final void addChangedTextTypeWord(final String originalWord, final String newWord, final Long timestamp) {
|
||||
changedTextTypes.add(timestamp, originalWord, newWord);
|
||||
if (getType().hasSubtype(originalWord)) {
|
||||
addChangedCardTypes(CardType.parse(newWord), CardType.parse(originalWord), false, false, false, false, false, timestamp);
|
||||
addChangedCardTypes(CardType.parse(newWord), CardType.parse(originalWord),
|
||||
false, false, false, false, false, false, false, timestamp);
|
||||
}
|
||||
updateKeywordsChangedText(timestamp);
|
||||
updateChangedText();
|
||||
@@ -3474,7 +3503,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
keywordsGrantedByTextChanges.add(newKw);
|
||||
}
|
||||
}
|
||||
addChangedCardKeywordsInternal(addKeywords, removeKeywords, false, timestamp, true);
|
||||
addChangedCardKeywordsInternal(addKeywords, removeKeywords, false, false, timestamp, true);
|
||||
}
|
||||
|
||||
private void updateKeywordsOnRemoveChangedText(final KeywordsChange k) {
|
||||
@@ -4738,8 +4767,10 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
public final void animateBestow(final boolean updateView) {
|
||||
bestowTimestamp = getGame().getNextTimestamp();
|
||||
addChangedCardTypes(new CardType(Collections.singletonList("Aura")),
|
||||
new CardType(Collections.singletonList("Creature")), false, false, false, false, true, bestowTimestamp, updateView);
|
||||
addChangedCardKeywords(Collections.singletonList("Enchant creature"), Lists.<String>newArrayList(), false, bestowTimestamp, updateView);
|
||||
new CardType(Collections.singletonList("Creature")),
|
||||
false, false, false, false, false, false, true, bestowTimestamp, updateView);
|
||||
addChangedCardKeywords(Collections.singletonList("Enchant creature"), Lists.<String>newArrayList(),
|
||||
false, false, bestowTimestamp, updateView);
|
||||
}
|
||||
|
||||
public final void unanimateBestow() {
|
||||
|
||||
@@ -79,6 +79,7 @@ public class CardFactoryUtil {
|
||||
" | SpellDescription$ Add {" + strcolor + "}.";
|
||||
SpellAbility sa = AbilityFactory.getAbility(abString, state);
|
||||
sa.setIntrinsic(true); // always intristic
|
||||
sa.setBasicLandAbility(true); // to exclude it from other suspress effects
|
||||
return sa;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ public class KeywordsChange {
|
||||
private final List<KeywordInterface> removeKeywordInterfaces = Lists.newArrayList();
|
||||
private final List<String> removeKeywords = Lists.newArrayList();
|
||||
private boolean removeAllKeywords;
|
||||
private boolean removeIntrinsicKeywords;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -49,7 +50,8 @@ public class KeywordsChange {
|
||||
public KeywordsChange(
|
||||
final Iterable<String> keywordList,
|
||||
final Collection<String> removeKeywordList,
|
||||
final boolean removeAll) {
|
||||
final boolean removeAll,
|
||||
final boolean removeIntrinsic) {
|
||||
if (keywordList != null) {
|
||||
this.keywords.addAll(keywordList);
|
||||
}
|
||||
@@ -59,12 +61,14 @@ public class KeywordsChange {
|
||||
}
|
||||
|
||||
this.removeAllKeywords = removeAll;
|
||||
this.removeIntrinsicKeywords = removeIntrinsic;
|
||||
}
|
||||
|
||||
public KeywordsChange(
|
||||
final Collection<KeywordInterface> keywordList,
|
||||
final Collection<KeywordInterface> removeKeywordInterfaces,
|
||||
final boolean removeAll) {
|
||||
final boolean removeAll,
|
||||
final boolean removeIntrinsic) {
|
||||
if (keywordList != null) {
|
||||
this.keywords.insertAll(keywordList);
|
||||
}
|
||||
@@ -74,6 +78,7 @@ public class KeywordsChange {
|
||||
}
|
||||
|
||||
this.removeAllKeywords = removeAll;
|
||||
this.removeIntrinsicKeywords = removeIntrinsic;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,6 +114,10 @@ public class KeywordsChange {
|
||||
return this.removeAllKeywords;
|
||||
}
|
||||
|
||||
public final boolean isRemoveIntrinsicKeywords() {
|
||||
return this.removeIntrinsicKeywords;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether this KeywordsChange doesn't have any effect.
|
||||
*/
|
||||
@@ -135,8 +144,9 @@ public class KeywordsChange {
|
||||
public final KeywordsChange merge(
|
||||
final Collection<KeywordInterface> keywordList,
|
||||
final Collection<KeywordInterface> removeKeywordList,
|
||||
final boolean removeAll) {
|
||||
KeywordsChange result = new KeywordsChange(keywordList, removeKeywordList, removeAll);
|
||||
final boolean removeAll,
|
||||
final boolean removeIntrinsic) {
|
||||
KeywordsChange result = new KeywordsChange(keywordList, removeKeywordList, removeAll, removeIntrinsic);
|
||||
result.__merge(this);
|
||||
return result;
|
||||
}
|
||||
@@ -144,8 +154,9 @@ public class KeywordsChange {
|
||||
public final KeywordsChange merge(
|
||||
final Iterable<String> keywordList,
|
||||
final Collection<String> removeKeywordList,
|
||||
final boolean removeAll) {
|
||||
KeywordsChange result = new KeywordsChange(keywordList, removeKeywordList, removeAll);
|
||||
final boolean removeAll,
|
||||
final boolean removeIntrinsic) {
|
||||
KeywordsChange result = new KeywordsChange(keywordList, removeKeywordList, removeAll, removeIntrinsic);
|
||||
result.__merge(this);
|
||||
return result;
|
||||
}
|
||||
@@ -157,5 +168,8 @@ public class KeywordsChange {
|
||||
if (other.removeAllKeywords) {
|
||||
removeAllKeywords = true;
|
||||
}
|
||||
if (other.removeIntrinsicKeywords) {
|
||||
removeIntrinsicKeywords = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ public class ManaPool implements Iterable<Mana> {
|
||||
&& host.getType().hasStringType(mana.getManaAbility().getAddsKeywordsType())) {
|
||||
final long timestamp = sa.getHostCard().getGame().getNextTimestamp();
|
||||
final List<String> kws = Arrays.asList(mana.getAddedKeywords().split(" & "));
|
||||
host.addChangedCardKeywords(kws, new ArrayList<String>(), false, timestamp);
|
||||
host.addChangedCardKeywords(kws, null, false, false, timestamp);
|
||||
if (mana.addsKeywordsUntil()) {
|
||||
final GameCommand untilEOT = new GameCommand() {
|
||||
private static final long serialVersionUID = -8285169579025607693L;
|
||||
|
||||
@@ -986,12 +986,13 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
final KeywordsChange cks = changedKeywords.get(timestamp);
|
||||
|
||||
;
|
||||
changedKeywords.put(timestamp, cks.merge(addKeywords, removeKeywords, cks.isRemoveAllKeywords()));
|
||||
changedKeywords.put(timestamp, cks.merge(addKeywords, removeKeywords,
|
||||
cks.isRemoveAllKeywords(), cks.isRemoveIntrinsicKeywords()));
|
||||
updateKeywords();
|
||||
return;
|
||||
}
|
||||
|
||||
changedKeywords.put(timestamp, new KeywordsChange(addKeywords, removeKeywords, false));
|
||||
changedKeywords.put(timestamp, new KeywordsChange(addKeywords, removeKeywords, false, false));
|
||||
updateKeywords();
|
||||
game.fireEvent(new GameEventPlayerStatsChanged(this));
|
||||
}
|
||||
|
||||
@@ -106,6 +106,8 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
private boolean blessing = false;
|
||||
private Integer chapter = null;
|
||||
|
||||
private boolean basicLandAbility = false;
|
||||
|
||||
private SplitSide splitSide = null;
|
||||
enum SplitSide { LEFT, RIGHT };
|
||||
private int totalManaSpent = 0;
|
||||
@@ -754,6 +756,13 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
return flashBackAbility;
|
||||
}
|
||||
|
||||
public void setBasicLandAbility(final boolean basicLandAbility0) {
|
||||
basicLandAbility = basicLandAbility0;
|
||||
}
|
||||
public boolean isBasicLandAbility() {
|
||||
return basicLandAbility && isIntrinsic();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the aftermath
|
||||
*/
|
||||
|
||||
@@ -126,7 +126,9 @@ public class StaticAbility extends CardTraitBase implements Comparable<StaticAbi
|
||||
|
||||
if (hasParam("AddType") || hasParam("RemoveType")
|
||||
|| hasParam("RemoveCardTypes") || hasParam("RemoveSubTypes")
|
||||
|| hasParam("RemoveSuperTypes") || hasParam("RemoveCreatureTypes")) {
|
||||
|| hasParam("RemoveSuperTypes") || hasParam("RemoveLandTypes")
|
||||
|| hasParam("RemoveCreatureTypes") || hasParam("RemoveArtifactTypes")
|
||||
|| hasParam("RemoveEnchantmentTypes")) {
|
||||
layers.add(StaticAbilityLayer.TYPE);
|
||||
}
|
||||
|
||||
|
||||
@@ -126,12 +126,15 @@ public final class StaticAbilityContinuous {
|
||||
String[] addStatics = null;
|
||||
List<SpellAbility> addFullAbs = null;
|
||||
boolean removeAllAbilities = false;
|
||||
boolean removeIntrinsicAbilities = false;
|
||||
boolean removeNonMana = false;
|
||||
boolean removeSuperTypes = false;
|
||||
boolean removeCardTypes = false;
|
||||
boolean removeSubTypes = false;
|
||||
boolean removeLandTypes = false;
|
||||
boolean removeCreatureTypes = false;
|
||||
boolean removeArtifactTypes = false;
|
||||
boolean removeEnchantmentTypes = false;
|
||||
|
||||
List<Player> mayLookAt = null;
|
||||
List<Player> withFlash = null;
|
||||
@@ -253,6 +256,11 @@ public final class StaticAbilityContinuous {
|
||||
removeNonMana = true;
|
||||
}
|
||||
}
|
||||
// do this in type layer too in case of blood moon
|
||||
if ((layer == StaticAbilityLayer.ABILITIES1 || layer == StaticAbilityLayer.TYPE)
|
||||
&& params.containsKey("RemoveIntrinsicAbilities")) {
|
||||
removeIntrinsicAbilities = true;
|
||||
}
|
||||
|
||||
if (layer == StaticAbilityLayer.ABILITIES2 && params.containsKey("AddAbility")) {
|
||||
final String[] sVars = params.get("AddAbility").split(" & ");
|
||||
@@ -310,12 +318,18 @@ public final class StaticAbilityContinuous {
|
||||
removeSubTypes = true;
|
||||
}
|
||||
|
||||
if (params.containsKey("RemoveLandTypes")) {
|
||||
removeLandTypes = true;
|
||||
}
|
||||
if (params.containsKey("RemoveCreatureTypes")) {
|
||||
removeCreatureTypes = true;
|
||||
}
|
||||
if (params.containsKey("RemoveArtifactTypes")) {
|
||||
removeArtifactTypes = true;
|
||||
}
|
||||
if (params.containsKey("RemoveEnchantmentTypes")) {
|
||||
removeEnchantmentTypes = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (layer == StaticAbilityLayer.COLOR) {
|
||||
@@ -604,7 +618,7 @@ public final class StaticAbilityContinuous {
|
||||
// add keywords
|
||||
// TODO regular keywords currently don't try to use keyword multiplier
|
||||
// (Although nothing uses it at this time)
|
||||
if ((addKeywords != null) || (removeKeywords != null) || removeAllAbilities) {
|
||||
if ((addKeywords != null) || (removeKeywords != null) || removeAllAbilities || removeIntrinsicAbilities) {
|
||||
String[] newKeywords = null;
|
||||
if (addKeywords != null) {
|
||||
newKeywords = Arrays.copyOf(addKeywords, addKeywords.length);
|
||||
@@ -622,7 +636,8 @@ public final class StaticAbilityContinuous {
|
||||
}
|
||||
}
|
||||
|
||||
affectedCard.addChangedCardKeywords(newKeywords, removeKeywords, removeAllAbilities,
|
||||
affectedCard.addChangedCardKeywords(newKeywords, removeKeywords,
|
||||
removeAllAbilities, removeIntrinsicAbilities,
|
||||
hostCard.getTimestamp());
|
||||
}
|
||||
|
||||
@@ -686,7 +701,8 @@ public final class StaticAbilityContinuous {
|
||||
// add Types
|
||||
if ((addTypes != null) || (removeTypes != null)) {
|
||||
affectedCard.addChangedCardTypes(addTypes, removeTypes, removeSuperTypes, removeCardTypes,
|
||||
removeSubTypes, removeCreatureTypes, removeArtifactTypes, hostCard.getTimestamp());
|
||||
removeSubTypes, removeLandTypes, removeCreatureTypes, removeArtifactTypes,
|
||||
removeEnchantmentTypes, hostCard.getTimestamp());
|
||||
}
|
||||
|
||||
// add colors
|
||||
@@ -731,30 +747,43 @@ public final class StaticAbilityContinuous {
|
||||
}
|
||||
|
||||
// remove triggers
|
||||
if ((layer == StaticAbilityLayer.ABILITIES2 && (params.containsKey("RemoveTriggers")) || removeAllAbilities)) {
|
||||
if ((layer == StaticAbilityLayer.ABILITIES2 && (params.containsKey("RemoveTriggers"))
|
||||
|| removeAllAbilities || removeIntrinsicAbilities)) {
|
||||
for (final Trigger trigger : affectedCard.getTriggers()) {
|
||||
if (removeAllAbilities || (removeIntrinsicAbilities && trigger.isIntrinsic())) {
|
||||
trigger.setTemporarilySuppressed(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove activated and static abilities
|
||||
if (removeAllAbilities) {
|
||||
if (removeAllAbilities || removeIntrinsicAbilities) {
|
||||
if (removeNonMana) { // Blood Sun
|
||||
for (final SpellAbility mana : affectedCard.getNonManaAbilities()) {
|
||||
if (removeAllAbilities
|
||||
|| (removeIntrinsicAbilities && mana.isIntrinsic() && !mana.isBasicLandAbility())) {
|
||||
mana.setTemporarilySuppressed(true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (final SpellAbility ab : affectedCard.getSpellAbilities()) {
|
||||
if (removeAllAbilities
|
||||
|| (removeIntrinsicAbilities && ab.isIntrinsic() && !ab.isBasicLandAbility())) {
|
||||
ab.setTemporarilySuppressed(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (final StaticAbility stA : affectedCard.getStaticAbilities()) {
|
||||
if (removeAllAbilities || (removeIntrinsicAbilities && stA.isIntrinsic())) {
|
||||
stA.setTemporarilySuppressed(true);
|
||||
}
|
||||
}
|
||||
for (final ReplacementEffect rE : affectedCard.getReplacementEffects()) {
|
||||
if (removeAllAbilities || (removeIntrinsicAbilities && rE.isIntrinsic())) {
|
||||
rE.setTemporarilySuppressed(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mayLookAt != null) {
|
||||
for (Player p : mayLookAt) {
|
||||
|
||||
Reference in New Issue
Block a user