mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
Commit large scale CardView refactoring to support head-to-head better, handle hidden and face down cards better, and reduce flickering of P/T and other attributes
This commit is contained in:
@@ -14,6 +14,7 @@ public class ImageKeys {
|
|||||||
public static final String TOURNAMENTPACK_PREFIX = "o:";
|
public static final String TOURNAMENTPACK_PREFIX = "o:";
|
||||||
|
|
||||||
public static final String MORPH_IMAGE = "morph";
|
public static final String MORPH_IMAGE = "morph";
|
||||||
|
public static final String HIDDEN_CARD = TOKEN_PREFIX + MORPH_IMAGE;
|
||||||
|
|
||||||
public static final String BACKFACE_POSTFIX = "$alt";
|
public static final String BACKFACE_POSTFIX = "$alt";
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
|||||||
private final Deque<SpellAbilityStackInstance> stack = new LinkedBlockingDeque<SpellAbilityStackInstance>();
|
private final Deque<SpellAbilityStackInstance> stack = new LinkedBlockingDeque<SpellAbilityStackInstance>();
|
||||||
private final Stack<SpellAbilityStackInstance> frozenStack = new Stack<SpellAbilityStackInstance>();
|
private final Stack<SpellAbilityStackInstance> frozenStack = new Stack<SpellAbilityStackInstance>();
|
||||||
private final Stack<SpellAbility> undoStack = new Stack<SpellAbility>();
|
private final Stack<SpellAbility> undoStack = new Stack<SpellAbility>();
|
||||||
|
private Player undoStackOwner;
|
||||||
|
|
||||||
private boolean frozen = false;
|
private boolean frozen = false;
|
||||||
private boolean bResolving = false;
|
private boolean bResolving = false;
|
||||||
@@ -126,7 +127,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
|||||||
this.thisTurnCast.clear();
|
this.thisTurnCast.clear();
|
||||||
this.curResolvingCard = null;
|
this.curResolvingCard = null;
|
||||||
this.frozenStack.clear();
|
this.frozenStack.clear();
|
||||||
this.undoStack.clear();
|
this.clearUndoStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -239,8 +240,8 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
|||||||
*
|
*
|
||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public final boolean canUndo() {
|
public final boolean canUndo(Player player) {
|
||||||
return !undoStack.isEmpty();
|
return undoStackOwner == player;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -256,6 +257,9 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
|||||||
SpellAbility sa = undoStack.pop();
|
SpellAbility sa = undoStack.pop();
|
||||||
sa.undo();
|
sa.undo();
|
||||||
sa.getActivatingPlayer().getManaPool().refundManaPaid(sa);
|
sa.getActivatingPlayer().getManaPool().refundManaPaid(sa);
|
||||||
|
if (undoStack.isEmpty()) {
|
||||||
|
undoStackOwner = null;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,7 +269,9 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
|||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public final void clearUndoStack() {
|
public final void clearUndoStack() {
|
||||||
|
if (undoStackOwner == null) { return; }
|
||||||
undoStack.clear();
|
undoStack.clear();
|
||||||
|
undoStackOwner = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -289,13 +295,16 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
|||||||
System.out.println(source.getName() + " - activatingPlayer not set before adding to stack.");
|
System.out.println(source.getName() + " - activatingPlayer not set before adding to stack.");
|
||||||
}
|
}
|
||||||
|
|
||||||
//either push onto or clear undo stack based on whether
|
//either push onto or clear undo stack based on whether spell/ability is undoable
|
||||||
//spell/ability is undoable and activator is the Gui player
|
if (sp.isUndoable()) {
|
||||||
if (sp.isUndoable() && activator.getController().isGuiPlayer()) {
|
if (undoStackOwner != activator) {
|
||||||
|
clearUndoStack(); //clear if undo stack owner changes
|
||||||
|
undoStackOwner = activator;
|
||||||
|
}
|
||||||
undoStack.push(sp);
|
undoStack.push(sp);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
undoStack.clear();
|
clearUndoStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sp.isManaAbility()) { // Mana Abilities go straight through
|
if (sp.isManaAbility()) { // Mana Abilities go straight through
|
||||||
|
|||||||
@@ -194,10 +194,11 @@ public class VAssignDamage {
|
|||||||
this.damage.put(null, dt);
|
this.damage.put(null, dt);
|
||||||
this.defenders.add(dt);
|
this.defenders.add(dt);
|
||||||
CardView fakeCard = null;
|
CardView fakeCard = null;
|
||||||
if (defender instanceof CardView)
|
if (defender instanceof CardView) {
|
||||||
fakeCard = (CardView)defender;
|
fakeCard = (CardView)defender;
|
||||||
|
}
|
||||||
else if (defender instanceof PlayerView) {
|
else if (defender instanceof PlayerView) {
|
||||||
fakeCard = new CardView(true);
|
fakeCard = new CardView(-1);
|
||||||
fakeCard.getOriginal().setName(this.defender.toString());
|
fakeCard.getOriginal().setName(this.defender.toString());
|
||||||
final PlayerView p = (PlayerView)defender;
|
final PlayerView p = (PlayerView)defender;
|
||||||
fakeCard.setOwner(p);
|
fakeCard.setOwner(p);
|
||||||
|
|||||||
@@ -635,13 +635,11 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
|||||||
|
|
||||||
final List<CardPanel> newPanels = new ArrayList<CardPanel>();
|
final List<CardPanel> newPanels = new ArrayList<CardPanel>();
|
||||||
for (final CardView card : toAdd) {
|
for (final CardView card : toAdd) {
|
||||||
if (card.isUiDisplayable()) { //only include cards that are meant for display
|
final CardPanel placeholder = new CardPanel(card);
|
||||||
final CardPanel placeholder = new CardPanel(card);
|
placeholder.setDisplayEnabled(false);
|
||||||
placeholder.setDisplayEnabled(false);
|
this.getCardPanels().add(placeholder);
|
||||||
this.getCardPanels().add(placeholder);
|
this.add(placeholder);
|
||||||
this.add(placeholder);
|
newPanels.add(placeholder);
|
||||||
newPanels.add(placeholder);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!newPanels.isEmpty()) {
|
if (!newPanels.isEmpty()) {
|
||||||
|
|||||||
@@ -235,7 +235,13 @@ public class Forge implements ApplicationListener {
|
|||||||
|
|
||||||
graphics.begin(screenWidth, screenHeight);
|
graphics.begin(screenWidth, screenHeight);
|
||||||
screen.screenPos.setSize(screenWidth, screenHeight);
|
screen.screenPos.setSize(screenWidth, screenHeight);
|
||||||
|
if (screen.getRotate180()) {
|
||||||
|
graphics.startRotateTransform(screenWidth / 2, screenHeight / 2, 180);
|
||||||
|
}
|
||||||
screen.draw(graphics);
|
screen.draw(graphics);
|
||||||
|
if (screen.getRotate180()) {
|
||||||
|
graphics.endTransform();
|
||||||
|
}
|
||||||
for (FOverlay overlay : FOverlay.getOverlays()) {
|
for (FOverlay overlay : FOverlay.getOverlays()) {
|
||||||
overlay.screenPos.setSize(screenWidth, screenHeight);
|
overlay.screenPos.setSize(screenWidth, screenHeight);
|
||||||
overlay.setSize(screenWidth, screenHeight); //update overlay sizes as they're rendered
|
overlay.setSize(screenWidth, screenHeight); //update overlay sizes as they're rendered
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import forge.item.IPaperCard;
|
|||||||
import forge.match.MatchUtil;
|
import forge.match.MatchUtil;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.properties.ForgePreferences.FPref;
|
import forge.properties.ForgePreferences.FPref;
|
||||||
import forge.screens.match.MatchController;
|
|
||||||
import forge.toolbox.FCardPanel;
|
import forge.toolbox.FCardPanel;
|
||||||
import forge.toolbox.FDialog;
|
import forge.toolbox.FDialog;
|
||||||
import forge.toolbox.FList;
|
import forge.toolbox.FList;
|
||||||
@@ -268,7 +267,7 @@ public class CardRenderer {
|
|||||||
|
|
||||||
public static void drawCardListItem(Graphics g, FSkinFont font, FSkinColor foreColor, CardView card, int count, String suffix, float x, float y, float w, float h, boolean compactMode) {
|
public static void drawCardListItem(Graphics g, FSkinFont font, FSkinColor foreColor, CardView card, int count, String suffix, float x, float y, float w, float h, boolean compactMode) {
|
||||||
final CardStateView state = card.getOriginal();
|
final CardStateView state = card.getOriginal();
|
||||||
if (card.isUiDisplayable()) {
|
if (card.getId() > 0) {
|
||||||
drawCardListItem(g, font, foreColor, getCardArt(card), card, card.getSetCode(),
|
drawCardListItem(g, font, foreColor, getCardArt(card), card, card.getSetCode(),
|
||||||
card.getRarity(), state.getPower(), state.getToughness(),
|
card.getRarity(), state.getPower(), state.getToughness(),
|
||||||
state.getLoyalty(), count, suffix, x, y, w, h, compactMode);
|
state.getLoyalty(), count, suffix, x, y, w, h, compactMode);
|
||||||
@@ -286,22 +285,10 @@ public class CardRenderer {
|
|||||||
}
|
}
|
||||||
public static void drawCardListItem(Graphics g, FSkinFont font, FSkinColor foreColor, IPaperCard pc, int count, String suffix, float x, float y, float w, float h, boolean compactMode) {
|
public static void drawCardListItem(Graphics g, FSkinFont font, FSkinColor foreColor, IPaperCard pc, int count, String suffix, float x, float y, float w, float h, boolean compactMode) {
|
||||||
final CardView card = ViewUtil.getCardForUi(pc);
|
final CardView card = ViewUtil.getCardForUi(pc);
|
||||||
if (card.isUiDisplayable()) {
|
final CardStateView state = card.getOriginal();
|
||||||
final CardStateView state = card.getOriginal();
|
drawCardListItem(g, font, foreColor, getCardArt(pc), card, pc.getEdition(),
|
||||||
drawCardListItem(g, font, foreColor, getCardArt(pc), card, pc.getEdition(),
|
pc.getRarity(), state.getPower(), state.getToughness(),
|
||||||
pc.getRarity(), state.getPower(), state.getToughness(),
|
state.getLoyalty(), count, suffix, x, y, w, h, compactMode);
|
||||||
state.getLoyalty(), count, suffix, x, y, w, h, compactMode);
|
|
||||||
}
|
|
||||||
else { //if fake card, just draw card name centered
|
|
||||||
String name = pc.getName();
|
|
||||||
if (count > 0) { //preface name with count if applicable
|
|
||||||
name = count + " " + name;
|
|
||||||
}
|
|
||||||
if (suffix != null) {
|
|
||||||
name += suffix;
|
|
||||||
}
|
|
||||||
g.drawText(name, font, foreColor, x, y, w, h, false, HAlignment.CENTER, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public static void drawCardListItem(Graphics g, FSkinFont font, FSkinColor foreColor, FImageComplex cardArt, CardView card, String set, CardRarity rarity, int power, int toughness, int loyalty, int count, String suffix, float x, float y, float w, float h, boolean compactMode) {
|
public static void drawCardListItem(Graphics g, FSkinFont font, FSkinColor foreColor, FImageComplex cardArt, CardView card, String set, CardRarity rarity, int power, int toughness, int loyalty, int count, String suffix, float x, float y, float w, float h, boolean compactMode) {
|
||||||
float cardArtHeight = h + 2 * FList.PADDING;
|
float cardArtHeight = h + 2 * FList.PADDING;
|
||||||
@@ -544,13 +531,13 @@ public class CardRenderer {
|
|||||||
w -= 2 * padding;
|
w -= 2 * padding;
|
||||||
h -= 2 * padding;
|
h -= 2 * padding;
|
||||||
|
|
||||||
CardStateView details = MatchController.getCardDetails(card);
|
CardStateView details = card.getOriginal();
|
||||||
DetailColors borderColor = CardDetailUtil.getBorderColor(details);
|
DetailColors borderColor = CardDetailUtil.getBorderColor(details);
|
||||||
Color color = FSkinColor.fromRGB(borderColor.r, borderColor.g, borderColor.b);
|
Color color = FSkinColor.fromRGB(borderColor.r, borderColor.g, borderColor.b);
|
||||||
color = FSkinColor.tintColor(Color.WHITE, color, CardRenderer.PT_BOX_TINT);
|
color = FSkinColor.tintColor(Color.WHITE, color, CardRenderer.PT_BOX_TINT);
|
||||||
|
|
||||||
//draw name and mana cost overlays if card is small or default card image being used
|
//draw name and mana cost overlays if card is small or default card image being used
|
||||||
if (h <= NAME_COST_THRESHOLD) {
|
if (h <= NAME_COST_THRESHOLD && card.mayBeShown()) {
|
||||||
if (showCardNameOverlay(card)) {
|
if (showCardNameOverlay(card)) {
|
||||||
g.drawOutlinedText(details.getName(), FSkinFont.forHeight(h * 0.18f), Color.WHITE, Color.BLACK, x + padding, y + padding, w - 2 * padding, h * 0.4f, true, HAlignment.LEFT, false);
|
g.drawOutlinedText(details.getName(), FSkinFont.forHeight(h * 0.18f), Color.WHITE, Color.BLACK, x + padding, y + padding, w - 2 * padding, h * 0.4f, true, HAlignment.LEFT, false);
|
||||||
}
|
}
|
||||||
@@ -626,7 +613,7 @@ public class CardRenderer {
|
|||||||
CardFaceSymbols.drawSymbol("sacrifice", g, (x + (w / 2)) - sacSymbolSize / 2, (y + (h / 2)) - sacSymbolSize / 2, otherSymbolsSize, otherSymbolsSize);
|
CardFaceSymbols.drawSymbol("sacrifice", g, (x + (w / 2)) - sacSymbolSize / 2, (y + (h / 2)) - sacSymbolSize / 2, otherSymbolsSize, otherSymbolsSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onTop && showCardPowerOverlay(card)) { //make sure card p/t box appears on top
|
if (onTop && showCardPowerOverlay(card) && (card.mayBeShown() || card.isFaceDown())) { //make sure card p/t box appears on top
|
||||||
//only needed if on top since otherwise P/T will be hidden
|
//only needed if on top since otherwise P/T will be hidden
|
||||||
drawPtBox(g, card, details, color, x, y, w, h);
|
drawPtBox(g, card, details, color, x, y, w, h);
|
||||||
}
|
}
|
||||||
@@ -688,7 +675,7 @@ public class CardRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void drawFoilEffect(Graphics g, CardView card, float x, float y, float w, float h) {
|
public static void drawFoilEffect(Graphics g, CardView card, float x, float y, float w, float h) {
|
||||||
if (isPreferenceEnabled(FPref.UI_OVERLAY_FOIL_EFFECT)) {
|
if (isPreferenceEnabled(FPref.UI_OVERLAY_FOIL_EFFECT) && card.mayBeShown()) {
|
||||||
int foil = card.getOriginal().getFoilIndex();
|
int foil = card.getOriginal().getFoilIndex();
|
||||||
if (foil > 0) {
|
if (foil > 0) {
|
||||||
CardFaceSymbols.drawOther(g, String.format("foil%02d", foil), x, y, w, h);
|
CardFaceSymbols.drawOther(g, String.format("foil%02d", foil), x, y, w, h);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import forge.item.PaperCard;
|
|||||||
import forge.itemmanager.CardManager;
|
import forge.itemmanager.CardManager;
|
||||||
import forge.itemmanager.ItemManagerConfig;
|
import forge.itemmanager.ItemManagerConfig;
|
||||||
import forge.screens.FScreen;
|
import forge.screens.FScreen;
|
||||||
|
import forge.screens.match.MatchController;
|
||||||
import forge.toolbox.FButton;
|
import forge.toolbox.FButton;
|
||||||
import forge.toolbox.FEvent;
|
import forge.toolbox.FEvent;
|
||||||
import forge.toolbox.FEvent.FEventHandler;
|
import forge.toolbox.FEvent.FEventHandler;
|
||||||
@@ -33,7 +34,9 @@ public class FDeckViewer extends FScreen {
|
|||||||
public static void show(final Deck deck) {
|
public static void show(final Deck deck) {
|
||||||
if (deck == null) { return; }
|
if (deck == null) { return; }
|
||||||
|
|
||||||
Forge.openScreen(new FDeckViewer(deck));
|
FDeckViewer deckViewer = new FDeckViewer(deck);
|
||||||
|
deckViewer.setRotate180(MatchController.getView() != null && MatchController.getView().isTopHumanPlayerActive());
|
||||||
|
Forge.openScreen(deckViewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private FDeckViewer(Deck deck0) {
|
private FDeckViewer(Deck deck0) {
|
||||||
|
|||||||
@@ -3,10 +3,8 @@ package forge.screens.match;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
@@ -47,14 +45,12 @@ import forge.view.GameEntityView;
|
|||||||
import forge.view.LocalGameView;
|
import forge.view.LocalGameView;
|
||||||
import forge.view.PlayerView;
|
import forge.view.PlayerView;
|
||||||
import forge.view.SpellAbilityView;
|
import forge.view.SpellAbilityView;
|
||||||
import forge.view.CardView.CardStateView;
|
|
||||||
|
|
||||||
public class MatchController implements IMatchController {
|
public class MatchController implements IMatchController {
|
||||||
private MatchController() { }
|
private MatchController() { }
|
||||||
public static final MatchController instance = new MatchController();
|
public static final MatchController instance = new MatchController();
|
||||||
|
|
||||||
private static final Map<LobbyPlayer, FImage> avatarImages = new HashMap<LobbyPlayer, FImage>();
|
private static final Map<LobbyPlayer, FImage> avatarImages = new HashMap<LobbyPlayer, FImage>();
|
||||||
private static final Map<Integer, CardStateView> cardDetailsCache = new HashMap<Integer, CardStateView>();
|
|
||||||
|
|
||||||
private static MatchScreen view;
|
private static MatchScreen view;
|
||||||
|
|
||||||
@@ -75,39 +71,10 @@ public class MatchController implements IMatchController {
|
|||||||
avatarImages.put(lp, avatarImage);
|
avatarImages.put(lp, avatarImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CardStateView getCardDetails(CardView card) {
|
|
||||||
final CardStateView details = cardDetailsCache.get(card.getId());
|
|
||||||
if (details == null) {
|
|
||||||
cardDetailsCache.put(card.getId(), card.getOriginal());
|
|
||||||
return card.getOriginal();
|
|
||||||
}
|
|
||||||
return details;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void refreshCardDetails(Iterable<CardView> cards) {
|
public void refreshCardDetails(Iterable<CardView> cards) {
|
||||||
Set<PlayerView> playersNeedingFieldUpdate = null;
|
//ensure cards appear in the correct row of the field
|
||||||
|
for (VPlayerPanel pnl : view.getPlayerPanels().values()) {
|
||||||
for (final CardView c : cards) {
|
pnl.getField().update();
|
||||||
//for each card in play, if it changed from creature to non-creature or vice versa,
|
|
||||||
//or if it changed from land to non-land or vice-versa,
|
|
||||||
//ensure field containing that card is updated to reflect that change
|
|
||||||
final CardStateView state = c.getOriginal();
|
|
||||||
if (c.getZone() == ZoneType.Battlefield) {
|
|
||||||
CardStateView oldDetails = cardDetailsCache.get(c);
|
|
||||||
if (oldDetails == null || state.isCreature() != oldDetails.isCreature() || state.isLand() != oldDetails.isLand()) {
|
|
||||||
if (playersNeedingFieldUpdate == null) {
|
|
||||||
playersNeedingFieldUpdate = new HashSet<PlayerView>();
|
|
||||||
}
|
|
||||||
playersNeedingFieldUpdate.add(c.getController());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cardDetailsCache.put(c.getId(), c.getOriginal());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playersNeedingFieldUpdate != null) { //update field for any players necessary
|
|
||||||
for (PlayerView p : playersNeedingFieldUpdate) {
|
|
||||||
view.getPlayerPanel(p).getField().update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +85,6 @@ public class MatchController implements IMatchController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean resetForNewGame() {
|
public boolean resetForNewGame() {
|
||||||
cardDetailsCache.clear(); //ensure details cache cleared before starting a new game
|
|
||||||
CardAreaPanel.resetForNewGame(); //ensure card panels reset between games
|
CardAreaPanel.resetForNewGame(); //ensure card panels reset between games
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -359,7 +325,7 @@ public class MatchController implements IMatchController {
|
|||||||
@Override
|
@Override
|
||||||
public void afterGameEnd() {
|
public void afterGameEnd() {
|
||||||
Forge.back();
|
Forge.back();
|
||||||
cardDetailsCache.clear(); //ensure card details cache cleared ending game
|
view = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void actuateMatchPreferences() {
|
private static void actuateMatchPreferences() {
|
||||||
|
|||||||
@@ -48,13 +48,11 @@ public abstract class VCardDisplayArea extends VDisplayArea {
|
|||||||
|
|
||||||
CardAreaPanel newCardPanel = null;
|
CardAreaPanel newCardPanel = null;
|
||||||
for (CardView card : model) {
|
for (CardView card : model) {
|
||||||
if (card.isUiDisplayable()) { //only include cards that are meant for display
|
CardAreaPanel cardPanel = CardAreaPanel.get(card);
|
||||||
CardAreaPanel cardPanel = CardAreaPanel.get(card);
|
addCardPanelToDisplayArea(cardPanel);
|
||||||
addCardPanelToDisplayArea(cardPanel);
|
cardPanels.add(cardPanel);
|
||||||
cardPanels.add(cardPanel);
|
if (newCardPanel == null && !orderedCards.contains(card)) {
|
||||||
if (newCardPanel == null && !orderedCards.contains(card)) {
|
newCardPanel = cardPanel;
|
||||||
newCardPanel = cardPanel;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
revalidate();
|
revalidate();
|
||||||
@@ -330,6 +328,14 @@ public abstract class VCardDisplayArea extends VDisplayArea {
|
|||||||
return origin;
|
return origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected float getTappedAngle() {
|
||||||
|
if (displayArea != null && displayArea.rotateCards180) {
|
||||||
|
return -super.getTappedAngle(); //reverse tap angle if rotated 180 degrees
|
||||||
|
}
|
||||||
|
return super.getTappedAngle();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Graphics g) {
|
public void draw(Graphics g) {
|
||||||
if (displayArea != null && displayArea.rotateCards180) {
|
if (displayArea != null && displayArea.rotateCards180) {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import java.util.List;
|
|||||||
|
|
||||||
import forge.FThreads;
|
import forge.FThreads;
|
||||||
import forge.GuiBase;
|
import forge.GuiBase;
|
||||||
import forge.screens.match.MatchController;
|
|
||||||
import forge.screens.match.views.VCardDisplayArea.CardAreaPanel;
|
import forge.screens.match.views.VCardDisplayArea.CardAreaPanel;
|
||||||
import forge.toolbox.FContainer;
|
import forge.toolbox.FContainer;
|
||||||
import forge.view.CardView;
|
import forge.view.CardView;
|
||||||
@@ -62,7 +61,7 @@ public class VField extends FContainer {
|
|||||||
|
|
||||||
for (CardView card : model) {
|
for (CardView card : model) {
|
||||||
CardAreaPanel cardPanel = CardAreaPanel.get(card);
|
CardAreaPanel cardPanel = CardAreaPanel.get(card);
|
||||||
CardStateView details = MatchController.getCardDetails(card); //use details so creature/land check is accurate
|
CardStateView details = card.getOriginal();
|
||||||
if (cardPanel.getAttachedToPanel() == null) { //skip attached panels
|
if (cardPanel.getAttachedToPanel() == null) { //skip attached panels
|
||||||
if (details.isCreature()) {
|
if (details.isCreature()) {
|
||||||
if (!tryStackCard(card, creatures)) {
|
if (!tryStackCard(card, creatures)) {
|
||||||
@@ -124,14 +123,7 @@ public class VField extends FContainer {
|
|||||||
final CardAreaPanel toPanel = CardAreaPanel.get(card);
|
final CardAreaPanel toPanel = CardAreaPanel.get(card);
|
||||||
if (toPanel == null) { return; }
|
if (toPanel == null) { return; }
|
||||||
|
|
||||||
if (card.isTapped()) {
|
toPanel.setTapped(card.isTapped());
|
||||||
toPanel.setTapped(true);
|
|
||||||
toPanel.setTappedAngle(CardAreaPanel.TAPPED_ANGLE);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
toPanel.setTapped(false);
|
|
||||||
toPanel.setTappedAngle(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
toPanel.getAttachedPanels().clear();
|
toPanel.getAttachedPanels().clear();
|
||||||
if (card.isEnchanted()) {
|
if (card.isEnchanted()) {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package forge.screens.match.views;
|
package forge.screens.match.views;
|
||||||
|
|
||||||
import forge.LobbyPlayer;
|
|
||||||
import forge.assets.FSkinImage;
|
import forge.assets.FSkinImage;
|
||||||
import forge.deck.Deck;
|
import forge.deck.Deck;
|
||||||
import forge.deck.FDeckViewer;
|
import forge.deck.FDeckViewer;
|
||||||
@@ -10,7 +9,6 @@ import forge.game.spellability.SpellAbility;
|
|||||||
import forge.match.MatchUtil;
|
import forge.match.MatchUtil;
|
||||||
import forge.menu.FDropDownMenu;
|
import forge.menu.FDropDownMenu;
|
||||||
import forge.menu.FMenuItem;
|
import forge.menu.FMenuItem;
|
||||||
import forge.player.GamePlayerUtil;
|
|
||||||
import forge.screens.settings.SettingsScreen;
|
import forge.screens.settings.SettingsScreen;
|
||||||
import forge.toolbox.FEvent;
|
import forge.toolbox.FEvent;
|
||||||
import forge.toolbox.FEvent.FEventHandler;
|
import forge.toolbox.FEvent.FEventHandler;
|
||||||
@@ -50,8 +48,7 @@ public class VGameMenu extends FDropDownMenu {
|
|||||||
addItem(new FMenuItem("Deck List", FSkinImage.DECKLIST, new FEventHandler() {
|
addItem(new FMenuItem("Deck List", FSkinImage.DECKLIST, new FEventHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleEvent(FEvent e) {
|
public void handleEvent(FEvent e) {
|
||||||
final LobbyPlayer guiPlayer = GamePlayerUtil.getGuiPlayer();
|
final Deck deck = MatchUtil.getCurrentPlayer().getRegisteredPlayer().getDeck();
|
||||||
final Deck deck = MatchUtil.getGameView().getDeck(guiPlayer);
|
|
||||||
if (deck != null) {
|
if (deck != null) {
|
||||||
FDeckViewer.show(deck);
|
FDeckViewer.show(deck);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,14 +53,6 @@ public class VPhaseIndicator extends FContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRotate180(boolean b0) {
|
|
||||||
//only rotate phase labels themselves
|
|
||||||
for (PhaseLabel lbl : phaseLabels.values()) {
|
|
||||||
lbl.setRotate180(b0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getPreferredHeight(float width) {
|
public float getPreferredHeight(float width) {
|
||||||
//build string to use to determine ideal font
|
//build string to use to determine ideal font
|
||||||
float w = width / phaseLabels.size();
|
float w = width / phaseLabels.size();
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import forge.util.Utils;
|
|||||||
import forge.view.CardView;
|
import forge.view.CardView;
|
||||||
|
|
||||||
public class FCardPanel extends FDisplayObject {
|
public class FCardPanel extends FDisplayObject {
|
||||||
public static final float TAPPED_ANGLE = -90;
|
|
||||||
public static final float ASPECT_RATIO = 3.5f / 2.5f;
|
public static final float ASPECT_RATIO = 3.5f / 2.5f;
|
||||||
public static final float PADDING = Utils.scale(2);
|
public static final float PADDING = Utils.scale(2);
|
||||||
public static final float TARGET_ORIGIN_FACTOR_X = 0.15f;
|
public static final float TARGET_ORIGIN_FACTOR_X = 0.15f;
|
||||||
@@ -15,7 +14,6 @@ public class FCardPanel extends FDisplayObject {
|
|||||||
|
|
||||||
private CardView card;
|
private CardView card;
|
||||||
private boolean tapped;
|
private boolean tapped;
|
||||||
private float tappedAngle = 0;
|
|
||||||
private boolean highlighted;
|
private boolean highlighted;
|
||||||
|
|
||||||
public FCardPanel() {
|
public FCardPanel() {
|
||||||
@@ -46,11 +44,8 @@ public class FCardPanel extends FDisplayObject {
|
|||||||
tapped = tapped0;
|
tapped = tapped0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getTappedAngle() {
|
protected float getTappedAngle() {
|
||||||
return tappedAngle;
|
return -90;
|
||||||
}
|
|
||||||
public void setTappedAngle(float tappedAngle0) {
|
|
||||||
tappedAngle = tappedAngle0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean renderedCardContains(float x, float y) {
|
protected boolean renderedCardContains(float x, float y) {
|
||||||
@@ -96,7 +91,7 @@ public class FCardPanel extends FDisplayObject {
|
|||||||
|
|
||||||
if (tapped) {
|
if (tapped) {
|
||||||
float edgeOffset = w / 2f;
|
float edgeOffset = w / 2f;
|
||||||
g.startRotateTransform(x + edgeOffset, y + h - edgeOffset, tappedAngle);
|
g.startRotateTransform(x + edgeOffset, y + h - edgeOffset, getTappedAngle());
|
||||||
}
|
}
|
||||||
|
|
||||||
CardRenderer.drawCardWithOverlays(g, card, x, y, w, h, getStackPosition());
|
CardRenderer.drawCardWithOverlays(g, card, x, y, w, h, getStackPosition());
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class CardDetailUtil {
|
|||||||
if (card == null) {
|
if (card == null) {
|
||||||
return getBorderColors(null, false, false, false).iterator().next();
|
return getBorderColors(null, false, false, false).iterator().next();
|
||||||
}
|
}
|
||||||
return getBorderColors(card.getColors(), card.isLand(), card.getCard().isUiDisplayable(), false).iterator().next();
|
return getBorderColors(card.getColors(), card.isLand(), card.getCard().mayBeShown(), false).iterator().next();
|
||||||
}
|
}
|
||||||
public static DetailColors getBorderColor(final ColorSet cardColors, final boolean isLand, boolean canShow) {
|
public static DetailColors getBorderColor(final ColorSet cardColors, final boolean isLand, boolean canShow) {
|
||||||
return getBorderColors(cardColors, isLand, canShow, false).get(0);
|
return getBorderColors(cardColors, isLand, canShow, false).get(0);
|
||||||
@@ -62,7 +62,7 @@ public class CardDetailUtil {
|
|||||||
if (card == null) {
|
if (card == null) {
|
||||||
return getBorderColors(null, false, false, true);
|
return getBorderColors(null, false, false, true);
|
||||||
}
|
}
|
||||||
return getBorderColors(card.getColors(), card.isLand(), card.getCard().isUiDisplayable(), true);
|
return getBorderColors(card.getColors(), card.isLand(), card.getCard().mayBeShown(), true);
|
||||||
}
|
}
|
||||||
private static List<DetailColors> getBorderColors(final ColorSet cardColors, final boolean isLand, boolean canShow, boolean supportMultiple) {
|
private static List<DetailColors> getBorderColors(final ColorSet cardColors, final boolean isLand, boolean canShow, boolean supportMultiple) {
|
||||||
List<DetailColors> borderColors = new ArrayList<DetailColors>();
|
List<DetailColors> borderColors = new ArrayList<DetailColors>();
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import forge.game.event.GameEventCombatChanged;
|
|||||||
import forge.game.event.GameEventCombatEnded;
|
import forge.game.event.GameEventCombatEnded;
|
||||||
import forge.game.event.GameEventGameFinished;
|
import forge.game.event.GameEventGameFinished;
|
||||||
import forge.game.event.GameEventGameOutcome;
|
import forge.game.event.GameEventGameOutcome;
|
||||||
|
import forge.game.event.GameEventGameStarted;
|
||||||
import forge.game.event.GameEventManaPool;
|
import forge.game.event.GameEventManaPool;
|
||||||
import forge.game.event.GameEventPlayerControl;
|
import forge.game.event.GameEventPlayerControl;
|
||||||
import forge.game.event.GameEventPlayerLivesChanged;
|
import forge.game.event.GameEventPlayerLivesChanged;
|
||||||
@@ -74,9 +75,16 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
|||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void receiveGameEvent(final GameEvent ev) {
|
public void receiveGameEvent(final GameEvent ev) {
|
||||||
|
gameView.updateViews();
|
||||||
ev.visit(this);
|
ev.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(GameEventGameStarted event) {
|
||||||
|
gameView.endUpdateDelay(); //allow views to update once game starts
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private final AtomicBoolean phaseUpdPlanned = new AtomicBoolean(false);
|
private final AtomicBoolean phaseUpdPlanned = new AtomicBoolean(false);
|
||||||
@Override
|
@Override
|
||||||
public Void visit(final GameEventTurnPhase ev) {
|
public Void visit(final GameEventTurnPhase ev) {
|
||||||
@@ -142,7 +150,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
|||||||
|
|
||||||
final List<CardView> options = Lists.newArrayList();
|
final List<CardView> options = Lists.newArrayList();
|
||||||
for (final Entry<Player, Card> kv : ev.cards.entries()) {
|
for (final Entry<Player, Card> kv : ev.cards.entries()) {
|
||||||
final CardView fakeCard = new CardView(true); //use fake card so real cards appear with proper formatting
|
final CardView fakeCard = new CardView(-1); //use fake card so real cards appear with proper formatting
|
||||||
fakeCard.getOriginal().setName(" -- From " + Lang.getPossesive(kv.getKey().getName()) + " deck --");
|
fakeCard.getOriginal().setName(" -- From " + Lang.getPossesive(kv.getKey().getName()) + " deck --");
|
||||||
options.add(fakeCard);
|
options.add(fakeCard);
|
||||||
options.add(gameView.getCardView(kv.getValue()));
|
options.add(gameView.getCardView(kv.getValue()));
|
||||||
@@ -294,8 +302,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
synchronized (cardsToUpdate) {
|
synchronized (cardsToUpdate) {
|
||||||
final Iterable<CardView> newCardsToUpdate = gameView.getRefreshedCardViews(cardsToUpdate);
|
MatchUtil.updateCards(cardsToUpdate);
|
||||||
MatchUtil.updateCards(newCardsToUpdate);
|
|
||||||
cardsToUpdate.clear();
|
cardsToUpdate.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ import forge.game.trigger.TriggerType;
|
|||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.match.input.InputPlaybackControl;
|
import forge.match.input.InputPlaybackControl;
|
||||||
import forge.match.input.InputQueue;
|
import forge.match.input.InputQueue;
|
||||||
import forge.match.input.InputSynchronized;
|
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.player.GamePlayerUtil;
|
import forge.player.GamePlayerUtil;
|
||||||
import forge.player.LobbyPlayerHuman;
|
import forge.player.LobbyPlayerHuman;
|
||||||
@@ -71,6 +70,7 @@ import forge.view.WatchLocalGame;
|
|||||||
public class MatchUtil {
|
public class MatchUtil {
|
||||||
private static IMatchController controller;
|
private static IMatchController controller;
|
||||||
private static Game game;
|
private static Game game;
|
||||||
|
private static Player currentPlayer;
|
||||||
private static final List<LocalGameView> gameViews = new ArrayList<LocalGameView>();
|
private static final List<LocalGameView> gameViews = new ArrayList<LocalGameView>();
|
||||||
|
|
||||||
/** Cache of players. */
|
/** Cache of players. */
|
||||||
@@ -180,6 +180,10 @@ public class MatchUtil {
|
|||||||
if (p.getController() instanceof PlayerControllerHuman) {
|
if (p.getController() instanceof PlayerControllerHuman) {
|
||||||
final PlayerControllerHuman controller = (PlayerControllerHuman) p.getController();
|
final PlayerControllerHuman controller = (PlayerControllerHuman) p.getController();
|
||||||
LocalGameView gameView = controller.getGameView();
|
LocalGameView gameView = controller.getGameView();
|
||||||
|
if (humanCount == 0) {
|
||||||
|
currentPlayer = p;
|
||||||
|
gameView.startUpdateDelay(); //delay updating views until game finishes initializing
|
||||||
|
}
|
||||||
game.subscribeToEvents(new FControlGameEventHandler(gameView, humanCount == 0));
|
game.subscribeToEvents(new FControlGameEventHandler(gameView, humanCount == 0));
|
||||||
gameViews.add(gameView);
|
gameViews.add(gameView);
|
||||||
humanCount++;
|
humanCount++;
|
||||||
@@ -188,7 +192,9 @@ public class MatchUtil {
|
|||||||
|
|
||||||
if (humanCount == 0) { //watch game but do not participate
|
if (humanCount == 0) { //watch game but do not participate
|
||||||
LocalGameView gameView = new WatchLocalGame(GuiBase.getInterface(), game);
|
LocalGameView gameView = new WatchLocalGame(GuiBase.getInterface(), game);
|
||||||
gameView.setLocalPlayer(sortedPlayers.get(0));
|
currentPlayer = sortedPlayers.get(0);
|
||||||
|
gameView.setLocalPlayer(currentPlayer);
|
||||||
|
gameView.startUpdateDelay();
|
||||||
game.subscribeToEvents(new FControlGameEventHandler(gameView, true));
|
game.subscribeToEvents(new FControlGameEventHandler(gameView, true));
|
||||||
gameViews.add(gameView);
|
gameViews.add(gameView);
|
||||||
}
|
}
|
||||||
@@ -235,7 +241,7 @@ public class MatchUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static LocalGameView getGameView() {
|
public static LocalGameView getGameView() {
|
||||||
return getGameView(getCurrentPlayer());
|
return getGameView(currentPlayer);
|
||||||
}
|
}
|
||||||
public static LocalGameView getGameView(Player player) {
|
public static LocalGameView getGameView(Player player) {
|
||||||
switch (gameViews.size()) {
|
switch (gameViews.size()) {
|
||||||
@@ -244,10 +250,7 @@ public class MatchUtil {
|
|||||||
case 0:
|
case 0:
|
||||||
return null;
|
return null;
|
||||||
default:
|
default:
|
||||||
if (player != null && player.getController() instanceof PlayerControllerHuman) {
|
return gameViews.get(player.getId());
|
||||||
return ((PlayerControllerHuman)player.getController()).getGameView();
|
|
||||||
}
|
|
||||||
return gameViews.get(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,23 +283,14 @@ public class MatchUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Player getCurrentPlayer() {
|
public static Player getCurrentPlayer() {
|
||||||
if (game == null) { return null; }
|
return currentPlayer;
|
||||||
|
}
|
||||||
LobbyPlayer lobbyPlayer = getGuiPlayer();
|
public static void setCurrentPlayer(Player currentPlayer0) {
|
||||||
|
if (currentPlayer == currentPlayer0) { return; }
|
||||||
|
currentPlayer = currentPlayer0;
|
||||||
if (gameViews.size() > 1) {
|
if (gameViews.size() > 1) {
|
||||||
//account for if second human player is currently being prompted
|
gameViews.get(currentPlayer.getId()).updateViews(); //ensure views updated when current player changes to account for changes in card visibility
|
||||||
InputSynchronized activeInput = InputQueue.getActiveInput();
|
|
||||||
if (activeInput != null) {
|
|
||||||
lobbyPlayer = activeInput.getOwner().getLobbyPlayer();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Player p : game.getPlayers()) {
|
|
||||||
if (p.getLobbyPlayer() == lobbyPlayer) {
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void alphaStrike() {
|
public static void alphaStrike() {
|
||||||
@@ -368,7 +362,7 @@ public class MatchUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Player priorityPlayer = game.getPhaseHandler().getPriorityPlayer();
|
Player priorityPlayer = game.getPhaseHandler().getPriorityPlayer();
|
||||||
boolean humanHasPriority = priorityPlayer == null || priorityPlayer.getLobbyPlayer() == getGuiPlayer();
|
boolean humanHasPriority = priorityPlayer == null || priorityPlayer.getLobbyPlayer() instanceof LobbyPlayerHuman;
|
||||||
|
|
||||||
if (humanCount > 0 && humanHasPriority) {
|
if (humanCount > 0 && humanHasPriority) {
|
||||||
game.getAction().checkGameOverCondition();
|
game.getAction().checkGameOverCondition();
|
||||||
@@ -388,6 +382,7 @@ public class MatchUtil {
|
|||||||
if (game == null) { return; }
|
if (game == null) { return; }
|
||||||
|
|
||||||
game = null;
|
game = null;
|
||||||
|
currentPlayer = null;
|
||||||
gameViews.clear();
|
gameViews.clear();
|
||||||
players.clear();
|
players.clear();
|
||||||
cards.clear();
|
cards.clear();
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ import java.util.Observer;
|
|||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import forge.FThreads;
|
import forge.FThreads;
|
||||||
|
import forge.game.card.Card;
|
||||||
|
import forge.game.player.Player;
|
||||||
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.interfaces.IGuiBase;
|
import forge.interfaces.IGuiBase;
|
||||||
import forge.util.ITriggerEvent;
|
import forge.util.ITriggerEvent;
|
||||||
import forge.view.CardView;
|
import forge.view.CardView;
|
||||||
@@ -97,34 +100,23 @@ public class InputProxy implements Observer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public final void selectPlayer(final PlayerView playerView, final ITriggerEvent triggerEvent) {
|
||||||
* <p>
|
|
||||||
* selectPlayer.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param player
|
|
||||||
* a {@link forge.game.player.Player} object.
|
|
||||||
*/
|
|
||||||
public final void selectPlayer(final PlayerView player, final ITriggerEvent triggerEvent) {
|
|
||||||
final Input inp = getInput();
|
final Input inp = getInput();
|
||||||
if (inp != null) {
|
if (inp != null) {
|
||||||
inp.selectPlayer(gameView.getPlayer(player), triggerEvent);
|
final Player player = gameView.getPlayer(playerView);
|
||||||
|
if (player != null) {
|
||||||
|
inp.selectPlayer(player, triggerEvent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* selectCard.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param cardView
|
|
||||||
* a {@link forge.game.card.Card} object.
|
|
||||||
* @param triggerEvent
|
|
||||||
*/
|
|
||||||
public final boolean selectCard(final CardView cardView, final ITriggerEvent triggerEvent) {
|
public final boolean selectCard(final CardView cardView, final ITriggerEvent triggerEvent) {
|
||||||
final Input inp = getInput();
|
final Input inp = getInput();
|
||||||
if (inp != null) {
|
if (inp != null) {
|
||||||
return inp.selectCard(gameView.getCard(cardView), triggerEvent);
|
final Card card = gameView.getCard(cardView);
|
||||||
|
if (card != null) {
|
||||||
|
return inp.selectCard(card, triggerEvent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -132,7 +124,10 @@ public class InputProxy implements Observer {
|
|||||||
public final void selectAbility(final SpellAbilityView ab) {
|
public final void selectAbility(final SpellAbilityView ab) {
|
||||||
final Input inp = getInput();
|
final Input inp = getInput();
|
||||||
if (inp != null) {
|
if (inp != null) {
|
||||||
inp.selectAbility(gameView.getSpellAbility(ab));
|
final SpellAbility sa = gameView.getSpellAbility(ab);
|
||||||
|
if (sa != null) {
|
||||||
|
inp.selectAbility(sa);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import java.util.concurrent.BlockingDeque;
|
|||||||
import java.util.concurrent.LinkedBlockingDeque;
|
import java.util.concurrent.LinkedBlockingDeque;
|
||||||
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
|
import forge.match.MatchUtil;
|
||||||
import forge.view.IGameView;
|
import forge.view.IGameView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,12 +34,6 @@ import forge.view.IGameView;
|
|||||||
* @version $Id: InputQueue.java 24769 2014-02-09 13:56:04Z Hellfish $
|
* @version $Id: InputQueue.java 24769 2014-02-09 13:56:04Z Hellfish $
|
||||||
*/
|
*/
|
||||||
public class InputQueue extends Observable {
|
public class InputQueue extends Observable {
|
||||||
private static InputSynchronized activeInput;
|
|
||||||
|
|
||||||
public static InputSynchronized getActiveInput() {
|
|
||||||
return activeInput;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final BlockingDeque<InputSynchronized> inputStack = new LinkedBlockingDeque<InputSynchronized>();
|
private final BlockingDeque<InputSynchronized> inputStack = new LinkedBlockingDeque<InputSynchronized>();
|
||||||
private final InputLockUI inputLock;
|
private final InputLockUI inputLock;
|
||||||
|
|
||||||
@@ -62,9 +57,6 @@ public class InputQueue extends Observable {
|
|||||||
if (topMostInput != inp) {
|
if (topMostInput != inp) {
|
||||||
throw new RuntimeException("Cannot remove input " + inp.getClass().getSimpleName() + " because it's not on top of stack. Stack = " + inputStack );
|
throw new RuntimeException("Cannot remove input " + inp.getClass().getSimpleName() + " because it's not on top of stack. Stack = " + inputStack );
|
||||||
}
|
}
|
||||||
if (inp == activeInput) {
|
|
||||||
activeInput = null;
|
|
||||||
}
|
|
||||||
updateObservers();
|
updateObservers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +81,9 @@ public class InputQueue extends Observable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setInput(final InputSynchronized input) {
|
public void setInput(final InputSynchronized input) {
|
||||||
activeInput = input;
|
if (MatchUtil.getHumanCount() > 1) { //update current player if needed
|
||||||
|
MatchUtil.setCurrentPlayer(MatchUtil.players.getKey(input.getOwner().getId()));
|
||||||
|
}
|
||||||
inputStack.push(input);
|
inputStack.push(input);
|
||||||
inputLock.setGui(input.getGui());
|
inputLock.setGui(input.getGui());
|
||||||
InputBase.waitForOtherPlayer();
|
InputBase.waitForOtherPlayer();
|
||||||
|
|||||||
@@ -11,11 +11,10 @@ import java.util.Collection;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.Range;
|
import org.apache.commons.lang3.Range;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||||
@@ -29,8 +28,6 @@ import com.google.common.collect.Iterables;
|
|||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
|
|
||||||
import forge.FThreads;
|
import forge.FThreads;
|
||||||
import forge.LobbyPlayer;
|
import forge.LobbyPlayer;
|
||||||
import forge.achievement.AchievementCollection;
|
import forge.achievement.AchievementCollection;
|
||||||
@@ -124,7 +121,6 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
* Cards this player may look at right now, for example when searching a
|
* Cards this player may look at right now, for example when searching a
|
||||||
* library.
|
* library.
|
||||||
*/
|
*/
|
||||||
private final Set<Card> mayLookAt = Sets.newHashSet();
|
|
||||||
private boolean mayLookAtAllCards = false;
|
private boolean mayLookAtAllCards = false;
|
||||||
|
|
||||||
public PlayerControllerHuman(Game game0, Player p, LobbyPlayer lp, IGuiBase gui) {
|
public PlayerControllerHuman(Game game0, Player p, LobbyPlayer lp, IGuiBase gui) {
|
||||||
@@ -163,6 +159,30 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
return mayLookAtAllCards;
|
return mayLookAtAllCards;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final HashSet<Card> tempShownCards = new HashSet<Card>();
|
||||||
|
private void tempShowCard(Card c) {
|
||||||
|
CardView cv = MatchUtil.cards.get(c.getId());
|
||||||
|
if (!cv.mayBeShown()) {
|
||||||
|
cv.setMayBeShown(true);
|
||||||
|
tempShownCards.add(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void tempShowCards(Iterable<Card> cards) {
|
||||||
|
if (mayLookAtAllCards) { return; } //no needed if this is set
|
||||||
|
|
||||||
|
for (Card c : cards) {
|
||||||
|
tempShowCard(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void endTempShowCards() {
|
||||||
|
if (tempShownCards.isEmpty()) { return; }
|
||||||
|
|
||||||
|
for (Card c : tempShownCards) {
|
||||||
|
MatchUtil.cards.get(c.getId()).setMayBeShown(false);
|
||||||
|
}
|
||||||
|
tempShownCards.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set this to {@code true} to enable this player to see all cards any other
|
* Set this to {@code true} to enable this player to see all cards any other
|
||||||
* player can see.
|
* player can see.
|
||||||
@@ -355,9 +375,9 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
return Lists.newArrayList(sc.getSelected());
|
return Lists.newArrayList(sc.getSelected());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.mayLookAt.addAll(sourceList);
|
tempShowCards(sourceList);
|
||||||
final List<CardView> choices = SGuiChoose.many(getGui(), title, "Chosen Cards", min, max, gameView.getCardViews(sourceList), gameView.getCardView(sa.getHostCard()));
|
final List<CardView> choices = SGuiChoose.many(getGui(), title, "Chosen Cards", min, max, gameView.getCardViews(sourceList), gameView.getCardView(sa.getHostCard()));
|
||||||
this.mayLookAt.removeAll(sourceList);
|
endTempShowCards();
|
||||||
|
|
||||||
return getCards(choices);
|
return getCards(choices);
|
||||||
}
|
}
|
||||||
@@ -398,11 +418,11 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
for (final T t : options) {
|
for (final T t : options) {
|
||||||
if (t instanceof Card) {
|
if (t instanceof Card) {
|
||||||
// assume you may see any card passed through here
|
// assume you may see any card passed through here
|
||||||
mayLookAt.add((Card) t);
|
tempShowCard((Card) t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final GameEntityView result = isOptional ? SGuiChoose.oneOrNone(getGui(), title, gameView.getGameEntityViews((Iterable<GameEntity>) options)) : SGuiChoose.one(getGui(), title, gameView.getGameEntityViews((Iterable<GameEntity>) options));
|
final GameEntityView result = isOptional ? SGuiChoose.oneOrNone(getGui(), title, gameView.getGameEntityViews((Iterable<GameEntity>) options)) : SGuiChoose.one(getGui(), title, gameView.getGameEntityViews((Iterable<GameEntity>) options));
|
||||||
mayLookAt.clear();
|
endTempShowCards();
|
||||||
return (T) gameView.getGameEntity(result);
|
return (T) gameView.getGameEntity(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -540,9 +560,9 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
}
|
}
|
||||||
String fm = formatMessage(message, owner);
|
String fm = formatMessage(message, owner);
|
||||||
if (!cards.isEmpty()) {
|
if (!cards.isEmpty()) {
|
||||||
mayLookAt.addAll(cards);
|
tempShowCards(cards);
|
||||||
SGuiChoose.reveal(getGui(), fm, gameView.getCardViews(cards));
|
SGuiChoose.reveal(getGui(), fm, gameView.getCardViews(cards));
|
||||||
mayLookAt.clear();
|
endTempShowCards();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SGuiDialog.message(getGui(), formatMessage("There are no cards in {player's} " +
|
SGuiDialog.message(getGui(), formatMessage("There are no cards in {player's} " +
|
||||||
@@ -555,7 +575,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
List<Card> toBottom = null;
|
List<Card> toBottom = null;
|
||||||
List<Card> toTop = null;
|
List<Card> toTop = null;
|
||||||
|
|
||||||
mayLookAt.addAll(topN);
|
tempShowCards(topN);
|
||||||
if (topN.size() == 1) {
|
if (topN.size() == 1) {
|
||||||
if (willPutCardOnTop(topN.get(0))) {
|
if (willPutCardOnTop(topN.get(0))) {
|
||||||
toTop = topN;
|
toTop = topN;
|
||||||
@@ -579,7 +599,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
toTop = gameView.getCards(toTopViews);
|
toTop = gameView.getCards(toTopViews);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mayLookAt.clear();
|
endTempShowCards();
|
||||||
return ImmutablePair.of(toTop, toBottom);
|
return ImmutablePair.of(toTop, toBottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -594,7 +614,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
@Override
|
@Override
|
||||||
public List<Card> orderMoveToZoneList(List<Card> cards, ZoneType destinationZone) {
|
public List<Card> orderMoveToZoneList(List<Card> cards, ZoneType destinationZone) {
|
||||||
List<CardView> choices;
|
List<CardView> choices;
|
||||||
mayLookAt.addAll(cards);
|
tempShowCards(cards);
|
||||||
switch (destinationZone) {
|
switch (destinationZone) {
|
||||||
case Library:
|
case Library:
|
||||||
choices = SGuiChoose.order(getGui(), "Choose order of cards to put into the library", "Closest to top", getCardViews(cards), null);
|
choices = SGuiChoose.order(getGui(), "Choose order of cards to put into the library", "Closest to top", getCardViews(cards), null);
|
||||||
@@ -616,20 +636,20 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
System.out.println("ZoneType " + destinationZone + " - Not Ordered");
|
System.out.println("ZoneType " + destinationZone + " - Not Ordered");
|
||||||
mayLookAt.clear();
|
endTempShowCards();
|
||||||
return cards;
|
return cards;
|
||||||
}
|
}
|
||||||
mayLookAt.clear();
|
endTempShowCards();
|
||||||
return getCards(choices);
|
return getCards(choices);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> valid, int min, int max) {
|
public List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> valid, int min, int max) {
|
||||||
if (p != player) {
|
if (p != player) {
|
||||||
mayLookAt.addAll(valid);
|
tempShowCards(valid);
|
||||||
final List<CardView> choices = SGuiChoose.many(getGui(), "Choose " + min + " card" + (min != 1 ? "s" : "") + " to discard",
|
final List<CardView> choices = SGuiChoose.many(getGui(), "Choose " + min + " card" + (min != 1 ? "s" : "") + " to discard",
|
||||||
"Discarded", min, min, gameView.getCardViews(valid), null);
|
"Discarded", min, min, gameView.getCardViews(valid), null);
|
||||||
mayLookAt.clear();
|
endTempShowCards();
|
||||||
return getCards(choices);
|
return getCards(choices);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1245,28 +1265,17 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
return SGuiDialog.confirm(getGui(), gameView.getCardView(sa.getHostCard()), "Choose a Pile", possibleValues);
|
return SGuiDialog.confirm(getGui(), gameView.getCardView(sa.getHostCard()), "Choose a Pile", possibleValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
mayLookAt.addAll(pile1);
|
tempShowCards(pile1);
|
||||||
mayLookAt.addAll(pile2);
|
tempShowCards(pile2);
|
||||||
|
|
||||||
final int idPile1 = Integer.MIN_VALUE, idPile2 = Integer.MIN_VALUE + 1;
|
|
||||||
final List<CardView> cards = Lists.newArrayListWithCapacity(pile1.size() + pile2.size() + 2);
|
final List<CardView> cards = Lists.newArrayListWithCapacity(pile1.size() + pile2.size() + 2);
|
||||||
final CardView pileView1 = new CardView(true) {
|
final CardView pileView1 = new CardView(Integer.MIN_VALUE);
|
||||||
@Override
|
pileView1.getOriginal().setName("--- Pile 1 ---");
|
||||||
public String toString() {
|
|
||||||
return "--- Pile 1 ---";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
pileView1.setId(idPile1);
|
|
||||||
cards.add(pileView1);
|
cards.add(pileView1);
|
||||||
cards.addAll(getCardViews(pile1));
|
cards.addAll(getCardViews(pile1));
|
||||||
|
|
||||||
final CardView pileView2 = new CardView(true) {
|
final CardView pileView2 = new CardView(Integer.MIN_VALUE + 1);
|
||||||
@Override
|
pileView2.getOriginal().setName("--- Pile 2 ---");
|
||||||
public String toString() {
|
|
||||||
return "--- Pile 2 ---";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
pileView2.setId(idPile2);
|
|
||||||
cards.add(pileView2);
|
cards.add(pileView2);
|
||||||
cards.addAll(getCardViews(pile2));
|
cards.addAll(getCardViews(pile2));
|
||||||
|
|
||||||
@@ -1277,13 +1286,14 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
if (chosen.equals(pileView1)) {
|
if (chosen.equals(pileView1)) {
|
||||||
result = true;
|
result = true;
|
||||||
break;
|
break;
|
||||||
} else if (chosen.equals(pileView2)) {
|
}
|
||||||
|
if (chosen.equals(pileView2)) {
|
||||||
result = false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mayLookAt.clear();
|
endTempShowCards();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1359,7 +1369,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canUndoLastAction() {
|
public boolean canUndoLastAction() {
|
||||||
if (!game.stack.canUndo()) {
|
if (!game.stack.canUndo(player)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final Player priorityPlayer = game.getPhaseHandler().getPriorityPlayer();
|
final Player priorityPlayer = game.getPhaseHandler().getPriorityPlayer();
|
||||||
@@ -1467,15 +1477,15 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean mayShowCard(final Card c) {
|
public boolean mayShowCard(final Card c) {
|
||||||
if (mayLookAtAllCards()) {
|
if (mayLookAtAllCards) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return c == null || mayLookAt.contains(c) || c.canBeShownTo(player);
|
return c == null || tempShownCards.contains(c) || c.canBeShownTo(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean mayShowCardFace(final Card c) {
|
public boolean mayShowCardFace(final Card c) {
|
||||||
if (mayLookAtAllCards()) {
|
if (mayLookAtAllCards) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return c == null || !c.isFaceDown() || c.canCardFaceBeShownTo(player);
|
return c == null || !c.isFaceDown() || c.canCardFaceBeShownTo(player);
|
||||||
|
|||||||
@@ -146,6 +146,14 @@ public class Cache<K extends IIdentifiable, V extends IIdentifiable> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Iterable<K> getKeys() {
|
||||||
|
return inverseCache.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterable<V> getValues() {
|
||||||
|
return cache.values();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear all the mappings in this Cache, except for any key that exists in
|
* Clear all the mappings in this Cache, except for any key that exists in
|
||||||
* the argument.
|
* the argument.
|
||||||
|
|||||||
@@ -30,18 +30,14 @@ import forge.game.zone.ZoneType;
|
|||||||
* @author elcnesh
|
* @author elcnesh
|
||||||
*/
|
*/
|
||||||
public class CardView extends GameEntityView {
|
public class CardView extends GameEntityView {
|
||||||
|
|
||||||
public static final CardView EMPTY = new CardView(true);
|
|
||||||
|
|
||||||
private final CardStateView
|
private final CardStateView
|
||||||
original = new CardStateView(),
|
original = new CardStateView(),
|
||||||
alternate = new CardStateView();
|
alternate = new CardStateView();
|
||||||
|
|
||||||
private boolean hasAltState;
|
private boolean hasAltState;
|
||||||
|
|
||||||
private int id;
|
private final int id;
|
||||||
/** Will be false for {@link forge.game.ability.effects.DetachedCardEffect}. */
|
private boolean mayBeShown;
|
||||||
private final boolean isUiDisplayable;
|
|
||||||
private PlayerView owner, controller;
|
private PlayerView owner, controller;
|
||||||
private ZoneType zone;
|
private ZoneType zone;
|
||||||
private boolean isCloned, isFaceDown, isFlipCard, isFlipped, isSplitCard, isTransformed;
|
private boolean isCloned, isFaceDown, isFlipCard, isFlipped, isSplitCard, isTransformed;
|
||||||
@@ -68,14 +64,14 @@ public class CardView extends GameEntityView {
|
|||||||
private Iterable<CardView> mustBlock;
|
private Iterable<CardView> mustBlock;
|
||||||
private CardView pairedWith;
|
private CardView pairedWith;
|
||||||
|
|
||||||
public CardView(final boolean isUiDisplayable) {
|
public CardView(int id0) {
|
||||||
this.isUiDisplayable = isUiDisplayable;
|
this.id = id0;
|
||||||
this.reset();
|
this.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
final Iterable<CardView> emptyIterable = ImmutableSet.of();
|
final Iterable<CardView> emptyIterable = ImmutableSet.of();
|
||||||
this.id = 0;
|
this.mayBeShown = false;
|
||||||
this.hasAltState = false;
|
this.hasAltState = false;
|
||||||
this.owner = null;
|
this.owner = null;
|
||||||
this.controller = null;
|
this.controller = null;
|
||||||
@@ -120,12 +116,11 @@ public class CardView extends GameEntityView {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setId(final int id) {
|
public boolean mayBeShown() {
|
||||||
this.id = id;
|
return this.mayBeShown;
|
||||||
}
|
}
|
||||||
|
public void setMayBeShown(boolean b0) {
|
||||||
public boolean isUiDisplayable() {
|
this.mayBeShown = b0;
|
||||||
return isUiDisplayable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -726,12 +721,19 @@ public class CardView extends GameEntityView {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
if (this.getId() <= 0) { //if fake card, just return name
|
||||||
|
return this.getOriginal().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mayBeShown) {
|
||||||
|
return "(Unknown card)";
|
||||||
|
}
|
||||||
|
|
||||||
if (StringUtils.isEmpty(this.getOriginal().getName())) {
|
if (StringUtils.isEmpty(this.getOriginal().getName())) {
|
||||||
if (this.getId() <= 0) {
|
if (this.hasAltState()) {
|
||||||
return "(Unknown card)";
|
|
||||||
} else if (this.hasAltState()) {
|
|
||||||
return "Face-down card (" + this.getAlternate().getName() + ")";
|
return "Face-down card (" + this.getAlternate().getName() + ")";
|
||||||
}
|
}
|
||||||
|
return "(" + this.getId() + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.getOriginal().getName() + " (" + this.getId() + ")";
|
return this.getOriginal().getName() + " (" + this.getId() + ")";
|
||||||
@@ -765,7 +767,7 @@ public class CardView extends GameEntityView {
|
|||||||
public void reset() {
|
public void reset() {
|
||||||
this.name = "";
|
this.name = "";
|
||||||
this.colors = ColorSet.getNullColor();
|
this.colors = ColorSet.getNullColor();
|
||||||
this.imageKey = ImageKeys.TOKEN_PREFIX + ImageKeys.MORPH_IMAGE;
|
this.imageKey = ImageKeys.HIDDEN_CARD;
|
||||||
this.type = Collections.emptyList();
|
this.type = Collections.emptyList();
|
||||||
this.manaCost = ManaCost.NO_COST;
|
this.manaCost = ManaCost.NO_COST;
|
||||||
this.power = 0;
|
this.power = 0;
|
||||||
@@ -822,7 +824,7 @@ public class CardView extends GameEntityView {
|
|||||||
* @return the imageKey
|
* @return the imageKey
|
||||||
*/
|
*/
|
||||||
public String getImageKey() {
|
public String getImageKey() {
|
||||||
return imageKey;
|
return mayBeShown ? imageKey : ImageKeys.HIDDEN_CARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public abstract class LocalGameView implements IGameView {
|
|||||||
protected final InputQueue inputQueue;
|
protected final InputQueue inputQueue;
|
||||||
protected final InputProxy inputProxy;
|
protected final InputProxy inputProxy;
|
||||||
private PlayerView localPlayerView;
|
private PlayerView localPlayerView;
|
||||||
|
private int updateDelays;
|
||||||
|
|
||||||
public LocalGameView(IGuiBase gui0, Game game0) {
|
public LocalGameView(IGuiBase gui0, Game game0) {
|
||||||
game = game0;
|
game = game0;
|
||||||
@@ -349,30 +350,6 @@ public abstract class LocalGameView implements IGameView {
|
|||||||
return ViewUtil.transformIfNotNull(players, FN_GET_PLAYER_VIEW);
|
return ViewUtil.transformIfNotNull(players, FN_GET_PLAYER_VIEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerView getPlayerView(final Player p) {
|
|
||||||
if (p == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayerView view = MatchUtil.players.get(p.getId());
|
|
||||||
if (view != null) {
|
|
||||||
getPlayerView(p, view);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
view = new PlayerView(p.getLobbyPlayer(), p.getId());
|
|
||||||
MatchUtil.players.put(p, view);
|
|
||||||
getPlayerView(p, view);
|
|
||||||
}
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
private PlayerView getPlayerViewFast(final Player p) {
|
|
||||||
if (p == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return MatchUtil.players.get(p.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Player getPlayer(final PlayerView p) {
|
public Player getPlayer(final PlayerView p) {
|
||||||
if (p == null) {
|
if (p == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -380,7 +357,23 @@ public abstract class LocalGameView implements IGameView {
|
|||||||
return MatchUtil.players.getKey(p.getId());
|
return MatchUtil.players.getKey(p.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getPlayerView(final Player p, final PlayerView view) {
|
public PlayerView getPlayerView(final Player p) {
|
||||||
|
if (p == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerView view = MatchUtil.players.get(p.getId());
|
||||||
|
if (view == null) {
|
||||||
|
view = new PlayerView(p.getLobbyPlayer(), p.getId());
|
||||||
|
if (updateDelays == 0) {
|
||||||
|
writePlayerToView(p, view);
|
||||||
|
}
|
||||||
|
MatchUtil.players.put(p, view);
|
||||||
|
}
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writePlayerToView(final Player p, final PlayerView view) {
|
||||||
view.setCommanderInfo(CardFactoryUtil.getCommanderInfo(p).trim().replace("\r\n", "; "));
|
view.setCommanderInfo(CardFactoryUtil.getCommanderInfo(p).trim().replace("\r\n", "; "));
|
||||||
view.setKeywords(p.getKeywords());
|
view.setKeywords(p.getKeywords());
|
||||||
view.setLife(p.getLife());
|
view.setLife(p.getLife());
|
||||||
@@ -408,47 +401,42 @@ public abstract class LocalGameView implements IGameView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CardView getCardView(final Card c) {
|
public CardView getCardView(final Card c) {
|
||||||
if (c == null) {
|
if (c == null || c != c.getCardForUi()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Card cUi = c.getCardForUi();
|
|
||||||
final boolean isDisplayable = cUi == c;
|
|
||||||
final boolean mayShow = mayShowCard(c);
|
|
||||||
|
|
||||||
CardView view = MatchUtil.cards.get(c.getId());
|
CardView view = MatchUtil.cards.get(c.getId());
|
||||||
final boolean isNewView;
|
if (view == null) {
|
||||||
if (view != null) {
|
view = new CardView(c.getId());
|
||||||
// Update to ensure the Card reference in the cache
|
if (updateDelays == 0) {
|
||||||
// is not an outdated Card.
|
writeCardToView(c, view, MatchUtil.getGameView());
|
||||||
if (view.getId() > 0) {
|
|
||||||
MatchUtil.cards.updateKey(view.getId(), c);
|
|
||||||
}
|
}
|
||||||
isNewView = false;
|
|
||||||
} else if (isDisplayable && mayShow) {
|
|
||||||
view = new CardView(isDisplayable);
|
|
||||||
view.setId(c.getId());
|
|
||||||
MatchUtil.cards.put(c, view);
|
MatchUtil.cards.put(c, view);
|
||||||
isNewView = true;
|
|
||||||
} else {
|
|
||||||
return CardView.EMPTY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mayShow) {
|
|
||||||
writeCardToView(cUi, view);
|
|
||||||
}
|
|
||||||
else if (isDisplayable) {
|
|
||||||
if (!isNewView) {
|
|
||||||
view.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void startUpdateDelay() {
|
||||||
|
updateDelays++;
|
||||||
|
}
|
||||||
|
public void endUpdateDelay() {
|
||||||
|
if (updateDelays > 0 && --updateDelays == 0) {
|
||||||
|
updateViews();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateViews() {
|
||||||
|
if (updateDelays > 0) { return; }
|
||||||
|
|
||||||
|
for (Player p : MatchUtil.players.getKeys()) {
|
||||||
|
writePlayerToView(p, getPlayerView(p));
|
||||||
|
}
|
||||||
|
LocalGameView gameView = MatchUtil.getGameView();
|
||||||
|
for (Card c : MatchUtil.cards.getKeys()) {
|
||||||
|
writeCardToView(c, getCardView(c), gameView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final Function<Card, CardView> FN_GET_CARD_VIEW = new Function<Card, CardView>() {
|
private final Function<Card, CardView> FN_GET_CARD_VIEW = new Function<Card, CardView>() {
|
||||||
@Override
|
@Override
|
||||||
public CardView apply(final Card input) {
|
public CardView apply(final Card input) {
|
||||||
@@ -460,41 +448,6 @@ public abstract class LocalGameView implements IGameView {
|
|||||||
return ViewUtil.transformIfNotNull(cards, FN_GET_CARD_VIEW);
|
return ViewUtil.transformIfNotNull(cards, FN_GET_CARD_VIEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final List<CardView> getRefreshedCardViews(final Iterable<CardView> cardViews) {
|
|
||||||
return ViewUtil.transformIfNotNull(cardViews, new Function<CardView, CardView>() {
|
|
||||||
@Override
|
|
||||||
public CardView apply(final CardView input) {
|
|
||||||
return MatchUtil.cards.getCurrentValue(input);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private CardView getCardViewFast(final Card c) {
|
|
||||||
if (c == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final CardView view = MatchUtil.cards.get(c.getId());
|
|
||||||
if (mayShowCard(c)) {
|
|
||||||
return view;
|
|
||||||
} else if (view.isUiDisplayable()) {
|
|
||||||
return CardView.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Function<Card, CardView> FN_GET_CARDVIEW_FAST = new Function<Card, CardView>() {
|
|
||||||
@Override
|
|
||||||
public CardView apply(Card input) {
|
|
||||||
return getCardViewFast(input);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private List<CardView> getCardViewsFast(final Iterable<Card> cards) {
|
|
||||||
return ViewUtil.transformIfNotNull(cards, FN_GET_CARDVIEW_FAST);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Card getCard(final CardView c) {
|
public Card getCard(final CardView c) {
|
||||||
if (c == null) {
|
if (c == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -513,29 +466,29 @@ public abstract class LocalGameView implements IGameView {
|
|||||||
return ViewUtil.transformIfNotNull(cards, FN_GET_CARD);
|
return ViewUtil.transformIfNotNull(cards, FN_GET_CARD);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeCardToView(final Card c, final CardView view) {
|
private void writeCardToView(final Card c, final CardView view, final LocalGameView gameView) {
|
||||||
// First, write the values independent of other views.
|
// First, write the values independent of other views.
|
||||||
ViewUtil.writeNonDependentCardViewProperties(c, view, mayShowCardFace(c));
|
ViewUtil.writeNonDependentCardViewProperties(c, view, gameView.mayShowCard(c), gameView.mayShowCardFace(c));
|
||||||
// Next, write the values that depend on other views.
|
// Next, write the values that depend on other views.
|
||||||
final Combat combat = game.getCombat();
|
final Combat combat = game.getCombat();
|
||||||
view.setOwner(getPlayerViewFast(c.getOwner()));
|
view.setOwner(getPlayerView(c.getOwner()));
|
||||||
view.setController(getPlayerViewFast(c.getController()));
|
view.setController(getPlayerView(c.getController()));
|
||||||
view.setAttacking(combat != null && combat.isAttacking(c));
|
view.setAttacking(combat != null && combat.isAttacking(c));
|
||||||
view.setBlocking(combat != null && combat.isBlocking(c));
|
view.setBlocking(combat != null && combat.isBlocking(c));
|
||||||
view.setChosenPlayer(getPlayerViewFast(c.getChosenPlayer()));
|
view.setChosenPlayer(getPlayerView(c.getChosenPlayer()));
|
||||||
view.setEquipping(getCardViewFast(Iterables.getFirst(c.getEquipping(), null)));
|
view.setEquipping(getCardView(Iterables.getFirst(c.getEquipping(), null)));
|
||||||
view.setEquippedBy(getCardViewsFast(c.getEquippedBy()));
|
view.setEquippedBy(getCardViews(c.getEquippedBy()));
|
||||||
view.setEnchantingCard(getCardViewFast(c.getEnchantingCard()));
|
view.setEnchantingCard(getCardView(c.getEnchantingCard()));
|
||||||
view.setEnchantingPlayer(getPlayerViewFast(c.getEnchantingPlayer()));
|
view.setEnchantingPlayer(getPlayerView(c.getEnchantingPlayer()));
|
||||||
view.setEnchantedBy(getCardViewsFast(c.getEnchantedBy()));
|
view.setEnchantedBy(getCardViews(c.getEnchantedBy()));
|
||||||
view.setFortifiedBy(getCardViewsFast(c.getFortifiedBy()));
|
view.setFortifiedBy(getCardViews(c.getFortifiedBy()));
|
||||||
view.setGainControlTargets(getCardViewsFast(c.getGainControlTargets()));
|
view.setGainControlTargets(getCardViews(c.getGainControlTargets()));
|
||||||
view.setCloneOrigin(getCardViewFast(c.getCloneOrigin()));
|
view.setCloneOrigin(getCardView(c.getCloneOrigin()));
|
||||||
view.setImprinted(getCardViewsFast(c.getImprinted()));
|
view.setImprinted(getCardViews(c.getImprinted()));
|
||||||
view.setHauntedBy(getCardViewsFast(c.getHauntedBy()));
|
view.setHauntedBy(getCardViews(c.getHauntedBy()));
|
||||||
view.setHaunting(getCardViewFast(c.getHaunting()));
|
view.setHaunting(getCardView(c.getHaunting()));
|
||||||
view.setMustBlock(c.getMustBlockCards() == null ? Collections.<CardView>emptySet() : getCardViewsFast(c.getMustBlockCards()));
|
view.setMustBlock(c.getMustBlockCards() == null ? Collections.<CardView>emptySet() : getCardViews(c.getMustBlockCards()));
|
||||||
view.setPairedWith(getCardViewFast(c.getPairedWith()));
|
view.setPairedWith(getCardView(c.getPairedWith()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpellAbilityView getSpellAbilityView(final SpellAbility sa) {
|
public SpellAbilityView getSpellAbilityView(final SpellAbility sa) {
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ public final class ViewUtil {
|
|||||||
* @param view
|
* @param view
|
||||||
* the {@link CardView} to write to.
|
* the {@link CardView} to write to.
|
||||||
*/
|
*/
|
||||||
public static void writeNonDependentCardViewProperties(final Card c, final CardView view, final boolean mayShowCardFace) {
|
public static void writeNonDependentCardViewProperties(final Card c, final CardView view, final boolean mayShowCard, final boolean mayShowCardFace) {
|
||||||
final boolean hasAltState = c.isDoubleFaced() || c.isFlipCard() || c.isSplitCard() || (c.isFaceDown() && mayShowCardFace);
|
final boolean hasAltState = c.isDoubleFaced() || c.isFlipCard() || c.isSplitCard() || (c.isFaceDown() && mayShowCardFace);
|
||||||
view.setId(c.getUniqueNumber());
|
view.setMayBeShown(mayShowCard);
|
||||||
view.setZone(c.getZone() == null ? null : c.getZone().getZoneType());
|
view.setZone(c.getZone() == null ? null : c.getZone().getZoneType());
|
||||||
view.setHasAltState(hasAltState);
|
view.setHasAltState(hasAltState);
|
||||||
view.setFaceDown(c.isFaceDown());
|
view.setFaceDown(c.isFaceDown());
|
||||||
@@ -130,8 +130,11 @@ public final class ViewUtil {
|
|||||||
|
|
||||||
public static CardView getCardForUi(final IPaperCard pc) {
|
public static CardView getCardForUi(final IPaperCard pc) {
|
||||||
final Card c = Card.getCardForUi(pc);
|
final Card c = Card.getCardForUi(pc);
|
||||||
final CardView view = new CardView(true);
|
if (c.getCardForUi() != c) {
|
||||||
writeNonDependentCardViewProperties(c, view, c.getCardForUi() == c);
|
return null;
|
||||||
|
}
|
||||||
|
final CardView view = new CardView(c.getId());
|
||||||
|
writeNonDependentCardViewProperties(c, view, true, true);
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user