mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
Use caching for CombatView (plus some random NPE and concurrency fixes).
This commit is contained in:
@@ -440,7 +440,7 @@ public class Game implements IGameStateObject {
|
||||
return card.getZone();
|
||||
}
|
||||
|
||||
public List<Card> getCardsIn(final ZoneType zone) {
|
||||
public synchronized List<Card> getCardsIn(final ZoneType zone) {
|
||||
if (zone == ZoneType.Stack) {
|
||||
return getStackZone().getCards();
|
||||
}
|
||||
|
||||
@@ -4,9 +4,11 @@ import forge.game.Game;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardFactoryUtil;
|
||||
import forge.game.event.GameEventCombatChanged;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
import forge.game.trigger.TriggerType;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -29,13 +31,14 @@ public class BecomesBlockedEffect extends SpellAbilityEffect {
|
||||
|
||||
@Override
|
||||
public void resolve(SpellAbility sa) {
|
||||
|
||||
boolean isCombatChanged = false;
|
||||
final Game game = sa.getActivatingPlayer().getGame();
|
||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
for (final Card c : getTargetCards(sa)) {
|
||||
if ((tgt == null) || c.canBeTargetedBy(sa)) {
|
||||
game.getCombat().setBlocked(c, true);
|
||||
if (!c.getDamageHistory().getCreatureGotBlockedThisCombat()) {
|
||||
isCombatChanged = true;
|
||||
final HashMap<String, Object> runParams = new HashMap<String, Object>();
|
||||
runParams.put("Attacker", c);
|
||||
runParams.put("Blockers", new ArrayList<Card>());
|
||||
@@ -50,5 +53,8 @@ public class BecomesBlockedEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
|
||||
if (isCombatChanged) {
|
||||
game.fireEvent(new GameEventCombatChanged());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.*;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.game.event.GameEventCombatChanged;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerActionConfirmMode;
|
||||
import forge.game.spellability.AbilitySub;
|
||||
@@ -511,6 +512,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
// Blockeres are already declared, set this to unblocked
|
||||
game.getCombat().addAttacker(tgtC, defenders.get(0));
|
||||
game.getCombat().getBandOfAttacker(tgtC).setBlocked(false);
|
||||
game.fireEvent(new GameEventCombatChanged());
|
||||
}
|
||||
}
|
||||
if (sa.hasParam("Tapped") || sa.hasParam("Ninjutsu")) {
|
||||
@@ -880,6 +882,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
final List<GameEntity> e = combat.getDefenders();
|
||||
final GameEntity defender = player.getController().chooseSingleEntityForEffect(e, sa, "Declare " + c);
|
||||
combat.addAttacker(c, defender);
|
||||
game.fireEvent(new GameEventCombatChanged());
|
||||
}
|
||||
}
|
||||
if (sa.hasParam("Blocking")) {
|
||||
@@ -891,6 +894,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
if (combat.isAttacking(attacker)) {
|
||||
combat.addBlocker(attacker, c);
|
||||
combat.orderAttackersForDamageAssignment(c);
|
||||
game.fireEvent(new GameEventCombatChanged());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardFactory;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.event.GameEventCombatChanged;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
@@ -189,6 +190,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
|
||||
if (sa.hasParam("CopyAttacking") && game.getPhaseHandler().inCombat()) {
|
||||
final GameEntity defender = AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("CopyAttacking"), sa).get(0);
|
||||
game.getCombat().addAttacker(copyInPlay, defender);
|
||||
game.fireEvent(new GameEventCombatChanged());
|
||||
}
|
||||
|
||||
if (sa.hasParam("AttachedTo")) {
|
||||
|
||||
@@ -27,6 +27,7 @@ import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardFactory;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.game.event.GameEventCombatChanged;
|
||||
import forge.game.event.GameEventTokenCreated;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
@@ -297,6 +298,7 @@ public class TokenEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
|
||||
boolean combatChanged = false;
|
||||
final Game game = controller.getGame();
|
||||
for (final Card c : tokens) {
|
||||
if (this.tokenAttacking && game.getPhaseHandler().inCombat()) {
|
||||
@@ -304,6 +306,7 @@ public class TokenEffect extends SpellAbilityEffect {
|
||||
final List<GameEntity> defs = combat.getDefenders();
|
||||
final GameEntity defender = c.getController().getController().chooseSingleEntityForEffect(defs, sa, "Choose which defender to attack with " + c, false);
|
||||
combat.addAttacker(c, defender);
|
||||
combatChanged = true;
|
||||
}
|
||||
if (this.tokenBlocking != null && game.getPhaseHandler().inCombat()) {
|
||||
Combat combat = game.getPhaseHandler().getCombat();
|
||||
@@ -315,6 +318,7 @@ public class TokenEffect extends SpellAbilityEffect {
|
||||
} else {
|
||||
// TODO Flash Foliage: set blocked; attackerBlocked trigger; damage
|
||||
}
|
||||
combatChanged = true;
|
||||
}
|
||||
}
|
||||
if (remember) {
|
||||
@@ -336,6 +340,10 @@ public class TokenEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (combatChanged) {
|
||||
game.fireEvent(new GameEventCombatChanged());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package forge.game.event;
|
||||
|
||||
public class GameEventCombatChanged extends GameEvent {
|
||||
|
||||
public GameEventCombatChanged() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,6 +18,7 @@ public interface IGameEventVisitor<T> {
|
||||
T visit(GameEventCardTapped event);
|
||||
T visit(GameEventCardStatsChanged event);
|
||||
T visit(GameEventCardCounters event);
|
||||
T visit(GameEventCombatChanged event);
|
||||
T visit(GameEventCombatEnded event);
|
||||
T visit(GameEventGameFinished event);
|
||||
T visit(GameEventGameOutcome event);
|
||||
@@ -60,6 +61,8 @@ public interface IGameEventVisitor<T> {
|
||||
public T visit(GameEventCardStatsChanged event) { return null; }
|
||||
public T visit(GameEventCardCounters event) { return null; }
|
||||
public T visit(GameEventCardPhased event) { return null; }
|
||||
public T visit(GameEventCombatChanged event) { return null; }
|
||||
public T visit(GameEventCombatEnded event) { return null; }
|
||||
public T visit(GameEventGameFinished event) { return null; }
|
||||
public T visit(GameEventGameOutcome event) { return null; }
|
||||
public T visit(GameEventFlipCoin event) { return null; }
|
||||
@@ -84,7 +87,6 @@ public interface IGameEventVisitor<T> {
|
||||
public T visit(GameEventTurnPhase event) { return null; }
|
||||
public T visit(GameEventPlayerDamaged event) { return null; }
|
||||
public T visit(GameEventZone event) { return null; }
|
||||
public T visit(GameEventCombatEnded event) { return null; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -473,7 +473,7 @@ public class PhaseHandler implements java.io.Serializable, IGameStateObject {
|
||||
}
|
||||
}
|
||||
|
||||
private Combat declareAttackersTurnBasedAction() {
|
||||
private void declareAttackersTurnBasedAction() {
|
||||
Player whoDeclares = playerDeclaresAttackers == null || playerDeclaresAttackers.hasLost() ? playerTurn : playerDeclaresAttackers;
|
||||
|
||||
if (CombatUtil.canAttack(playerTurn)) {
|
||||
@@ -481,7 +481,7 @@ public class PhaseHandler implements java.io.Serializable, IGameStateObject {
|
||||
}
|
||||
|
||||
if (game.isGameOver()) { // they just like to close window at any moment
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
combat.removeAbsentCombatants();
|
||||
@@ -544,7 +544,8 @@ public class PhaseHandler implements java.io.Serializable, IGameStateObject {
|
||||
for (final Card c : combat.getAttackers()) {
|
||||
CombatUtil.checkDeclaredAttacker(game, c, combat);
|
||||
}
|
||||
return combat;
|
||||
|
||||
game.fireEvent(new GameEventCombatChanged());
|
||||
}
|
||||
|
||||
|
||||
@@ -686,6 +687,8 @@ public class PhaseHandler implements java.io.Serializable, IGameStateObject {
|
||||
|
||||
a.getDamageHistory().setCreatureGotBlockedThisCombat(true);
|
||||
}
|
||||
|
||||
game.fireEvent(new GameEventCombatChanged());
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user