Merge remote-tracking branch 'core-developers/master' into translationsfixes

This commit is contained in:
klaxnek
2020-10-12 17:16:25 +02:00
18 changed files with 324 additions and 44 deletions

View File

@@ -6,6 +6,7 @@ import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Matrix4;
@@ -37,8 +38,75 @@ public class Graphics {
private int failedClipCount;
private float alphaComposite = 1;
private int transformCount = 0;
private String sVertex = "uniform mat4 u_projTrans;\n" +
"\n" +
"attribute vec4 a_position;\n" +
"attribute vec2 a_texCoord0;\n" +
"attribute vec4 a_color;\n" +
"\n" +
"varying vec4 v_color;\n" +
"varying vec2 v_texCoord;\n" +
"\n" +
"uniform vec2 u_viewportInverse;\n" +
"\n" +
"void main() {\n" +
" gl_Position = u_projTrans * a_position;\n" +
" v_texCoord = a_texCoord0;\n" +
" v_color = a_color;\n" +
"}";
private String sFragment = "#ifdef GL_ES\n" +
"precision mediump float;\n" +
"precision mediump int;\n" +
"#endif\n" +
"\n" +
"uniform sampler2D u_texture;\n" +
"\n" +
"// The inverse of the viewport dimensions along X and Y\n" +
"uniform vec2 u_viewportInverse;\n" +
"\n" +
"// Color of the outline\n" +
"uniform vec3 u_color;\n" +
"\n" +
"// Thickness of the outline\n" +
"uniform float u_offset;\n" +
"\n" +
"// Step to check for neighbors\n" +
"uniform float u_step;\n" +
"\n" +
"varying vec4 v_color;\n" +
"varying vec2 v_texCoord;\n" +
"\n" +
"#define ALPHA_VALUE_BORDER 0.5\n" +
"\n" +
"void main() {\n" +
" vec2 T = v_texCoord.xy;\n" +
"\n" +
" float alpha = 0.0;\n" +
" bool allin = true;\n" +
" for( float ix = -u_offset; ix < u_offset; ix += u_step )\n" +
" {\n" +
" for( float iy = -u_offset; iy < u_offset; iy += u_step )\n" +
" {\n" +
" float newAlpha = texture2D(u_texture, T + vec2(ix, iy) * u_viewportInverse).a;\n" +
" allin = allin && newAlpha > ALPHA_VALUE_BORDER;\n" +
" if (newAlpha > ALPHA_VALUE_BORDER && newAlpha >= alpha)\n" +
" {\n" +
" alpha = newAlpha;\n" +
" }\n" +
" }\n" +
" }\n" +
" if (allin)\n" +
" {\n" +
" alpha = 0.0;\n" +
" }\n" +
"\n" +
" gl_FragColor = vec4(u_color,alpha);\n" +
"}";
private final ShaderProgram shaderOutline = new ShaderProgram(sVertex, sFragment);
public Graphics() {
ShaderProgram.pedantic = false;
}
public void begin(float regionWidth0, float regionHeight0) {
@@ -60,6 +128,7 @@ public class Graphics {
public void dispose() {
batch.dispose();
shapeRenderer.dispose();
shaderOutline.dispose();
}
public SpriteBatch getBatch() {
@@ -604,6 +673,56 @@ public class Graphics {
public void drawImage(TextureRegion image, float x, float y, float w, float h) {
batch.draw(image, adjustX(x), adjustY(y, h), w, h);
}
public void drawImage(TextureRegion image, TextureRegion glowImageReference, float x, float y, float w, float h, Color glowColor, boolean selected) {
//1st image is the image on top of the shader, 2nd image is for the outline reference for the shader glow...
// if the 1st image don't have transparency in the middle (only on the sides, top and bottom, use the 1st image as outline reference...
if (!selected) {
batch.draw(image, adjustX(x), adjustY(y, h), w, h);
} else {
batch.end();
shaderOutline.begin();
shaderOutline.setUniformf("u_viewportInverse", new Vector2(1f / w, 1f / h));
shaderOutline.setUniformf("u_offset", 3f);
shaderOutline.setUniformf("u_step", Math.min(1f, w / 70f));
shaderOutline.setUniformf("u_color", new Vector3(glowColor.r, glowColor.g, glowColor.b));
shaderOutline.end();
batch.setShader(shaderOutline);
batch.begin();
//glow
batch.draw(glowImageReference, adjustX(x), adjustY(y, h), w, h);
batch.end();
batch.setShader(null);
batch.begin();
//img
batch.draw(image, adjustX(x), adjustY(y, h), w, h);
}
}
public void drawDeckBox(FImage cardArt, float scale, TextureRegion image, TextureRegion glowImageReference, float x, float y, float w, float h, Color glowColor, boolean selected) {
float yBox = y-(h*0.25f);
if (!selected) {
cardArt.draw(this,x+((w-w*scale)/2), y+((h-h*scale)/3f), w*scale, h*scale/1.85f);
batch.draw(image, adjustX(x), adjustY(yBox, h), w, h);
} else {
batch.end();
shaderOutline.begin();
shaderOutline.setUniformf("u_viewportInverse", new Vector2(1f / w, 1f / h));
shaderOutline.setUniformf("u_offset", 3f);
shaderOutline.setUniformf("u_step", Math.min(1f, w / 70f));
shaderOutline.setUniformf("u_color", new Vector3(glowColor.r, glowColor.g, glowColor.b));
shaderOutline.end();
batch.setShader(shaderOutline);
batch.begin();
//glow
batch.draw(glowImageReference, adjustX(x), adjustY(yBox, h), w, h);
batch.end();
batch.setShader(null);
batch.begin();
//cardart
cardArt.draw(this,x+((w-w*scale)/2), y+((h-h*scale)/3f), w*scale, h*scale/1.85f);
//deckbox
batch.draw(image, adjustX(x), adjustY(yBox, h), w, h);
}
}
public void drawRepeatingImage(Texture image, float x, float y, float w, float h) {
if (startClip(x, y, w, h)) { //only render if clip successful, otherwise it will escape bounds

View File

@@ -30,7 +30,8 @@ public class FSkin {
private static final Map<FSkinProp, FSkinImage> images = new HashMap<>(512);
private static final Map<Integer, TextureRegion> avatars = new HashMap<>(150);
private static final Map<Integer, TextureRegion> sleeves = new HashMap<>(64);
private static final Map<Integer, TextureRegion> borders = new HashMap<>(2);
private static final Map<Integer, TextureRegion> borders = new HashMap<>();
private static final Map<Integer, TextureRegion> deckbox = new HashMap<>();
private static Array<String> allSkins;
private static FileHandle preferredDir;
@@ -196,6 +197,7 @@ public class FSkin {
final FileHandle f10 = getDefaultSkinFile(ForgeConstants.SPRITE_BORDER_FILE);
final FileHandle f11 = getSkinFile(ForgeConstants.SPRITE_BUTTONS_FILE);
final FileHandle f12 = getSkinFile(ForgeConstants.SPRITE_START_FILE);
final FileHandle f13 = getDefaultSkinFile(ForgeConstants.SPRITE_DECKBOX_FILE);
try {
textures.put(f1.path(), new Texture(f1));
@@ -331,10 +333,20 @@ public class FSkin {
FSkin.sleeves.put(scount++, new TextureRegion(txDefaultSleeves, i, j, 360, 500));
}
}
//borders
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));
//deckboxes
Texture deckboxes = new Texture(f13, textureFilter);
if (textureFilter)
deckboxes.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear);
//gold bg
FSkin.deckbox.put(0, new TextureRegion(deckboxes, 2, 2, 488, 680));
//deck box for card art
FSkin.deckbox.put(1, new TextureRegion(deckboxes, 492, 2, 488, 680));
//generic deck box
FSkin.deckbox.put(2, new TextureRegion(deckboxes, 982, 2, 488, 680));
preferredIcons.dispose();
pxDefaultAvatars.dispose();
@@ -430,5 +442,9 @@ public class FSkin {
return borders;
}
public static Map<Integer, TextureRegion> getDeckbox() {
return deckbox;
}
public static boolean isLoaded() { return loaded; }
}

View File

@@ -190,11 +190,17 @@ public class CardFaceSymbols {
}
public static void drawColorSet(Graphics g, ColorSet colorSet, float x, float y, final float imageSize) {
drawColorSet(g, colorSet, x, y, imageSize, false);
}
public static void drawColorSet(Graphics g, ColorSet colorSet, float x, float y, final float imageSize, boolean vertical) {
final float dx = imageSize;
for (final ManaCostShard s : colorSet.getOrderedShards()) {
drawSymbol(s.getImageKey(), g, x, y, imageSize, imageSize);
if (!vertical)
x += dx;
else
y += dx;
}
}

View File

@@ -63,6 +63,7 @@ public class FDeckChooser extends FScreen {
private Callback<Deck> callback;
private NetDeckCategory netDeckCategory;
private boolean refreshingDeckType;
private boolean firstactivation = true;
private final DeckManager lstDecks;
private final FButton btnNewDeck = new FButton(Localizer.getInstance().getMessage("lblNewDeck"));
@@ -226,6 +227,11 @@ public class FDeckChooser extends FScreen {
@Override
public void onActivate() {
//somehow a loaded deck state from startup don't refresh accordingly for imageview so refresh it on first activation
if(firstactivation) {
needRefreshOnActivate = true;
firstactivation = false;
}
if (needRefreshOnActivate) {
needRefreshOnActivate = false;
refreshDecksList(selectedDeckType, true, null);

View File

@@ -1,17 +1,22 @@
package forge.itemmanager.views;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import forge.Forge;
import forge.Forge.KeyInputAdapter;
import forge.Graphics;
import forge.assets.FImage;
import forge.assets.FImageComplex;
import forge.assets.FSkin;
import forge.assets.FSkinColor;
import forge.assets.FSkinImage;
import forge.assets.FSkinColor.Colors;
import forge.assets.FSkinFont;
import forge.assets.ImageCache;
import forge.card.CardFaceSymbols;
import forge.card.CardRenderer;
import forge.card.CardRenderer.CardStackPosition;
import forge.card.CardZoom;
import forge.card.ColorSet;
import forge.deck.ArchetypeDeckGenerator;
import forge.deck.CardThemedDeckGenerator;
import forge.deck.CommanderDeckGenerator;
@@ -36,6 +41,7 @@ import forge.toolbox.FEvent.FEventHandler;
import forge.toolbox.FLabel;
import forge.toolbox.FScrollPane;
import forge.util.Localizer;
import forge.util.TextUtil;
import forge.util.Utils;
import java.util.ArrayList;
@@ -869,7 +875,7 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
ItemInfo item = getItemAtPoint(x + getLeft(), y + getTop());
if (item != null) {
if(item.getKey() instanceof CardThemedDeckGenerator || item.getKey() instanceof CommanderDeckGenerator
|| item.getKey() instanceof ArchetypeDeckGenerator){
|| item.getKey() instanceof ArchetypeDeckGenerator || item.getKey() instanceof DeckProxy){
FDeckViewer.show(((DeckProxy)item.getKey()).getDeck());
return true;
}
@@ -922,6 +928,7 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
private int index;
private CardStackPosition pos;
private boolean selected;
private final float IMAGE_SIZE = CardRenderer.MANA_SYMBOL_SIZE;
private ItemInfo(T item0, Group group0) {
item = item0;
@@ -954,30 +961,89 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
final float y = getTop() - group.getTop() - getScrollValue();
final float w = getWidth();
final float h = getHeight();
if (selected) { //if round border is enabled, the select highlight is also rounded..
Texture dpImg = null;
boolean deckSelectMode = false;
if (item instanceof DeckProxy) {
dpImg = ImageCache.getImage(item);
deckSelectMode = true;
}
if (selected) {
if (!deckSelectMode) {
//if round border is enabled, the select highlight is also rounded..
if (Forge.enableUIMask) {
//fillroundrect has rough/aliased corner
g.fillRoundRect(Color.GREEN, x - SEL_BORDER_SIZE, y - SEL_BORDER_SIZE,
w + 2 * SEL_BORDER_SIZE, h + 2 * SEL_BORDER_SIZE, (h - w) / 10);
g.fillRoundRect(Color.GREEN, x - SEL_BORDER_SIZE, y - SEL_BORDER_SIZE, w + 2 * SEL_BORDER_SIZE, h + 2 * SEL_BORDER_SIZE, (h - w) / 10);
//drawroundrect has GL_SMOOTH to `smoothen/faux` the aliased corner
g.drawRoundRect(1f, Color.GREEN, x - SEL_BORDER_SIZE, y - SEL_BORDER_SIZE,
w + 1.5f * SEL_BORDER_SIZE, h + 1.5f * SEL_BORDER_SIZE, (h - w) / 10);
g.drawRoundRect(1f, Color.GREEN, x - SEL_BORDER_SIZE, y - SEL_BORDER_SIZE, w + 1.5f * SEL_BORDER_SIZE, h + 1.5f * SEL_BORDER_SIZE, (h - w) / 10);
}
else //default rectangle highlight
g.fillRect(Color.GREEN, x - SEL_BORDER_SIZE, y - SEL_BORDER_SIZE,
w + 2 * SEL_BORDER_SIZE, h + 2 * SEL_BORDER_SIZE);
g.fillRect(Color.GREEN, x - SEL_BORDER_SIZE, y - SEL_BORDER_SIZE, w + 2 * SEL_BORDER_SIZE, h + 2 * SEL_BORDER_SIZE);
}
}
if (item instanceof PaperCard) {
CardRenderer.drawCard(g, (PaperCard) item, x, y, w, h, pos);
} else if (deckSelectMode) {
DeckProxy dp = ((DeckProxy) item);
ColorSet deckColor = dp.getColor();
float scale = 0.75f;
if (dpImg != null) {//generated decks have missing info...
if (Forge.enableUIMask){
//commander bg
g.drawImage(FSkin.getDeckbox().get(0), FSkin.getDeckbox().get(0), x, y, w, h, Color.GREEN, selected);
TextureRegion tr = ImageCache.croppedBorderImage(dpImg);
g.drawImage(tr, x+(w-w*scale)/2, y+(h-h*scale)/1.5f, w*scale, h*scale);
} else {
if (selected)
g.fillRect(Color.GREEN, x - SEL_BORDER_SIZE, y - SEL_BORDER_SIZE, w + 2 * SEL_BORDER_SIZE, h + 2 * SEL_BORDER_SIZE);
g.drawImage(dpImg, x, y, w, h);
}
else {
//fake labelname shadow
g.drawText(item.getName(), GROUP_HEADER_FONT, Color.BLACK, (x + PADDING)-1f, (y + PADDING*2)+1f, w - 2 * PADDING, h - 2 * PADDING, true, Align.center, false);
//labelname
g.drawText(item.getName(), GROUP_HEADER_FONT, Color.WHITE, x + PADDING, y + PADDING*2, w - 2 * PADDING, h - 2 * PADDING, true, Align.center, false);
} else {
if (!dp.isGeneratedDeck()){
FImageComplex cardArt = CardRenderer.getCardArt(dp.getHighestCMCCard().getImageKey(false), false, false, false);
//draw the deckbox
if (cardArt != null){
g.drawDeckBox(cardArt, scale, FSkin.getDeckbox().get(1), FSkin.getDeckbox().get(2), x, y, w, h, Color.GREEN, selected);
}
} else {
//generic box
g.drawImage(FSkin.getDeckbox().get(2), FSkin.getDeckbox().get(2), x, y-(h*0.25f), w, h, Color.GREEN, selected);
}
if (deckColor != null) {
//deck color identity
float symbolSize = IMAGE_SIZE;
if (Forge.isLandscapeMode()) {
if (columnCount == 4)
symbolSize = IMAGE_SIZE * 1.5f;
else if (columnCount == 3)
symbolSize = IMAGE_SIZE * 2f;
else if (columnCount == 2)
symbolSize = IMAGE_SIZE * 3f;
else if (columnCount == 1)
symbolSize = IMAGE_SIZE * 4f;
} else {
if (columnCount > 2)
symbolSize = IMAGE_SIZE * (0.5f);
}
//vertical mana icons
CardFaceSymbols.drawColorSet(g, deckColor, x +(w-symbolSize), y+(h/8), symbolSize, true);
}
String deckname = TextUtil.fastReplace(item.getName(),"] #", "]\n#");
//deckname fakeshadow
g.drawText(deckname, GROUP_HEADER_FONT, Color.BLACK, (x + PADDING)-1f, (y + (h/10) + PADDING)+1f, w - 2 * PADDING, h - 2 * PADDING, true, Align.center, true);
//deck name
g.drawText(deckname, GROUP_HEADER_FONT, Color.WHITE, x + PADDING, y + (h/10) + PADDING, w - 2 * PADDING, h - 2 * PADDING, true, Align.center, true);
}
} else {
Texture img = ImageCache.getImage(item);
if (img != null) {
g.drawImage(img, x, y, w, h);
}
else {
} else {
g.fillRect(Color.BLACK, x, y, w, h);
g.drawText(item.getName(), GROUP_HEADER_FONT, Color.WHITE, x + PADDING, y + PADDING, w - 2 * PADDING, h - 2 * PADDING, true, Align.center, false);
}

View File

@@ -101,6 +101,7 @@ public class ConquestRewardDialog extends FScrollPane {
float startX = x;
int cardCount = cardRevealers.size();
try {
cardRevealers.get(0).setBounds(x, y, cardWidth, cardHeight);
for (int i = 1; i < cardCount; i++) {
if (i % columnCount == 0) {
@@ -112,6 +113,10 @@ public class ConquestRewardDialog extends FScrollPane {
}
cardRevealers.get(i).setBounds(x, y, cardWidth, cardHeight);
}
} catch (Exception ex) {
System.err.println(ex.getMessage());
}
return new ScrollBounds(visibleWidth, y + cardHeight + PADDING);
}

View File

@@ -13,10 +13,13 @@ import forge.assets.FSkinProp;
import forge.assets.IHasSkinProp;
import forge.assets.TextRenderer;
import forge.assets.FSkinColor.Colors;
import forge.card.CardFaceSymbols;
import forge.card.CardRenderer;
import forge.card.CardZoom;
import forge.card.CardRenderer.CardStackPosition;
import forge.card.CardZoom.ActivateHandler;
import forge.card.mana.ManaCost;
import forge.card.mana.ManaCostParser;
import forge.game.card.CardView;
import forge.game.card.IHasCardView;
import forge.game.player.PlayerView;
@@ -29,8 +32,11 @@ import forge.itemmanager.filters.ItemFilter;
import forge.screens.match.MatchController;
import forge.screens.match.views.VAvatar;
import forge.screens.match.views.VStack;
import forge.util.TextUtil;
import forge.util.Utils;
import static forge.card.CardRenderer.MANA_SYMBOL_SIZE;
public class FChoiceList<T> extends FList<T> implements ActivateHandler {
public static final FSkinColor ITEM_COLOR = FSkinColor.get(Colors.CLR_ZEBRA);
public static final FSkinColor ALT_ITEM_COLOR = ITEM_COLOR.getContrastColor(-20);
@@ -337,9 +343,19 @@ public class FChoiceList<T> extends FList<T> implements ActivateHandler {
@Override
public void drawValue(Graphics g, T value, FSkinFont font, FSkinColor foreColor, boolean pressed, float x, float y, float w, float h) {
//update manacost text to draw symbols instead
if (value.toString().contains(" {")){
String[] values = value.toString().split(" ");
String cost = TextUtil.fastReplace(values[1],"}{", " ");
cost = TextUtil.fastReplace(TextUtil.fastReplace(cost,"{", ""),"}", "");
ManaCost manaCost = new ManaCost(new ManaCostParser(cost));
CardFaceSymbols.drawManaCost(g, manaCost, x + font.getBounds(values[0]+" ").width, y + (h - MANA_SYMBOL_SIZE) / 2, MANA_SYMBOL_SIZE);
g.drawText(values[0], font, foreColor, x, y, w, h, allowDefaultItemWrap(), Align.left, true);
} else {
g.drawText(getChoiceText(value), font, foreColor, x, y, w, h, allowDefaultItemWrap(), Align.left, true);
}
}
}
protected class NumberRenderer extends DefaultItemRenderer {
@Override
public FSkinFont getDefaultFont() {

View File

@@ -12,4 +12,5 @@ SVar:X:Count$xPaid
SVar:Y:Count$RememberedSize
SVar:XLands:Number$0
DeckHas:Ability$Sacrifice
AI:RemoveDeck:All
Oracle:Sacrifice X lands. For each land sacrificed this way, draw a card. You may play X additional lands this turn. Lands you control enter the battlefield tapped this turn.

View File

@@ -494,6 +494,7 @@ lblCreateaDeck=Erzeuge ein Deck.
#CSubmenuQuestPrefs.java
lblEnteraNumber=Nummer eingeben
lblSavefailed=Speichern fehlgeschlagen
lblEnteraDecimal=Eine Zahl eingeben
#DialogChooseFormats.java
cbWantReprints=Erlaube passende Drucke aus anderen Sets
lblChooseFormats=Wähle Format
@@ -734,6 +735,8 @@ lblWinsperDraftRotation=Siege pro Draft notwendig
ttWinsperDraftRotation=Wenn ein Draft nicht soweit fertig gespielt wird, wird er entfernt oder ersetzt.
lblRotationType=Austauschtyp
ttRotationType=Bei 0 verschwinden alte Drafts, bei 1 wird er durch einen neuen ersetzt.
lblWildOpponentMultiplier=Wild-Multiplikator
lblWildOpponentNumber=Anzahl der Wild-Gegner
#StatTypeFilter.java
lblclicktotoogle=Klicke zum Umschalten des Filters, Rechtsklick für Einzelanzeige von:
#SItemManagerUtil.java
@@ -2587,7 +2590,5 @@ lblEnterMessageToSend=Nachricht zum Senden eingeben
lblDetectedInvalidHostAddress=Ungültige Host-Adresse ({0}) wurde festgestellt.
#Player.java
lblChooseACompanion=Wähle einen Gefährten
lblWildOpponentMultiplier=Wild-Multiplikator
lblEnteraDecimal=Eine Zahl eingeben
lblWildOpponentNumber=Anzahl der Wild-Gegner
#QuestPreferences.java
lblWildOpponentNumberError=Anzahl der Wild-Gegner kann nur 0 bis 3 sein

View File

@@ -494,6 +494,7 @@ lblCreateaDeck=Create a Deck.
#CSubmenuQuestPrefs.java
lblEnteraNumber=Enter a number
lblSavefailed=Save failed
lblEnteraDecimal=Enter a decimal
#DialogChooseFormats.java
cbWantReprints=Allow compatible reprints from other sets
lblChooseFormats=Choose formats
@@ -734,6 +735,8 @@ lblWinsperDraftRotation=Wins per Draft Rotation
ttWinsperDraftRotation=If a Draft is not played for this many match wins, it will be removed or replaced.
lblRotationType=Rotation Type
ttRotationType=If set to 0, old drafts disappear, if set to 1, they are replaced with another one using different sets.
lblWildOpponentNumber=Number of Wild Opponents
lblWildOpponentMultiplier=Wild Multiplier
#StatTypeFilter.java
lblclicktotoogle=click to toggle the filter, right-click to show only
#SItemManagerUtil.java
@@ -2587,7 +2590,5 @@ lblEnterMessageToSend=Enter message to send
lblDetectedInvalidHostAddress=Invalid host address ({0}) was detected.
#Player.java
lblChooseACompanion=Choose a companion
lblWildOpponentMultiplier=Wild Multiplier
lblEnteraDecimal=Enter a decimal
lblWildOpponentNumber=Number of Wild Opponents
#QuestPreferences.java
lblWildOpponentNumberError=Wild Opponents can only be 0 to 3

View File

@@ -494,6 +494,7 @@ lblCreateaDeck=Crear un Mazo.
#CSubmenuQuestPrefs.java
lblEnteraNumber=Ingrese un numero
lblSavefailed=Error al guardar
lblEnteraDecimal=Enter a decimal
#DialogChooseFormats.java
cbWantReprints=Permitir reimpresiones compatibles de otras ediciones.
lblChooseFormats=Elije Formatos
@@ -734,6 +735,8 @@ lblWinsperDraftRotation=Victorias Rotación de Draft
ttWinsperDraftRotation=Si no se juega un Draft para esta cantidad de victorias, se eliminará o reemplazará.
lblRotationType=Tipo de Rotación
ttRotationType=Si se establece en 0, los anteriores Draft desaparecen, si se establece en 1, se reemplazan por otros que utilizan sets diferentes.
lblWildOpponentNumber=Number of Wild Opponents
lblWildOpponentMultiplier=Wild Multiplier
#StatTypeFilter.java
lblclicktotoogle=haga clic para alternar el filtro, haga clic con el botón derecho para mostrar solo
#SItemManagerUtil.java
@@ -2587,3 +2590,5 @@ lblEnterMessageToSend=Ingrese el mensaje para enviar
lblDetectedInvalidHostAddress=Se detectó una dirección de host no válida ({0}).
#Player.java
lblChooseACompanion=Elige un compañero
#QuestPreferences.java
lblWildOpponentNumberError=Wild Opponents can only be 0 to 3

View File

@@ -494,6 +494,7 @@ lblCreateaDeck=Crea un mazzo.
#CSubmenuQuestPrefs.java
lblEnteraNumber=Inserisci un numero
lblSavefailed=Salvataggio fallito
lblEnteraDecimal=Enter a decimal
#DialogChooseFormats.java
cbWantReprints=Consenti ristampe compatibili da altri set
lblChooseFormats=Scegli i formati
@@ -734,6 +735,8 @@ lblWinsperDraftRotation=Vittorie per Draft Rotation
ttWinsperDraftRotation=Se una Draft non viene giocata per questo numero di vittorie, verrà rimossa o sostituita.
lblRotationType=Tipo di rotazione
ttRotationType=Se impostato su 0, le vecchie bozze scompaiono, se impostate su 1, vengono sostituite con un''altra utilizzando set diversi.
lblWildOpponentNumber=Number of Wild Opponents
lblWildOpponentMultiplier=Wild Multiplier
#StatTypeFilter.java
lblclicktotoogle=fai clic per attivare o disattivare il filtro, fai clic con il pulsante destro del mouse per mostrare solo
#SItemManagerUtil.java
@@ -2587,3 +2590,5 @@ lblEnterMessageToSend=Enter message to send
lblDetectedInvalidHostAddress=Invalid host address ({0}) was detected.
#Player.java
lblChooseACompanion=Choose a companion
#QuestPreferences.java
lblWildOpponentNumberError=Wild Opponents can only be 0 to 3

View File

@@ -494,6 +494,7 @@ lblCreateaDeck=创建一个套牌
#CSubmenuQuestPrefs.java
lblEnteraNumber=输入一个数
lblSavefailed=保存错误
lblEnteraDecimal=输入一个十进制小数
#DialogChooseFormats.java
cbWantReprints=允许来自其他系列的重印牌
lblChooseFormats=选择赛制
@@ -734,6 +735,8 @@ lblWinsperDraftRotation=每次轮抓胜利轮替
ttWinsperDraftRotation=如果轮抓没有赢这么多场,那么它将被删除或者替换。
lblRotationType=轮替类型
ttRotationType=如果设置为0旧系列消失如果设置为1则用不同系列替换。
lblWildOpponentNumber=野外对手数量
lblWildOpponentMultiplier=野外对手倍数
#StatTypeFilter.java
lblclicktotoogle=单击以切换筛选器,右键单机以仅显示
#SItemManagerUtil.java
@@ -2587,3 +2590,5 @@ lblEnterMessageToSend=输入要发送的信息
lblDetectedInvalidHostAddress=检测到无效的主机地址({0})。
#Player.java
lblChooseACompanion=选择一个行侣
#QuestPreferences.java
lblWildOpponentNumberError=野外对手数只能在0-3之间

Binary file not shown.

After

Width:  |  Height:  |  Size: 758 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 504 KiB

View File

@@ -1,11 +1,15 @@
package forge.deck;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import forge.card.CardSplitType;
import org.apache.commons.lang3.StringUtils;
import com.google.common.base.Function;
@@ -260,6 +264,29 @@ public class DeckProxy implements InventoryItem {
return highestRarity;
}
public PaperCard getHighestCMCCard() {
PaperCard key = null;
Map<PaperCard, Integer> keyCMC = new HashMap<>(64);
for (final Entry <PaperCard, Integer> pc : getDeck().getAllCardsInASinglePool()) {
if (pc.getKey().getRules().getManaCost() != null) {
if (pc.getKey().getRules().getSplitType() != CardSplitType.Split)
keyCMC.put(pc.getKey(),pc.getKey().getRules().getManaCost().getCMC());
}
}
if (!keyCMC.isEmpty()) {
int max = Collections.max(keyCMC.values());
//get any max cmc
for (Entry<PaperCard, Integer> entry : keyCMC.entrySet()) {
if (entry.getValue()==max) {
return entry.getKey();
}
}
}
return key;
}
public Set<GameFormat> getFormats() {
if (formats == null) {
formats = FModel.getFormats().getAllFormatsOfDeck(getDeck());

View File

@@ -100,6 +100,7 @@ public final class ForgeConstants {
public static final String SPRITE_ABILITY_FILE = "sprite_ability.png";
public static final String SPRITE_BORDER_FILE = "sprite_border.png";
public static final String SPRITE_BUTTONS_FILE = "sprite_buttons.png";
public static final String SPRITE_DECKBOX_FILE = "sprite_deckbox.png";
public static final String SPRITE_START_FILE = "sprite_start.png";
public static final String SPRITE_MANAICONS_FILE = "sprite_manaicons.png";
public static final String SPRITE_AVATARS_FILE = "sprite_avatars.png";

View File

@@ -18,16 +18,15 @@ import org.apache.commons.lang3.StringUtils;
import forge.ImageKeys;
import forge.deck.Deck;
import forge.deck.DeckProxy;
import forge.deck.io.DeckSerializer;
import forge.deck.io.DeckStorage;
import forge.model.FModel;
import forge.quest.QuestEvent;
import forge.quest.QuestEventDifficulty;
import forge.quest.QuestEventDuel;
import forge.util.FileSection;
import forge.util.FileUtil;
import forge.util.TextUtil;
import forge.util.storage.IStorage;
import forge.util.storage.StorageReaderFolder;
public class MainWorldDuelReader extends StorageReaderFolder<QuestEventDuel> {
@@ -77,10 +76,11 @@ public class MainWorldDuelReader extends StorageReaderFolder<QuestEventDuel> {
}
// then I add wild decks in constructed directory
IStorage<Deck> constructedDecks = FModel.getDecks().getConstructed();
Iterator it = constructedDecks.iterator();
Iterable<DeckProxy> constructedDecks = DeckProxy.getAllConstructedDecks();
Iterator<DeckProxy> it = constructedDecks.iterator();
while(it.hasNext()) {
Deck currDeck = (Deck) it.next();
Deck currDeck = it.next().getDeck();
final QuestEventDuel newDeck = read(currDeck);
String newKey = keySelector.apply(newDeck);
if (result.containsKey(newKey)) {