diff --git a/forge-gui-desktop/src/main/java/forge/sound/AudioClip.java b/forge-gui-desktop/src/main/java/forge/sound/AudioClip.java index 19c15568c11..831dc2806c6 100644 --- a/forge-gui-desktop/src/main/java/forge/sound/AudioClip.java +++ b/forge-gui-desktop/src/main/java/forge/sound/AudioClip.java @@ -25,6 +25,7 @@ import forge.properties.ForgeConstants; import java.io.File; import java.io.IOException; import java.util.MissingResourceException; +import java.util.function.Supplier; /** @@ -35,6 +36,8 @@ import java.util.MissingResourceException; */ public class AudioClip implements IAudioClip { private Clip clip; + private boolean started; + private boolean looping; public static boolean fileExists(String fileName) { File fSound = new File(ForgeConstants.SOUND_DIR, fileName); @@ -52,6 +55,7 @@ public class AudioClip implements IAudioClip { AudioFormat format = stream.getFormat(); DataLine.Info info = new DataLine.Info(Clip.class, stream.getFormat(), ((int) stream.getFrameLength() * format.getFrameSize())); clip = (Clip) AudioSystem.getLine(info); + clip.addLineListener(this::lineStatusChanged); clip.open(stream); return; @@ -72,13 +76,21 @@ public class AudioClip implements IAudioClip { if (null == clip) { return; } - clip.setMicrosecondPosition(0); - try { - Thread.sleep(SoundSystem.DELAY); - } catch (InterruptedException ex) { - ex.printStackTrace(); + synchronized (this) { + if (clip.isRunning()) { + // introduce small delay to make a batch sounds more granular, + // e.g. when you auto-tap 4 lands the 4 tap sounds should + // not become completely merged + waitSoundSystemDelay(); + } + clip.setMicrosecondPosition(0); + if (!this.looping && clip.isRunning()) { + return; + } + this.started = false; + clip.start(); + wait(() -> this.started); } - clip.start(); } @Override @@ -86,13 +98,16 @@ public class AudioClip implements IAudioClip { if (null == clip) { return; } - clip.setMicrosecondPosition(0); - try { - Thread.sleep(SoundSystem.DELAY); - } catch (InterruptedException ex) { - ex.printStackTrace(); + synchronized (this) { + clip.setMicrosecondPosition(0); + if (this.looping && clip.isRunning()) { + return; + } + this.started = false; + clip.loop(Clip.LOOP_CONTINUOUSLY); + wait(() -> this.started); + this.looping = true; } - clip.loop(Clip.LOOP_CONTINUOUSLY); } @Override @@ -100,7 +115,10 @@ public class AudioClip implements IAudioClip { if (null == clip) { return; } - clip.stop(); + synchronized (this) { + clip.stop(); + this.looping = false; + } } @Override @@ -110,4 +128,28 @@ public class AudioClip implements IAudioClip { } return !clip.isRunning(); } + + private void wait(Supplier completed) { + final int attempts = 5; + for (int i = 0; i < attempts; i++) { + if (completed.get() || !waitSoundSystemDelay()) { + break; + } + } + } + + private boolean waitSoundSystemDelay() { + try { + Thread.sleep(SoundSystem.DELAY); + return true; + } catch (InterruptedException ex) { + ex.printStackTrace(); + return false; + } + } + + private void lineStatusChanged(LineEvent line) { + LineEvent.Type status = line.getType(); + this.started |= status == LineEvent.Type.START; + } } diff --git a/forge-gui-mobile/src/forge/Forge.java b/forge-gui-mobile/src/forge/Forge.java index f74fd303907..2be333bc7c5 100644 --- a/forge-gui-mobile/src/forge/Forge.java +++ b/forge-gui-mobile/src/forge/Forge.java @@ -50,6 +50,8 @@ public class Forge implements ApplicationListener { private static final Stack screens = new Stack(); private static boolean textureFiltering = false; private static boolean destroyThis = false; + public static String extrawide = "default"; + public static float heigtModifier = 0.0f; public static ApplicationListener getApp(Clipboard clipboard0, IDeviceAdapter deviceAdapter0, String assetDir0) { if (GuiBase.getInterface() == null) { @@ -134,6 +136,9 @@ public class Forge implements ApplicationListener { NewGameMenu.getPreferredScreen().open(); } + //adjust height modifier + adjustHeightModifier(getScreenWidth(), getScreenHeight()); + //update landscape mode preference if it doesn't match what the app loaded as if (FModel.getPreferences().getPrefBoolean(FPref.UI_LANDSCAPE_MODE) != isLandscapeMode) { FModel.getPreferences().setPref(FPref.UI_LANDSCAPE_MODE, isLandscapeMode); @@ -162,6 +167,29 @@ public class Forge implements ApplicationListener { } } + public static void setHeightModifier(float height) { + heigtModifier = height; + } + + public static float getHeightModifier() { + return heigtModifier; + } + + public static void adjustHeightModifier(float DisplayW, float DisplayH) { + if(isLandscapeMode()) + {//TODO: Fullscreen support for Display without screen controls + float aspectratio = DisplayW / DisplayH; + if(aspectratio > 1.82f) {/* extra wide */ + setHeightModifier(200.0f); + extrawide = "extrawide"; + } + else if(aspectratio > 1.7f) {/* wide */ + setHeightModifier(100.0f); + extrawide = "wide"; + } + } + } + public static void showMenu() { if (currentScreen == null) { return; } endKeyInput(); //end key input before menu shown @@ -175,7 +203,7 @@ public class Forge implements ApplicationListener { } public static void back() { - if(destroyThis) + if(destroyThis && isLandscapeMode()) return; if (screens.size() < 2) { exit(false); //prompt to exit if attempting to go back from home screen @@ -494,7 +522,7 @@ public class Forge implements ApplicationListener { if(keyCode == Keys.BACK){ if (destroyThis) deviceAdapter.exit(); - else if(onHomeScreen()) + else if(onHomeScreen() && isLandscapeMode()) back(); } if (keyInputAdapter == null) { diff --git a/forge-gui-mobile/src/forge/deck/FDeckImportDialog.java b/forge-gui-mobile/src/forge/deck/FDeckImportDialog.java index 1d00f01b24a..e00e009a551 100644 --- a/forge-gui-mobile/src/forge/deck/FDeckImportDialog.java +++ b/forge-gui-mobile/src/forge/deck/FDeckImportDialog.java @@ -42,7 +42,12 @@ public class FDeckImportDialog extends FDialog { private final FTextArea txtInput = add(new FTextArea(true)); private final FCheckBox newEditionCheck = add(new FCheckBox("Import latest version of card", true)); private final FCheckBox dateTimeCheck = add(new FCheckBox("Use only sets released before:", false)); - private final FCheckBox onlyCoreExpCheck = add(new FCheckBox("Use only core and expansion sets", true)); + /*setting onlyCoreExpCheck to false allow the copied cards to pass the check of deck contents + forge-core\src\main\java\forge\deck\Deck.javaDeck.java starting @ Line 320 which is called by + forge-gui-mobile\src\forge\deck\FDeckEditor.java starting @ Line 373 + (as of latest commit: 8e6655e3ee67688cff66b422d4722c58392eaa7e) + */ + private final FCheckBox onlyCoreExpCheck = add(new FCheckBox("Use only core and expansion sets", false)); private final FComboBox monthDropdown = add(new FComboBox()); //don't need wrappers since skin can't change while this dialog is open private final FComboBox yearDropdown = add(new FComboBox()); diff --git a/forge-gui-mobile/src/forge/screens/match/MatchScreen.java b/forge-gui-mobile/src/forge/screens/match/MatchScreen.java index 67e478e7d23..3f08f076fd0 100644 --- a/forge-gui-mobile/src/forge/screens/match/MatchScreen.java +++ b/forge-gui-mobile/src/forge/screens/match/MatchScreen.java @@ -3,7 +3,6 @@ package forge.screens.match; import java.util.*; import java.util.Map.Entry; -import forge.properties.ForgeConstants; import org.apache.commons.lang3.tuple.Pair; import com.badlogic.gdx.Input.Keys; @@ -508,10 +507,20 @@ public class MatchScreen extends FScreen { float w = getWidth() - x; if(FModel.getPreferences().getPrefBoolean(FPref.UI_DYNAMIC_PLANECHASE_BG) - && hasActivePlane()) //TODO: scale BG to correct aspect ratio/crop center - setPlanarBG(g, getPlaneName(), x, y, w, ForgeConstants.isGdxPortLandscape ? getHeight() : midField); - else - g.drawImage(FSkinTexture.BG_MATCH, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); + && hasActivePlane()) + setPlanarBG(g, getPlaneName(), x, y, w, midField); + else { + float bgFullWidth; + float scaledbgHeight; + float bgHeight = midField + bottomPlayerPanel.getField().getHeight() - y; + bgFullWidth = bgHeight * FSkinTexture.BG_MATCH.getWidth() / FSkinTexture.BG_MATCH.getHeight(); + if (bgFullWidth < w) { + scaledbgHeight = w * (bgHeight / bgFullWidth); + bgFullWidth = w; + bgHeight = scaledbgHeight; + } + g.drawImage(FSkinTexture.BG_MATCH, x + (w - bgFullWidth) / 2, y, bgFullWidth, bgHeight); + } } } @@ -649,245 +658,799 @@ public class MatchScreen extends FScreen { return false; } private void setPlanarBG(Graphics g, String planeName, float x, float y, float w, float midField ){ + float planeFullWidth; + float scaledPlaneHeight; + float planeHeight = midField + bottomPlayerPanel.getField().getHeight() - y; switch (planeName) { - case "Academy at Tolaria West": - g.drawImage(FSkinTexture.BG_PLANE1, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Agyrem": - g.drawImage(FSkinTexture.BG_PLANE2, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Akoum": - g.drawImage(FSkinTexture.BG_PLANE3, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Aretopolis": - g.drawImage(FSkinTexture.BG_PLANE4, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Astral Arena": - g.drawImage(FSkinTexture.BG_PLANE5, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Bant": - g.drawImage(FSkinTexture.BG_PLANE6, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Bloodhill Bastion": - g.drawImage(FSkinTexture.BG_PLANE7, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Cliffside Market": - g.drawImage(FSkinTexture.BG_PLANE8, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Edge of Malacol": - g.drawImage(FSkinTexture.BG_PLANE9, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Eloren Wilds": - g.drawImage(FSkinTexture.BG_PLANE10, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Feeding Grounds": - g.drawImage(FSkinTexture.BG_PLANE11, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Fields of Summer": - g.drawImage(FSkinTexture.BG_PLANE12, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Furnace Layer": - g.drawImage(FSkinTexture.BG_PLANE13, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Gavony": - g.drawImage(FSkinTexture.BG_PLANE14, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Glen Elendra": - g.drawImage(FSkinTexture.BG_PLANE15, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Glimmervoid Basin": - g.drawImage(FSkinTexture.BG_PLANE16, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Goldmeadow": - g.drawImage(FSkinTexture.BG_PLANE17, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Grand Ossuary": - g.drawImage(FSkinTexture.BG_PLANE18, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Grixis": - g.drawImage(FSkinTexture.BG_PLANE19, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Grove of the Dreampods": - g.drawImage(FSkinTexture.BG_PLANE20, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Hedron Fields of Agadeem": - g.drawImage(FSkinTexture.BG_PLANE21, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Immersturm": - g.drawImage(FSkinTexture.BG_PLANE22, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Isle of Vesuva": - g.drawImage(FSkinTexture.BG_PLANE23, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Izzet Steam Maze": - g.drawImage(FSkinTexture.BG_PLANE24, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Jund": - g.drawImage(FSkinTexture.BG_PLANE25, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Kessig": - g.drawImage(FSkinTexture.BG_PLANE26, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Kharasha Foothills": - g.drawImage(FSkinTexture.BG_PLANE27, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Kilnspire District": - g.drawImage(FSkinTexture.BG_PLANE28, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Krosa": - g.drawImage(FSkinTexture.BG_PLANE29, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Lair of the Ashen Idol": - g.drawImage(FSkinTexture.BG_PLANE30, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Lethe Lake": - g.drawImage(FSkinTexture.BG_PLANE31, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Llanowar": - g.drawImage(FSkinTexture.BG_PLANE32, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Minamo": - g.drawImage(FSkinTexture.BG_PLANE33, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Mount Keralia": - g.drawImage(FSkinTexture.BG_PLANE34, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Murasa": - g.drawImage(FSkinTexture.BG_PLANE35, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Naar Isle": - g.drawImage(FSkinTexture.BG_PLANE36, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Naya": - g.drawImage(FSkinTexture.BG_PLANE37, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Nephalia": - g.drawImage(FSkinTexture.BG_PLANE38, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Norn's Dominion": - g.drawImage(FSkinTexture.BG_PLANE39, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Onakke Catacomb": - g.drawImage(FSkinTexture.BG_PLANE40, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Orochi Colony": - g.drawImage(FSkinTexture.BG_PLANE41, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Orzhova": - g.drawImage(FSkinTexture.BG_PLANE42, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Otaria": - g.drawImage(FSkinTexture.BG_PLANE43, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Panopticon": - g.drawImage(FSkinTexture.BG_PLANE44, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Pools of Becoming": - g.drawImage(FSkinTexture.BG_PLANE45, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Prahv": - g.drawImage(FSkinTexture.BG_PLANE46, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Quicksilver Sea": - g.drawImage(FSkinTexture.BG_PLANE47, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Raven's Run": - g.drawImage(FSkinTexture.BG_PLANE48, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Sanctum of Serra": - g.drawImage(FSkinTexture.BG_PLANE49, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Sea of Sand": - g.drawImage(FSkinTexture.BG_PLANE50, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Selesnya Loft Gardens": - g.drawImage(FSkinTexture.BG_PLANE51, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Shiv": - g.drawImage(FSkinTexture.BG_PLANE52, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Skybreen": - g.drawImage(FSkinTexture.BG_PLANE53, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Sokenzan": - g.drawImage(FSkinTexture.BG_PLANE54, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Stairs to Infinity": - g.drawImage(FSkinTexture.BG_PLANE55, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Stensia": - g.drawImage(FSkinTexture.BG_PLANE56, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Stronghold Furnace": - g.drawImage(FSkinTexture.BG_PLANE57, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Takenuma": - g.drawImage(FSkinTexture.BG_PLANE58, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Tazeem": - g.drawImage(FSkinTexture.BG_PLANE59, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "The Aether Flues": - g.drawImage(FSkinTexture.BG_PLANE60, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "The Dark Barony": - g.drawImage(FSkinTexture.BG_PLANE61, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "The Eon Fog": - g.drawImage(FSkinTexture.BG_PLANE62, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "The Fourth Sphere": - g.drawImage(FSkinTexture.BG_PLANE63, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "The Great Forest": - g.drawImage(FSkinTexture.BG_PLANE64, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "The Hippodrome": - g.drawImage(FSkinTexture.BG_PLANE65, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "The Maelstrom": - g.drawImage(FSkinTexture.BG_PLANE66, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "The Zephyr Maze": - g.drawImage(FSkinTexture.BG_PLANE67, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Trail of the Mage-Rings": - g.drawImage(FSkinTexture.BG_PLANE68, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Truga Jungle": - g.drawImage(FSkinTexture.BG_PLANE69, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Turri Island": - g.drawImage(FSkinTexture.BG_PLANE70, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Undercity Reaches": - g.drawImage(FSkinTexture.BG_PLANE71, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Velis Vel": - g.drawImage(FSkinTexture.BG_PLANE72, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Windriddle Palaces": - g.drawImage(FSkinTexture.BG_PLANE73, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Tember City": - g.drawImage(FSkinTexture.BG_PLANE74, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Celestine Reef": - g.drawImage(FSkinTexture.BG_PLANE75, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Horizon Boughs": - g.drawImage(FSkinTexture.BG_PLANE76, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Mirrored Depths": - g.drawImage(FSkinTexture.BG_PLANE77, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; - case "Talon Gates": - g.drawImage(FSkinTexture.BG_PLANE78, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); - break; + case "Academy at Tolaria West": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE1.getWidth() / FSkinTexture.BG_PLANE1.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE1, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Agyrem": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE2.getWidth() / FSkinTexture.BG_PLANE2.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE2, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Akoum": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE3.getWidth() / FSkinTexture.BG_PLANE3.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE3, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Aretopolis": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE4.getWidth() / FSkinTexture.BG_PLANE4.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE4, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Astral Arena": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE5.getWidth() / FSkinTexture.BG_PLANE5.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE5, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Bant": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE6.getWidth() / FSkinTexture.BG_PLANE6.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE6, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Bloodhill Bastion": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE7.getWidth() / FSkinTexture.BG_PLANE7.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE7, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Cliffside Market": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE8.getWidth() / FSkinTexture.BG_PLANE8.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE8, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Edge of Malacol": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE9.getWidth() / FSkinTexture.BG_PLANE9.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE9, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Eloren Wilds": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE10.getWidth() / FSkinTexture.BG_PLANE10.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE10, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Feeding Grounds": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE11.getWidth() / FSkinTexture.BG_PLANE11.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE11, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Fields of Summer": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE12.getWidth() / FSkinTexture.BG_PLANE12.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE12, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Furnace Layer": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE13.getWidth() / FSkinTexture.BG_PLANE13.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE13, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Gavony": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE14.getWidth() / FSkinTexture.BG_PLANE14.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE14, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Glen Elendra": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE15.getWidth() / FSkinTexture.BG_PLANE15.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE15, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Glimmervoid Basin": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE16.getWidth() / FSkinTexture.BG_PLANE16.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE16, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Goldmeadow": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE17.getWidth() / FSkinTexture.BG_PLANE17.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE17, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Grand Ossuary": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE18.getWidth() / FSkinTexture.BG_PLANE18.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE18, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Grixis": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE19.getWidth() / FSkinTexture.BG_PLANE19.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE19, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Grove of the Dreampods": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE20.getWidth() / FSkinTexture.BG_PLANE20.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE20, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Hedron Fields of Agadeem": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE21.getWidth() / FSkinTexture.BG_PLANE21.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE21, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Immersturm": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE22.getWidth() / FSkinTexture.BG_PLANE22.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE22, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Isle of Vesuva": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE23.getWidth() / FSkinTexture.BG_PLANE23.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE23, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Izzet Steam Maze": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE24.getWidth() / FSkinTexture.BG_PLANE24.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE24, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Jund": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE25.getWidth() / FSkinTexture.BG_PLANE25.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE25, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Kessig": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE26.getWidth() / FSkinTexture.BG_PLANE26.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE26, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Kharasha Foothills": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE27.getWidth() / FSkinTexture.BG_PLANE27.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE27, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Kilnspire District": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE28.getWidth() / FSkinTexture.BG_PLANE28.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE28, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Krosa": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE29.getWidth() / FSkinTexture.BG_PLANE29.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE29, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Lair of the Ashen Idol": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE30.getWidth() / FSkinTexture.BG_PLANE30.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE30, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Lethe Lake": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE31.getWidth() / FSkinTexture.BG_PLANE31.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE31, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Llanowar": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE32.getWidth() / FSkinTexture.BG_PLANE32.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE32, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Minamo": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE33.getWidth() / FSkinTexture.BG_PLANE33.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE33, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Mount Keralia": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE34.getWidth() / FSkinTexture.BG_PLANE34.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE34, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Murasa": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE35.getWidth() / FSkinTexture.BG_PLANE35.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE35, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Naar Isle": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE36.getWidth() / FSkinTexture.BG_PLANE36.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE36, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Naya": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE37.getWidth() / FSkinTexture.BG_PLANE37.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE37, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Nephalia": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE38.getWidth() / FSkinTexture.BG_PLANE38.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE38, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Norn's Dominion": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE39.getWidth() / FSkinTexture.BG_PLANE39.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE39, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Onakke Catacomb": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE40.getWidth() / FSkinTexture.BG_PLANE40.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE40, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Orochi Colony": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE41.getWidth() / FSkinTexture.BG_PLANE41.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE41, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Orzhova": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE42.getWidth() / FSkinTexture.BG_PLANE42.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE42, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Otaria": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE43.getWidth() / FSkinTexture.BG_PLANE43.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE43, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Panopticon": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE44.getWidth() / FSkinTexture.BG_PLANE44.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE44, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Pools of Becoming": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE45.getWidth() / FSkinTexture.BG_PLANE45.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE45, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Prahv": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE46.getWidth() / FSkinTexture.BG_PLANE46.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE46, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Quicksilver Sea": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE47.getWidth() / FSkinTexture.BG_PLANE47.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE47, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Raven's Run": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE48.getWidth() / FSkinTexture.BG_PLANE48.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE48, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Sanctum of Serra": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE49.getWidth() / FSkinTexture.BG_PLANE49.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE49, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Sea of Sand": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE50.getWidth() / FSkinTexture.BG_PLANE50.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE50, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Selesnya Loft Gardens": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE51.getWidth() / FSkinTexture.BG_PLANE51.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE51, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Shiv": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE52.getWidth() / FSkinTexture.BG_PLANE52.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE52, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Skybreen": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE53.getWidth() / FSkinTexture.BG_PLANE53.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE53, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Sokenzan": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE54.getWidth() / FSkinTexture.BG_PLANE54.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE54, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Stairs to Infinity": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE55.getWidth() / FSkinTexture.BG_PLANE55.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE55, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Stensia": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE56.getWidth() / FSkinTexture.BG_PLANE56.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE56, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Stronghold Furnace": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE57.getWidth() / FSkinTexture.BG_PLANE57.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE57, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Takenuma": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE58.getWidth() / FSkinTexture.BG_PLANE58.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE58, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Tazeem": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE59.getWidth() / FSkinTexture.BG_PLANE59.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE59, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "The Aether Flues": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE60.getWidth() / FSkinTexture.BG_PLANE60.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE60, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "The Dark Barony": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE61.getWidth() / FSkinTexture.BG_PLANE61.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE61, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "The Eon Fog": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE62.getWidth() / FSkinTexture.BG_PLANE62.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE62, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "The Fourth Sphere": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE63.getWidth() / FSkinTexture.BG_PLANE63.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE63, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "The Great Forest": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE64.getWidth() / FSkinTexture.BG_PLANE64.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE64, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "The Hippodrome": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE65.getWidth() / FSkinTexture.BG_PLANE65.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE65, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "The Maelstrom": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE66.getWidth() / FSkinTexture.BG_PLANE66.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE66, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "The Zephyr Maze": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE67.getWidth() / FSkinTexture.BG_PLANE67.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE67, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Trail of the Mage-Rings": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE68.getWidth() / FSkinTexture.BG_PLANE68.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE68, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Truga Jungle": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE69.getWidth() / FSkinTexture.BG_PLANE69.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE69, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Turri Island": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE70.getWidth() / FSkinTexture.BG_PLANE70.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE70, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Undercity Reaches": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE71.getWidth() / FSkinTexture.BG_PLANE71.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE71, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Velis Vel": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE72.getWidth() / FSkinTexture.BG_PLANE72.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE72, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Windriddle Palaces": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE73.getWidth() / FSkinTexture.BG_PLANE73.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE73, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Tember City": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE74.getWidth() / FSkinTexture.BG_PLANE74.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE74, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Celestine Reef": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE75.getWidth() / FSkinTexture.BG_PLANE75.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE75, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Horizon Boughs": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE76.getWidth() / FSkinTexture.BG_PLANE76.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE76, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Mirrored Depths": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE77.getWidth() / FSkinTexture.BG_PLANE77.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE77, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; + case "Talon Gates": { + planeFullWidth = planeHeight * FSkinTexture.BG_PLANE78.getWidth() / FSkinTexture.BG_PLANE78.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_PLANE78, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); + } + break; default: { - //draw default - g.drawImage(FSkinTexture.BG_MATCH, x, y, w, midField + bottomPlayerPanel.getField().getHeight() - y); + planeFullWidth = planeHeight * FSkinTexture.BG_MATCH.getWidth() / FSkinTexture.BG_MATCH.getHeight(); + if (planeFullWidth < w) { + scaledPlaneHeight = w * (planeHeight / planeFullWidth); + planeFullWidth = w; + planeHeight = scaledPlaneHeight; + } + g.drawImage(FSkinTexture.BG_MATCH, x + (w - planeFullWidth) / 2, y, planeFullWidth, planeHeight); } } } diff --git a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestPlaneSelector.java b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestPlaneSelector.java index 1c78d317915..92303b8dc50 100644 --- a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestPlaneSelector.java +++ b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestPlaneSelector.java @@ -9,6 +9,7 @@ import com.google.common.base.Predicate; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; +import forge.Forge; import forge.Graphics; import forge.assets.FImage; import forge.assets.FSkinColor; @@ -151,6 +152,7 @@ public class ConquestPlaneSelector extends FDisplayObject { @Override public void draw(Graphics g) { + float hmod = Forge.getHeightModifier(); float w = getWidth(); float h = getHeight(); @@ -164,7 +166,7 @@ public class ConquestPlaneSelector extends FDisplayObject { FImage monitor = FSkinImage.PLANE_MONITOR; float monitorLeft = FOptionPane.PADDING / 2; float monitorWidth = w - 2 * monitorLeft; - float monitorHeight = monitorWidth * monitor.getHeight() / monitor.getWidth(); + float monitorHeight = (monitorWidth * monitor.getHeight() / monitor.getWidth()) - hmod; float monitorLeftOffset = monitorWidth * MONITOR_LEFT_MULTIPLIER; float monitorTopOffset = monitorHeight * MONITOR_TOP_MULTIPLIER; float monitorBottomOffset = monitorHeight * MONITOR_BOTTOM_MULTIPLIER; @@ -186,7 +188,7 @@ public class ConquestPlaneSelector extends FDisplayObject { float scaledArtHeight = monitorWidth * (artHeight / fullArtWidth); fullArtWidth = monitorWidth; artHeightClipMod = scaledArtHeight - artHeight; - artHeight = scaledArtHeight; + artHeight = scaledArtHeight; } g.startClip(x, y, artWidth, artHeight - artHeightClipMod); diff --git a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestPlaneswalkScreen.java b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestPlaneswalkScreen.java index 4af66742ffd..2fed378a3fe 100644 --- a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestPlaneswalkScreen.java +++ b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestPlaneswalkScreen.java @@ -46,9 +46,9 @@ public class ConquestPlaneswalkScreen extends FScreen { @Override protected void doLayout(float startY, float width, float height) { planeSelector.setBounds(0, startY, width, height - startY); - + float btnMod = Forge.extrawide.equals("extrawide") ? 1.5f : 2.5f; float buttonWidth = width * 0.6f; - float buttonHeight = btnPlaneswalk.getFont().getCapHeight() * 2.5f; + float buttonHeight = btnPlaneswalk.getFont().getCapHeight() * btnMod; btnPlaneswalk.setBounds((width - buttonWidth) / 2, height - buttonHeight - PADDING, buttonWidth, buttonHeight); } diff --git a/forge-gui/res/cardsfolder/v/vraskas_stoneglare.txt b/forge-gui/res/cardsfolder/v/vraskas_stoneglare.txt index f4801d7b67f..1a6c3cb90d1 100644 --- a/forge-gui/res/cardsfolder/v/vraskas_stoneglare.txt +++ b/forge-gui/res/cardsfolder/v/vraskas_stoneglare.txt @@ -4,5 +4,6 @@ Types:Sorcery A:SP$ Destroy | Cost$ 4 B G | ValidTgts$ Creature | TgtPrompt$ Select target creature | SubAbility$ DBGainLife | SpellDescription$ Destroy target creature. You gain life equal to its toughness. You may search your library and/or graveyard from a card named Vraska, Regal Gorgon, reveal it, and put it into your hand. If you search your library this way, shuffle it. SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ X | SubAbility$ DBCleanup | References$ X | SubAbility$ DBSearch SVar:DBSearch:DB$ ChangeZone | Origin$ Library,Graveyard | Destination$ Hand | ChangeType$ Card.namedVraska; Regal Gorgon | ChangeNum$ 1 | Optional$ True +SVar:X:TargetedLKI$CardToughness DeckNeeds:Name$Vraska, Regal Gorgon Oracle:Destroy target creature. You gain life equal to its toughness. You may search your library and/or graveyard from a card named Vraska, Regal Gorgon, reveal it, and put it in to your hand. If you search your library this way, shuffle it. diff --git a/forge-gui/res/cube/Ryan Overturf's Grixis Cube (MTGO).dck b/forge-gui/res/cube/Ryan Overturf's Grixis Cube (MTGO).dck new file mode 100644 index 00000000000..c92da263279 --- /dev/null +++ b/forge-gui/res/cube/Ryan Overturf's Grixis Cube (MTGO).dck @@ -0,0 +1,543 @@ +[metadata] +Name=Ryan Overturf's Grixis Cube (MTGO) +[Main] +1 Abbot of Keral Keep|ORI +1 Abrade|HOU +1 Academy Ruins|TSP +1 Agent of Treachery|M20 +1 All Is Dust|ROE +1 Aminatou's Augury|C18 +1 Ancestral Vision|TSP +1 Ancient Tomb|UMA +1 Anger of the Gods|IMA +1 Angrath's Rampage|WAR +1 Animate Dead|EMA +1 Arc Trail|DDN +1 Arcane Artisan|BBD +1 Arguel's Blood Fast|V17 +1 Aria of Flame|MH1 +1 Ash Zealot|RTR +1 Augur of Bolas|WAR +1 Avalanche Riders|TSB +1 Badlands|VMA +1 Baleful Strix|PC2 +1 Baral, Chief of Compliance|AER +1 Basalt Monolith|CM2 +1 Batterskull|NPH +1 Bedevil|RNA +1 Bedlam Reveler|EMN +1 Bitterblossom|UMA +1 Blackcleave Cliffs|SOM +1 Blast Zone|WAR +1 Blightsteel Colossus|MBS +1 Blink of an Eye|DOM +1 Blinkmoth Nexus|MM2 +1 Blood Artist|C17 +1 Blood Crypt|DIS +1 Bloodghast|IMA +1 Bloodsoaked Champion|KTK +1 Bloodstained Mire|KTK +1 Bolas's Citadel|WAR +1 Bomat Courier|KLD +1 Braids, Cabal Minion|EMA +1 Brain Freeze|VMA +1 Brain Maggot|JOU +1 Brainstorm|C18 +1 Buried Alive|UMA +1 Burning of Xinye|V14 +1 Burst Lightning|MM2 +1 Cabal Ritual|VMA +1 Candelabra of Tawnos|ME4 +1 Canyon Slough|AKH +1 Careful Study|ODY +1 Carrion Feeder|SCG +1 Cascade Bluffs|A25 +1 Cast Down|DOM +1 Cathartic Reunion|KLD +1 Chain Lightning|BBD +1 Chainer's Edict|UMA +1 Chains of Mephistopheles|MED +1 Champion of Wits|HOU +1 Chandra, Acolyte of Flame|M20 +1 Chandra, Awakened Inferno|M20 +1 Chandra, Fire of Kaladesh|V17 +1 Chandra, Flamecaller|OGW +1 Chandra, Torch of Defiance|KLD +1 Charcoal Diamond|C14 +1 Chart a Course|XLN +1 Chromatic Lantern|GRN +1 Chrome Mox|EMA +1 City of Traitors|EXO +1 Coalition Relic|A25 +1 Coercive Portal|VMA +1 Coldsteel Heart|CSP +1 Collective Brutality|EMN +1 Commence the Endgame|WAR +1 Commit // Memory|AKH +1 Compulsive Research|RAV +1 Consecrated Sphinx|MBS +1 Corpse Dance|TMP +1 Counterspell|EMA +1 Countersquall|UMA +1 Creeping Tar Pit|UMA +1 Crucible of Worlds|M19 +1 Cruel Ultimatum|DDH +1 Crumbling Necropolis|C17 +1 Cryptbreaker|EMN +1 Cryptic Command|IMA +1 Crystal Vein|CMA +1 Cut // Ribbons|AKH +1 Dack Fayden|CNS +1 Dack's Duplicate|CNS +1 Damnation|PLC +1 Daretti, Ingenious Iconoclast|PZ2 +1 Daretti, Scrap Savant|CM2 +1 Dark Confidant|RAV +1 Dark Petition|ORI +1 Dark Ritual|A25 +1 Darkslick Shores|SOM +1 Darksteel Citadel|MM2 +1 Darksteel Ingot|CM2 +1 Davriel, Rogue Shadowmage|WAR +1 Daze|NEM +1 Defense Grid|ULG +1 Defile|MH1 +1 Delver of Secrets|V17 +1 Demonic Tutor|LEA +1 Desperate Ritual|UMA +1 Devastating Summons|ROE +1 Dig Through Time|UMA +1 Dimir Signet|RAV +1 Dire Fleet Daredevil|RIX +1 Disallow|AER +1 Discovery // Dispersal|GRN +1 Dismember|MM2 +1 Doom Whisperer|GRN +1 Dragonlord Silumgar|DTK +1 Dragonskull Summit|XLN +1 Drawn from Dreams|M20 +1 Dread Wanderer|AKH +1 Dreadbore|GK2 +1 Dreadhorde Arcanist|WAR +1 Dreadship Reef|CM2 +1 Dream Halls|TPR +1 Dreamstealer|HOU +1 Drill Bit|RNA +1 Drowned Catacomb|XLN +1 Duplicant|C18 +1 Duress|M20 +1 Earthshaker Khenra|HOU +1 Echo of Eons|MH1 +1 Eidolon of the Great Revel|A25 +1 Eldrazi Obligator|OGW +1 Eldrazi Temple|DDP +1 Electrodominance|RNA +1 Electrolyze|GK1 +1 Empty the Warrens|DDS +1 Emrakul, the Aeons Torn|ROE +1 Emrakul, the Promised End|EMN +1 Enclave Cryptologist|ROE +1 Endbringer|OGW +1 Entomb|UMA +1 Epochrasite|CM2 +1 Erebos, God of the Dead|THS +1 Everflowing Chalice|CM2 +1 Exhume|TD2 +1 Expansion // Explosion|GRN +1 Experimental Frenzy|GRN +1 Fact or Fiction|MH1 +1 Faithless Looting|UMA +1 Falkenrath Aristocrat|MM3 +1 Falkenrath Gorger|SOI +1 Fatal Push|AER +1 Fellwar Stone|CM2 +1 Fetid Pools|AKH +1 Fiery Confluence|CM2 +1 Fiery Islet|MH1 +1 Figure of Destiny|DDL +1 Filigree Familiar|GNT +1 Finale of Eternity|WAR +1 Finale of Promise|WAR +1 Finale of Revelation|WAR +1 Fire // Ice|UMA +1 Fire Diamond|CM2 +1 Fireblast|JVC +1 Firebolt|MH1 +1 Firemind Vessel|WAR +1 Flame Slash|CN2 +1 Flusterstorm|MH1 +1 Forbid|EXO +1 Force of Negation|MH1 +1 Force of Will|EMA +1 Force Spike|ME3 +1 Forked Bolt|ROE +1 Frantic Search|ULG +1 Frost Titan|C14 +1 Fulminator Mage|SHM +1 Future Sight|MH1 +1 Gatekeeper of Malakir|ZEN +1 Geralf's Messenger|DKA +1 Gifted Aetherborn|AER +1 Gilded Lotus|DOM +1 Gitaxian Probe|NPH +1 Glen Elendra Archmage|UMA +1 Glint-Nest Crane|KLD +1 Glorybringer|AKH +1 Go for the Throat|C17 +1 Goblin Bombardment|TPR +1 Goblin Bushwhacker|ZEN +1 Goblin Chainwhirler|DOM +1 Goblin Cratermaker|GRN +1 Goblin Dark-Dwellers|OGW +1 Goblin Electromancer|GRN +1 Goblin Engineer|MH1 +1 Goblin Guide|ZEN +1 Goblin Rabblemaster|M15 +1 Goblin Ruinblaster|ZEN +1 Goblin Welder|CM2 +1 God-Eternal Kefnet|WAR +1 Gonti, Lord of Luxury|KLD +1 Goryo's Vengeance|UMA +1 Grand Architect|TD2 +1 Grave Titan|M11 +1 Gravecrawler|DKA +1 Graven Cairns|FUT +1 Gray Merchant of Asphodel|THS +1 Great Furnace|MRD +1 Greater Gargadon|MMA +1 Grim Lavamancer|E01 +1 Grim Monolith|ULG +1 Griselbrand|MM3 +1 Guardian Idol|IMA +1 Gutterbones|RNA +1 Hangarback Walker|ORI +1 Harbinger of the Tides|DDT +1 Hazoret the Fervent|AKH +1 Heart of Kiran|AER +1 Hedron Archive|C18 +1 Hellrider|DKA +1 Hero's Downfall|THS +1 High Tide|VMA +1 Hordeling Outburst|A25 +1 Hostage Taker|XLN +1 Hour of Devastation|HOU +1 Hydroblast|EMA +1 Hymn to Tourach|EMA +1 Hypnotic Specter|M10 +1 Ichor Wellspring|MBS +1 Ilharg, the Raze-Boar|WAR +1 Imperial Seal|ME2 +1 Impulse|BBD +1 Inferno Titan|M12 +1 Inkwell Leviathan|CFX +1 Innocent Blood|DDR +1 Inquisition of Kozilek|CN2 +1 Intuition|TPR +1 Ionize|GRN +1 Izzet Charm|DDJ +1 Izzet Signet|DDJ +1 Jace Beleren|SS1 +1 Jace, Architect of Thought|DDM +1 Jace, the Mind Sculptor|VMA +1 Jace, Vryn's Prodigy|ORI +1 Judith, the Scourge Diva|RNA +1 Kalitas, Traitor of Ghet|OGW +1 Kari Zev, Skyship Raider|AER +1 Karn Liberated|NPH +1 Karn, Scion of Urza|DOM +1 Keranos, God of Storms|JOU +1 Kess, Dissident Mage|MH1 +1 Kitesail Freebooter|XLN +1 Knight of the Ebon Legion|M20 +1 Kolaghan's Command|DTK +1 Koth of the Hammer|DDI +1 Kozilek's Return|OGW +1 Kozilek, Butcher of Truth|UMA +1 Kuldotha Forgemaster|TD2 +1 Languish|GNT +1 Lashwrithe|C14 +1 Lavaclaw Reaches|UMA +1 Legion Warboss|GRN +1 Light Up the Stage|RNA +1 Lightning Bolt|LEA +1 Lightning Greaves|CM2 +1 Lightning Mauler|AVR +1 Liliana of the Veil|UMA +1 Liliana's Triumph|WAR +1 Liliana, Death's Majesty|AKH +1 Liliana, Dreadhorde General|WAR +1 Liliana, Heretical Healer|V17 +1 Liliana, the Last Hope|EMN +1 Lion's Eye Diamond|VMA +1 Lodestone Golem|MM2 +1 Looter il-Kor|TSP +1 Lotus Bloom|TSP +1 Lotus Petal|TMP +1 Magma Jet|JVC +1 Magus of the Wheel|A25 +1 Magus of the Will|C16 +1 Makeshift Mannequin|LRW +1 Man-o'-War|EMA +1 Mana Flare|MED +1 Mana Leak|IMA +1 Manamorphose|MMA +1 Manic Vandal|M12 +1 Manifold Key|M20 +1 Massacre Wurm|MBS +1 Master of Etherium|C16 +1 Master of Waves|DDT +1 Matter Reshaper|OGW +1 Memory Jar|VMA +1 Memory Lapse|EMA +1 Mesmeric Fiend|A25 +1 Metalworker|UDS +1 Meteor Golem|M20 +1 Midnight Reaper|GRN +1 Mind Stone|WTH +1 Mind's Desire|VMA +1 Mindslaver|MRD +1 Miscalculation|ULG +1 Mishra's Factory|A25 +1 Mission Briefing|GRN +1 Mizzium Mortars|GK1 +1 Mizzix's Mastery|PZ1 +1 Mogg War Marshal|EMA +1 Molten Rain|MM3 +1 Molten Slagheap|CMA +1 Moment of Craving|RIX +1 Monastery Swiftspear|IMA +1 Mox Diamond|TPR +1 Mox Opal|MM2 +1 Mu Yanling, Sky Dancer|M20 +1 Mulldrifter|MMA +1 Mutavault|M14 +1 Myr Battlesphere|C18 +1 Myriad Landscape|C14 +1 Mystic Confluence|BBD +1 Mystic Forge|M20 +1 Mystical Tutor|MIR +1 Narset, Parter of Veils|WAR +1 Necromancy|VIS +1 Negate|M20 +1 Never // Return|AKH +1 Nicol Bolas, Dragon-God|WAR +1 Nicol Bolas, Planeswalker|CFX +1 Nicol Bolas, the Ravager|M19 +1 Night's Whisper|EMA +1 Nightveil Specter|GK1 +1 Niv-Mizzet, Parun|GRN +1 Notion Thief|A25 +1 Noxious Gearhulk|KLD +1 Nykthos, Shrine to Nyx|THS +1 Oona's Prowler|LRW +1 Ophiomancer|C13 +1 Opt|DOM +1 Overmaster|TOR +1 Pack Rat|RTR +1 Painful Truths|BFZ +1 Palladium Myr|SOM +1 Peat Bog|MMQ +1 Pentad Prism|HOP +1 Phantasmal Image|MM3 +1 Phyrexian Arena|CN2 +1 Phyrexian Metamorph|NPH +1 Phyrexian Obliterator|A25 +1 Phyrexian Revoker|M15 +1 Pia and Kiran Nalaar|DDU +1 Pia Nalaar|KLD +1 Pilgrim's Eye|GNT +1 Pillage|MH1 +1 Pithing Needle|SOK +1 Plaguecrafter|GRN +1 Polluted Delta|EXP +1 Ponder|LRW +1 Precursor Golem|MM2 +1 Preordain|M11 +1 Priest of Forgotten Gods|RNA +1 Prismatic Lens|UMA +1 Prismatic Vista|MH1 +1 Prophetic Bolt|C15 +1 Pteramander|RNA +1 Putrid Imp|TOR +1 Pyretic Ritual|M11 +1 Pyroblast|EMA +1 Pyroclasm|A25 +1 Quicken|DDS +1 Rain of Filth|USG +1 Rakdos Cackler|GK2 +1 Rakdos Signet|GK2 +1 Rakdos's Return|GK2 +1 Ral Zarek|DGM +1 Ral's Outburst|WAR +1 Ral, Storm Conduit|WAR +1 Ramunap Ruins|HOU +1 Ravenous Chupacabra|A25 +1 Reality Smasher|OGW +1 Reanimate|UMA +1 Reckless Bushwhacker|OGW +1 Recurring Nightmare|TPR +1 Rekindling Phoenix|RIX +1 Release the Gremlins|AER +1 Relentless Dead|SOI +1 Relic of Progenitus|EMA +1 Remand|MM2 +1 Repeal|IMA +1 Riftwing Cloudskate|MMA +1 Rishadan Port|A25 +1 Risk Factor|GRN +1 Rite of Flame|CSP +1 Rix Maadi Reveler|RNA +1 Ruinous Path|C18 +1 Runaway Steam-Kin|GRN +1 Saheeli, Sublime Artificer|WAR +1 Sandstone Needle|MMQ +1 Saprazzan Skerry|MMQ +1 Sarkhan the Masterless|WAR +1 Scalding Tarn|ZEN +1 Scavenger Grounds|HOU +1 Scheming Symmetry|M20 +1 Scrapheap Scrounger|KLD +1 Scroll Rack|TMP +1 Search for Azcanta|XLN +1 Seasoned Pyromancer|MH1 +1 Seat of the Synod|C18 +1 Seething Song|DDG +1 Sensei's Divining Top|EMA +1 Sentinel Tower|BBD +1 Serum Visions|5DN +1 Shallow Grave|MIR +1 Shelldock Isle|LRW +1 Sheoldred, Whispering One|IMA +1 Shivan Reef|DDU +1 Show and Tell|CN2 +1 Shrine of Burning Rage|NPH +1 Siege-Gang Commander|GNT +1 Silumgar's Command|C17 +1 Simian Spirit Guide|A25 +1 Sire of Insanity|DGM +1 Skullclamp|C17 +1 Sky Diamond|C14 +1 Slavering Nulls|DDH +1 Sling-Gang Lieutenant|MH1 +1 Smokestack|V14 +1 Smoldering Marsh|EXP +1 Smuggler's Copter|KLD +1 Snapcaster Mage|UMA +1 Sneak Attack|EMA +1 Solemn Simulacrum|MRD +1 Sorcerous Spyglass|XLN +1 Spell Pierce|XLN +1 Spellseeker|BBD +1 Spellskite|MM2 +1 Spire of Industry|AER +1 Spirebluff Canal|KLD +1 Staff of Nin|CM2 +1 Star Compass|IMA +1 Steam Vents|GPT +1 Steel Hellkite|C18 +1 Stoke the Flames|M15 +1 Stormblood Berserker|M12 +1 Stratus Dancer|DTK +1 Strip Mine|EXP +1 Stromkirk Noble|ISD +1 Sulfur Falls|DOM +1 Sulfuric Vortex|EMA +1 Sulfurous Springs|ICE +1 Sundering Titan|ARC +1 Sunken Hollow|BFZ +1 Sunken Ruins|SHM +1 Supreme Will|HOU +1 Sweltering Suns|AKH +1 Sword of Fire and Ice|MMA +1 Sword of Sinew and Steel|MH1 +1 Sygg, River Cutthroat|SHM +1 Talisman of Creativity|MH1 +1 Talisman of Dominance|E01 +1 Talisman of Indulgence|MRD +1 Talrand, Sky Summoner|UMA +1 Tamiyo, the Moon Sage|AVR +1 Tangle Wire|V13 +1 Tectonic Edge|WWK +1 Teferi, Mage of Zhalfir|IMA +1 Tempest Djinn|DOM +1 Temple of Deceit|THS +1 Temple of Epiphany|M20 +1 Temple of Malice|BNG +1 Tendrils of Agony|VMA +1 Terminate|C17 +1 Tezzeret the Seeker|ALA +1 Tezzeret, Agent of Bolas|MBS +1 Thassa, God of the Sea|THS +1 The Antiquities War|DOM +1 The Elderspell|WAR +1 The Eldest Reborn|DOM +1 The Scarab God|HOU +1 Theater of Horrors|RNA +1 Thief of Sanity|GRN +1 Thing in the Ice|SOI +1 Thirst for Knowledge|C18 +1 Thought Erasure|GRN +1 Thought Vessel|CM2 +1 Thought-Knot Seer|OGW +1 Thoughtseize|IMA +1 Thousand-Year Storm|GRN +1 Thran Dynamo|IMA +1 Through the Breach|UMA +1 Thundermaw Hellkite|IMA +1 Tidespout Tyrant|BBD +1 Time Spiral|USG +1 Time Warp|E02 +1 Timetwister|VMA +1 To the Slaughter|SOI +1 Tolarian Academy|VMA +1 Torrential Gearhulk|KLD +1 Toxic Deluge|EMA +1 Trash for Treasure|C16 +1 Treachery|UDS +1 Treasure Cruise|UMA +1 Treasure Map|XLN +1 Trinket Mage|DDU +1 True-Name Nemesis|BBD +1 Turnabout|VMA +1 Tyrant's Scorn|WAR +1 Ugin, the Ineffable|WAR +1 Ugin, the Spirit Dragon|FRF +1 Ulamog, the Ceaseless Hunger|BFZ +1 Ultimate Price|GK2 +1 Umezawa's Jitte|V16 +1 Underground River|CM2 +1 Underground Sea|VMA +1 Undermine|DDH +1 Upheaval|V14 +1 Urborg, Tomb of Yawgmoth|UMA +1 Urza, Lord High Artificer|MH1 +1 Vampire Hexmage|CNS +1 Vampire Nighthawk|C17 +1 Vampiric Tutor|EMA +1 Vault of Whispers|HOP +1 Vedalken Shackles|5DN +1 Vendilion Clique|A25 +1 Venser, Shaper Savant|MM3 +1 Viashino Pyromancer|M19 +1 Vilis, Broker of Blood|M20 +1 Volcanic Island|LEB +1 Volrath's Stronghold|TPR +1 Vraska's Contempt|XLN +1 Walking Ballista|AER +1 Wandering Fumarole|OGW +1 Wasteland|EMA +1 Watery Grave|GRN +1 Wayfarer's Bauble|CM2 +1 Wheel of Fortune|VMA +1 Whirler Rogue|GNT +1 Wildfire|MM2 +1 Winter Orb|EMA +1 Worn Powerstone|EMA +1 Wretched Confluence|CMA +1 Wurmcoil Engine|CM2 +1 Yawgmoth's Will|VMA +1 Yawgmoth, Thran Physician|MH1 +1 Young Pyromancer|UMA +1 Zealous Conscripts|MM3 +1 Zulaport Cutthroat|GNT +1 Zurgo Bellstriker|DTK diff --git a/forge-gui/res/draft/Ryan Overturf's Grixis Cube (MTGO).draft b/forge-gui/res/draft/Ryan Overturf's Grixis Cube (MTGO).draft new file mode 100644 index 00000000000..b05bd980243 --- /dev/null +++ b/forge-gui/res/draft/Ryan Overturf's Grixis Cube (MTGO).draft @@ -0,0 +1,6 @@ +Name:Ryan Overturf's Grixis Cube (MTGO) +DeckFile:Ryan Overturf's Grixis Cube (MTGO) +Singleton:True + +Booster: 15 Any +NumPacks: 3 diff --git a/forge-gui/res/formats/Sanctioned/Modern.txt b/forge-gui/res/formats/Sanctioned/Modern.txt index f7be8d3870a..df29bc5345f 100644 --- a/forge-gui/res/formats/Sanctioned/Modern.txt +++ b/forge-gui/res/formats/Sanctioned/Modern.txt @@ -4,4 +4,4 @@ Order:102 Subtype:Modern Type:Sanctioned Sets:8ED, MRD, DST, 5DN, CHK, BOK, SOK, 9ED, RAV, GPT, DIS, CSP, TSP, TSB, PLC, FUT, 10E, LRW, EVE, SHM, MOR, ALA, CFX, ARB, M10, ZEN, WWK, ROE, M11, SOM, MBS, NPH, M12, ISD, DKA, AVR, M13, RTR, GTC, DGM, M14, THS, BNG, JOU, M15, KTK, FRF, DTK, MM2, ORI, BFZ, OGW, SOI, EMN, KLD, AER, AKH, W17, HOU, XLN, RIX, DOM, M19, G18, GRN, RNA, WAR, MH1, M20 -Banned:Ancient Den; Birthing Pod; Blazing Shoal; Bridge From Below; Chrome Mox; Cloudpost; Dark Depths; Deathrite Shaman; Dig Through Time; Dread Return; Eye of Ugin; Gitaxian Probe; Glimpse of Nature; Golgari Grave-Troll; Great Furnace; Green Sun's Zenith; Hypergenesis; Krark-Clan Ironworks; Mental Misstep; Ponder; Preordain; Punishing Fire; Rite of Flame; Seat of the Synod; Second Sunrise; Seething Song; Sensei's Divining Top; Skullclamp; Splinter Twin; Stoneforge Mystic; Summer Bloom; Treasure Cruise; Tree of Tales; Umezawa's Jitte; Vault of Whispers +Banned:Ancient Den; Birthing Pod; Blazing Shoal; Bridge From Below; Chrome Mox; Cloudpost; Dark Depths; Deathrite Shaman; Dig Through Time; Dread Return; Eye of Ugin; Faithless Looting; Gitaxian Probe; Glimpse of Nature; Golgari Grave-Troll; Great Furnace; Green Sun's Zenith; Hogaak, Arisen Necropolis; Hypergenesis; Krark-Clan Ironworks; Mental Misstep; Ponder; Preordain; Punishing Fire; Rite of Flame; Seat of the Synod; Second Sunrise; Seething Song; Sensei's Divining Top; Skullclamp; Splinter Twin; Summer Bloom; Treasure Cruise; Tree of Tales; Umezawa's Jitte; Vault of Whispers diff --git a/forge-gui/res/formats/Sanctioned/Standard.txt b/forge-gui/res/formats/Sanctioned/Standard.txt index 8997b52a7c8..b0be1c482f3 100644 --- a/forge-gui/res/formats/Sanctioned/Standard.txt +++ b/forge-gui/res/formats/Sanctioned/Standard.txt @@ -4,4 +4,4 @@ Order:101 Subtype:Standard Type:Sanctioned Sets:XLN, RIX, DOM, M19, G18, GRN, RNA, WAR, M20 -Banned: Rampaging Ferocidon +Banned: diff --git a/forge-gui/res/formats/Sanctioned/Vintage.txt b/forge-gui/res/formats/Sanctioned/Vintage.txt index f7dc5c7c4c8..8d31690ff2d 100644 --- a/forge-gui/res/formats/Sanctioned/Vintage.txt +++ b/forge-gui/res/formats/Sanctioned/Vintage.txt @@ -4,5 +4,5 @@ Order:104 Subtype:Vintage Type:Sanctioned Banned:Adriana's Valor; Advantageous Proclamation; Assemble the Rank and Vile; Backup Plan; Brago's Favor; Double Stroke; Echoing Boon; Emissary's Ploy; Hired Heist; Hold the Perimeter; Hymn of the Wilds; Immediate Action; Incendiary Dissent; Iterative Analysis; Muzzio's Preparations; Natural Unity; Power Play; Secret Summoning; Secrets of Paradise; Sentinel Dispatch; Sovereign's Realm; Summoner's Bond; Unexpected Potential; Weight Advantage; Worldknit; Amulet of Quoz; Bronze Tablet; Contract from Below; Darkpact; Demonic Attorney; Jeweled Bird; Rebirth; Tempest Efreet; Timmerian Fiends; Chaos Orb; Falling Star; Shahrazad -Restricted:Ancestral Recall; Balance; Black Lotus; Brainstorm; Chalice of the Void; Channel; Demonic Consultation; Demonic Tutor; Dig Through Time; Fastbond; Flash; Gitaxian Probe; Gush; Imperial Seal; Library of Alexandria; Lion's Eye Diamond; Lodestone Golem; Lotus Petal; Mana Crypt; Mana Vault; Memory Jar; Merchant Scroll; Mind's Desire; Monastery Mentor; Mox Emerald; Mox Jet; Mox Pearl; Mox Ruby; Mox Sapphire; Mystical Tutor; Necropotence; Ponder; Sol Ring; Strip Mine; Thorn of Amethyst; Time Vault; Time Walk; Timetwister; Tinker; Tolarian Academy; Treasure Cruise; Trinisphere; Vampiric Tutor; Wheel of Fortune; Windfall; Yawgmoth's Will +Restricted:Ancestral Recall; Balance; Black Lotus; Brainstorm; Chalice of the Void; Channel; Demonic Consultation; Demonic Tutor; Dig Through Time; Flash; Gitaxian Probe; Golgari Grave-Troll; Gush; Imperial Seal; Karn, the Great Creator; Library of Alexandria; Lion's Eye Diamond; Lodestone Golem; Lotus Petal; Mana Crypt; Mana Vault; Memory Jar; Mental Misstep; Merchant Scroll; Mind's Desire; Monastery Mentor; Mox Emerald; Mox Jet; Mox Pearl; Mox Ruby; Mox Sapphire; Mystic Forge; Mystical Tutor; Necropotence; Ponder; Sol Ring; Strip Mine; Thorn of Amethyst; Time Vault; Time Walk; Timetwister; Tinker; Tolarian Academy; Treasure Cruise; Trinisphere; Vampiric Tutor; Wheel of Fortune; Windfall; Yawgmoth's Will diff --git a/forge-gui/res/puzzle/PS_M207.pzl b/forge-gui/res/puzzle/PS_M207.pzl new file mode 100644 index 00000000000..33a36d6b642 --- /dev/null +++ b/forge-gui/res/puzzle/PS_M207.pzl @@ -0,0 +1,16 @@ +[metadata] +Name:Possibility Storm - Magic Core Set 2020 #07 +URL:http://www.possibilitystorm.com/wp-content/uploads/2019/08/126.-M207.jpg +Goal:Win +Turns:1 +Difficulty:Rare +Description:Win this turn. Your Dauntless Bodyguard chose Shanna, Sisay's Legacy when it entered the battlefield. +[state] +humanlife=20 +ailife=7 +turn=1 +activeplayer=human +activephase=MAIN1 +humanhand=Strength of the Pack;Depose // Deploy;Storm the Citadel;Masterful Replication;Short Sword +humanbattlefield=Gideon Blackblade|Counters:LOYALTY=6;Blackblade Reforged;Omnispell Adept;Shanna, Sisay's Legacy|Id:9;Sigiled Sword of Valeron|AttachedTo:9;Dauntless Bodyguard|ChosenCards:9|Id:10|NoETBTrigs;Forebear's Blade|AttachedTo:10;Hallowed Fountain|NoETBTrigs;Hallowed Fountain|NoETBTrigs;Hallowed Fountain|NoETBTrigs;Temple Garden|NoETBTrigs;Temple Garden|NoETBTrigs;Temple Garden|NoETBTrigs +aibattlefield=Charity Extractor;Looming Altisaur;Gate Colossus;Looming Altisaur;Charity Extractor diff --git a/forge-gui/res/skins/default/bg_match.jpg b/forge-gui/res/skins/default/bg_match.jpg index b82df4692a6..ce143a5381d 100644 Binary files a/forge-gui/res/skins/default/bg_match.jpg and b/forge-gui/res/skins/default/bg_match.jpg differ diff --git a/forge-gui/src/main/java/forge/download/GuiDownloadService.java b/forge-gui/src/main/java/forge/download/GuiDownloadService.java index b6e308b55bc..88f39d77b95 100644 --- a/forge-gui/src/main/java/forge/download/GuiDownloadService.java +++ b/forge-gui/src/main/java/forge/download/GuiDownloadService.java @@ -255,6 +255,8 @@ public abstract class GuiDownloadService implements Runnable { byte[] buffer = new byte[1024]; for (Entry kv : files.entrySet()) { + boolean isJPG = true; + boolean isLogged = false; if (cancel) {//stop prevent sleep GuiBase.getInterface().preventSystemSleep(false); break; } @@ -265,8 +267,10 @@ public abstract class GuiDownloadService implements Runnable { //decode URL Key String decodedKey = URLDecoder.decode(kv.getKey()); final File fileDest = new File(decodedKey); + final String filePath = fileDest.getPath(); + final String subLastIndex = filePath.contains("pics") ? "\\pics\\" : "\\db\\"; - System.out.println(count + "/" + totalCount + " - " + fileDest); + System.out.println(count + "/" + totalCount + " - .." + filePath.substring(filePath.lastIndexOf(subLastIndex)+1)); FileOutputStream fos = null; try { @@ -287,8 +291,12 @@ public abstract class GuiDownloadService implements Runnable { // if file is not found and this is a JPG, give PNG a shot... if ((conn.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) && (url.endsWith(".jpg"))) { + isJPG = false; conn.disconnect(); - System.out.println(" File not found: " + url); + if(url.contains("/images/")){ + isLogged = true; + System.out.println("File not found: .." + url.substring(url.lastIndexOf("/images/")+1)); + } url = url.substring(0,url.length() - 4) + ".png"; imageUrl = new URL(url); conn = (HttpURLConnection) imageUrl.openConnection(p); @@ -307,7 +315,8 @@ public abstract class GuiDownloadService implements Runnable { break; case HttpURLConnection.HTTP_NOT_FOUND: conn.disconnect(); - System.out.println(" File not found: " + url); + if(url.contains("/images/") && !isJPG && !isLogged) + System.out.println("File not found: .." + url.substring(url.lastIndexOf("/images/")+1)); break; default: conn.disconnect();