mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
fixing NPE in CCombat.getCombatDescription. CCombat is given its own copy of combat that cannot be taken away by a different thread.
This commit is contained in:
@@ -56,7 +56,6 @@ import forge.gui.home.CHomeUI;
|
|||||||
import forge.gui.home.VHomeUI;
|
import forge.gui.home.VHomeUI;
|
||||||
import forge.gui.match.CMatchUI;
|
import forge.gui.match.CMatchUI;
|
||||||
import forge.gui.match.VMatchUI;
|
import forge.gui.match.VMatchUI;
|
||||||
import forge.gui.match.controllers.CCombat;
|
|
||||||
import forge.gui.match.controllers.CDock;
|
import forge.gui.match.controllers.CDock;
|
||||||
import forge.gui.match.controllers.CLog;
|
import forge.gui.match.controllers.CLog;
|
||||||
import forge.gui.match.controllers.CMessage;
|
import forge.gui.match.controllers.CMessage;
|
||||||
@@ -415,7 +414,6 @@ public enum FControl {
|
|||||||
CDock.SINGLETON_INSTANCE.setModel(game, humanLobbyPlayer);
|
CDock.SINGLETON_INSTANCE.setModel(game, humanLobbyPlayer);
|
||||||
CStack.SINGLETON_INSTANCE.setModel(game.getStack(), humanLobbyPlayer);
|
CStack.SINGLETON_INSTANCE.setModel(game.getStack(), humanLobbyPlayer);
|
||||||
CLog.SINGLETON_INSTANCE.setModel(game.getGameLog());
|
CLog.SINGLETON_INSTANCE.setModel(game.getGameLog());
|
||||||
CCombat.SINGLETON_INSTANCE.setModel(game);
|
|
||||||
CMessage.SINGLETON_INSTANCE.setModel(game);
|
CMessage.SINGLETON_INSTANCE.setModel(game);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
|||||||
if ( combatUpdPlanned.getAndSet(true) ) return null;
|
if ( combatUpdPlanned.getAndSet(true) ) return null;
|
||||||
FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() {
|
FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() {
|
||||||
combatUpdPlanned.set(false);
|
combatUpdPlanned.set(false);
|
||||||
CMatchUI.SINGLETON_INSTANCE.showCombat();
|
CMatchUI.SINGLETON_INSTANCE.showCombat(fc.getObservedGame().getCombat());
|
||||||
} });
|
} });
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -280,11 +280,11 @@ public class Combat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** If there are multiple blockers, the Attacker declares the Assignment Order */
|
/** If there are multiple blockers, the Attacker declares the Assignment Order */
|
||||||
public void orderBlockersForDamageAssignment() {
|
public void orderBlockersForDamageAssignment() { // this method performs controller's role
|
||||||
|
|
||||||
for(Collection<AttackingBand> abs : attackedEntities.values())
|
for(Collection<AttackingBand> abs : attackedEntities.values())
|
||||||
for (final AttackingBand band : abs) {
|
for (final AttackingBand band : abs) {
|
||||||
if (band.isEmpty()) continue; // there should not be empty bands
|
if (band.isEmpty()) continue;
|
||||||
|
|
||||||
Collection<Card> blockers = blockedBands.get(band);
|
Collection<Card> blockers = blockedBands.get(band);
|
||||||
if ( blockers == null || blockers.isEmpty() )
|
if ( blockers == null || blockers.isEmpty() )
|
||||||
@@ -300,7 +300,7 @@ public class Combat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void orderAttackersForDamageAssignment() {
|
public void orderAttackersForDamageAssignment() { // this method performs controller's role
|
||||||
// If there are multiple blockers, the Attacker declares the Assignment Order
|
// If there are multiple blockers, the Attacker declares the Assignment Order
|
||||||
for (final Card blocker : getAllBlockers()) {
|
for (final Card blocker : getAllBlockers()) {
|
||||||
List<Card> attackers = getAttackersBlockedBy(blocker);
|
List<Card> attackers = getAttackersBlockedBy(blocker);
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ public class InputAttack extends InputSyncronizedBase {
|
|||||||
|
|
||||||
private void showCombat() {
|
private void showCombat() {
|
||||||
playerAttacks.getZone(ZoneType.Battlefield).updateObservers(); // redraw sword icons
|
playerAttacks.getZone(ZoneType.Battlefield).updateObservers(); // redraw sword icons
|
||||||
CMatchUI.SINGLETON_INSTANCE.showCombat();
|
CMatchUI.SINGLETON_INSTANCE.showCombat(combat);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ public class InputBlock extends InputSyncronizedBase {
|
|||||||
showMessage(sb.toString());
|
showMessage(sb.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
CMatchUI.SINGLETON_INSTANCE.showCombat();
|
CMatchUI.SINGLETON_INSTANCE.showCombat(combat);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@@ -102,7 +102,7 @@ public class InputBlock extends InputSyncronizedBase {
|
|||||||
|
|
||||||
if (isMetaDown && card.getController() == defender) {
|
if (isMetaDown && card.getController() == defender) {
|
||||||
combat.removeFromCombat(card);
|
combat.removeFromCombat(card);
|
||||||
CMatchUI.SINGLETON_INSTANCE.showCombat();
|
CMatchUI.SINGLETON_INSTANCE.showCombat(combat);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import forge.FThreads;
|
|||||||
import forge.GameEntity;
|
import forge.GameEntity;
|
||||||
import forge.ImageCache;
|
import forge.ImageCache;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
|
import forge.game.combat.Combat;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.LobbyPlayer;
|
import forge.game.player.LobbyPlayer;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -260,10 +261,11 @@ public enum CMatchUI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void showCombat() {
|
public void showCombat(Combat combat) {
|
||||||
if (Singletons.getControl().getObservedGame().getPhaseHandler().inCombat()) {
|
if (combat != null) {
|
||||||
SDisplayUtil.showTab(EDocID.REPORT_COMBAT.getDoc());
|
SDisplayUtil.showTab(EDocID.REPORT_COMBAT.getDoc());
|
||||||
}
|
}
|
||||||
|
CCombat.SINGLETON_INSTANCE.setModel(combat);
|
||||||
CCombat.SINGLETON_INSTANCE.update();
|
CCombat.SINGLETON_INSTANCE.update();
|
||||||
} // showBlockers()
|
} // showBlockers()
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ import java.util.List;
|
|||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.Command;
|
import forge.Command;
|
||||||
import forge.GameEntity;
|
import forge.GameEntity;
|
||||||
import forge.game.Game;
|
|
||||||
import forge.game.combat.AttackingBand;
|
import forge.game.combat.AttackingBand;
|
||||||
import forge.game.combat.Combat;
|
import forge.game.combat.Combat;
|
||||||
import forge.game.phase.PhaseHandler;
|
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.gui.framework.ICDoc;
|
import forge.gui.framework.ICDoc;
|
||||||
import forge.gui.match.views.VCombat;
|
import forge.gui.match.views.VCombat;
|
||||||
@@ -24,7 +22,7 @@ public enum CCombat implements ICDoc {
|
|||||||
/** */
|
/** */
|
||||||
SINGLETON_INSTANCE;
|
SINGLETON_INSTANCE;
|
||||||
|
|
||||||
private Game game;
|
private Combat combat;
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see forge.gui.framework.ICDoc#getCommandOnSelect()
|
* @see forge.gui.framework.ICDoc#getCommandOnSelect()
|
||||||
@@ -46,16 +44,16 @@ public enum CCombat implements ICDoc {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update() {
|
||||||
PhaseHandler pH = game.getPhaseHandler();
|
Combat localCombat = this.combat; // noone will re-assign this from other thread.
|
||||||
if (pH.inCombat()) // display combat
|
if (localCombat != null )
|
||||||
VCombat.SINGLETON_INSTANCE.updateCombat(pH.getCombat().getAttackers().size(), getCombatDescription(pH.getCombat()));
|
VCombat.SINGLETON_INSTANCE.updateCombat(localCombat.getAttackers().size(), getCombatDescription(localCombat));
|
||||||
else
|
else
|
||||||
VCombat.SINGLETON_INSTANCE.updateCombat(0, "");
|
VCombat.SINGLETON_INSTANCE.updateCombat(0, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setModel(Game game)
|
public void setModel(Combat combat)
|
||||||
{
|
{
|
||||||
this.game = game;
|
this.combat = combat;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,6 +81,9 @@ public enum CCombat implements ICDoc {
|
|||||||
// Associate Bands, Attackers Blockers
|
// Associate Bands, Attackers Blockers
|
||||||
boolean previousBand = false;
|
boolean previousBand = false;
|
||||||
for(AttackingBand band : bands) {
|
for(AttackingBand band : bands) {
|
||||||
|
if (band.isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
// Space out band blocks from non-band blocks
|
// Space out band blocks from non-band blocks
|
||||||
if (previousBand) {
|
if (previousBand) {
|
||||||
display.append("\n");
|
display.append("\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user