Card Sleeves

This commit is contained in:
Anthony Calosa
2019-10-22 16:12:03 +08:00
parent bec4db6c6d
commit 402885391f
34 changed files with 473 additions and 81 deletions

View File

@@ -11,6 +11,7 @@ import org.apache.commons.lang3.StringUtils;
public abstract class LobbyPlayer { public abstract class LobbyPlayer {
protected String name; protected String name;
private int avatarIndex = -1; private int avatarIndex = -1;
private int sleeveIndex = -1;
private String avatarCardImageKey; private String avatarCardImageKey;
public LobbyPlayer(String name) { public LobbyPlayer(String name) {
@@ -59,9 +60,15 @@ public abstract class LobbyPlayer {
public int getAvatarIndex() { public int getAvatarIndex() {
return avatarIndex; return avatarIndex;
} }
public int getSleeveIndex() {
return sleeveIndex;
}
public void setAvatarIndex(int avatarIndex) { public void setAvatarIndex(int avatarIndex) {
this.avatarIndex = avatarIndex; this.avatarIndex = avatarIndex;
} }
public void setSleeveIndex(int sleeveIndex) {
this.sleeveIndex = sleeveIndex;
}
public String getAvatarCardImageKey() { public String getAvatarCardImageKey() {
return avatarCardImageKey; return avatarCardImageKey;

View File

@@ -2430,6 +2430,7 @@ public class Player extends GameEntity implements Comparable<Player> {
controllerCreator = ctrlr; controllerCreator = ctrlr;
controller = ctrlr; controller = ctrlr;
updateAvatar(); updateAvatar();
updateSleeve();
view.updateIsAI(this); view.updateIsAI(this);
view.updateLobbyPlayerName(this); view.updateLobbyPlayerName(this);
} }
@@ -2439,6 +2440,10 @@ public class Player extends GameEntity implements Comparable<Player> {
view.updateAvatarCardImageKey(this); view.updateAvatarCardImageKey(this);
} }
public void updateSleeve() {
view.updateSleeveIndex(this);
}
/** /**
* Run a procedure using a different controller * Run a procedure using a different controller
*/ */

View File

@@ -85,6 +85,13 @@ public class PlayerView extends GameEntityView {
set(TrackableProperty.AvatarCardImageKey, p.getLobbyPlayer().getAvatarCardImageKey()); set(TrackableProperty.AvatarCardImageKey, p.getLobbyPlayer().getAvatarCardImageKey());
} }
public int getSleeveIndex() {
return get(TrackableProperty.SleeveIndex);
}
void updateSleeveIndex(Player p) {
set(TrackableProperty.SleeveIndex, p.getLobbyPlayer().getSleeveIndex());
}
public String getCurrentPlaneName() { return get(TrackableProperty.CurrentPlane); } public String getCurrentPlaneName() { return get(TrackableProperty.CurrentPlane); }
void updateCurrentPlaneName( String plane ) { void updateCurrentPlaneName( String plane ) {
set(TrackableProperty.CurrentPlane, plane); set(TrackableProperty.CurrentPlane, plane);

View File

@@ -122,6 +122,7 @@ public enum TrackableProperty {
LobbyPlayerName(TrackableTypes.StringType), LobbyPlayerName(TrackableTypes.StringType),
AvatarIndex(TrackableTypes.IntegerType), AvatarIndex(TrackableTypes.IntegerType),
AvatarCardImageKey(TrackableTypes.StringType), AvatarCardImageKey(TrackableTypes.StringType),
SleeveIndex(TrackableTypes.IntegerType),
Opponents(TrackableTypes.PlayerViewCollectionType), Opponents(TrackableTypes.PlayerViewCollectionType),
Life(TrackableTypes.IntegerType), Life(TrackableTypes.IntegerType),
PoisonCounters(TrackableTypes.IntegerType), PoisonCounters(TrackableTypes.IntegerType),

View File

@@ -202,6 +202,12 @@ public class GuiDesktop implements IGuiBase {
return 0; return 0;
} }
@Override
public int getSleevesCount() {
//TODO
return 0;
}
@Override @Override
public String showFileDialog(final String title, final String defaultDir) { public String showFileDialog(final String title, final String defaultDir) {
final JFileChooser fc = new JFileChooser(defaultDir); final JFileChooser fc = new JFileChooser(defaultDir);

View File

@@ -397,7 +397,7 @@ public class VLobby implements ILobbyView {
private UpdateLobbyPlayerEvent getSlot(final int index) { private UpdateLobbyPlayerEvent getSlot(final int index) {
final PlayerPanel panel = playerPanels.get(index); final PlayerPanel panel = playerPanels.get(index);
return UpdateLobbyPlayerEvent.create(panel.getType(), panel.getPlayerName(), panel.getAvatarIndex(), panel.getTeam(), panel.isArchenemy(), panel.isReady(), panel.isDevMode(), panel.getAiOptions()); return UpdateLobbyPlayerEvent.create(panel.getType(), panel.getPlayerName(), panel.getAvatarIndex(), -1/*TODO panel.getSleeveIndex()*/, panel.getTeam(), panel.isArchenemy(), panel.isReady(), panel.isDevMode(), panel.getAiOptions());
} }
/** Builds the actual deck panel layouts for each player. /** Builds the actual deck panel layouts for each player.

View File

@@ -244,6 +244,14 @@ public class GuiMobile implements IGuiBase {
return 0; return 0;
} }
@Override
public int getSleevesCount() {
if (FSkin.isLoaded()) {
return FSkin.getSleeves().size();
}
return 0;
}
@Override @Override
public String showFileDialog(final String title, final String defaultDir) { public String showFileDialog(final String title, final String defaultDir) {
return ForgeConstants.USER_GAMES_DIR + "Test.fgs"; //TODO: Show dialog return ForgeConstants.USER_GAMES_DIR + "Test.fgs"; //TODO: Show dialog

View File

@@ -1,11 +1,10 @@
package forge.assets; package forge.assets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import com.badlogic.gdx.utils.Array;
import forge.Forge;
import org.apache.commons.lang3.text.WordUtils; import org.apache.commons.lang3.text.WordUtils;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
@@ -30,8 +29,10 @@ import forge.toolbox.FProgressBar;
public class FSkin { public class FSkin {
private static final Map<FSkinProp, FSkinImage> images = new HashMap<>(); private static final Map<FSkinProp, FSkinImage> images = new HashMap<>();
private static final Map<Integer, TextureRegion> avatars = new HashMap<>(); private static final Map<Integer, TextureRegion> avatars = new HashMap<>();
private static final Map<Integer, TextureRegion> sleeves = new HashMap<>();
private static final Map<Integer, TextureRegion> borders = new HashMap<>();
private static List<String> allSkins; private static Array<String> allSkins;
private static FileHandle preferredDir; private static FileHandle preferredDir;
private static String preferredName; private static String preferredName;
private static boolean loaded = false; private static boolean loaded = false;
@@ -98,12 +99,12 @@ public class FSkin {
else { else {
if (splashScreen != null) { if (splashScreen != null) {
if (allSkins == null) { //initialize if (allSkins == null) { //initialize
allSkins = new ArrayList<>(); allSkins = new Array<>();
final List<String> skinDirectoryNames = getSkinDirectoryNames(); final Array<String> skinDirectoryNames = getSkinDirectoryNames();
for (final String skinDirectoryName : skinDirectoryNames) { for (final String skinDirectoryName : skinDirectoryNames) {
allSkins.add(WordUtils.capitalize(skinDirectoryName.replace('_', ' '))); allSkins.add(WordUtils.capitalize(skinDirectoryName.replace('_', ' ')));
} }
Collections.sort(allSkins); allSkins.sort();
} }
} }
@@ -172,6 +173,9 @@ public class FSkin {
} }
avatars.clear(); avatars.clear();
sleeves.clear();
boolean textureFilter = Forge.isTextureFilteringEnabled();
final Map<String, Texture> textures = new HashMap<>(); final Map<String, Texture> textures = new HashMap<>();
@@ -183,6 +187,9 @@ public class FSkin {
final FileHandle f5 = getSkinFile(ForgeConstants.SPRITE_AVATARS_FILE); final FileHandle f5 = getSkinFile(ForgeConstants.SPRITE_AVATARS_FILE);
final FileHandle f6 = getDefaultSkinFile(SourceFile.OLD_FOILS.getFilename()); final FileHandle f6 = getDefaultSkinFile(SourceFile.OLD_FOILS.getFilename());
final FileHandle f7 = getDefaultSkinFile(ForgeConstants.SPRITE_MANAICONS_FILE); final FileHandle f7 = getDefaultSkinFile(ForgeConstants.SPRITE_MANAICONS_FILE);
final FileHandle f8 = getDefaultSkinFile(ForgeConstants.SPRITE_SLEEVES_FILE);
final FileHandle f9 = getDefaultSkinFile(ForgeConstants.SPRITE_SLEEVES2_FILE);
final FileHandle f10 = getDefaultSkinFile(ForgeConstants.SPRITE_BORDER_FILE);
try { try {
textures.put(f1.path(), new Texture(f1)); textures.put(f1.path(), new Texture(f1));
@@ -218,16 +225,25 @@ public class FSkin {
//assemble avatar textures //assemble avatar textures
int counter = 0; int counter = 0;
int scount = 0;
Color pxTest; Color pxTest;
Pixmap pxDefaultAvatars, pxPreferredAvatars; Pixmap pxDefaultAvatars, pxPreferredAvatars, pxDefaultSleeves;
Texture txDefaultAvatars, txPreferredAvatars; Texture txDefaultAvatars, txPreferredAvatars, txDefaultSleeves;
pxDefaultAvatars = new Pixmap(f4); pxDefaultAvatars = new Pixmap(f4);
txDefaultAvatars = new Texture(f4); pxDefaultSleeves = new Pixmap(f8);
txDefaultAvatars = new Texture(f4, textureFilter);
if (textureFilter)
txDefaultAvatars.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear);
txDefaultSleeves = new Texture(f8, textureFilter);
if (textureFilter)
txDefaultSleeves.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear);
if (f5.exists()) { if (f5.exists()) {
pxPreferredAvatars = new Pixmap(f5); pxPreferredAvatars = new Pixmap(f5);
txPreferredAvatars = new Texture(f5); txPreferredAvatars = new Texture(f5, textureFilter);
if (textureFilter)
txPreferredAvatars.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear);
final int pw = pxPreferredAvatars.getWidth(); final int pw = pxPreferredAvatars.getWidth();
final int ph = pxPreferredAvatars.getHeight(); final int ph = pxPreferredAvatars.getHeight();
@@ -255,8 +271,42 @@ public class FSkin {
} }
} }
final int sw = pxDefaultSleeves.getWidth();
final int sh = pxDefaultSleeves.getHeight();
for (int j = 0; j < sh; j += 500) {
for (int i = 0; i < sw; i += 360) {
pxTest = new Color(pxDefaultSleeves.getPixel(i + 180, j + 250));
if (pxTest.a == 0) { continue; }
FSkin.sleeves.put(scount++, new TextureRegion(txDefaultSleeves, i, j, 360, 500));
}
}
//re init second set of sleeves
pxDefaultSleeves = new Pixmap(f9);
txDefaultSleeves = new Texture(f9, textureFilter);
if (textureFilter)
txDefaultSleeves.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear);
final int sw2 = pxDefaultSleeves.getWidth();
final int sh2 = pxDefaultSleeves.getHeight();
for (int j = 0; j < sh2; j += 500) {
for (int i = 0; i < sw2; i += 360) {
pxTest = new Color(pxDefaultSleeves.getPixel(i + 180, j + 250));
if (pxTest.a == 0) { continue; }
FSkin.sleeves.put(scount++, new TextureRegion(txDefaultSleeves, i, j, 360, 500));
}
}
Texture bordersBW = new Texture(f10);
FSkin.borders.put(0, new TextureRegion(bordersBW, 2, 2, 672, 936));
FSkin.borders.put(1, new TextureRegion(bordersBW, 676, 2, 672, 936));
preferredIcons.dispose(); preferredIcons.dispose();
pxDefaultAvatars.dispose(); pxDefaultAvatars.dispose();
pxDefaultSleeves.dispose();;
} }
catch (final Exception e) { catch (final Exception e) {
System.err.println("FSkin$loadFull: Missing a sprite (default icons, " System.err.println("FSkin$loadFull: Missing a sprite (default icons, "
@@ -314,8 +364,8 @@ public class FSkin {
* *
* @return the skins * @return the skins
*/ */
public static List<String> getSkinDirectoryNames() { public static Array<String> getSkinDirectoryNames() {
final List<String> mySkins = new ArrayList<>(); final Array<String> mySkins = new Array<>();
final FileHandle dir = Gdx.files.absolute(ForgeConstants.SKINS_DIR); final FileHandle dir = Gdx.files.absolute(ForgeConstants.SKINS_DIR);
for (FileHandle skinFile : dir.list()) { for (FileHandle skinFile : dir.list()) {
@@ -340,5 +390,13 @@ public class FSkin {
return avatars; return avatars;
} }
public static Map<Integer, TextureRegion> getSleeves() {
return sleeves;
}
public static Map<Integer, TextureRegion> getBorders() {
return borders;
}
public static boolean isLoaded() { return loaded; } public static boolean isLoaded() { return loaded; }
} }

View File

@@ -214,6 +214,16 @@ public class ImageCache {
return Color.valueOf("#fffffd"); return Color.valueOf("#fffffd");
return Color.valueOf("#171717"); return Color.valueOf("#171717");
} }
public static int getFSkinBorders(CardView c) {
if (c == null)
return 0;
CardView.CardStateView state = c.getCurrentState();
CardEdition ed = FModel.getMagicDb().getEditions().get(state.getSetCode());
if (ed != null && ed.isWhiteBorder() && state.getFoilIndex() == 0)
return 1;
return 0;
}
public static boolean isExtendedArt(CardView c) { public static boolean isExtendedArt(CardView c) {
if (c == null) if (c == null)
return false; return false;

View File

@@ -6,7 +6,10 @@ import com.badlogic.gdx.utils.Align;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import forge.Forge; import forge.Forge;
import forge.Graphics; import forge.Graphics;
import forge.ImageKeys;
import forge.assets.FBufferedImage; import forge.assets.FBufferedImage;
import forge.assets.FImage;
import forge.assets.FSkin;
import forge.assets.FSkinColor; import forge.assets.FSkinColor;
import forge.assets.FSkinFont; import forge.assets.FSkinFont;
import forge.assets.FSkinImage; import forge.assets.FSkinImage;
@@ -326,7 +329,9 @@ public class CardImageRenderer {
} }
public static void drawZoom(Graphics g, CardView card, GameView gameView, boolean altState, float x, float y, float w, float h, float dispW, float dispH, boolean isCurrentCard) { public static void drawZoom(Graphics g, CardView card, GameView gameView, boolean altState, float x, float y, float w, float h, float dispW, float dispH, boolean isCurrentCard) {
boolean canshow = MatchController.instance.mayView(card);
final Texture image = ImageCache.getImage(card.getState(altState).getImageKey(MatchController.instance.getLocalPlayers()), true); final Texture image = ImageCache.getImage(card.getState(altState).getImageKey(MatchController.instance.getLocalPlayers()), true);
FImage sleeves = MatchController.getPlayerSleeve(card.getOwner());
if (image == null) { //draw details if can't draw zoom if (image == null) { //draw details if can't draw zoom
drawDetails(g, card, gameView, altState, x, y, w, h); drawDetails(g, card, gameView, altState, x, y, w, h);
return; return;
@@ -337,8 +342,6 @@ public class CardImageRenderer {
return; return;
} }
boolean canLook = MatchController.instance.mayView(card);
if (image == ImageCache.defaultImage) { //support drawing card image manually if card image not found if (image == ImageCache.defaultImage) { //support drawing card image manually if card image not found
drawCardImage(g, card, altState, x, y, w, h, CardStackPosition.Top); drawCardImage(g, card, altState, x, y, w, h, CardStackPosition.Top);
} }
@@ -358,47 +361,43 @@ public class CardImageRenderer {
if (ImageCache.isExtendedArt(card)) if (ImageCache.isExtendedArt(card))
g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, -90); g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, -90);
else { else {
if (rotatePlane) g.drawRotatedImage(FSkin.getBorders().get(0), new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, -90);
g.drawfillBorder(3, ImageCache.borderColor(card), new_xRotate, new_yRotate, new_h, new_w, radius); g.drawRotatedImage(ImageCache.croppedBorderImage(image), new_x+radius/2, new_y+radius/2, new_w*0.96f, new_h*0.96f, (new_x+radius/2) + (new_w*0.96f) / 2, (new_y+radius/2) + (new_h*0.96f) / 2, -90);
else
g.drawfillBorder(3, ImageCache.borderColor(card), x, y, w, h, radius);
g.drawRotatedImage(ImageCache.croppedBorderImage(image), new_x+radius/2.3f, new_y+radius/2, new_w*0.96f, new_h*0.96f, (new_x+radius/2.3f) + (new_w*0.96f) / 2, (new_y+radius/2) + (new_h*0.96f) / 2, -90);
} }
} }
else else
g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, -90); g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, -90);
} else if (rotateSplit && isCurrentCard && card.isSplitCard() && canLook) { } else if (rotateSplit && isCurrentCard && card.isSplitCard() && canshow) {
boolean isAftermath = card.getText().contains("Aftermath") || card.getAlternateState().getOracleText().contains("Aftermath"); boolean isAftermath = card.getText().contains("Aftermath") || card.getAlternateState().getOracleText().contains("Aftermath");
if (Forge.enableUIMask) { if (Forge.enableUIMask) {
if (ImageCache.isExtendedArt(card)) if (ImageCache.isExtendedArt(card))
g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, isAftermath ? 90 : -90); g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, isAftermath ? 90 : -90);
else { else {
if (rotateSplit) g.drawRotatedImage(FSkin.getBorders().get(ImageCache.getFSkinBorders(card)), new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, isAftermath ? 90 : -90);
g.drawfillBorder(3, ImageCache.borderColor(card), new_xRotate, new_yRotate, new_h, new_w, radius); g.drawRotatedImage(ImageCache.croppedBorderImage(image), new_x + radius / 2, new_y + radius / 2, new_w * 0.96f, new_h * 0.96f, (new_x + radius / 2) + (new_w * 0.96f) / 2, (new_y + radius / 2) + (new_h * 0.96f) / 2, isAftermath ? 90 : -90);
else
g.drawfillBorder(3, ImageCache.borderColor(card), x, y, w, h, radius);
g.drawRotatedImage(ImageCache.croppedBorderImage(image), new_x + radius / 2.3f, new_y + radius / 2, new_w * 0.96f, new_h * 0.96f, (new_x + radius / 2.3f) + (new_w * 0.96f) / 2, (new_y + radius / 2) + (new_h * 0.96f) / 2, isAftermath ? 90 : -90);
} }
} }
else else
g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, isAftermath ? 90 : -90); g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, isAftermath ? 90 : -90);
} }
else { else {
if (Forge.enableUIMask) { if (Forge.enableUIMask && canshow && !ImageKeys.getTokenKey(ImageKeys.MORPH_IMAGE).equals(card.getState(altState).getImageKey())) {
if (ImageCache.isExtendedArt(card)) if (ImageCache.isExtendedArt(card))
g.drawImage(image, x, y, w, h); g.drawImage(image, x, y, w, h);
else { else {
g.drawImage(ImageCache.getBorderImage(card, canLook), x, y, w, h); g.drawImage(ImageCache.getBorderImage(card, canshow), x, y, w, h);
g.drawImage(ImageCache.croppedBorderImage(image), x + radius / 2.4f, y + radius / 2, w * 0.96f, h * 0.96f); g.drawImage(ImageCache.croppedBorderImage(image), x + radius / 2.4f, y + radius / 2, w * 0.96f, h * 0.96f);
} }
} }
else else {
if (canshow && !ImageKeys.getTokenKey(ImageKeys.MORPH_IMAGE).equals(card.getState(altState).getImageKey()))
g.drawImage(image, x, y, w, h); g.drawImage(image, x, y, w, h);
else // sleeve
g.drawImage(sleeves, x, y, w, h);
} }
} }
CardRenderer.drawFoilEffect(g, card, x, y, w, h, isCurrentCard && canLook && image != ImageCache.defaultImage); }
CardRenderer.drawFoilEffect(g, card, x, y, w, h, isCurrentCard && canshow && image != ImageCache.defaultImage);
} }
public static void drawDetails(Graphics g, CardView card, GameView gameView, boolean altState, float x, float y, float w, float h) { public static void drawDetails(Graphics g, CardView card, GameView gameView, boolean altState, float x, float y, float w, float h) {

View File

@@ -19,9 +19,12 @@ import forge.CachedCardImage;
import forge.Forge; import forge.Forge;
import forge.FThreads; import forge.FThreads;
import forge.Graphics; import forge.Graphics;
import forge.ImageKeys;
import forge.StaticData; import forge.StaticData;
import forge.assets.FImage;
import forge.assets.FImageComplex; import forge.assets.FImageComplex;
import forge.assets.FRotatedImage; import forge.assets.FRotatedImage;
import forge.assets.FSkin;
import forge.assets.FSkinColor; import forge.assets.FSkinColor;
import forge.assets.FSkinFont; import forge.assets.FSkinFont;
import forge.assets.FSkinImage; import forge.assets.FSkinImage;
@@ -430,7 +433,9 @@ public class CardRenderer {
} }
} }
public static void drawCard(Graphics g, CardView card, float x, float y, float w, float h, CardStackPosition pos, boolean rotate) { public static void drawCard(Graphics g, CardView card, float x, float y, float w, float h, CardStackPosition pos, boolean rotate) {
boolean canshow = MatchController.instance.mayView(card) && !ImageKeys.getTokenKey(ImageKeys.MORPH_IMAGE).equals(card.getCurrentState().getImageKey());
Texture image = new RendererCachedCardImage(card, false).getImage(); Texture image = new RendererCachedCardImage(card, false).getImage();
FImage sleeves = MatchController.getPlayerSleeve(card.getOwner());
float radius = (h - w)/8; float radius = (h - w)/8;
if (image != null) { if (image != null) {
@@ -444,7 +449,7 @@ public class CardRenderer {
if (ImageCache.isExtendedArt(card)) if (ImageCache.isExtendedArt(card))
g.drawRotatedImage(image, x, y, w, h, x + w / 2, y + h / 2, -90); g.drawRotatedImage(image, x, y, w, h, x + w / 2, y + h / 2, -90);
else { else {
g.drawfillBorder(3, ImageCache.borderColor(card), x, y, w, h, radius); g.drawRotatedImage(FSkin.getBorders().get(0), x, y, w, h, x + w / 2, y + h / 2, -90);
g.drawRotatedImage(ImageCache.croppedBorderImage(image), x+radius/2.3f, y+radius/2, w*0.96f, h*0.96f, (x+radius/2.3f) + (w*0.96f) / 2, (y+radius/2) + (h*0.96f) / 2, -90); g.drawRotatedImage(ImageCache.croppedBorderImage(image), x+radius/2.3f, y+radius/2, w*0.96f, h*0.96f, (x+radius/2.3f) + (w*0.96f) / 2, (y+radius/2) + (h*0.96f) / 2, -90);
} }
} }
@@ -452,17 +457,21 @@ public class CardRenderer {
g.drawRotatedImage(image, x, y, w, h, x + w / 2, y + h / 2, -90); g.drawRotatedImage(image, x, y, w, h, x + w / 2, y + h / 2, -90);
} }
else { else {
if (Forge.enableUIMask) { if (Forge.enableUIMask && canshow) {
if (ImageCache.isExtendedArt(card)) if (ImageCache.isExtendedArt(card))
g.drawImage(image, x, y, w, h); g.drawImage(image, x, y, w, h);
else { else {
boolean t = (card.getCurrentState().getOriginalColors() != card.getCurrentState().getColors()) || card.getCurrentState().hasChangeColors(); boolean t = (card.getCurrentState().getOriginalColors() != card.getCurrentState().getColors()) || card.getCurrentState().hasChangeColors();
g.drawBorderImage(ImageCache.getBorderImage(card, MatchController.instance.mayView(card)), ImageCache.getTint(card), x, y, w, h, t); //tint check for changed colors g.drawBorderImage(ImageCache.getBorderImage(card, canshow), ImageCache.getTint(card), x, y, w, h, t); //tint check for changed colors
g.drawImage(ImageCache.croppedBorderImage(image), x + radius / 2.4f, y + radius / 2, w * 0.96f, h * 0.96f); g.drawImage(ImageCache.croppedBorderImage(image), x + radius / 2.4f, y + radius / 2, w * 0.96f, h * 0.96f);
} }
} }
else else {
if (canshow)
g.drawImage(image, x, y, w, h); g.drawImage(image, x, y, w, h);
else // draw card back sleeves
g.drawImage(sleeves, x, y, w, h);
}
} }
} }
drawFoilEffect(g, card, x, y, w, h, false); drawFoilEffect(g, card, x, y, w, h, false);

View File

@@ -37,7 +37,7 @@ public class AvatarSelector extends FScreen {
} }
private static final float PADDING = Utils.scale(5); private static final float PADDING = Utils.scale(5);
private static final int COLUMNS = 4; private static final int COLUMNS = 5;
private final int currentIndex; private final int currentIndex;
private final List<Integer> usedAvatars; private final List<Integer> usedAvatars;

View File

@@ -308,6 +308,13 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
prefs.setPref(FPref.UI_AVATARS, pOneIndex + "," + pTwoIndex); prefs.setPref(FPref.UI_AVATARS, pOneIndex + "," + pTwoIndex);
prefs.save(); prefs.save();
} }
void updateSleevePrefs() {
int pOneIndex = playerPanels.get(0).getSleeveIndex();
int pTwoIndex = playerPanels.get(1).getSleeveIndex();
prefs.setPref(FPref.UI_SLEEVES, pOneIndex + "," + pTwoIndex);
prefs.save();
}
/** Updates the avatars from preferences on update. */ /** Updates the avatars from preferences on update. */
private void updatePlayersFromPrefs() { private void updatePlayersFromPrefs() {
@@ -320,6 +327,13 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
playerPanels.get(i).setAvatarIndex(avatarIndex); playerPanels.get(i).setAvatarIndex(avatarIndex);
} }
// Sleeves
String[] sleevePrefs = prefs.getPref(FPref.UI_SLEEVES).split(",");
for (int i = 0; i < sleevePrefs.length; i++) {
int sleeveIndex = Integer.parseInt(sleevePrefs[i]);
playerPanels.get(i).setSleeveIndex(sleeveIndex);
}
// Name // Name
String prefName = prefs.getPref(FPref.PLAYER_NAME); String prefName = prefs.getPref(FPref.PLAYER_NAME);
playerPanels.get(0).setPlayerName(StringUtils.isBlank(prefName) ? Localizer.getInstance().getMessage("lblHuman") : prefName); playerPanels.get(0).setPlayerName(StringUtils.isBlank(prefName) ? Localizer.getInstance().getMessage("lblHuman") : prefName);
@@ -334,6 +348,15 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
return usedAvatars; return usedAvatars;
} }
List<Integer> getUsedSleeves() {
List<Integer> usedSleeves = Arrays.asList(-1,-1,-1,-1,-1,-1,-1,-1);
int i = 0;
for (PlayerPanel pp : playerPanels) {
usedSleeves.set(i++, pp.getSleeveIndex());
}
return usedSleeves;
}
List<String> getPlayerNames() { List<String> getPlayerNames() {
List<String> names = new ArrayList<>(); List<String> names = new ArrayList<>();
for (PlayerPanel pp : playerPanels) { for (PlayerPanel pp : playerPanels) {
@@ -527,8 +550,17 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
final LobbySlotType type = slot.getType(); final LobbySlotType type = slot.getType();
panel.setType(type); panel.setType(type);
if (type != LobbySlotType.AI) {
panel.setPlayerName(slot.getName()); panel.setPlayerName(slot.getName());
panel.setAvatarIndex(slot.getAvatarIndex()); //override where???
} else {
//AI: this one overrides the setplayername if blank
if (panel.getPlayerName().isEmpty())
panel.setPlayerName(slot.getName());
//AI: override settings if somehow player changes it for AI
slot.setAvatarIndex(panel.getAvatarIndex());
slot.setSleeveIndex(panel.getSleeveIndex());
}
panel.setTeam(slot.getTeam()); panel.setTeam(slot.getTeam());
panel.setIsReady(slot.isReady()); panel.setIsReady(slot.isReady());
panel.setIsDevMode(slot.isDevMode()); panel.setIsDevMode(slot.isDevMode());
@@ -667,7 +699,7 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
private UpdateLobbyPlayerEvent getSlot(final int index) { private UpdateLobbyPlayerEvent getSlot(final int index) {
final PlayerPanel panel = playerPanels.get(index); final PlayerPanel panel = playerPanels.get(index);
return UpdateLobbyPlayerEvent.create(panel.getType(), panel.getPlayerName(), panel.getAvatarIndex(), panel.getTeam(), panel.isArchenemy(), panel.isReady(), panel.isDevMode(), panel.getAiOptions()); return UpdateLobbyPlayerEvent.create(panel.getType(), panel.getPlayerName(), panel.getAvatarIndex(), panel.getSleeveIndex(), panel.getTeam(), panel.isArchenemy(), panel.isReady(), panel.isDevMode(), panel.getAiOptions());
} }
public List<PlayerPanel> getPlayerPanels() { public List<PlayerPanel> getPlayerPanels() {

View File

@@ -59,7 +59,8 @@ public class PlayerPanel extends FContainer {
private final FLabel nameRandomiser; private final FLabel nameRandomiser;
private final FLabel avatarLabel = new FLabel.Builder().opaque(true).iconScaleFactor(0.99f).alphaComposite(1).iconInBackground(true).build(); private final FLabel avatarLabel = new FLabel.Builder().opaque(true).iconScaleFactor(0.99f).alphaComposite(1).iconInBackground(true).build();
private int avatarIndex; private final FLabel sleeveLabel = new FLabel.Builder().opaque(true).iconScaleFactor(0.99f).alphaComposite(1).iconInBackground(true).build();
private int avatarIndex, sleeveIndex;
final Localizer localizer = Localizer.getInstance(); final Localizer localizer = Localizer.getInstance();
private final FTextField txtPlayerName = new FTextField(localizer.getMessage("lblPlayerName")); private final FTextField txtPlayerName = new FTextField(localizer.getMessage("lblPlayerName"));
@@ -98,6 +99,7 @@ public class PlayerPanel extends FContainer {
setType(slot.getType()); setType(slot.getType());
setPlayerName(slot.getName()); setPlayerName(slot.getName());
setAvatarIndex(slot.getAvatarIndex()); setAvatarIndex(slot.getAvatarIndex());
setSleeveIndex(slot.getSleeveIndex());
devModeSwitch = new FToggleSwitch(localizer.getMessage("lblNormal"), localizer.getMessage("lblDevMode")); devModeSwitch = new FToggleSwitch(localizer.getMessage("lblNormal"), localizer.getMessage("lblDevMode"));
devModeSwitch.setVisible(isNetworkHost()); devModeSwitch.setVisible(isNetworkHost());
@@ -189,6 +191,9 @@ public class PlayerPanel extends FContainer {
createAvatar(); createAvatar();
add(avatarLabel); add(avatarLabel);
createSleeve();
add(sleeveLabel);
createNameEditor(); createNameEditor();
add(newLabel(localizer.getMessage("lblName") + ":")); add(newLabel(localizer.getMessage("lblName") + ":"));
add(txtPlayerName); add(txtPlayerName);
@@ -299,12 +304,16 @@ public class PlayerPanel extends FContainer {
float y = PADDING; float y = PADDING;
float fieldHeight = txtPlayerName.getHeight(); float fieldHeight = txtPlayerName.getHeight();
float avatarSize = 2 * fieldHeight + PADDING; float avatarSize = 2 * fieldHeight + PADDING;
float sleeveSize = 2 * fieldHeight + PADDING;
float sleeveSizeW = (sleeveSize/4)*3;
float dy = fieldHeight + PADDING; float dy = fieldHeight + PADDING;
avatarLabel.setBounds(x, y, avatarSize, avatarSize); avatarLabel.setBounds(x, y, avatarSize, avatarSize);
x += avatarSize + PADDING; x += avatarSize + PADDING;
sleeveLabel.setBounds(x, y, sleeveSizeW, sleeveSize);
x += sleeveSizeW + PADDING;
float w = width - x - fieldHeight - 2 * PADDING; float w = width - x - fieldHeight - 2 * PADDING;
txtPlayerName.setBounds(x, y, w, fieldHeight); txtPlayerName.setBounds(x, y, w, fieldHeight); //add space for card back
x += w + PADDING; x += w + PADDING;
nameRandomiser.setBounds(x, y, fieldHeight, fieldHeight); nameRandomiser.setBounds(x, y, fieldHeight, fieldHeight);
@@ -312,8 +321,8 @@ public class PlayerPanel extends FContainer {
humanAiSwitch.setSize(humanAiSwitch.getAutoSizeWidth(fieldHeight), fieldHeight); humanAiSwitch.setSize(humanAiSwitch.getAutoSizeWidth(fieldHeight), fieldHeight);
x = width - humanAiSwitch.getWidth() - PADDING; x = width - humanAiSwitch.getWidth() - PADDING;
humanAiSwitch.setPosition(x, y); humanAiSwitch.setPosition(x, y);
w = x - avatarSize - 3 * PADDING; w = x - (avatarSize+sleeveSizeW+PADDING) - 3 * PADDING;
x = avatarSize + 2 * PADDING; x = (avatarSize+sleeveSizeW+PADDING) + 2 * PADDING;
if (cbArchenemyTeam.isVisible()) { if (cbArchenemyTeam.isVisible()) {
cbArchenemyTeam.setBounds(x, y, w, fieldHeight); cbArchenemyTeam.setBounds(x, y, w, fieldHeight);
} }
@@ -411,6 +420,7 @@ public class PlayerPanel extends FContainer {
//update may edit in-case it changed as a result of the AI change //update may edit in-case it changed as a result of the AI change
setMayEdit(screen.getLobby().mayEdit(index)); setMayEdit(screen.getLobby().mayEdit(index));
setAvatarIndex(slot.getAvatarIndex()); setAvatarIndex(slot.getAvatarIndex());
setSleeveIndex(slot.getSleeveIndex());
setPlayerName(slot.getName()); setPlayerName(slot.getName());
} }
} }
@@ -480,6 +490,25 @@ public class PlayerPanel extends FContainer {
} }
}; };
private FEventHandler sleeveCommand = new FEventHandler() {
@Override
public void handleEvent(FEvent e) {
SleevesSelector.show(getPlayerName(), sleeveIndex, screen.getUsedSleeves(), new Callback<Integer>() {
@Override
public void run(Integer result) {
setSleeveIndex(result);
if (index < 2) {
screen.updateSleevePrefs();
}
if (allowNetworking) {
screen.firePlayerChangeListener(index);
}
}
});
}
};
public void setDeckSelectorButtonText(String text) { public void setDeckSelectorButtonText(String text) {
btnDeck.setText(text); btnDeck.setText(text);
} }
@@ -664,6 +693,17 @@ public class PlayerPanel extends FContainer {
avatarLabel.setCommand(avatarCommand); avatarLabel.setCommand(avatarCommand);
} }
private void createSleeve() {
String[] currentPrefs = prefs.getPref(FPref.UI_SLEEVES).split(",");
if (index < currentPrefs.length) {
setSleeveIndex(Integer.parseInt(currentPrefs[index]));
}
else {
setSleeveIndex(SleevesSelector.getRandomSleeves(screen.getUsedSleeves()));
}
sleeveLabel.setCommand(sleeveCommand);
}
public void setAvatarIndex(int newAvatarIndex) { public void setAvatarIndex(int newAvatarIndex) {
avatarIndex = newAvatarIndex; avatarIndex = newAvatarIndex;
if (avatarIndex != -1) { if (avatarIndex != -1) {
@@ -674,10 +714,24 @@ public class PlayerPanel extends FContainer {
} }
} }
public void setSleeveIndex(int newSleeveIndex) {
sleeveIndex = newSleeveIndex;
if (sleeveIndex != -1) {
sleeveLabel.setIcon(new FTextureRegionImage(FSkin.getSleeves().get(newSleeveIndex)));
}
else {
sleeveLabel.setIcon(null);
}
}
public int getAvatarIndex() { public int getAvatarIndex() {
return avatarIndex; return avatarIndex;
} }
public int getSleeveIndex() {
return sleeveIndex;
}
public void setPlayerName(String string) { public void setPlayerName(String string) {
txtPlayerName.setText(string); txtPlayerName.setText(string);
} }
@@ -759,6 +813,7 @@ public class PlayerPanel extends FContainer {
if (mayEdit == mayEdit0) { return; } if (mayEdit == mayEdit0) { return; }
mayEdit = mayEdit0; mayEdit = mayEdit0;
avatarLabel.setEnabled(mayEdit); avatarLabel.setEnabled(mayEdit);
sleeveLabel.setEnabled(mayEdit);
txtPlayerName.setEnabled(mayEdit); txtPlayerName.setEnabled(mayEdit);
nameRandomiser.setEnabled(mayEdit); nameRandomiser.setEnabled(mayEdit);
humanAiSwitch.setEnabled(mayEdit); humanAiSwitch.setEnabled(mayEdit);

View File

@@ -0,0 +1,119 @@
package forge.screens.constructed;
import forge.Forge;
import forge.assets.FImage;
import forge.assets.FSkin;
import forge.assets.FSkinImage;
import forge.assets.FTextureRegionImage;
import forge.screens.FScreen;
import forge.toolbox.FDisplayObject;
import forge.toolbox.FEvent;
import forge.toolbox.FEvent.FEventHandler;
import forge.toolbox.FLabel;
import forge.toolbox.FScrollPane;
import forge.util.Callback;
import forge.util.MyRandom;
import forge.util.Utils;
import java.util.List;
import java.util.Map;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Align;
public class SleevesSelector extends FScreen {
public static int getRandomSleeves(List<Integer> usedSleeves) {
int random = 0;
do {
random = MyRandom.getRandom().nextInt(FSkin.getSleeves().size());
} while (usedSleeves.contains(random));
return random;
}
public static void show(final String playerName, final int currentIndex0, final List<Integer> usedSleeves0, final Callback<Integer> callback0) {
SleevesSelector selector = new SleevesSelector(playerName, currentIndex0, usedSleeves0, callback0);
Forge.openScreen(selector);
}
private static final float PADDING = Utils.scale(5);
private static final int COLUMNS = 5;
private final int currentIndex;
private final List<Integer> usedSleeves;
private final Callback<Integer> callback;
private final FScrollPane scroller = new FScrollPane() {
@Override
protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) {
int rowCount = 0;
float x = PADDING;
float y = PADDING;
float labelSize = (visibleWidth - (COLUMNS + 1) * PADDING) / COLUMNS;
for (FDisplayObject lbl : scroller.getChildren()) {
if (rowCount == COLUMNS) { //wrap to next line
x = PADDING;
y += labelSize + PADDING;
rowCount = 0;
}
lbl.setBounds(x, y, labelSize, labelSize);
x += labelSize + PADDING;
rowCount++;
}
return new ScrollBounds(visibleWidth, y + labelSize + PADDING);
}
};
private SleevesSelector(final String playerName, final int currentIndex0, final List<Integer> usedSleeves0, final Callback<Integer> callback0) {
super("Select Sleeves for " + playerName);
currentIndex = currentIndex0;
usedSleeves = usedSleeves0;
callback = callback0;
//add label for selecting random sleeves first
addSleevesLabel(FSkinImage.UNKNOWN, -1);
//add label for currently selected sleeves next
final Map<Integer, TextureRegion> sleeveMap = FSkin.getSleeves();
addSleevesLabel(new FTextureRegionImage(sleeveMap.get(currentIndex)), currentIndex);
//add label for remaining sleeves
for (final Integer i : sleeveMap.keySet()) {
if (currentIndex != i) {
addSleevesLabel(new FTextureRegionImage(sleeveMap.get(i)), i);
}
}
add(scroller);
}
private void addSleevesLabel(final FImage img, final int index) {
final FLabel lbl = new FLabel.Builder().icon(img).iconScaleFactor(0.99f).align(Align.center)
.iconInBackground(true).selectable(true).selected(currentIndex == index)
.build();
if (index == -1) {
lbl.setCommand(new FEventHandler() {
@Override
public void handleEvent(FEvent e) {
callback.run(getRandomSleeves(usedSleeves));
Forge.back();
}
});
}
else {
lbl.setCommand(new FEventHandler() {
@Override
public void handleEvent(FEvent e) {
callback.run(index);
Forge.back();
}
});
}
scroller.add(lbl);
}
@Override
protected void doLayout(float startY, float width, float height) {
scroller.setBounds(0, startY, width, height - startY);
}
}

View File

@@ -7,6 +7,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import forge.assets.FSkinImage;
import forge.util.Localizer; import forge.util.Localizer;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -68,6 +69,8 @@ public class MatchController extends AbstractGuiGame {
private static final Map<String, FImage> avatarImages = new HashMap<>(); private static final Map<String, FImage> avatarImages = new HashMap<>();
private static final Map<String, FImage> sleeveImages = new HashMap<>();
private static HostedMatch hostedMatch; private static HostedMatch hostedMatch;
private static MatchScreen view; private static MatchScreen view;
@@ -100,6 +103,17 @@ public class MatchController extends AbstractGuiGame {
return avatar; return avatar;
} }
public static FImage getPlayerSleeve(final PlayerView p) {
if (p == null)
return FSkinImage.UNKNOWN;
final String lp = p.getLobbyPlayerName();
FImage sleeve = sleeveImages.get(lp);
if (sleeve == null) {
sleeve = new FTextureRegionImage(FSkin.getSleeves().get(p.getSleeveIndex()));
}
return sleeve;
}
@Override @Override
public void refreshCardDetails(final Iterable<CardView> cards) { public void refreshCardDetails(final Iterable<CardView> cards) {
//ensure cards appear in the correct row of the field //ensure cards appear in the correct row of the field

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 KiB

View File

@@ -46,6 +46,7 @@ public interface IGuiBase {
boolean showBoxedProduct(String title, String message, List<PaperCard> list); boolean showBoxedProduct(String title, String message, List<PaperCard> list);
PaperCard chooseCard(String title, String message, List<PaperCard> list); PaperCard chooseCard(String title, String message, List<PaperCard> list);
int getAvatarCount(); int getAvatarCount();
int getSleevesCount();
void copyToClipboard(String text); void copyToClipboard(String text);
void browseToUrl(String url) throws IOException, URISyntaxException; void browseToUrl(String url) throws IOException, URISyntaxException;
IAudioClip createAudioClip(String filename); IAudioClip createAudioClip(String filename);

View File

@@ -158,7 +158,7 @@ public abstract class GameLobby implements IHasGameType {
public void addSlot() { public void addSlot() {
final int newIndex = getNumberOfSlots(); final int newIndex = getNumberOfSlots();
final LobbySlotType type = allowNetworking ? LobbySlotType.OPEN : LobbySlotType.AI; final LobbySlotType type = allowNetworking ? LobbySlotType.OPEN : LobbySlotType.AI;
addSlot(new LobbySlot(type, null, newIndex, newIndex, false, !allowNetworking, Collections.emptySet())); addSlot(new LobbySlot(type, null, newIndex, newIndex, newIndex, false, !allowNetworking, Collections.emptySet()));
} }
protected final void addSlot(final LobbySlot slot) { protected final void addSlot(final LobbySlot slot) {
if (slot == null) { if (slot == null) {
@@ -198,6 +198,15 @@ public abstract class GameLobby implements IHasGameType {
} }
return result; return result;
} }
protected final static int[] localSleeveIndices() {
final String[] sSleeves = FModel.getPreferences().getPref(FPref.UI_SLEEVES).split(",");
final int[] result = new int[sSleeves.length];
for (int i = 0; i < sSleeves.length; i++) {
final Integer val = Ints.tryParse(sSleeves[i]);
result[i] = val == null ? -1 : val.intValue();
}
return result;
}
public void removeSlot(final int index) { public void removeSlot(final int index) {
if (index < 0 || index >= data.slots.size()) { if (index < 0 || index >= data.slots.size()) {
@@ -415,6 +424,7 @@ public abstract class GameLobby implements IHasGameType {
final IGuiGame gui = getGui(data.slots.indexOf(slot)); final IGuiGame gui = getGui(data.slots.indexOf(slot));
final String name = slot.getName(); final String name = slot.getName();
final int avatar = slot.getAvatarIndex(); final int avatar = slot.getAvatarIndex();
final int sleeve = slot.getSleeveIndex();
final boolean isArchenemy = slot.isArchenemy(); final boolean isArchenemy = slot.isArchenemy();
final int team = GameType.Archenemy.equals(currentGameType) && !isArchenemy ? 1 : slot.getTeam(); final int team = GameType.Archenemy.equals(currentGameType) && !isArchenemy ? 1 : slot.getTeam();
final Set<AIOption> aiOptions = slot.getAiOptions(); final Set<AIOption> aiOptions = slot.getAiOptions();
@@ -422,7 +432,7 @@ public abstract class GameLobby implements IHasGameType {
final boolean isAI = slot.getType() == LobbySlotType.AI; final boolean isAI = slot.getType() == LobbySlotType.AI;
final LobbyPlayer lobbyPlayer; final LobbyPlayer lobbyPlayer;
if (isAI) { if (isAI) {
lobbyPlayer = GamePlayerUtil.createAiPlayer(name, avatar, aiOptions); lobbyPlayer = GamePlayerUtil.createAiPlayer(name, avatar, sleeve, aiOptions);
} }
else { else {
boolean setNameNow = false; boolean setNameNow = false;
@@ -430,7 +440,7 @@ public abstract class GameLobby implements IHasGameType {
setNameNow = true; setNameNow = true;
hasNameBeenSet = true; hasNameBeenSet = true;
} }
lobbyPlayer = GamePlayerUtil.getGuiPlayer(name, avatar, setNameNow); lobbyPlayer = GamePlayerUtil.getGuiPlayer(name, avatar, sleeve, setNameNow);
} }
Deck deck = slot.getDeck(); Deck deck = slot.getDeck();

View File

@@ -158,6 +158,7 @@ public class HostedMatch {
final FCollectionView<Player> players = game.getPlayers(); final FCollectionView<Player> players = game.getPlayers();
final String[] avatarIndices = FModel.getPreferences().getPref(FPref.UI_AVATARS).split(","); final String[] avatarIndices = FModel.getPreferences().getPref(FPref.UI_AVATARS).split(",");
final String[] sleeveIndices = FModel.getPreferences().getPref(FPref.UI_SLEEVES).split(",");
final GameView gameView = getGameView(); final GameView gameView = getGameView();
humanCount = 0; humanCount = 0;
@@ -175,6 +176,16 @@ public class HostedMatch {
} }
} }
p.updateAvatar(); p.updateAvatar();
//sleeve
p.getLobbyPlayer().setSleeveIndex(rp.getPlayer().getSleeveIndex());
if (p.getLobbyPlayer().getSleeveIndex() == -1) {
if (iPlayer < sleeveIndices.length) {
p.getLobbyPlayer().setSleeveIndex(Integer.parseInt(sleeveIndices[iPlayer]));
} else {
p.getLobbyPlayer().setSleeveIndex(0);
}
}
p.updateSleeve();
if (p.getController() instanceof PlayerControllerHuman) { if (p.getController() instanceof PlayerControllerHuman) {
final PlayerControllerHuman humanController = (PlayerControllerHuman) p.getController(); final PlayerControllerHuman humanController = (PlayerControllerHuman) p.getController();

View File

@@ -15,6 +15,7 @@ public final class LobbySlot implements Serializable {
private LobbySlotType type; private LobbySlotType type;
private String name; private String name;
private int avatarIndex; private int avatarIndex;
private int sleeveIndex;
private int team; private int team;
private boolean isArchenemy; private boolean isArchenemy;
private boolean isReady; private boolean isReady;
@@ -22,10 +23,11 @@ public final class LobbySlot implements Serializable {
private Deck deck; private Deck deck;
private ImmutableSet<AIOption> aiOptions; private ImmutableSet<AIOption> aiOptions;
public LobbySlot(final LobbySlotType type, final String name, final int avatarIndex, final int team, final boolean isArchenemy, final boolean isReady, final Set<AIOption> aiOptions) { public LobbySlot(final LobbySlotType type, final String name, final int avatarIndex, final int sleeveIndex, final int team, final boolean isArchenemy, final boolean isReady, final Set<AIOption> aiOptions) {
this.type = type; this.type = type;
this.name = name; this.name = name;
this.avatarIndex = avatarIndex; this.avatarIndex = avatarIndex;
this.sleeveIndex = sleeveIndex;
this.team = team; this.team = team;
this.isArchenemy = isArchenemy; this.isArchenemy = isArchenemy;
this.isReady = isReady; this.isReady = isReady;
@@ -47,6 +49,10 @@ public final class LobbySlot implements Serializable {
setAvatarIndex(data.getAvatarIndex()); setAvatarIndex(data.getAvatarIndex());
changed = true; changed = true;
} }
if (data.getSleeveIndex() != -1) {
setSleeveIndex(data.getSleeveIndex());
changed = true;
}
if (data.getTeam() != -1) { if (data.getTeam() != -1) {
setTeam(data.getTeam()); setTeam(data.getTeam());
changed = true; changed = true;
@@ -93,9 +99,15 @@ public final class LobbySlot implements Serializable {
public int getAvatarIndex() { public int getAvatarIndex() {
return avatarIndex; return avatarIndex;
} }
public int getSleeveIndex() {
return sleeveIndex;
}
public void setAvatarIndex(final int avatarIndex) { public void setAvatarIndex(final int avatarIndex) {
this.avatarIndex = avatarIndex; this.avatarIndex = avatarIndex;
} }
public void setSleeveIndex(final int sleeveIndex) {
this.sleeveIndex = sleeveIndex;
}
public int getTeam() { public int getTeam() {
return team; return team;

View File

@@ -13,11 +13,12 @@ public final class LocalLobby extends GameLobby {
final String humanName = localName(); final String humanName = localName();
final int[] avatarIndices = localAvatarIndices(); final int[] avatarIndices = localAvatarIndices();
final int[] sleeveIndices = localSleeveIndices();
final LobbySlot slot0 = new LobbySlot(LobbySlotType.LOCAL, humanName, avatarIndices[0], 0, true, true, Collections.emptySet()); final LobbySlot slot0 = new LobbySlot(LobbySlotType.LOCAL, humanName, avatarIndices[0], sleeveIndices[0],0, true, true, Collections.emptySet());
addSlot(slot0); addSlot(slot0);
final LobbySlot slot1 = new LobbySlot(LobbySlotType.AI, null, avatarIndices[1], 1, false, true, Collections.emptySet()); final LobbySlot slot1 = new LobbySlot(LobbySlotType.AI, null, avatarIndices[1], sleeveIndices[1],1, false, true, Collections.emptySet());
addSlot(slot1); addSlot(slot1);
} }

View File

@@ -14,11 +14,12 @@ public final class OfflineLobby extends GameLobby {
final String humanName = localName(); final String humanName = localName();
final int[] avatarIndices = localAvatarIndices(); final int[] avatarIndices = localAvatarIndices();
final int[] sleeveIndices = localSleeveIndices();
final LobbySlot slot0 = new LobbySlot(LobbySlotType.LOCAL, humanName, avatarIndices[0], 0, true, false, Collections.emptySet()); final LobbySlot slot0 = new LobbySlot(LobbySlotType.LOCAL, humanName, avatarIndices[0], sleeveIndices[0], 0, true, false, Collections.emptySet());
addSlot(slot0); addSlot(slot0);
final LobbySlot slot1 = new LobbySlot(LobbySlotType.OPEN, null, -1, -1, false, false, Collections.emptySet()); final LobbySlot slot1 = new LobbySlot(LobbySlotType.OPEN, null, -1, -1,-1, false, false, Collections.emptySet());
addSlot(slot1); addSlot(slot1);
} }

View File

@@ -198,7 +198,8 @@ final class GameClientHandler extends GameProtocolHandler<IGuiGame> {
); );
LobbyPlayer lobbyPlayer = new LobbyPlayerHuman( LobbyPlayer lobbyPlayer = new LobbyPlayerHuman(
playerSlot.getName(), playerSlot.getName(),
playerSlot.getAvatarIndex() playerSlot.getAvatarIndex(),
playerSlot.getSleeveIndex()
); );
player.setPlayer(lobbyPlayer); player.setPlayer(lobbyPlayer);
player.setTeamNumber(playerSlot.getTeam()); player.setTeamNumber(playerSlot.getTeam());
@@ -287,7 +288,7 @@ final class GameClientHandler extends GameProtocolHandler<IGuiGame> {
@Override @Override
public void channelActive(final ChannelHandlerContext ctx) { public void channelActive(final ChannelHandlerContext ctx) {
// Don't use send() here, as this.channel is not yet set! // Don't use send() here, as this.channel is not yet set!
ctx.channel().writeAndFlush(new LoginEvent(FModel.getPreferences().getPref(FPref.PLAYER_NAME), Integer.parseInt(FModel.getPreferences().getPref(FPref.UI_AVATARS).split(",")[0]))); ctx.channel().writeAndFlush(new LoginEvent(FModel.getPreferences().getPref(FPref.PLAYER_NAME), Integer.parseInt(FModel.getPreferences().getPref(FPref.UI_AVATARS).split(",")[0]), Integer.parseInt(FModel.getPreferences().getPref(FPref.UI_SLEEVES).split(",")[0])));
} }
} }

View File

@@ -6,10 +6,11 @@ public class LoginEvent implements NetEvent {
private static final long serialVersionUID = -8865183377417377938L; private static final long serialVersionUID = -8865183377417377938L;
private final String username; private final String username;
private final int avatarIndex; private final int avatarIndex, sleeveIndex;
public LoginEvent(final String username, final int avatarIndex) { public LoginEvent(final String username, final int avatarIndex, final int sleeveIndex) {
this.username = username; this.username = username;
this.avatarIndex = avatarIndex; this.avatarIndex = avatarIndex;
this.sleeveIndex = sleeveIndex;
} }
@Override @Override
@@ -23,4 +24,8 @@ public class LoginEvent implements NetEvent {
public int getAvatarIndex() { public int getAvatarIndex() {
return avatarIndex; return avatarIndex;
} }
public int getSleeveIndex() {
return sleeveIndex;
}
} }

View File

@@ -16,6 +16,7 @@ public final class UpdateLobbyPlayerEvent implements NetEvent {
private LobbySlotType type = null; private LobbySlotType type = null;
private String name = null; private String name = null;
private int avatarIndex = -1; private int avatarIndex = -1;
private int sleeveIndex = -1;
private int team = -1; private int team = -1;
private Boolean isArchenemy = null; private Boolean isArchenemy = null;
private Boolean isReady = null; private Boolean isReady = null;
@@ -26,11 +27,11 @@ public final class UpdateLobbyPlayerEvent implements NetEvent {
private Set<AIOption> aiOptions = null; private Set<AIOption> aiOptions = null;
public static UpdateLobbyPlayerEvent create(final LobbySlotType type, final String name, final int avatarIndex, final int team, final boolean isArchenemy, final boolean isReady, final Set<AIOption> aiOptions) { public static UpdateLobbyPlayerEvent create(final LobbySlotType type, final String name, final int avatarIndex, final int sleeveIndex, final int team, final boolean isArchenemy, final boolean isReady, final Set<AIOption> aiOptions) {
return new UpdateLobbyPlayerEvent(type, name, avatarIndex, team, isArchenemy, isReady, aiOptions); return new UpdateLobbyPlayerEvent(type, name, avatarIndex, sleeveIndex, team, isArchenemy, isReady, aiOptions);
} }
public static UpdateLobbyPlayerEvent create(final LobbySlotType type, final String name, final int avatarIndex, final int team, final boolean isArchenemy, final boolean isReady, final boolean isDevMode, final Set<AIOption> aiOptions) { public static UpdateLobbyPlayerEvent create(final LobbySlotType type, final String name, final int avatarIndex, final int sleeveIndex, final int team, final boolean isArchenemy, final boolean isReady, final boolean isDevMode, final Set<AIOption> aiOptions) {
return new UpdateLobbyPlayerEvent(type, name, avatarIndex, team, isArchenemy, isReady, isDevMode, aiOptions); return new UpdateLobbyPlayerEvent(type, name, avatarIndex, sleeveIndex, team, isArchenemy, isReady, isDevMode, aiOptions);
} }
public static UpdateLobbyPlayerEvent deckUpdate(final Deck deck) { public static UpdateLobbyPlayerEvent deckUpdate(final Deck deck) {
return new UpdateLobbyPlayerEvent(deck); return new UpdateLobbyPlayerEvent(deck);
@@ -59,6 +60,7 @@ public final class UpdateLobbyPlayerEvent implements NetEvent {
final LobbySlotType type, final LobbySlotType type,
final String name, final String name,
final int avatarIndex, final int avatarIndex,
final int sleeveIndex,
final int team, final int team,
final boolean isArchenemy, final boolean isArchenemy,
final boolean isReady, final boolean isReady,
@@ -66,6 +68,7 @@ public final class UpdateLobbyPlayerEvent implements NetEvent {
this.type = type; this.type = type;
this.name = name; this.name = name;
this.avatarIndex = avatarIndex; this.avatarIndex = avatarIndex;
this.sleeveIndex = sleeveIndex;
this.team = team; this.team = team;
this.isArchenemy = isArchenemy; this.isArchenemy = isArchenemy;
this.isReady = isReady; this.isReady = isReady;
@@ -76,6 +79,7 @@ public final class UpdateLobbyPlayerEvent implements NetEvent {
final LobbySlotType type, final LobbySlotType type,
final String name, final String name,
final int avatarIndex, final int avatarIndex,
final int sleeveIndex,
final int team, final int team,
final boolean isArchenemy, final boolean isArchenemy,
final boolean isReady, final boolean isReady,
@@ -84,6 +88,7 @@ public final class UpdateLobbyPlayerEvent implements NetEvent {
this.type = type; this.type = type;
this.name = name; this.name = name;
this.avatarIndex = avatarIndex; this.avatarIndex = avatarIndex;
this.sleeveIndex = sleeveIndex;
this.team = team; this.team = team;
this.isArchenemy = isArchenemy; this.isArchenemy = isArchenemy;
this.isReady = isReady; this.isReady = isReady;
@@ -104,6 +109,9 @@ public final class UpdateLobbyPlayerEvent implements NetEvent {
public int getAvatarIndex() { public int getAvatarIndex() {
return avatarIndex; return avatarIndex;
} }
public int getSleeveIndex() {
return sleeveIndex;
}
public int getTeam() { public int getTeam() {
return team; return team;
} }

View File

@@ -329,7 +329,7 @@ public final class FServerManager {
final RemoteClient client = clients.get(ctx.channel()); final RemoteClient client = clients.get(ctx.channel());
if (msg instanceof LoginEvent) { if (msg instanceof LoginEvent) {
final LoginEvent event = (LoginEvent) msg; final LoginEvent event = (LoginEvent) msg;
final int index = localLobby.connectPlayer(event.getUsername(), event.getAvatarIndex()); final int index = localLobby.connectPlayer(event.getUsername(), event.getAvatarIndex(), event.getSleeveIndex());
if (index == -1) { if (index == -1) {
ctx.close(); ctx.close();
} else { } else {

View File

@@ -13,25 +13,26 @@ public final class ServerGameLobby extends GameLobby {
public ServerGameLobby() { public ServerGameLobby() {
super(true); super(true);
addSlot(new LobbySlot(LobbySlotType.LOCAL, localName(), localAvatarIndices()[0], 0, true, false, Collections.emptySet())); addSlot(new LobbySlot(LobbySlotType.LOCAL, localName(), localAvatarIndices()[0], localSleeveIndices()[0],0, true, false, Collections.emptySet()));
addSlot(new LobbySlot(LobbySlotType.OPEN, null, -1, 1, false, false, Collections.emptySet())); addSlot(new LobbySlot(LobbySlotType.OPEN, null, -1, -1, 1, false, false, Collections.emptySet()));
} }
public int connectPlayer(final String name, final int avatarIndex) { public int connectPlayer(final String name, final int avatarIndex, final int sleeveIndex) {
final int nSlots = getNumberOfSlots(); final int nSlots = getNumberOfSlots();
for (int index = 0; index < nSlots; index++) { for (int index = 0; index < nSlots; index++) {
final LobbySlot slot = getSlot(index); final LobbySlot slot = getSlot(index);
if (slot.getType() == LobbySlotType.OPEN) { if (slot.getType() == LobbySlotType.OPEN) {
connectPlayer(name, avatarIndex, slot); connectPlayer(name, avatarIndex, sleeveIndex, slot);
return index; return index;
} }
} }
return -1; return -1;
} }
private void connectPlayer(final String name, final int avatarIndex, final LobbySlot slot) { private void connectPlayer(final String name, final int avatarIndex, final int sleeveIndex, final LobbySlot slot) {
slot.setType(LobbySlotType.REMOTE); slot.setType(LobbySlotType.REMOTE);
slot.setName(name); slot.setName(name);
slot.setAvatarIndex(avatarIndex); slot.setAvatarIndex(avatarIndex);
slot.setSleeveIndex(sleeveIndex);
updateView(false); updateView(false);
} }
public void disconnectPlayer(final int index) { public void disconnectPlayer(final int index) {

View File

@@ -127,7 +127,7 @@ public class ConquestController {
starter.add(humanStart.setPlayer(humanPlayer)); starter.add(humanStart.setPlayer(humanPlayer));
final IGuiGame gui = GuiBase.getInterface().getNewGuiGame(); final IGuiGame gui = GuiBase.getInterface().getNewGuiGame();
final LobbyPlayer aiPlayer = GamePlayerUtil.createAiPlayer(aiPlayerName, -1); final LobbyPlayer aiPlayer = GamePlayerUtil.createAiPlayer(aiPlayerName, -1, -1);
battle.setOpponentAvatar(aiPlayer, gui); battle.setOpponentAvatar(aiPlayer, gui);
starter.add(aiStart.setPlayer(aiPlayer)); starter.add(aiStart.setPlayer(aiPlayer));

View File

@@ -23,7 +23,7 @@ public final class GamePlayerUtil {
public static final LobbyPlayer getGuiPlayer() { public static final LobbyPlayer getGuiPlayer() {
return guiPlayer; return guiPlayer;
} }
public static final LobbyPlayer getGuiPlayer(final String name, final int avatarIndex, final boolean writePref) { public static final LobbyPlayer getGuiPlayer(final String name, final int avatarIndex, final int sleeveIndex, final boolean writePref) {
if (writePref) { if (writePref) {
if (!name.equals(guiPlayer.getName())) { if (!name.equals(guiPlayer.getName())) {
guiPlayer.setName(name); guiPlayer.setName(name);
@@ -33,7 +33,7 @@ public final class GamePlayerUtil {
return guiPlayer; return guiPlayer;
} }
//use separate LobbyPlayerHuman instance for human players beyond first //use separate LobbyPlayerHuman instance for human players beyond first
return new LobbyPlayerHuman(name, avatarIndex); return new LobbyPlayerHuman(name, avatarIndex, sleeveIndex);
} }
public static final LobbyPlayer getQuestPlayer() { public static final LobbyPlayer getQuestPlayer() {
@@ -45,19 +45,25 @@ public final class GamePlayerUtil {
} }
public final static LobbyPlayer createAiPlayer(final String name) { public final static LobbyPlayer createAiPlayer(final String name) {
final int avatarCount = GuiBase.getInterface().getAvatarCount(); final int avatarCount = GuiBase.getInterface().getAvatarCount();
return createAiPlayer(name, avatarCount == 0 ? 0 : MyRandom.getRandom().nextInt(avatarCount)); final int sleeveCount = GuiBase.getInterface().getSleevesCount();
return createAiPlayer(name, avatarCount == 0 ? 0 : MyRandom.getRandom().nextInt(avatarCount), sleeveCount == 0 ? 0 : MyRandom.getRandom().nextInt(sleeveCount));
} }
public final static LobbyPlayer createAiPlayer(final String name, final String profileOverride) { public final static LobbyPlayer createAiPlayer(final String name, final String profileOverride) {
final int avatarCount = GuiBase.getInterface().getAvatarCount(); final int avatarCount = GuiBase.getInterface().getAvatarCount();
return createAiPlayer(name, avatarCount == 0 ? 0 : MyRandom.getRandom().nextInt(avatarCount), null, profileOverride); final int sleeveCount = GuiBase.getInterface().getSleevesCount();
return createAiPlayer(name, avatarCount == 0 ? 0 : MyRandom.getRandom().nextInt(avatarCount), sleeveCount == 0 ? 0 : MyRandom.getRandom().nextInt(sleeveCount), null, profileOverride);
} }
public final static LobbyPlayer createAiPlayer(final String name, final int avatarIndex) { public final static LobbyPlayer createAiPlayer(final String name, final int avatarIndex) {
return createAiPlayer(name, avatarIndex, null, ""); final int sleeveCount = GuiBase.getInterface().getSleevesCount();
return createAiPlayer(name, avatarIndex, sleeveCount == 0 ? 0 : MyRandom.getRandom().nextInt(sleeveCount), null, "");
} }
public final static LobbyPlayer createAiPlayer(final String name, final int avatarIndex, final Set<AIOption> options) { public final static LobbyPlayer createAiPlayer(final String name, final int avatarIndex, final int sleeveIndex) {
return createAiPlayer(name, avatarIndex, options, ""); return createAiPlayer(name, avatarIndex, sleeveIndex, null, "");
} }
public final static LobbyPlayer createAiPlayer(final String name, final int avatarIndex, final Set<AIOption> options, final String profileOverride) { public final static LobbyPlayer createAiPlayer(final String name, final int avatarIndex, final int sleeveIndex, final Set<AIOption> options) {
return createAiPlayer(name, avatarIndex, sleeveIndex, options, "");
}
public final static LobbyPlayer createAiPlayer(final String name, final int avatarIndex, final int sleeveIndex, final Set<AIOption> options, final String profileOverride) {
final LobbyPlayerAi player = new LobbyPlayerAi(name, options); final LobbyPlayerAi player = new LobbyPlayerAi(name, options);
// TODO: implement specific AI profiles for quest mode. // TODO: implement specific AI profiles for quest mode.
@@ -87,6 +93,7 @@ public final class GamePlayerUtil {
player.setAiProfile(profile); player.setAiProfile(profile);
player.setAvatarIndex(avatarIndex); player.setAvatarIndex(avatarIndex);
player.setSleeveIndex(sleeveIndex);
return player; return player;
} }

View File

@@ -9,11 +9,12 @@ import forge.util.GuiDisplayUtil;
public class LobbyPlayerHuman extends LobbyPlayer implements IGameEntitiesFactory { public class LobbyPlayerHuman extends LobbyPlayer implements IGameEntitiesFactory {
public LobbyPlayerHuman(final String name) { public LobbyPlayerHuman(final String name) {
this(name, -1); this(name, -1, -1);
} }
public LobbyPlayerHuman(final String name, final int avatarIndex) { public LobbyPlayerHuman(final String name, final int avatarIndex, final int sleeveIndex) {
super(name); super(name);
setAvatarIndex(avatarIndex); setAvatarIndex(avatarIndex);
setSleeveIndex(sleeveIndex);
} }
@Override @Override

View File

@@ -97,6 +97,8 @@ public final class ForgeConstants {
public static final String SPRITE_BORDER_FILE = "sprite_border.png"; public static final String SPRITE_BORDER_FILE = "sprite_border.png";
public static final String SPRITE_MANAICONS_FILE = "sprite_manaicons.png"; public static final String SPRITE_MANAICONS_FILE = "sprite_manaicons.png";
public static final String SPRITE_AVATARS_FILE = "sprite_avatars.png"; public static final String SPRITE_AVATARS_FILE = "sprite_avatars.png";
public static final String SPRITE_SLEEVES_FILE = "sprite_sleeves.png";
public static final String SPRITE_SLEEVES2_FILE = "sprite_sleeves2.png";
public static final String SPRITE_FAVICONS_FILE = "sprite_favicons.png"; public static final String SPRITE_FAVICONS_FILE = "sprite_favicons.png";
public static final String SPRITE_PLANAR_CONQUEST_FILE = "sprite_planar_conquest.png"; public static final String SPRITE_PLANAR_CONQUEST_FILE = "sprite_planar_conquest.png";
public static final String FONT_FILE = "font1.ttf"; public static final String FONT_FILE = "font1.ttf";

View File

@@ -73,6 +73,7 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
UI_RANDOM_FOIL ("false"), UI_RANDOM_FOIL ("false"),
UI_ENABLE_AI_CHEATS ("false"), UI_ENABLE_AI_CHEATS ("false"),
UI_AVATARS ("0,1"), UI_AVATARS ("0,1"),
UI_SLEEVES ("0,1"),
UI_SHOW_CARD_OVERLAYS ("true"), UI_SHOW_CARD_OVERLAYS ("true"),
UI_OVERLAY_CARD_NAME ("true"), UI_OVERLAY_CARD_NAME ("true"),
UI_OVERLAY_CARD_POWER ("true"), UI_OVERLAY_CARD_POWER ("true"),