mirror of
https://github.com/correl/mage.git
synced 2025-04-02 11:25:59 -09:00
* UI: improved and fixed possible targets highlighting:
* added blockers highlighting on declare blockers step; * fixed that blocker targets highlights all attackers instead real; * fixed wrong attackers draw in images render mode;
This commit is contained in:
parent
c58b28f94f
commit
0e6dbb4eed
7 changed files with 167 additions and 132 deletions
Mage.Client/src/main/java
mage/client/game
org/mage/card/arcane
Mage.Common/src/main/java/mage
Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human
|
@ -696,6 +696,13 @@ public final class GamePanel extends javax.swing.JPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<UUID> possibleBlockers = new ArrayList<>();
|
||||||
|
if (options != null && options.containsKey(Constants.Option.POSSIBLE_BLOCKERS)) {
|
||||||
|
if (options.get(Constants.Option.POSSIBLE_BLOCKERS) instanceof List) {
|
||||||
|
possibleBlockers.addAll((List) options.get(Constants.Option.POSSIBLE_BLOCKERS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (PlayerView player : game.getPlayers()) {
|
for (PlayerView player : game.getPlayers()) {
|
||||||
if (players.containsKey(player.getPlayerId())) {
|
if (players.containsKey(player.getPlayerId())) {
|
||||||
if (!possibleAttackers.isEmpty()) {
|
if (!possibleAttackers.isEmpty()) {
|
||||||
|
@ -705,6 +712,13 @@ public final class GamePanel extends javax.swing.JPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!possibleBlockers.isEmpty()) {
|
||||||
|
for (UUID permanentId : possibleBlockers) {
|
||||||
|
if (player.getBattlefield().containsKey(permanentId)) {
|
||||||
|
player.getBattlefield().get(permanentId).setCanBlock(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
players.get(player.getPlayerId()).update(player);
|
players.get(player.getPlayerId()).update(player);
|
||||||
if (player.getPlayerId().equals(playerId)) {
|
if (player.getPlayerId().equals(playerId)) {
|
||||||
skipButtons.updateFromPlayer(player);
|
skipButtons.updateFromPlayer(player);
|
||||||
|
|
|
@ -1,17 +1,5 @@
|
||||||
package org.mage.card.arcane;
|
package org.mage.card.arcane;
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.util.StringTokenizer;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.jdesktop.swingx.graphics.GraphicsUtilities;
|
|
||||||
import org.mage.plugins.card.images.ImageCache;
|
|
||||||
import org.mage.plugins.card.utils.impl.ImageManagerImpl;
|
|
||||||
|
|
||||||
import mage.cards.action.ActionCallback;
|
import mage.cards.action.ActionCallback;
|
||||||
import mage.client.constants.Constants;
|
import mage.client.constants.Constants;
|
||||||
import mage.client.dialog.PreferencesDialog;
|
import mage.client.dialog.PreferencesDialog;
|
||||||
|
@ -25,6 +13,16 @@ import mage.view.CardView;
|
||||||
import mage.view.CounterView;
|
import mage.view.CounterView;
|
||||||
import mage.view.PermanentView;
|
import mage.view.PermanentView;
|
||||||
import mage.view.StackAbilityView;
|
import mage.view.StackAbilityView;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.jdesktop.swingx.graphics.GraphicsUtilities;
|
||||||
|
import org.mage.plugins.card.images.ImageCache;
|
||||||
|
import org.mage.plugins.card.utils.impl.ImageManagerImpl;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for drawing the mage card object by using a form based JComponent
|
* Class for drawing the mage card object by using a form based JComponent
|
||||||
|
@ -117,8 +115,9 @@ public class CardPanelComponentImpl extends CardPanel {
|
||||||
final boolean isChoosable;
|
final boolean isChoosable;
|
||||||
final boolean isPlayable;
|
final boolean isPlayable;
|
||||||
final boolean canAttack;
|
final boolean canAttack;
|
||||||
|
final boolean canBlock;
|
||||||
|
|
||||||
public Key(int width, int height, int cardWidth, int cardHeight, int cardXOffset, int cardYOffset, boolean hasImage, boolean isSelected, boolean isChoosable, boolean isPlayable, boolean canAttack) {
|
public Key(int width, int height, int cardWidth, int cardHeight, int cardXOffset, int cardYOffset, boolean hasImage, boolean isSelected, boolean isChoosable, boolean isPlayable, boolean canAttack, boolean canBlock) {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
this.cardWidth = cardWidth;
|
this.cardWidth = cardWidth;
|
||||||
|
@ -130,6 +129,7 @@ public class CardPanelComponentImpl extends CardPanel {
|
||||||
this.isChoosable = isChoosable;
|
this.isChoosable = isChoosable;
|
||||||
this.isPlayable = isPlayable;
|
this.isPlayable = isPlayable;
|
||||||
this.canAttack = canAttack;
|
this.canAttack = canAttack;
|
||||||
|
this.canBlock = canBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -146,6 +146,7 @@ public class CardPanelComponentImpl extends CardPanel {
|
||||||
hash = 19 * hash + (this.isChoosable ? 1 : 0);
|
hash = 19 * hash + (this.isChoosable ? 1 : 0);
|
||||||
hash = 19 * hash + (this.isPlayable ? 1 : 0);
|
hash = 19 * hash + (this.isPlayable ? 1 : 0);
|
||||||
hash = 19 * hash + (this.canAttack ? 1 : 0);
|
hash = 19 * hash + (this.canAttack ? 1 : 0);
|
||||||
|
hash = 19 * hash + (this.canBlock ? 1 : 0);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +195,7 @@ public class CardPanelComponentImpl extends CardPanel {
|
||||||
if (this.canAttack != other.canAttack) {
|
if (this.canAttack != other.canAttack) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return this.canBlock == other.canBlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,20 +203,20 @@ public class CardPanelComponentImpl extends CardPanel {
|
||||||
IMAGE_CACHE = ImageCaches.register(SoftValuesLoadingCache.from(CardPanelComponentImpl::createImage));
|
IMAGE_CACHE = ImageCaches.register(SoftValuesLoadingCache.from(CardPanelComponentImpl::createImage));
|
||||||
}
|
}
|
||||||
|
|
||||||
static private boolean canShowCardIcons(int cardFullWidth, boolean cardHasImage){
|
static private boolean canShowCardIcons(int cardFullWidth, boolean cardHasImage) {
|
||||||
// cards without images show icons and text always
|
// cards without images show icons and text always
|
||||||
// TODO: apply "card names on card" setting to icon too?
|
// TODO: apply "card names on card" setting to icon too?
|
||||||
// TODO: fix card min-max size to hide (compare to settings size, not direct 60 and 200)
|
// TODO: fix card min-max size to hide (compare to settings size, not direct 60 and 200)
|
||||||
return ((cardFullWidth > 60) && (cardFullWidth < 200)) || (!cardHasImage);
|
return ((cardFullWidth > 60) && (cardFullWidth < 200)) || (!cardHasImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CardSizes{
|
private static class CardSizes {
|
||||||
Rectangle rectFull;
|
Rectangle rectFull;
|
||||||
Rectangle rectSelection;
|
Rectangle rectSelection;
|
||||||
Rectangle rectBorder;
|
Rectangle rectBorder;
|
||||||
Rectangle rectCard;
|
Rectangle rectCard;
|
||||||
|
|
||||||
CardSizes(int offsetX, int offsetY, int fullWidth, int fullHeight){
|
CardSizes(int offsetX, int offsetY, int fullWidth, int fullHeight) {
|
||||||
|
|
||||||
int realBorderSizeX = Math.round(fullWidth * BLACK_BORDER_SIZE);
|
int realBorderSizeX = Math.round(fullWidth * BLACK_BORDER_SIZE);
|
||||||
int realBorderSizeY = Math.round(fullWidth * BLACK_BORDER_SIZE);
|
int realBorderSizeY = Math.round(fullWidth * BLACK_BORDER_SIZE);
|
||||||
|
@ -406,7 +407,8 @@ public class CardPanelComponentImpl extends CardPanel {
|
||||||
g2d.drawImage(
|
g2d.drawImage(
|
||||||
IMAGE_CACHE.getOrThrow(
|
IMAGE_CACHE.getOrThrow(
|
||||||
new Key(getWidth(), getHeight(), getCardWidth(), getCardHeight(), getCardXOffset(), getCardYOffset(),
|
new Key(getWidth(), getHeight(), getCardWidth(), getCardHeight(), getCardXOffset(), getCardYOffset(),
|
||||||
hasImage, isSelected(), isChoosable(), getGameCard().isPlayable(), getGameCard().isCanAttack())),
|
hasImage, isSelected(), isChoosable(), getGameCard().isPlayable(), getGameCard().isCanAttack(),
|
||||||
|
getGameCard().isCanBlock())),
|
||||||
0, 0, null);
|
0, 0, null);
|
||||||
g2d.dispose();
|
g2d.dispose();
|
||||||
}
|
}
|
||||||
|
@ -442,6 +444,12 @@ public class CardPanelComponentImpl extends CardPanel {
|
||||||
g2d.fillRoundRect(sizes.rectSelection.x, sizes.rectSelection.y, sizes.rectSelection.width, sizes.rectSelection.height, cornerSizeSelection, cornerSizeSelection);
|
g2d.fillRoundRect(sizes.rectSelection.x, sizes.rectSelection.y, sizes.rectSelection.width, sizes.rectSelection.height, cornerSizeSelection, cornerSizeSelection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// draw attack or block border (?inner part of selection?)
|
||||||
|
if (key.canAttack || key.canBlock) {
|
||||||
|
g2d.setColor(new Color(255, 50, 50, 230));
|
||||||
|
g2d.fillRoundRect(sizes.rectSelection.x + 1, sizes.rectSelection.y + 1, sizes.rectSelection.width - 2, sizes.rectSelection.height - 2, cornerSizeSelection, cornerSizeSelection);
|
||||||
|
}
|
||||||
|
|
||||||
// draw empty card with border
|
// draw empty card with border
|
||||||
if (!key.hasImage) {
|
if (!key.hasImage) {
|
||||||
// gray 1 px border
|
// gray 1 px border
|
||||||
|
@ -452,12 +460,6 @@ public class CardPanelComponentImpl extends CardPanel {
|
||||||
g2d.fillRoundRect(sizes.rectBorder.x + 1, sizes.rectBorder.y + 1, sizes.rectBorder.width - 2, sizes.rectBorder.height - 2, cornerSizeBorder, cornerSizeBorder);
|
g2d.fillRoundRect(sizes.rectBorder.x + 1, sizes.rectBorder.y + 1, sizes.rectBorder.width - 2, sizes.rectBorder.height - 2, cornerSizeBorder, cornerSizeBorder);
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw attack border (inner part of selection)
|
|
||||||
if (key.canAttack) {
|
|
||||||
g2d.setColor(new Color(0, 0, 255, 230));
|
|
||||||
g2d.fillRoundRect(sizes.rectBorder.x + 1, sizes.rectBorder.y + 1, sizes.rectBorder.width - 2, sizes.rectBorder.height - 2, cornerSizeBorder, cornerSizeBorder);
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw real card by component (see imagePanel and other layout's items)
|
// draw real card by component (see imagePanel and other layout's items)
|
||||||
|
|
||||||
//TODO:uncomment
|
//TODO:uncomment
|
||||||
|
@ -521,7 +523,7 @@ public class CardPanelComponentImpl extends CardPanel {
|
||||||
StringTokenizer tok = new StringTokenizer(manaCost, " ");
|
StringTokenizer tok = new StringTokenizer(manaCost, " ");
|
||||||
while (tok.hasMoreTokens()) {
|
while (tok.hasMoreTokens()) {
|
||||||
tok.nextToken();
|
tok.nextToken();
|
||||||
if(width != 0) {
|
if (width != 0) {
|
||||||
width += symbolMarginX;
|
width += symbolMarginX;
|
||||||
}
|
}
|
||||||
width += getSymbolWidth();
|
width += getSymbolWidth();
|
||||||
|
|
|
@ -1,17 +1,7 @@
|
||||||
package org.mage.card.arcane;
|
package org.mage.card.arcane;
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.jdesktop.swingx.graphics.GraphicsUtilities;
|
|
||||||
import org.mage.plugins.card.images.ImageCache;
|
|
||||||
|
|
||||||
import com.google.common.cache.Cache;
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
|
||||||
import mage.cards.action.ActionCallback;
|
import mage.cards.action.ActionCallback;
|
||||||
import mage.client.constants.Constants;
|
import mage.client.constants.Constants;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
|
@ -21,6 +11,14 @@ import mage.view.CardView;
|
||||||
import mage.view.CounterView;
|
import mage.view.CounterView;
|
||||||
import mage.view.PermanentView;
|
import mage.view.PermanentView;
|
||||||
import mage.view.StackAbilityView;
|
import mage.view.StackAbilityView;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.jdesktop.swingx.graphics.GraphicsUtilities;
|
||||||
|
import org.mage.plugins.card.images.ImageCache;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
public class CardPanelRenderImpl extends CardPanel {
|
public class CardPanelRenderImpl extends CardPanel {
|
||||||
|
|
||||||
|
@ -107,9 +105,7 @@ public class CardPanelRenderImpl extends CardPanel {
|
||||||
// are the same for a and b
|
// are the same for a and b
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (aa.getDamage() != bb.getDamage()) {
|
return aa.getDamage() == bb.getDamage();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -143,6 +139,7 @@ public class CardPanelRenderImpl extends CardPanel {
|
||||||
sb.append((char) (isChoosable ? 1 : 0));
|
sb.append((char) (isChoosable ? 1 : 0));
|
||||||
sb.append((char) (this.view.isPlayable() ? 1 : 0));
|
sb.append((char) (this.view.isPlayable() ? 1 : 0));
|
||||||
sb.append((char) (this.view.isCanAttack() ? 1 : 0));
|
sb.append((char) (this.view.isCanAttack() ? 1 : 0));
|
||||||
|
sb.append((char) (this.view.isCanBlock() ? 1 : 0));
|
||||||
sb.append((char) (this.view.isFaceDown() ? 1 : 0));
|
sb.append((char) (this.view.isFaceDown() ? 1 : 0));
|
||||||
sb.append((char) this.view.getFrameStyle().ordinal());
|
sb.append((char) this.view.getFrameStyle().ordinal());
|
||||||
if (this.view instanceof PermanentView) {
|
if (this.view instanceof PermanentView) {
|
||||||
|
@ -266,8 +263,8 @@ public class CardPanelRenderImpl extends CardPanel {
|
||||||
// Try to get card image from cache based on our card characteristics
|
// Try to get card image from cache based on our card characteristics
|
||||||
ImageKey key
|
ImageKey key
|
||||||
= new ImageKey(getGameCard(), artImage,
|
= new ImageKey(getGameCard(), artImage,
|
||||||
getCardWidth(), getCardHeight(),
|
getCardWidth(), getCardHeight(),
|
||||||
isChoosable(), isSelected());
|
isChoosable(), isSelected());
|
||||||
try {
|
try {
|
||||||
cardImage = IMAGE_CACHE.get(key, this::renderCard);
|
cardImage = IMAGE_CACHE.get(key, this::renderCard);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
|
|
|
@ -5,24 +5,6 @@
|
||||||
*/
|
*/
|
||||||
package org.mage.card.arcane;
|
package org.mage.card.arcane;
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.font.*;
|
|
||||||
import java.awt.geom.Arc2D;
|
|
||||||
import java.awt.geom.Area;
|
|
||||||
import java.awt.geom.Path2D;
|
|
||||||
import java.awt.geom.Rectangle2D;
|
|
||||||
import java.awt.geom.RoundRectangle2D;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.text.AttributedCharacterIterator;
|
|
||||||
import java.text.AttributedString;
|
|
||||||
import java.text.CharacterIterator;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.swing.*;
|
|
||||||
import mage.ObjectColor;
|
import mage.ObjectColor;
|
||||||
import mage.cards.ArtRect;
|
import mage.cards.ArtRect;
|
||||||
import mage.cards.FrameStyle;
|
import mage.cards.FrameStyle;
|
||||||
|
@ -34,6 +16,22 @@ import mage.util.SubTypeList;
|
||||||
import mage.view.CardView;
|
import mage.view.CardView;
|
||||||
import mage.view.PermanentView;
|
import mage.view.PermanentView;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.font.*;
|
||||||
|
import java.awt.geom.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.text.AttributedCharacterIterator;
|
||||||
|
import java.text.AttributedString;
|
||||||
|
import java.text.CharacterIterator;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.mage.card.arcane.ManaSymbols.getSizedManaSymbol;
|
import static org.mage.card.arcane.ManaSymbols.getSizedManaSymbol;
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,9 +54,10 @@ import static org.mage.card.arcane.ManaSymbols.getSizedManaSymbol;
|
||||||
render.draw(g, cardWidth, cardHeight);
|
render.draw(g, cardWidth, cardHeight);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author stravant@gmail.com
|
* @author stravant@gmail.com
|
||||||
*
|
* <p>
|
||||||
* Base rendering class for new border cards
|
* Base rendering class for new border cards
|
||||||
*/
|
*/
|
||||||
public class ModernCardRenderer extends CardRenderer {
|
public class ModernCardRenderer extends CardRenderer {
|
||||||
|
@ -98,6 +97,7 @@ public class ModernCardRenderer extends CardRenderer {
|
||||||
}
|
}
|
||||||
return new Font("Arial", Font.PLAIN, 1);
|
return new Font("Arial", Font.PLAIN, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Font BASE_BELEREN_FONT = loadFont("beleren-bold");
|
public static final Font BASE_BELEREN_FONT = loadFont("beleren-bold");
|
||||||
|
|
||||||
public static final Paint BG_TEXTURE_WHITE = loadBackgroundTexture("white");
|
public static final Paint BG_TEXTURE_WHITE = loadBackgroundTexture("white");
|
||||||
|
@ -275,7 +275,9 @@ public class ModernCardRenderer extends CardRenderer {
|
||||||
} else if (cardView.isPlayable()) {
|
} else if (cardView.isPlayable()) {
|
||||||
borderColor = new Color(153, 102, 204, 200);
|
borderColor = new Color(153, 102, 204, 200);
|
||||||
} else if (cardView.isCanAttack()) {
|
} else if (cardView.isCanAttack()) {
|
||||||
borderColor = new Color(0, 0, 255, 230);
|
borderColor = new Color(255, 50, 50, 230);
|
||||||
|
} else if (cardView.isCanBlock()) {
|
||||||
|
borderColor = new Color(255, 50, 50, 230);
|
||||||
} else {
|
} else {
|
||||||
borderColor = Color.BLACK;
|
borderColor = Color.BLACK;
|
||||||
}
|
}
|
||||||
|
@ -659,7 +661,7 @@ public class ModernCardRenderer extends CardRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawZendikarCurvedFace(Graphics2D g2, BufferedImage image, int x, int y, int x2, int y2,
|
public void drawZendikarCurvedFace(Graphics2D g2, BufferedImage image, int x, int y, int x2, int y2,
|
||||||
Color boxColor, Paint paint) {
|
Color boxColor, Paint paint) {
|
||||||
|
|
||||||
BufferedImage artToUse = faceArtImage;
|
BufferedImage artToUse = faceArtImage;
|
||||||
boolean hadToUseFullArt = false;
|
boolean hadToUseFullArt = false;
|
||||||
|
@ -707,8 +709,8 @@ public class ModernCardRenderer extends CardRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawBFZCurvedFace(Graphics2D g2, BufferedImage image, int x, int y, int x2, int y2,
|
public void drawBFZCurvedFace(Graphics2D g2, BufferedImage image, int x, int y, int x2, int y2,
|
||||||
int topxdelta, int endydelta,
|
int topxdelta, int endydelta,
|
||||||
Color boxColor, Paint paint) {
|
Color boxColor, Paint paint) {
|
||||||
BufferedImage artToUse = faceArtImage;
|
BufferedImage artToUse = faceArtImage;
|
||||||
boolean hadToUseFullArt = false;
|
boolean hadToUseFullArt = false;
|
||||||
if (faceArtImage == null) {
|
if (faceArtImage == null) {
|
||||||
|
@ -764,10 +766,10 @@ public class ModernCardRenderer extends CardRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawUSTCurves(Graphics2D g2, BufferedImage image, int x, int y, int x2, int y2,
|
public void drawUSTCurves(Graphics2D g2, BufferedImage image, int x, int y, int x2, int y2,
|
||||||
int topxdelta, int endydelta,
|
int topxdelta, int endydelta,
|
||||||
Color boxColor, Paint paint) {
|
Color boxColor, Paint paint) {
|
||||||
BufferedImage artToUse = artImage;
|
BufferedImage artToUse = artImage;
|
||||||
|
|
||||||
int srcW = x2;
|
int srcW = x2;
|
||||||
int srcH = y2;
|
int srcH = y2;
|
||||||
if (artToUse != null) {
|
if (artToUse != null) {
|
||||||
|
@ -999,23 +1001,23 @@ public class ModernCardRenderer extends CardRenderer {
|
||||||
|
|
||||||
Polygon symbol = new Polygon(
|
Polygon symbol = new Polygon(
|
||||||
new int[]{
|
new int[]{
|
||||||
x + w / 2,
|
x + w / 2,
|
||||||
(int) (x + w * 0.9),
|
(int) (x + w * 0.9),
|
||||||
x + w,
|
x + w,
|
||||||
(int) (x + w * 0.6),
|
(int) (x + w * 0.6),
|
||||||
x + w / 2,
|
x + w / 2,
|
||||||
(int) (x + w * 0.4),
|
(int) (x + w * 0.4),
|
||||||
x,
|
x,
|
||||||
(int) (x + w * 0.1),},
|
(int) (x + w * 0.1),},
|
||||||
new int[]{
|
new int[]{
|
||||||
y + h,
|
y + h,
|
||||||
(int) (y + 0.8 * h),
|
(int) (y + 0.8 * h),
|
||||||
y,
|
y,
|
||||||
(int) (y - 0.2 * h),
|
(int) (y - 0.2 * h),
|
||||||
y,
|
y,
|
||||||
(int) (y - 0.2 * h),
|
(int) (y - 0.2 * h),
|
||||||
y,
|
y,
|
||||||
(int) (y + 0.8 * h),},
|
(int) (y + 0.8 * h),},
|
||||||
8);
|
8);
|
||||||
|
|
||||||
// Draw + stroke
|
// Draw + stroke
|
||||||
|
@ -1124,7 +1126,7 @@ public class ModernCardRenderer extends CardRenderer {
|
||||||
drawBasicManaTextbox(g, x, y, w, h, ((TextboxBasicManaRule) allRules.get(0)).getBasicManaSymbol());
|
drawBasicManaTextbox(g, x, y, w, h, ((TextboxBasicManaRule) allRules.get(0)).getBasicManaSymbol());
|
||||||
return;
|
return;
|
||||||
} else // Big circle in the middle for Zendikar lands
|
} else // Big circle in the middle for Zendikar lands
|
||||||
if (allRules.size() == 1) {
|
if (allRules.size() == 1) {
|
||||||
// Size of mana symbol = 9/4 * h, 3/4h above line
|
// Size of mana symbol = 9/4 * h, 3/4h above line
|
||||||
if (allRules.get(0) instanceof TextboxBasicManaRule) {
|
if (allRules.get(0) instanceof TextboxBasicManaRule) {
|
||||||
drawBasicManaSymbol(g, x + w / 2 - 9 * h / 8 + 1, y - 3 * h / 4, 9 * h / 4, 9 * h / 4, ((TextboxBasicManaRule) allRules.get(0)).getBasicManaSymbol());
|
drawBasicManaSymbol(g, x + w / 2 - 9 * h / 8 + 1, y - 3 * h / 4, 9 * h / 4, 9 * h / 4, ((TextboxBasicManaRule) allRules.get(0)).getBasicManaSymbol());
|
||||||
|
@ -1278,45 +1280,45 @@ public class ModernCardRenderer extends CardRenderer {
|
||||||
if (loyaltyRule.loyaltyChange < 0 || loyaltyRule.loyaltyChange == TextboxLoyaltyRule.MINUS_X) {
|
if (loyaltyRule.loyaltyChange < 0 || loyaltyRule.loyaltyChange == TextboxLoyaltyRule.MINUS_X) {
|
||||||
symbol = new Polygon(
|
symbol = new Polygon(
|
||||||
new int[]{
|
new int[]{
|
||||||
symbolX,
|
symbolX,
|
||||||
symbolX + symbolWidth,
|
symbolX + symbolWidth,
|
||||||
symbolX + symbolWidth,
|
symbolX + symbolWidth,
|
||||||
symbolX + symbolWidth / 2,
|
symbolX + symbolWidth / 2,
|
||||||
symbolX,},
|
symbolX,},
|
||||||
new int[]{
|
new int[]{
|
||||||
symbolY,
|
symbolY,
|
||||||
symbolY,
|
symbolY,
|
||||||
symbolY + symbolHeight - 3,
|
symbolY + symbolHeight - 3,
|
||||||
symbolY + symbolHeight + 3,
|
symbolY + symbolHeight + 3,
|
||||||
symbolY + symbolHeight - 3,},
|
symbolY + symbolHeight - 3,},
|
||||||
5);
|
5);
|
||||||
} else if (loyaltyRule.loyaltyChange > 0) {
|
} else if (loyaltyRule.loyaltyChange > 0) {
|
||||||
symbol = new Polygon(
|
symbol = new Polygon(
|
||||||
new int[]{
|
new int[]{
|
||||||
symbolX,
|
symbolX,
|
||||||
symbolX + symbolWidth / 2,
|
symbolX + symbolWidth / 2,
|
||||||
symbolX + symbolWidth,
|
symbolX + symbolWidth,
|
||||||
symbolX + symbolWidth,
|
symbolX + symbolWidth,
|
||||||
symbolX,},
|
symbolX,},
|
||||||
new int[]{
|
new int[]{
|
||||||
symbolY + 3,
|
symbolY + 3,
|
||||||
symbolY - 3,
|
symbolY - 3,
|
||||||
symbolY + 3,
|
symbolY + 3,
|
||||||
symbolY + symbolHeight,
|
symbolY + symbolHeight,
|
||||||
symbolY + symbolHeight,},
|
symbolY + symbolHeight,},
|
||||||
5);
|
5);
|
||||||
} else {
|
} else {
|
||||||
symbol = new Polygon(
|
symbol = new Polygon(
|
||||||
new int[]{
|
new int[]{
|
||||||
symbolX,
|
symbolX,
|
||||||
symbolX + symbolWidth,
|
symbolX + symbolWidth,
|
||||||
symbolX + symbolWidth,
|
symbolX + symbolWidth,
|
||||||
symbolX,},
|
symbolX,},
|
||||||
new int[]{
|
new int[]{
|
||||||
symbolY,
|
symbolY,
|
||||||
symbolY,
|
symbolY,
|
||||||
symbolY + symbolHeight,
|
symbolY + symbolHeight,
|
||||||
symbolY + symbolHeight,},
|
symbolY + symbolHeight,},
|
||||||
4);
|
4);
|
||||||
}
|
}
|
||||||
g.setColor(new Color(0, 0, 0, 128));
|
g.setColor(new Color(0, 0, 0, 128));
|
||||||
|
@ -1610,13 +1612,13 @@ public class ModernCardRenderer extends CardRenderer {
|
||||||
Color[] translatedColors;
|
Color[] translatedColors;
|
||||||
if (types.contains(CardType.LAND)) {
|
if (types.contains(CardType.LAND)) {
|
||||||
translatedColors = new Color[]{
|
translatedColors = new Color[]{
|
||||||
getLandTextboxColor(twoColors.get(0)),
|
getLandTextboxColor(twoColors.get(0)),
|
||||||
getLandTextboxColor(twoColors.get(1))
|
getLandTextboxColor(twoColors.get(1))
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
translatedColors = new Color[]{
|
translatedColors = new Color[]{
|
||||||
getTextboxColor(twoColors.get(0)),
|
getTextboxColor(twoColors.get(0)),
|
||||||
getTextboxColor(twoColors.get(1))
|
getTextboxColor(twoColors.get(1))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
|
|
||||||
package mage.constants;
|
package mage.constants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
public final class Constants {
|
public final class Constants {
|
||||||
|
@ -50,19 +48,14 @@ public final class Constants {
|
||||||
*/
|
*/
|
||||||
public static final int PRIORITY_TIME_SEC = 1200;
|
public static final int PRIORITY_TIME_SEC = 1200;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public enum Option {
|
public enum Option {
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
public static final String POSSIBLE_ATTACKERS = "possibleAttackers";
|
public static final String POSSIBLE_ATTACKERS = "possibleAttackers";
|
||||||
|
public static final String POSSIBLE_BLOCKERS = "possibleBlockers";
|
||||||
public static final String SPECIAL_BUTTON = "specialButton";
|
public static final String SPECIAL_BUTTON = "specialButton";
|
||||||
// used to control automatic answers of optional effects
|
// used to control automatic answers of optional effects
|
||||||
public static final String ORIGINAL_ID = "originalId";
|
public static final String ORIGINAL_ID = "originalId";
|
||||||
public static final String SECOND_MESSAGE = "secondMessage";
|
public static final String SECOND_MESSAGE = "secondMessage";
|
||||||
public static final String HINT_TEXT = "hintText";
|
public static final String HINT_TEXT = "hintText";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.view;
|
package mage.view;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
|
@ -109,6 +108,7 @@ public class CardView extends SimpleCardView {
|
||||||
protected boolean isChoosable;
|
protected boolean isChoosable;
|
||||||
protected boolean selected;
|
protected boolean selected;
|
||||||
protected boolean canAttack;
|
protected boolean canAttack;
|
||||||
|
protected boolean canBlock;
|
||||||
protected boolean inViewerOnly;
|
protected boolean inViewerOnly;
|
||||||
|
|
||||||
protected Card originalCard = null;
|
protected Card originalCard = null;
|
||||||
|
@ -202,6 +202,7 @@ public class CardView extends SimpleCardView {
|
||||||
this.isChoosable = cardView.isChoosable;
|
this.isChoosable = cardView.isChoosable;
|
||||||
this.selected = cardView.selected;
|
this.selected = cardView.selected;
|
||||||
this.canAttack = cardView.canAttack;
|
this.canAttack = cardView.canAttack;
|
||||||
|
this.canBlock = cardView.canBlock;
|
||||||
this.inViewerOnly = cardView.inViewerOnly;
|
this.inViewerOnly = cardView.inViewerOnly;
|
||||||
this.originalCard = cardView.originalCard.copy();
|
this.originalCard = cardView.originalCard.copy();
|
||||||
}
|
}
|
||||||
|
@ -286,7 +287,7 @@ public class CardView extends SimpleCardView {
|
||||||
this.power = Integer.toString(card.getPower().getValue());
|
this.power = Integer.toString(card.getPower().getValue());
|
||||||
this.toughness = Integer.toString(card.getToughness().getValue());
|
this.toughness = Integer.toString(card.getToughness().getValue());
|
||||||
this.cardTypes = card.getCardType();
|
this.cardTypes = card.getCardType();
|
||||||
this.faceDown = ((Permanent) card).isFaceDown(game);
|
this.faceDown = card.isFaceDown(game);
|
||||||
} else {
|
} else {
|
||||||
// this.hideInfo = true;
|
// this.hideInfo = true;
|
||||||
return;
|
return;
|
||||||
|
@ -296,9 +297,9 @@ public class CardView extends SimpleCardView {
|
||||||
SplitCard splitCard = null;
|
SplitCard splitCard = null;
|
||||||
if (card.isSplitCard()) {
|
if (card.isSplitCard()) {
|
||||||
splitCard = (SplitCard) card;
|
splitCard = (SplitCard) card;
|
||||||
rotate = (((SplitCard) card).getSpellAbility().getSpellAbilityType()) != SpellAbilityType.SPLIT_AFTERMATH;
|
rotate = (card.getSpellAbility().getSpellAbilityType()) != SpellAbilityType.SPLIT_AFTERMATH;
|
||||||
} else if (card instanceof Spell) {
|
} else if (card instanceof Spell) {
|
||||||
switch (((Spell) card).getSpellAbility().getSpellAbilityType()) {
|
switch (card.getSpellAbility().getSpellAbilityType()) {
|
||||||
case SPLIT_FUSED:
|
case SPLIT_FUSED:
|
||||||
splitCard = (SplitCard) ((Spell) card).getCard();
|
splitCard = (SplitCard) ((Spell) card).getCard();
|
||||||
rotate = true;
|
rotate = true;
|
||||||
|
@ -390,12 +391,12 @@ public class CardView extends SimpleCardView {
|
||||||
this.cardNumber = ((PermanentToken) card).getToken().getOriginalCardNumber();
|
this.cardNumber = ((PermanentToken) card).getToken().getOriginalCardNumber();
|
||||||
} else {
|
} else {
|
||||||
// a created token
|
// a created token
|
||||||
this.expansionSetCode = ((PermanentToken) card).getExpansionSetCode();
|
this.expansionSetCode = card.getExpansionSetCode();
|
||||||
this.tokenDescriptor = ((PermanentToken) card).getTokenDescriptor();
|
this.tokenDescriptor = card.getTokenDescriptor();
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// set code und card number for token copies to get the image
|
// set code und card number for token copies to get the image
|
||||||
this.rules = ((PermanentToken) card).getRules(game);
|
this.rules = card.getRules(game);
|
||||||
this.type = ((PermanentToken) card).getToken().getTokenType();
|
this.type = ((PermanentToken) card).getToken().getTokenType();
|
||||||
} else {
|
} else {
|
||||||
this.rarity = card.getRarity();
|
this.rarity = card.getRarity();
|
||||||
|
@ -995,6 +996,14 @@ public class CardView extends SimpleCardView {
|
||||||
this.canAttack = canAttack;
|
this.canAttack = canAttack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isCanBlock() {
|
||||||
|
return canBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCanBlock(boolean canBlock) {
|
||||||
|
this.canBlock = canBlock;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isCreature() {
|
public boolean isCreature() {
|
||||||
return cardTypes.contains(CardType.CREATURE);
|
return cardTypes.contains(CardType.CREATURE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_RESET_ALL;
|
import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_RESET_ALL;
|
||||||
import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_RESET_ALL;
|
import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_RESET_ALL;
|
||||||
|
@ -1432,7 +1433,12 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
while (!abort) {
|
while (!abort) {
|
||||||
prepareForResponse(game);
|
prepareForResponse(game);
|
||||||
if (!isExecutingMacro()) {
|
if (!isExecutingMacro()) {
|
||||||
game.fireSelectEvent(playerId, "Select blockers");
|
Map<String, Serializable> options = new HashMap<>();
|
||||||
|
List<UUID> possibleBlockers = game.getBattlefield().getActivePermanents(filter, playerId, game).stream()
|
||||||
|
.map(p -> p.getId())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
options.put(Constants.Option.POSSIBLE_BLOCKERS, (Serializable) possibleBlockers);
|
||||||
|
game.fireSelectEvent(playerId, "Select blockers", options);
|
||||||
}
|
}
|
||||||
waitForResponse(game);
|
waitForResponse(game);
|
||||||
if (response.getBoolean() != null) {
|
if (response.getBoolean() != null) {
|
||||||
|
@ -1504,9 +1510,21 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
TargetAttackingCreature target = new TargetAttackingCreature();
|
TargetAttackingCreature target = new TargetAttackingCreature();
|
||||||
prepareForResponse(game);
|
prepareForResponse(game);
|
||||||
if (!isExecutingMacro()) {
|
if (!isExecutingMacro()) {
|
||||||
|
// possible attackers to block
|
||||||
|
Set<UUID> attackers = target.possibleTargets(null, playerId, game);
|
||||||
|
Permanent blocker = game.getPermanent(blockerId);
|
||||||
|
Set<UUID> possibleTargets = new HashSet<>();
|
||||||
|
for (UUID attackerId : attackers) {
|
||||||
|
CombatGroup group = game.getCombat().findGroup(attackerId);
|
||||||
|
if (group != null && blocker != null && group.canBlock(blocker, game)) {
|
||||||
|
possibleTargets.add(attackerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
game.fireSelectTargetEvent(playerId, new MessageToClient("Select attacker to block", getRelatedObjectName(blockerId, game)),
|
game.fireSelectTargetEvent(playerId, new MessageToClient("Select attacker to block", getRelatedObjectName(blockerId, game)),
|
||||||
target.possibleTargets(null, playerId, game), false, getOptions(target, null));
|
possibleTargets, false, getOptions(target, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
waitForResponse(game);
|
waitForResponse(game);
|
||||||
if (response.getBoolean() != null) {
|
if (response.getBoolean() != null) {
|
||||||
// do nothing
|
// do nothing
|
||||||
|
|
Loading…
Add table
Reference in a new issue