From c1da970c47db0e86d747679a301711a2792f17fe Mon Sep 17 00:00:00 2001 From: Hanmac Date: Wed, 16 May 2018 21:32:41 +0200 Subject: [PATCH] Card: move Abilities to Card and only create them once --- .../main/java/forge/ai/ComputerUtilCost.java | 1 - .../src/main/java/forge/game/GameAction.java | 10 ++-- .../main/java/forge/game/GameActionUtil.java | 52 ------------------- .../src/main/java/forge/game/card/Card.java | 44 +++++++++++----- .../java/forge/game/card/CardFactoryUtil.java | 9 ++++ .../forge/game/spellability/SpellAbility.java | 10 ---- .../StaticAbilityContinuous.java | 2 - 7 files changed, 46 insertions(+), 82 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java index 104e4843ff0..77ff6849087 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java @@ -608,7 +608,6 @@ public class ComputerUtilCost { Set colorsAvailable = Sets.newHashSet(); if (additionalLands != null) { - GameActionUtil.grantBasicLandsManaAbilities(additionalLands); cardsToConsider.addAll(additionalLands); } diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 58d99a2658a..70645eaf92a 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -848,9 +848,6 @@ public class GameAction { } } - final CardCollection lands = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.LANDS); - GameActionUtil.grantBasicLandsManaAbilities(lands); - for (final Card c : staticList) { for (int i = 0; i < c.getStaticCommandList().size(); i++) { final Object[] staticCheck = c.getStaticCommandList().get(i); @@ -896,13 +893,16 @@ public class GameAction { } } - final Map runParams = Maps.newHashMap(); - game.getTriggerHandler().runTrigger(TriggerType.Always, runParams, false); + if (runEvents) { + final Map runParams = Maps.newHashMap(); + game.getTriggerHandler().runTrigger(TriggerType.Always, runParams, false); + } // Update P/T and type in the view only once after all the cards have been processed, to avoid flickering for (Card c : affectedCards) { c.updatePowerToughnessForView(); c.updateTypesForView(); + c.updateAbilityTextForView(); // only update keywords and text for view to avoid flickering } if (runEvents && !affectedCards.isEmpty()) { diff --git a/forge-game/src/main/java/forge/game/GameActionUtil.java b/forge-game/src/main/java/forge/game/GameActionUtil.java index 5eea36a7da2..ee4f4fd7f79 100644 --- a/forge-game/src/main/java/forge/game/GameActionUtil.java +++ b/forge-game/src/main/java/forge/game/GameActionUtil.java @@ -22,10 +22,7 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Sets; -import forge.card.MagicColor; import forge.card.mana.ManaCostParser; -import forge.game.ability.AbilityFactory; -import forge.game.ability.AbilityFactory.AbilityRecordType; import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; import forge.game.card.*; @@ -40,7 +37,6 @@ import forge.util.TextUtil; import org.apache.commons.lang3.StringUtils; import java.util.List; -import java.util.Map; /** @@ -52,59 +48,11 @@ import java.util.Map; * @version $Id$ */ public final class GameActionUtil { - // Cache these instead of generating them on the fly, to avoid excessive allocations every time - // static abilities are checked. - @SuppressWarnings("unchecked") - private static final Map[] BASIC_LAND_ABILITIES_PARAMS = new Map[MagicColor.WUBRG.length]; - private static final AbilityRecordType[] BASIC_LAND_ABILITIES_TYPES = new AbilityRecordType[MagicColor.WUBRG.length]; - static { - for (int i = 0; i < MagicColor.WUBRG.length; i++ ) { - String color = MagicColor.toShortString(MagicColor.WUBRG[i]); - String abString = "AB$ Mana | Cost$ T | Produced$ " + color + - " | SpellDescription$ Add {" + color + "}."; - Map mapParams = AbilityFactory.getMapParams(abString); - BASIC_LAND_ABILITIES_PARAMS[i] = mapParams; - BASIC_LAND_ABILITIES_TYPES[i] = AbilityRecordType.getRecordType(mapParams); - } - } private GameActionUtil() { throw new AssertionError(); } - /** - * Gets the st land mana abilities. - * @param game - * - * @return the stLandManaAbilities - */ - public static void grantBasicLandsManaAbilities(List lands) { - // remove all abilities granted by this Command - for (final Card land : lands) { - List origManaAbs = Lists.newArrayList(land.getManaAbilities()); - // will get comodification exception without a different list - for (final SpellAbility sa : origManaAbs) { - if (sa.isBasicLandAbility()) { - land.getCurrentState().removeManaAbility(sa); - } - } - } - - // add all appropriate mana abilities based on current types - for (int i = 0; i < MagicColor.WUBRG.length; i++ ) { - String landType = MagicColor.Constant.BASIC_LANDS.get(i); - Map mapParams = BASIC_LAND_ABILITIES_PARAMS[i]; - AbilityRecordType type = BASIC_LAND_ABILITIES_TYPES[i]; - for (final Card land : lands) { - if (land.getType().hasSubtype(landType)) { - final SpellAbility sa = AbilityFactory.getAbility(mapParams, type, land, null); - sa.setBasicLandAbility(true); - land.getCurrentState().addManaAbility(sa); - } - } - } - } // stLandManaAbilities - /** *

* Find the alternative costs to a {@link SpellAbility}. diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index f01e63d54f2..3c99b77442b 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -254,6 +254,8 @@ public class Card extends GameEntity implements Comparable { private Table etbCounters = HashBasedTable.create(); + private SpellAbility[] basicLandAbilities = new SpellAbility[MagicColor.WUBRG.length]; + // Enumeration for CMC request types public enum SplitCMCMode { CurrentSideCMC, @@ -2168,6 +2170,11 @@ public class Card extends GameEntity implements Comparable { } public void updateSpellAbilities(List list, CardState state, Boolean mana) { + // do Basic Land Abilities there + if (mana == null || mana == true) { + updateBasicLandAbilities(list, state); + } + for (KeywordInterface kw : getUnhiddenKeywords(state)) { for (SpellAbility sa : kw.getAbilities()) { if (mana == null || mana == sa.isManaAbility()) { @@ -2177,6 +2184,30 @@ public class Card extends GameEntity implements Comparable { } } + private void updateBasicLandAbilities(List list, CardState state) { + final CardTypeView type = state.getTypeWithChanges(); + + if (!type.isLand()) { + // no land, do nothing there + return; + } + + for (int i = 0; i < MagicColor.WUBRG.length; i++ ) { + byte c = MagicColor.WUBRG[i]; + if (type.hasSubtype(MagicColor.Constant.BASIC_LANDS.get(i))) { + SpellAbility sa = basicLandAbilities[i]; + + // no Ability for this type yet, make a new one + if (sa == null) { + sa = CardFactoryUtil.buildBasicLandAbility(state, c); + basicLandAbilities[i] = sa; + } + + list.add(sa); + } + } + } + public final FCollectionView getIntrinsicSpellAbilities() { return currentState.getIntrinsicSpellAbilities(); } @@ -2785,20 +2816,9 @@ public class Card extends GameEntity implements Comparable { } public final void removeChangedCardTypes(final long timestamp, final boolean updateView) { - CardChangedType changed = changedCardTypes.remove(timestamp); - if (updateView) { + if (changedCardTypes.remove(timestamp) != null && updateView) { currentState.getView().updateType(currentState); } - - // if it stops being a land, the abilities does need to be removed - if (changed != null && changed.getAddType() != null && changed.getAddType().isLand()) { - for (final String s : changed.getAddType().getSubtypes()) { - if(CardType.isABasicLandType(s)) { - GameActionUtil.grantBasicLandsManaAbilities(ImmutableList.of(this)); - break; - } - } - } } public final void addColor(final String s, final boolean addToColors, final long timestamp) { diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index 16b57a7b8d1..4f1c987634e 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -73,6 +73,15 @@ import java.util.Map.Entry; */ public class CardFactoryUtil { + public static SpellAbility buildBasicLandAbility(final CardState state, byte color) { + String strcolor = MagicColor.toShortString(color); + String abString = "AB$ Mana | Cost$ T | Produced$ " + strcolor + + " | SpellDescription$ Add {" + strcolor + "}."; + SpellAbility sa = AbilityFactory.getAbility(abString, state); + sa.setIntrinsic(true); // always intristic + return sa; + } + /** *

* abilityMorphDown. diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java index 8f9a469506d..0cf37051c0e 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -80,8 +80,6 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit private Player deltrigActivatingPlayer = null; // used by delayed triggers to ensure the original activator can be restored private Player targetingPlayer = null; - private boolean basicLandAbility; // granted by basic land type - private Card grantorCard = null; // card which grants the ability (equipment or owner of static ability that gave this one) private SpellAbility mayPlayOriginal = null; @@ -1202,14 +1200,6 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit return cm != null && cm.getAmountOfX() > 0; } - public boolean isBasicLandAbility() { - return basicLandAbility; - } - - public void setBasicLandAbility(boolean basicLandAbility0) { - basicLandAbility = basicLandAbility0; - } - @Override public boolean canBeTargetedBy(SpellAbility sa) { return sa.canTargetSpellAbility(this); diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java index 90470138785..12111278489 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java @@ -769,8 +769,6 @@ public final class StaticAbilityContinuous { Player mayPlayController = params.containsKey("MayPlayCardOwner") ? affectedCard.getOwner() : controller; affectedCard.setMayPlay(mayPlayController, mayPlayWithoutManaCost, mayPlayAltManaCost, mayPlayWithFlash, mayPlayGrantZonePermissions, stAb); } - - affectedCard.updateAbilityTextForView(); // only update keywords and text for view to avoid flickering } return affectedCards;