Events are fired when static abilities recalculate

This commit is contained in:
Maxmtg
2013-07-05 15:06:15 +00:00
parent 628430f0e9
commit b12abc4533
10 changed files with 70 additions and 60 deletions

View File

@@ -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<StaticEffect> staticEffects;
private final ArrayList<StaticEffect> staticEffects = new ArrayList<StaticEffect>();
//Global rule changes
private final EnumSet<GlobalRuleChange> ruleChanges;
private final EnumSet<GlobalRuleChange> ruleChanges = EnumSet.noneOf(GlobalRuleChange.class);
private final Game game;
/**
* clearStaticEffect. TODO Write javadoc for this method.
*/
public final void clearStaticEffects() {
public final Set<Card> clearStaticEffects() {
ruleChanges.clear();
Set<Card> clearedCards = new HashSet<Card>();
// 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<StaticEffect>();
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<StaticEffect> getStaticEffects() {
return staticEffects;
}
/**
* removeStaticEffect TODO Write javadoc for this method.
*
* @param se
* a StaticEffect
*/
final void removeStaticEffect(final StaticEffect se) {
private final List<Card> removeStaticEffect(final StaticEffect se) {
final List<Card> affectedCards = se.getAffectedCards();
final ArrayList<Player> affectedPlayers = se.getAffectedPlayers();
final HashMap<String, String> 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<StaticEffect>();
this.ruleChanges = EnumSet.noneOf(GlobalRuleChange.class);
}
/**

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -227,21 +227,24 @@ public class StaticAbility {
*
* @param mode
* the mode
* @return
*/
public final void applyAbility(final String mode) {
public final List<Card> 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

View File

@@ -56,9 +56,10 @@ public class StaticAbilityContinuous {
*
* @param stAb
* a StaticAbility
* @return
*
*/
public static void applyContinuousAbility(final StaticAbility stAb) {
public static List<Card> applyContinuousAbility(final StaticAbility stAb) {
final HashMap<String, String> params = stAb.getMapParams();
final Card hostCard = stAb.getHostCard();
@@ -476,6 +477,8 @@ public class StaticAbilityContinuous {
}
}
}
return affectedCards;
}
private static ArrayList<Player> getAffectedPlayers(final StaticAbility stAb) {

View File

@@ -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<Void> {
}
private final List<Card> cardsToUpdate = new Vector<Card>();
private final Set<Card> cardsToUpdate = new HashSet<Card>();
private final Runnable updCards = new Runnable() {
@Override public void run() {
synchronized (cardsToUpdate) {
@@ -275,14 +278,24 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
return null;
}
private Void updateManyCards(Collection<Card> 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

View File

@@ -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<Card> 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<Card> 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));
}
/**

View File

@@ -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<Game, ?> umbraStalker = new Function<Game, Object>() {
@Override
public Object apply(Game game) {
// get all creatures
final List<Card> cards = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("Umbra Stalker"));
for (final Card c : cards) {
final Player player = c.getController();
final List<Card> grave = player.getCardsIn(ZoneType.Graveyard);
final int pt = CardFactoryUtil.getNumberOfManaSymbolsByColor("B", grave);
c.setBaseAttack(pt);
c.setBaseDefense(pt);
}
return null;
} // execute()
};
/** Constant <code>oldManOfTheSea</code>. */
private static Function<Game, ?> oldManOfTheSea = new Function<Game, Object>() {
@@ -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.
}

View File

@@ -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<Card> cards;
public GameEventCardStatsChanged(Card affected) {
card = affected;
cards = Arrays.asList(affected);
}
public GameEventCardStatsChanged(Collection<Card> 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 );
}
}

View File

@@ -338,7 +338,7 @@ public enum CMatchUI {
}
public void updateCards(List<Card> cardsToUpdate) {
public void updateCards(Set<Card> cardsToUpdate) {
for(Card c : cardsToUpdate) {
Zone zone = c.getGame().getZoneOf(c);
if ( null == zone )