mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 03:38:01 +00:00
Events are fired when static abilities recalculate
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
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 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 )
|
||||
|
||||
Reference in New Issue
Block a user