mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Update combat display code in GUI refactoring branch
This commit is contained in:
@@ -33,7 +33,6 @@ import forge.error.BugReportDialog;
|
||||
import forge.events.UiEvent;
|
||||
import forge.game.GameType;
|
||||
import forge.game.Match;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.IHasIcon;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
@@ -76,6 +75,7 @@ import forge.toolbox.special.PhaseLabel;
|
||||
import forge.util.BuildInfo;
|
||||
import forge.util.ITriggerEvent;
|
||||
import forge.view.CardView;
|
||||
import forge.view.CombatView;
|
||||
import forge.view.GameEntityView;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
@@ -378,7 +378,7 @@ public class GuiDesktop implements IGuiBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showCombat(Combat combat) {
|
||||
public void showCombat(final CombatView combat) {
|
||||
CMatchUI.SINGLETON_INSTANCE.showCombat(combat);
|
||||
}
|
||||
|
||||
|
||||
@@ -501,7 +501,7 @@ public enum FControl implements KeyEventDispatcher {
|
||||
final LobbyPlayer humanLobbyPlayer = getGuiPlayer();
|
||||
// The UI controls should use these game data as models
|
||||
final List<PlayerView> players = game0.getPlayers();
|
||||
CMatchUI.SINGLETON_INSTANCE.initMatch(players, humanLobbyPlayer);
|
||||
CMatchUI.SINGLETON_INSTANCE.initMatch(game0, players, humanLobbyPlayer);
|
||||
|
||||
localPlayer = null;
|
||||
gameHasHumanPlayer = false;
|
||||
|
||||
@@ -22,7 +22,7 @@ import forge.view.CardView;
|
||||
|
||||
/**
|
||||
* The class CardContainer. A card container is an object that references a
|
||||
* card.
|
||||
* {@link CardView}.
|
||||
*
|
||||
* @author Clemens Koza
|
||||
* @version V0.0 17.02.2010
|
||||
@@ -34,7 +34,7 @@ public interface CardContainer {
|
||||
* </p>
|
||||
*
|
||||
* @param card
|
||||
* a {@link forge.game.card.Card} object.
|
||||
* a {@link CardView} object.
|
||||
*/
|
||||
void setCard(CardView card);
|
||||
|
||||
@@ -43,7 +43,7 @@ public interface CardContainer {
|
||||
* getCard.
|
||||
* </p>
|
||||
*
|
||||
* @return a {@link forge.game.card.Card} object.
|
||||
* @return a {@link CardView} object.
|
||||
*/
|
||||
CardView getCard();
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ import javax.swing.JPanel;
|
||||
|
||||
import forge.ImageCache;
|
||||
import forge.ImageKeys;
|
||||
import forge.game.card.Card;
|
||||
import forge.item.InventoryItem;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
@@ -61,12 +60,6 @@ public final class CardPicturePanel extends JPanel {
|
||||
this.setImage();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setCard(final Card c) {
|
||||
this.displayed = c;
|
||||
this.setImage();
|
||||
}
|
||||
|
||||
public void setCard(final CardStateView c) {
|
||||
this.displayed = c;
|
||||
this.setImage();
|
||||
|
||||
@@ -42,7 +42,6 @@ import forge.events.IUiEventVisitor;
|
||||
import forge.events.UiEvent;
|
||||
import forge.events.UiEventAttackerDeclared;
|
||||
import forge.events.UiEventBlockerAssigned;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.framework.EDocID;
|
||||
@@ -71,7 +70,9 @@ import forge.toolbox.FSkin;
|
||||
import forge.toolbox.FSkin.SkinImage;
|
||||
import forge.toolbox.special.PhaseLabel;
|
||||
import forge.view.CardView;
|
||||
import forge.view.CombatView;
|
||||
import forge.view.GameEntityView;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
import forge.view.arcane.CardPanel;
|
||||
import forge.view.arcane.PlayArea;
|
||||
@@ -87,6 +88,7 @@ import forge.view.arcane.PlayArea;
|
||||
public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
private IGameView game;
|
||||
private List<PlayerView> sortedPlayers;
|
||||
private VMatchUI view;
|
||||
|
||||
@@ -122,7 +124,8 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
* @param numFieldPanels int
|
||||
* @param numHandPanels int
|
||||
*/
|
||||
public void initMatch(final List<PlayerView> players, LobbyPlayer localPlayer) {
|
||||
public void initMatch(final IGameView game, final List<PlayerView> players, LobbyPlayer localPlayer) {
|
||||
this.game = game;
|
||||
view = VMatchUI.SINGLETON_INSTANCE;
|
||||
// TODO fix for use with multiplayer
|
||||
|
||||
@@ -296,8 +299,8 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
return sortedPlayers.indexOf(player);
|
||||
}
|
||||
|
||||
public void showCombat(Combat combat) {
|
||||
if (combat != null && combat.getAttackers().size() > 0 && combat.getAttackingPlayer().getGame().getStack().isEmpty()) {
|
||||
public void showCombat(final CombatView combat) {
|
||||
if (combat != null && combat.getNumAttackers() > 0 && game.peekStack() == null) {
|
||||
if (selectedDocBeforeCombat == null) {
|
||||
IVDoc<? extends ICDoc> combatDoc = EDocID.REPORT_COMBAT.getDoc();
|
||||
if (combatDoc.getParentCell() != null) {
|
||||
@@ -317,7 +320,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
}
|
||||
CCombat.SINGLETON_INSTANCE.setModel(combat);
|
||||
CCombat.SINGLETON_INSTANCE.update();
|
||||
} // showBlockers()
|
||||
} // showCombat(CombatView)
|
||||
|
||||
final Set<PlayerView> highlightedPlayers = Sets.newHashSet();
|
||||
public void setHighlighted(PlayerView ge, boolean b) {
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
package forge.screens.match.controllers;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.UiCommand;
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.combat.AttackingBand;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.game.player.Player;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.screens.match.views.VCombat;
|
||||
import forge.util.Lang;
|
||||
|
||||
import java.util.List;
|
||||
import forge.view.CardView;
|
||||
import forge.view.CardView.CardStateView;
|
||||
import forge.view.CombatView;
|
||||
import forge.view.GameEntityView;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
/**
|
||||
* Controls the combat panel in the match UI.
|
||||
@@ -22,7 +24,7 @@ public enum CCombat implements ICDoc {
|
||||
/** */
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
private Combat combat;
|
||||
private CombatView combat;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#getCommandOnSelect()
|
||||
@@ -44,82 +46,88 @@ public enum CCombat implements ICDoc {
|
||||
*/
|
||||
@Override
|
||||
public void update() {
|
||||
Combat localCombat = this.combat; // noone will re-assign this from other thread.
|
||||
final CombatView localCombat = this.combat; // noone will re-assign this from other thread.
|
||||
if (localCombat != null) {
|
||||
VCombat.SINGLETON_INSTANCE.updateCombat(localCombat.getAttackers().size(), getCombatDescription(localCombat));
|
||||
}
|
||||
else {
|
||||
VCombat.SINGLETON_INSTANCE.updateCombat(localCombat.getNumAttackers(), getCombatDescription(localCombat));
|
||||
} else {
|
||||
VCombat.SINGLETON_INSTANCE.updateCombat(0, "");
|
||||
}
|
||||
}
|
||||
|
||||
public void setModel(Combat combat) {
|
||||
public void setModel(final CombatView combat) {
|
||||
this.combat = combat;
|
||||
}
|
||||
|
||||
private static String getCombatDescription(Combat combat) {
|
||||
private static String getCombatDescription(final CombatView localCombat) {
|
||||
final StringBuilder display = new StringBuilder();
|
||||
|
||||
// Not a big fan of the triple nested loop here
|
||||
for (GameEntity defender : combat.getDefenders()) {
|
||||
List<AttackingBand> bands = combat.getAttackingBandsOf(defender);
|
||||
if (bands == null || bands.isEmpty()) {
|
||||
continue;
|
||||
for (final GameEntityView defender : localCombat.getDefenders()) {
|
||||
display.append(getCombatDescription(localCombat, defender));
|
||||
}
|
||||
return display.toString().trim();
|
||||
}
|
||||
|
||||
private static String getCombatDescription(final CombatView localCombat, final GameEntityView defender) {
|
||||
final StringBuilder display = new StringBuilder();
|
||||
|
||||
Iterable<Iterable<CardView>> bands = localCombat.getAttackingBandsOf(defender);
|
||||
if (bands == null || Iterables.isEmpty(bands)) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
if (display.length() > 0) {
|
||||
display.append("\n");
|
||||
}
|
||||
|
||||
if (defender instanceof Card) {
|
||||
Player controller = ((Card) defender).getController();
|
||||
if (defender instanceof CardView) {
|
||||
final PlayerView controller = ((CardView) defender).getController();
|
||||
display.append(Lang.getPossesive(controller.getName())).append(" ");
|
||||
}
|
||||
|
||||
display.append(defender.getName()).append(" is attacked by:\n");
|
||||
display.append(defender).append(" is attacked by:\n");
|
||||
|
||||
// Associate Bands, Attackers Blockers
|
||||
boolean previousBand = false;
|
||||
for(AttackingBand band : bands) {
|
||||
if (band.isEmpty())
|
||||
for (final Iterable<CardView> band : bands) {
|
||||
final int bandSize = Iterables.size(band);
|
||||
if (bandSize == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Space out band blocks from non-band blocks
|
||||
if (previousBand) {
|
||||
display.append("\n");
|
||||
}
|
||||
|
||||
Boolean blocked = band.isBlocked();
|
||||
boolean isBand = band.getAttackers().size() > 1;
|
||||
final Iterable<CardView> blockers = localCombat.getBlockers(band);
|
||||
boolean blocked = (blockers == null);
|
||||
boolean isBand = bandSize > 1;
|
||||
if (isBand) {
|
||||
// Only print Band data if it's actually a band
|
||||
display.append(" > BAND");
|
||||
|
||||
if( blocked != null )
|
||||
display.append(blocked.booleanValue() ? " (blocked)" : " >>>");
|
||||
|
||||
display.append(blocked ? " (blocked)" : " >>>");
|
||||
display.append("\n");
|
||||
}
|
||||
|
||||
for (final Card c : band.getAttackers()) {
|
||||
for (final CardView attacker : band) {
|
||||
display.append(" > ");
|
||||
display.append(combatantToString(c)).append("\n");
|
||||
display.append(combatantToString(attacker)).append("\n");
|
||||
}
|
||||
|
||||
List<Card> blockers = combat.getBlockers(band);
|
||||
if (!isBand && blockers.isEmpty()) {
|
||||
if (!isBand) {
|
||||
if (blockers != null && Iterables.isEmpty(blockers)) {
|
||||
// if single creature is blocked, but no longer has blockers, tell the user!
|
||||
if (blocked != null)
|
||||
display.append(blocked.booleanValue() ? " (blocked)\n" : " >>>\n");
|
||||
display.append(" (blocked)\n");
|
||||
} else {
|
||||
display.append(" >>>\n");
|
||||
}
|
||||
}
|
||||
|
||||
for (final Card element : blockers) {
|
||||
display.append(" < ").append(combatantToString(element)).append("\n");
|
||||
for (final CardView blocker : blockers) {
|
||||
display.append(" < ").append(combatantToString(blocker)).append("\n");
|
||||
}
|
||||
previousBand = isBand;
|
||||
}
|
||||
}
|
||||
return display.toString().trim();
|
||||
|
||||
return display.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,15 +139,15 @@ public enum CCombat implements ICDoc {
|
||||
* a {@link forge.game.card.Card} object.
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
private static String combatantToString(final Card c) {
|
||||
private static String combatantToString(final CardView c) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final CardStateView state = c.getState();
|
||||
|
||||
final String name = (c.isFaceDown()) ? "Morph" : c.getName();
|
||||
final String name = state.getName();
|
||||
|
||||
sb.append("( ").append(c.getNetAttack()).append(" / ").append(c.getNetDefense()).append(" ) ... ");
|
||||
sb.append("( ").append(state.getPower()).append(" / ").append(state.getToughness()).append(" ) ... ");
|
||||
sb.append(name);
|
||||
sb.append(" [").append(c.getUniqueNumber()).append("] ");
|
||||
|
||||
sb.append(" [").append(c.getId()).append("] ");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ import forge.deck.CardPool;
|
||||
import forge.events.UiEvent;
|
||||
import forge.game.GameType;
|
||||
import forge.game.Match;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.IHasIcon;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
@@ -29,6 +28,7 @@ import forge.sound.IAudioClip;
|
||||
import forge.sound.IAudioMusic;
|
||||
import forge.util.ITriggerEvent;
|
||||
import forge.view.CardView;
|
||||
import forge.view.CombatView;
|
||||
import forge.view.GameEntityView;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
@@ -57,7 +57,7 @@ public interface IGuiBase {
|
||||
boolean showBoxedProduct(final String title, final String message, final List<PaperCard> list);
|
||||
void fireEvent(UiEvent e);
|
||||
void setCard(CardView card);
|
||||
void showCombat(Combat combat);
|
||||
void showCombat(CombatView combat);
|
||||
void setUsedToPay(CardView card, boolean b);
|
||||
void setHighlighted(PlayerView player, boolean b);
|
||||
void showPromptMessage(String message);
|
||||
|
||||
@@ -47,6 +47,7 @@ import forge.game.card.Card;
|
||||
import forge.game.card.CardFactoryUtil;
|
||||
import forge.game.card.CardShields;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.combat.AttackingBand;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.game.combat.CombatUtil;
|
||||
import forge.game.cost.Cost;
|
||||
@@ -1355,10 +1356,11 @@ public class PlayerControllerHuman extends PlayerController implements IGameView
|
||||
}
|
||||
|
||||
private final void updateCombatView(final Combat combat) {
|
||||
for (final Card c : combat.getAttackers()) {
|
||||
final GameEntity defender = combat.getDefenderByAttacker(c);
|
||||
final List<Card> blockers = combat.getBlockers(c);
|
||||
combatView.addAttacker(getCardView(c), getGameEntityView(defender), getCardViews(blockers));
|
||||
combatView.reset();
|
||||
for (final AttackingBand b : combat.getAttackingBands()) {
|
||||
final GameEntity defender = combat.getDefenderByAttacker(b);
|
||||
final List<Card> blockers = b.isBlocked() ? combat.getBlockers(b) : null;
|
||||
combatView.addAttackingBand(getCardViews(b.getAttackers()), getGameEntityView(defender), getCardViews(blockers));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,19 +4,30 @@ import java.util.Map;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
public class CombatView {
|
||||
|
||||
private Map<CardView, GameEntityView> attackersWithDefenders;
|
||||
private Map<CardView, Iterable<CardView>> attackersWithBlockers;
|
||||
private Map<Iterable<CardView>, GameEntityView> bandsWithDefenders;
|
||||
private Map<Iterable<CardView>, Iterable<CardView>> bandsWithBlockers;
|
||||
|
||||
public CombatView() {
|
||||
}
|
||||
|
||||
public int getNumAttackers() {
|
||||
return attackersWithDefenders.size();
|
||||
}
|
||||
|
||||
public Iterable<CardView> getAttackers() {
|
||||
return attackersWithDefenders.keySet();
|
||||
}
|
||||
|
||||
public Iterable<GameEntityView> getDefenders() {
|
||||
return Sets.newHashSet(attackersWithDefenders.values());
|
||||
}
|
||||
|
||||
public GameEntityView getDefender(final CardView attacker) {
|
||||
return attackersWithDefenders.get(attacker);
|
||||
}
|
||||
@@ -25,13 +36,38 @@ public class CombatView {
|
||||
return attackersWithBlockers.get(attacker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an {@link Iterable} of the blockers of the specified band, or
|
||||
* {@code null} if that band is unblocked.
|
||||
*
|
||||
* @param attackingBand
|
||||
* an {@link Iterable} representing an attacking band.
|
||||
* @return an {@link Iterable} of {@link CardView} objects, or {@code null}.
|
||||
*/
|
||||
public Iterable<CardView> getBlockers(final Iterable<CardView> attackingBand) {
|
||||
return bandsWithBlockers.get(attackingBand);
|
||||
}
|
||||
|
||||
public Iterable<CardView> getAttackersOf(final GameEntityView defender) {
|
||||
return Maps.filterValues(attackersWithDefenders, Predicates.equalTo(defender)).keySet();
|
||||
}
|
||||
public Iterable<Iterable<CardView>> getAttackingBandsOf(final GameEntityView defender) {
|
||||
return Maps.filterValues(bandsWithDefenders, Predicates.equalTo(defender)).keySet();
|
||||
}
|
||||
|
||||
public void addAttacker(final CardView attacker, final GameEntityView defender, final Iterable<CardView> blockers) {
|
||||
public void addAttackingBand(final Iterable<CardView> attackingBand, final GameEntityView defender, final Iterable<CardView> blockers) {
|
||||
for (final CardView attacker : attackingBand) {
|
||||
this.attackersWithDefenders.put(attacker, defender);
|
||||
this.attackersWithBlockers.put(attacker, blockers);
|
||||
}
|
||||
this.bandsWithDefenders.put(attackingBand, defender);
|
||||
this.bandsWithBlockers.put(attackingBand, blockers);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.attackersWithDefenders = Maps.newHashMap();
|
||||
this.attackersWithBlockers = Maps.newHashMap();
|
||||
this.bandsWithDefenders = Maps.newHashMap();
|
||||
this.bandsWithBlockers = Maps.newHashMap();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user