From b12abc453351d18eb2c26e4c58a7f55ec78a2b08 Mon Sep 17 00:00:00 2001 From: Maxmtg Date: Fri, 5 Jul 2013 15:06:15 +0000 Subject: [PATCH] Events are fired when static abilities recalculate --- src/main/java/forge/StaticEffects.java | 41 +++++++------------ .../ability/effects/BecomesBlockedEffect.java | 1 - .../card/cardfactory/CardFactoryUtil.java | 1 + .../card/staticability/StaticAbility.java | 11 +++-- .../StaticAbilityContinuous.java | 5 ++- .../control/FControlGameEventHandler.java | 19 +++++++-- src/main/java/forge/game/GameAction.java | 11 ++++- src/main/java/forge/game/GameActionUtil.java | 19 --------- .../game/event/GameEventCardStatsChanged.java | 20 +++++++-- src/main/java/forge/gui/match/CMatchUI.java | 2 +- 10 files changed, 70 insertions(+), 60 deletions(-) diff --git a/src/main/java/forge/StaticEffects.java b/src/main/java/forge/StaticEffects.java index 9b624a084f5..55eec901747 100644 --- a/src/main/java/forge/StaticEffects.java +++ b/src/main/java/forge/StaticEffects.java @@ -21,7 +21,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.EnumSet; import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Set; import com.esotericsoftware.minlog.Log; @@ -44,26 +46,23 @@ import forge.game.zone.ZoneType; public class StaticEffects { // **************** StaticAbility system ************************** - /** - * staticEffects. - */ - private ArrayList staticEffects; - + private final ArrayList staticEffects = new ArrayList(); //Global rule changes - private final EnumSet ruleChanges; + private final EnumSet ruleChanges = EnumSet.noneOf(GlobalRuleChange.class); + private final Game game; - /** - * clearStaticEffect. TODO Write javadoc for this method. - */ - public final void clearStaticEffects() { + public final Set clearStaticEffects() { ruleChanges.clear(); + Set clearedCards = new HashSet(); // remove all static effects - for (int i = 0; i < this.staticEffects.size(); i++) { - this.removeStaticEffect(this.staticEffects.get(i)); + for (StaticEffect se : staticEffects) { + clearedCards.addAll(this.removeStaticEffect(se)); } - this.staticEffects = new ArrayList(); + this.staticEffects.clear(); + + return clearedCards; } public void setGlobalRuleChange(GlobalRuleChange change) { @@ -84,20 +83,13 @@ public class StaticEffects { this.staticEffects.add(staticEffect); } - /** - * @return the staticEffects - */ - public ArrayList getStaticEffects() { - return staticEffects; - } - /** * removeStaticEffect TODO Write javadoc for this method. * * @param se * a StaticEffect */ - final void removeStaticEffect(final StaticEffect se) { + private final List removeStaticEffect(final StaticEffect se) { final List affectedCards = se.getAffectedCards(); final ArrayList affectedPlayers = se.getAffectedPlayers(); final HashMap params = se.getParams(); @@ -189,9 +181,7 @@ public class StaticEffects { } // modify the affected card - for (int i = 0; i < affectedCards.size(); i++) { - final Card affectedCard = affectedCards.get(i); - + for (final Card affectedCard : affectedCards) { // Gain control if (params.containsKey("GainControl")) { affectedCard.removeTempController(se.getTimestamp()); @@ -262,6 +252,7 @@ public class StaticEffects { } } se.clearTimestamps(); + return affectedCards; } // **************** End StaticAbility system ************************** @@ -283,8 +274,6 @@ public class StaticEffects { public StaticEffects(Game game) { this.game = game; this.initStateBasedEffectsList(); - this.staticEffects = new ArrayList(); - this.ruleChanges = EnumSet.noneOf(GlobalRuleChange.class); } /** diff --git a/src/main/java/forge/card/ability/effects/BecomesBlockedEffect.java b/src/main/java/forge/card/ability/effects/BecomesBlockedEffect.java index 393d919767c..875b31e45e9 100644 --- a/src/main/java/forge/card/ability/effects/BecomesBlockedEffect.java +++ b/src/main/java/forge/card/ability/effects/BecomesBlockedEffect.java @@ -9,7 +9,6 @@ import org.apache.commons.lang3.StringUtils; import forge.Card; import forge.card.ability.SpellAbilityEffect; import forge.card.cardfactory.CardFactoryUtil; -import forge.card.spellability.Ability; import forge.card.spellability.SpellAbility; import forge.card.spellability.TargetRestrictions; import forge.card.trigger.TriggerType; diff --git a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java index d62048d83b7..cc0adfd2c3b 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java @@ -1982,6 +1982,7 @@ public class CardFactoryUtil { String regularPart = String.format("AB$ Pump | Cost$ 0 | Defined$ CardUID_%d | NumAtt$ +%d | NumDef$ +%d | StackDescription$ %s", c.getUniqueNumber(), magnitude, magnitude, description); SpellAbility ability = AbilityFactory.getAbility( regularPart, c); + ability.setDescription(ability.getStackDescription()); list.add(ability); } } diff --git a/src/main/java/forge/card/staticability/StaticAbility.java b/src/main/java/forge/card/staticability/StaticAbility.java index 4c85e88e7c2..1009c56d14b 100644 --- a/src/main/java/forge/card/staticability/StaticAbility.java +++ b/src/main/java/forge/card/staticability/StaticAbility.java @@ -227,21 +227,24 @@ public class StaticAbility { * * @param mode * the mode + * @return */ - public final void applyAbility(final String mode) { + public final List applyAbility(final String mode) { // don't apply the ability if it hasn't got the right mode if (!this.params.get("Mode").equals(mode)) { - return; + return null; } if (this.isSuppressed() || !this.checkConditions()) { - return; + return null; } if (mode.equals("Continuous")) { - StaticAbilityContinuous.applyContinuousAbility(this); + return StaticAbilityContinuous.applyContinuousAbility(this); } + + return null; } // apply the ability if it has the right mode diff --git a/src/main/java/forge/card/staticability/StaticAbilityContinuous.java b/src/main/java/forge/card/staticability/StaticAbilityContinuous.java index 08184faec0f..eec731eadaa 100644 --- a/src/main/java/forge/card/staticability/StaticAbilityContinuous.java +++ b/src/main/java/forge/card/staticability/StaticAbilityContinuous.java @@ -56,9 +56,10 @@ public class StaticAbilityContinuous { * * @param stAb * a StaticAbility + * @return * */ - public static void applyContinuousAbility(final StaticAbility stAb) { + public static List applyContinuousAbility(final StaticAbility stAb) { final HashMap params = stAb.getMapParams(); final Card hostCard = stAb.getHostCard(); @@ -476,6 +477,8 @@ public class StaticAbilityContinuous { } } } + + return affectedCards; } private static ArrayList getAffectedPlayers(final StaticAbility stAb) { diff --git a/src/main/java/forge/control/FControlGameEventHandler.java b/src/main/java/forge/control/FControlGameEventHandler.java index 1a564af1846..65e0227dd90 100644 --- a/src/main/java/forge/control/FControlGameEventHandler.java +++ b/src/main/java/forge/control/FControlGameEventHandler.java @@ -1,6 +1,9 @@ package forge.control; +import java.util.Collection; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.Vector; import java.util.concurrent.atomic.AtomicBoolean; @@ -236,7 +239,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base { } - private final List cardsToUpdate = new Vector(); + private final Set cardsToUpdate = new HashSet(); private final Runnable updCards = new Runnable() { @Override public void run() { synchronized (cardsToUpdate) { @@ -275,14 +278,24 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base { return null; } + private Void updateManyCards(Collection cc) { + boolean needUpdate = false; + synchronized (cardsToUpdate) { + needUpdate = cardsToUpdate.isEmpty(); + cardsToUpdate.addAll(cc); + } + if( needUpdate ) + FThreads.invokeInEdtNowOrLater(updCards); + return null; + } + /* (non-Javadoc) * @see forge.game.event.IGameEventVisitor.Base#visit(forge.game.event.GameEventCardStatsChanged) */ @Override public Void visit(GameEventCardStatsChanged event) { // TODO Smart partial updates - PlayerZone z = (PlayerZone) event.card.getGame().getZoneOf(event.card); - return updateZone(z); + return updateManyCards(event.cards); } // Update manapool diff --git a/src/main/java/forge/game/GameAction.java b/src/main/java/forge/game/GameAction.java index 97510d4a545..d40ebc1ff9c 100644 --- a/src/main/java/forge/game/GameAction.java +++ b/src/main/java/forge/game/GameAction.java @@ -24,6 +24,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; +import java.util.Set; import com.google.common.base.Function; import com.google.common.base.Predicate; @@ -63,6 +64,7 @@ import forge.game.event.GameEventCardChangeZone; import forge.game.event.GameEventCardDestroyed; import forge.game.event.GameEventCardRegenerated; import forge.game.event.GameEventCardSacrificed; +import forge.game.event.GameEventCardStatsChanged; import forge.game.event.GameEventGameFinished; import forge.game.event.GameEventFlipCoin; import forge.game.event.GameEventGameStarted; @@ -790,7 +792,7 @@ public class GameAction { return; // remove old effects - game.getStaticEffects().clearStaticEffects(); + Set affectedCards = game.getStaticEffects().clearStaticEffects(); game.getTriggerHandler().cleanUpTemporaryTriggers(); game.getReplacementHandler().cleanUpTemporaryReplacements(); @@ -817,7 +819,9 @@ public class GameAction { }; Collections.sort(staticAbilities, comp); for (final StaticAbility stAb : staticAbilities) { - stAb.applyAbility("Continuous"); + List affectedHere = stAb.applyAbility("Continuous"); + if ( null != affectedHere ) + affectedCards.addAll(affectedHere); } // card state effects like Glorious Anthem @@ -827,6 +831,9 @@ public class GameAction { } GameActionUtil.grantBasicLandsManaAbilities(game); + + if ( !affectedCards.isEmpty() ) + game.fireEvent(new GameEventCardStatsChanged(affectedCards)); } /** diff --git a/src/main/java/forge/game/GameActionUtil.java b/src/main/java/forge/game/GameActionUtil.java index 38ec6131fe8..5afb67f80c5 100644 --- a/src/main/java/forge/game/GameActionUtil.java +++ b/src/main/java/forge/game/GameActionUtil.java @@ -42,7 +42,6 @@ import forge.card.ability.AbilityFactory; import forge.card.ability.AbilityFactory.AbilityRecordType; import forge.card.ability.AbilityUtils; import forge.card.ability.ApiType; -import forge.card.cardfactory.CardFactoryUtil; import forge.card.cost.Cost; import forge.card.mana.ManaCost; import forge.card.mana.ManaCostBeingPaid; @@ -533,23 +532,6 @@ public final class GameActionUtil { } } - /** stores the Command. */ - private static Function umbraStalker = new Function() { - @Override - public Object apply(Game game) { - // get all creatures - final List cards = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("Umbra Stalker")); - for (final Card c : cards) { - final Player player = c.getController(); - final List grave = player.getCardsIn(ZoneType.Graveyard); - final int pt = CardFactoryUtil.getNumberOfManaSymbolsByColor("B", grave); - c.setBaseAttack(pt); - c.setBaseDefense(pt); - } - return null; - } // execute() - }; - /** Constant oldManOfTheSea. */ private static Function oldManOfTheSea = new Function() { @@ -614,7 +596,6 @@ public final class GameActionUtil { GameActionUtil.getCommands().put("Liu_Bei", GameActionUtil.liuBei); GameActionUtil.getCommands().put("Old_Man_of_the_Sea", GameActionUtil.oldManOfTheSea); - GameActionUtil.getCommands().put("Umbra_Stalker", GameActionUtil.umbraStalker); // The commands above are in alphabetical order by cardname. } diff --git a/src/main/java/forge/game/event/GameEventCardStatsChanged.java b/src/main/java/forge/game/event/GameEventCardStatsChanged.java index 18e4bebf8b7..869f6cc95bf 100644 --- a/src/main/java/forge/game/event/GameEventCardStatsChanged.java +++ b/src/main/java/forge/game/event/GameEventCardStatsChanged.java @@ -1,7 +1,11 @@ package forge.game.event; +import java.util.Arrays; +import java.util.Collection; import org.apache.commons.lang.StringUtils; +import com.google.common.collect.Iterables; + import forge.Card; /** @@ -9,9 +13,13 @@ import forge.Card; */ public class GameEventCardStatsChanged extends GameEvent { - public final Card card; + public final Collection cards; public GameEventCardStatsChanged(Card affected) { - card = affected; + cards = Arrays.asList(affected); + } + + public GameEventCardStatsChanged(Collection affected) { + cards = affected; } /* (non-Javadoc) @@ -25,7 +33,13 @@ public class GameEventCardStatsChanged extends GameEvent { @Override public String toString() { - return String.format("Card state changes: %s (%s) %d/%d", card.getName(), StringUtils.join(card.getType(), ' '), card.getNetAttack(), card.getNetDefense() ); + Card card = Iterables.getFirst(cards, null); + if ( null == card ) + return "Card state changes: (empty list)"; + if( cards.size() == 1) + return String.format("Card state changes: %s (%s) %d/%d", card.getName(), StringUtils.join(card.getType(), ' '), card.getNetAttack(), card.getNetDefense() ); + else + return String.format("Card state changes: %s (%s) %d/%d and %d more", card.getName(), StringUtils.join(card.getType(), ' '), card.getNetAttack(), card.getNetDefense(), cards.size() - 1 ); } } diff --git a/src/main/java/forge/gui/match/CMatchUI.java b/src/main/java/forge/gui/match/CMatchUI.java index 412a8611538..ff340331c6d 100644 --- a/src/main/java/forge/gui/match/CMatchUI.java +++ b/src/main/java/forge/gui/match/CMatchUI.java @@ -338,7 +338,7 @@ public enum CMatchUI { } - public void updateCards(List cardsToUpdate) { + public void updateCards(Set cardsToUpdate) { for(Card c : cardsToUpdate) { Zone zone = c.getGame().getZoneOf(c); if ( null == zone )