Merge branch 'master' into ui-card-translation

This commit is contained in:
Peter
2019-07-30 12:19:51 +02:00
16 changed files with 479 additions and 7 deletions

View File

@@ -52,7 +52,7 @@ public class ChooseCardEffect extends SpellAbilityEffect {
}
CardCollectionView choices = game.getCardsIn(choiceZone);
if (sa.hasParam("Choices")) {
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host);
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host, sa);
}
if (sa.hasParam("TargetControls")) {
choices = CardLists.filterControlledBy(choices, tgtPlayers.get(0));

View File

@@ -2697,6 +2697,13 @@ public class Card extends GameEntity implements Comparable<Card> {
}
public final Player getController() {
if ((currentZone == null) || ((currentZone.getZoneType() != ZoneType.Battlefield) && (currentZone.getZoneType() != ZoneType.Stack))){
//only permanents and spells have controllers [108.4],
//so a card really only has a controller while it's on the stack or battlefield.
//everywhere else, just use the owner [108.4a].
return owner;
}
Entry<Long, Player> lastEntry = tempControllers.lastEntry();
if (lastEntry != null) {
final long lastTimestamp = lastEntry.getKey();

View File

@@ -3508,7 +3508,7 @@ public class CardFactoryUtil {
String abExile = "DB$ ChangeZone | Defined$ Self | Origin$ Stack | Destination$ Exile";
String delTrig = "DB$ DelayedTrigger | Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You " +
" | OptionalDecider$ You | RememberObjects$ Self | TriggerDescription$"
+ " At the beginning of your next upkeep, you may cast " + card.toString() + " without paying it's manacost.";
+ " At the beginning of your next upkeep, you may cast " + card.toString() + " without paying its mana cost.";
// TODO add check for still in exile
String abPlay = "DB$ Play | Defined$ Self | WithoutManaCost$ True | Optional$ True";

View File

@@ -28,6 +28,11 @@ public enum CSubmenuDownloaders implements ICDoc {
new GuiDownloader(new GuiDownloadPicturesLQ()).show();
}
};
private final UiCommand cmdPicDownloadHQ = new UiCommand() {
@Override public void run() {
new GuiDownloader(new GuiDownloadPicturesHQ()).show();
}
};
private final UiCommand cmdSetDownload = new UiCommand() {
@Override public void run() {
new GuiDownloader(new GuiDownloadSetPicturesLQ()).show();
@@ -80,6 +85,7 @@ public enum CSubmenuDownloaders implements ICDoc {
public void initialize() {
final VSubmenuDownloaders view = VSubmenuDownloaders.SINGLETON_INSTANCE;
view.setDownloadPicsCommand(cmdPicDownload);
view.setDownloadPicsHQCommand(cmdPicDownloadHQ);
view.setDownloadSetPicsCommand(cmdSetDownload);
view.setDownloadQuestImagesCommand(cmdQuestImages);
view.setDownloadAchievementImagesCommand(cmdAchievementImages);

View File

@@ -57,6 +57,7 @@ public enum VSubmenuDownloaders implements IVSubmenu<CSubmenuDownloaders> {
private final FLabel btnDownloadSetPics = _makeButton(localizer.getMessage("btnDownloadSetPics"));
private final FLabel btnDownloadPics = _makeButton(localizer.getMessage("btnDownloadPics"));
private final FLabel btnDownloadPicsHQ = _makeButton(localizer.getMessage("btnDownloadPicsHQ"));
private final FLabel btnDownloadQuestImages = _makeButton(localizer.getMessage("btnDownloadQuestImages"));
private final FLabel btnDownloadAchievementImages = _makeButton(localizer.getMessage("btnDownloadAchievementImages"));
private final FLabel btnReportBug = _makeButton(localizer.getMessage("btnReportBug"));
@@ -82,6 +83,9 @@ public enum VSubmenuDownloaders implements IVSubmenu<CSubmenuDownloaders> {
pnlContent.add(btnDownloadPics, constraintsBTN);
pnlContent.add(_makeLabel(localizer.getMessage("lblDownloadPics")), constraintsLBL);
pnlContent.add(btnDownloadPicsHQ, constraintsBTN);
pnlContent.add(_makeLabel(localizer.getMessage("lblDownloadPicsHQ")), constraintsLBL);
pnlContent.add(btnDownloadSetPics, constraintsBTN);
pnlContent.add(_makeLabel(localizer.getMessage("lblDownloadSetPics")), constraintsLBL);
@@ -159,6 +163,7 @@ public enum VSubmenuDownloaders implements IVSubmenu<CSubmenuDownloaders> {
}
public void setDownloadPicsCommand(UiCommand command) { btnDownloadPics.setCommand(command); }
public void setDownloadPicsHQCommand(UiCommand command) { btnDownloadPicsHQ.setCommand(command); }
public void setDownloadSetPicsCommand(UiCommand command) { btnDownloadSetPics.setCommand(command); }
public void setDownloadQuestImagesCommand(UiCommand command) { btnDownloadQuestImages.setCommand(command); }
public void setDownloadAchievementImagesCommand(UiCommand command) { btnDownloadAchievementImages.setCommand(command); }

View File

@@ -0,0 +1,42 @@
package forge.assets;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import forge.model.FModel;
import forge.properties.ForgeConstants;
import forge.properties.ForgePreferences;
import forge.properties.ForgePreferences.FPref;
import java.util.ArrayList;
import java.util.List;
public class FLanguage {
public static void changeLanguage(final String languageName) {
final ForgePreferences prefs = FModel.getPreferences();
if (languageName.equals(prefs.getPref(FPref.UI_LANGUAGE))) { return; }
//save language preference
prefs.setPref(FPref.UI_LANGUAGE, languageName);
prefs.save();
}
/**
* Gets the languages.
*
* @return the languages
*/
public static Iterable<String> getAllLanguages() {
final List<String> allLanguages = new ArrayList<String>();
final FileHandle dir = Gdx.files.absolute(ForgeConstants.LANG_DIR);
for (FileHandle languageFile : dir.list()) {
String languageName = languageFile.name();
if (!languageName.endsWith(".properties")) { continue; }
allLanguages.add(languageName.replace(".properties", ""));
}
return allLanguages;
}
}

View File

@@ -6,6 +6,7 @@ import forge.Graphics;
import forge.MulliganDefs;
import forge.StaticData;
import forge.ai.AiProfileUtil;
import forge.assets.FLanguage;
import forge.assets.FSkin;
import forge.assets.FSkinColor;
import forge.assets.FSkinFont;
@@ -48,6 +49,14 @@ public class SettingsPage extends TabPage<SettingsScreen> {
lstSettings.addGroup("Sound Options");
//General Settings
lstSettings.addItem(new CustomSelectSetting(FPref.UI_LANGUAGE, "Language",
"Select Language (Excluded Game part. Still a work in progress) (RESTART REQUIRED)",
FLanguage.getAllLanguages()) {
@Override
public void valueChanged(String newValue) {
FLanguage.changeLanguage(newValue);
}
}, 0);
lstSettings.addItem(new CustomSelectSetting(FPref.UI_SKIN, "Theme",
"Sets the theme that determines how display components are skinned.",
FSkin.getAllSkins()) {

View File

@@ -0,0 +1,16 @@
[metadata]
Code=SS2
Date=2019-06-28
Name=Signature Spellbook: Gideon
MciCode=ss2
Type=Reprint
[cards]
1 M Gideon Jura
2 R Martyr's Bond
3 R Path to Exile
4 R Rest in Peace
5 R Shielded by Faith
6 R True Conviction
7 R Worship
8 R Blackblade Reforged

View File

@@ -179,6 +179,7 @@ Achievements=Erfolge
# VSubmenuDownloaders.java
btnDownloadSetPics=Bilder(LQ) Sets herunterladen
btnDownloadPics=Bilder(LQ) Karten herunterladen
btnDownloadPicsHQ=Bilder(HQ) Karten herunterladen (Sehr langsam!)
btnDownloadQuestImages=Bilder für Quests herunterladen
btnDownloadAchievementImages=Bilder für Erfolge herunterladen
btnReportBug=Einen Fehler melden
@@ -189,6 +190,7 @@ btnHowToPlay=Wie man spielt
btnDownloadPrices=Kartenpreise herunterladen
btnLicensing=Lizenzhinweis
lblDownloadPics=Lädt ein Standardbild pro Karte.
lblDownloadPicsHQ=Lädt ein Standardbild (HQ) pro Karte.
lblDownloadSetPics=Lädt alle Bilder pro Karte. Eines für jedes Set, in welchem die Karte auftauchte.
lblDownloadQuestImages=Lädt die Bilder für den Quest-Modus.
lblDownloadAchievementImages=Lädt die Bilder zu den möglichen Erfolgen. Verschönert die Trophäensammlung.
@@ -317,7 +319,7 @@ lblIsGoingFirst=beginnt.
lblYouAreGoing=Du startest
lblMulligan=Mulligan
lblDoYouWantToKeepYourHand=Starthand behalten?
lblReturnForLondon=Lege %n Karten unter die Bibliothek
lblReturnForLondon=Lege %d Karten unter die Bibliothek
lblOk=OK
lblReset=Zurück
lblAuto=Auto

View File

@@ -178,6 +178,7 @@ KeyboardShortcuts=Keyboard Shortcuts
Achievements=Achievements
# VSubmenuDownloaders.java
btnDownloadSetPics=Download LQ Set Pictures
btnDownloadPicsHQ=Download HQ Card Pictures (Very Slow!)
btnDownloadPics=Download LQ Card Pictures
btnDownloadQuestImages=Download Quest Images
btnDownloadAchievementImages=Download Achievement Images
@@ -189,6 +190,7 @@ btnHowToPlay=How To Play
btnDownloadPrices=Download Card Prices
btnLicensing=License Details
lblDownloadPics=Download default card picture for each card.
lblDownloadPicsHQ=Download default card HQ picture for each card.
lblDownloadSetPics=Download all pictures of each card (one for each set the card appeared in)
lblDownloadQuestImages=Download tokens and icons used in Quest mode.
lblDownloadAchievementImages=Download achievement images to really make your trophies stand out.
@@ -317,7 +319,7 @@ lblIsGoingFirst=is going first
lblYouAreGoing=you are going
lblMulligan=Mulligan
lblDoYouWantToKeepYourHand=Do you want to keep your hand?
lblReturnForLondon=Return %n card(s) to bottom of library
lblReturnForLondon=Return %d card(s) to the bottom of your library
lblOk=Ok
lblReset=Reset
lblAuto=Auto

View File

@@ -179,6 +179,7 @@ Achievements=Logros
# VSubmenuDownloaders.java
btnDownloadSetPics=Descargar todos los Sets de Cartas
btnDownloadPics=Descargar todas las Cartas
btnDownloadPicsHQ=Descargar todas las Cartas en calidad alta (Muy lento!)
btnDownloadQuestImages=Descargar Imágenes del modo Quest
btnDownloadAchievementImages=Descagar Imágenes de los Logros
btnReportBug=Reportar un error
@@ -189,6 +190,7 @@ btnHowToPlay=Cómo jugar (Inglés)
btnDownloadPrices=Descargar los precios de las cartas
btnLicensing=Detalles de la licencia
lblDownloadPics=Descargar la imagen de la carta por defecto para cada carta.
lblDownloadPicsHQ=Descargar la imagen en calidad alta de la carta por defecto para cada carta.
lblDownloadSetPics=Descargue todas las imágenes de cada carta (una por cada set donde apareció la carta)
lblDownloadQuestImages=Descarga fichas e íconos utilizados en el modo Quest.
lblDownloadAchievementImages=Descarga imágenes de logros para que tus trofeos realmente destaquen.
@@ -317,7 +319,7 @@ lblIsGoingFirst=va primero
lblYouAreGoing=vas
lblMulligan=Mulligan
lblDoYouWantToKeepYourHand=¿Quieres quedarte tu mano?
lblReturnForLondon=Return %n card(s) to bottom of library
lblReturnForLondon=Return %d card(s) to the bottom of your library
lblOk=Ok
lblReset=Reset
lblAuto=Auto

View File

@@ -0,0 +1,16 @@
[metadata]
Name:Possibility Storm - Magic Core Set 2020 #03
URL:http://www.possibilitystorm.com/wp-content/uploads/2019/07/122.m203.jpg
Goal:Win
Turns:1
Difficulty:Mythic
Description:Win this turn. Assume your opponent has no mana available.
[state]
humanlife=20
ailife=12
turn=1
activeplayer=human
activephase=MAIN1
humanhand=Shatter;Teferi's Time Twist;Role Reversal;Trumpet Blast
humanbattlefield=Viashino Pyromancer;Retributive Wand;Captain's Hook;Saheeli, Sublime Artificer|Counters:LOYALTY=3;Island;Island;Mountain;Mountain
aibattlefield=Pardic Wanderer

View File

@@ -0,0 +1,356 @@
/*
* Forge: Play Magic: the Gathering.
* Copyright (C) 2011 Forge Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package forge.download;
import forge.item.PaperCard;
import forge.model.FModel;
import forge.properties.ForgeConstants;
import forge.util.ImageUtil;
import java.io.File;
import java.util.*;
public class GuiDownloadPicturesHQ extends GuiDownloadService {
final Map<String, String> downloads = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
Set<String> existingSets;
ArrayList<String> existingImages;
@Override
public String getTitle() {
return "Download HQ Card Pictures";
}
@Override
protected final Map<String, String> getNeededFiles() {
File f = new File(ForgeConstants.CACHE_CARD_PICS_DIR);
existingImages = new ArrayList<String>(Arrays.asList(f.list()));
existingSets = retrieveManifestDirectory();
for (final PaperCard c : FModel.getMagicDb().getCommonCards().getAllCards()) {
addDLObject(c, false);
if (ImageUtil.hasBackFacePicture(c)) {
addDLObject(c, true);
}
}
for (final PaperCard c : FModel.getMagicDb().getVariantCards().getAllCards()) {
addDLObject(c, false);
}
// Add missing tokens to the list of things to download.
addMissingItems(downloads, ForgeConstants.IMAGE_LIST_TOKENS_FILE, ForgeConstants.CACHE_TOKEN_PICS_DIR);
return downloads;
}
private void addDLObject(final PaperCard c, final boolean backFace) {
final String imageKey = ImageUtil.getImageKey(c, backFace, false);
final String destPath = ForgeConstants.CACHE_CARD_PICS_DIR + imageKey + ".jpg";
if (existingImages.contains(imageKey + ".jpg")) {
return;
}
if (downloads.containsKey(destPath)) {
return;
}
String setCode = c.getEdition();
String cardname = imageKey.replace(".full", "");
switch(setCode) {
case "CFX": setCode="CON"; break;
case "COM": setCode="CMD"; break;
case "FVE": setCode="V09"; break;
case "FVL": setCode="V11"; break;
case "FVR": setCode="V10"; break;
case "MED": setCode="ME1"; break;
case "MPS_AKH": setCode="AKH"; break;
case "MPS_KLD": setCode="MPS"; break;
case "MPS_RNA": setCode="MED"; break;
case "PDS": setCode="H09"; break;
case "PO2": setCode="P02"; break;
case "UGF": setCode="UGIN"; break;
}
setCode = getManualCode(cardname, setCode);
cardname = cardname.replace(" ", "+");
cardname = cardname.replace("'", "");
String scryfallurl = ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD + "named?fuzzy=" + cardname;
if(!setCode.equals("???")) scryfallurl += "&set=" + setCode.toLowerCase();
scryfallurl += "&format=image";
downloads.put(destPath, scryfallurl);
}
private String getManualCode(String cardname, String originalSetCode) {
String setCode=originalSetCode;
switch(cardname) {
case "Daretti, Ingenious Iconoclast":
case "Elspeth, Knight-Errant":
case "Garruk, Apex Predator":
case "Jace, the Mind Sculptor":
case "Liliana, the Last Hope":
case "Nahiri, the Harbinger":
case "Nicol Bolas, Planeswalker":
case "Sarkhan Unbroken":
case "Teferi, Hero of Dominaria":
case "Tezzeret, Agent of Bolas":
case "Tezzeret the Seeker":
case "Ugin, the Spirit Dragon": setCode="MED"; break;
case "Attrition":
case "Boil":
case "Capsize":
case "Counterbalance":
case "Daze":
case "Desolation Angel":
case "Divert":
case "Forbid":
case "Force of Will":
case "Loyal Retainers":
case "Mind Twist":
case "No Mercy":
case "Opposition":
case "Shatterstorm":
case "Slaughter Pact":
case "Stifle":
case "Sunder":
case "Worship":
case "Wrath of God": setCode="MP2"; break;
case "Behold the Power of Destruction":
case "Choose Your Champion":
case "Dance, Pathetic Marionette":
case "Embrace My Diabolical Vision":
case "Every Hope Shall Vanish":
case "Every Last Vestige Shall Rot":
case "Evil Comes to Fruition":
case "Feed the Machine":
case "I Bask in Your Silent Awe":
case "I Call on the Ancient Magics":
case "I Delight in Your Convulsions":
case "I Know All, I See All":
case "Ignite the Cloneforge!":
case "Into the Earthen Maw":
case "Introductions Are in Order":
case "Know Naught but Fire":
case "Look Skyward and Despair":
case "May Civilization Collapse":
case "Mortal Flesh Is Weak":
case "My Crushing Masterstroke":
case "My Genius Knows No Bounds":
case "My Undead Horde Awakens":
case "My Wish Is Your Command":
case "Nature Demands an Offering":
case "Nature Shields Its Own":
case "Nothing Can Stop Me Now":
case "Only Blood Ends Your Nightmares":
case "Realms Befitting My Majesty":
case "Roots of All Evil":
case "Rotted Ones, Lay Siege":
case "Surrender Your Thoughts":
case "The Dead Shall Serve":
case "The Fate of the Flammable":
case "The Iron Guardian Stirs":
case "The Pieces Are Coming Together":
case "The Very Soil Shall Shake":
case "Tooth, Claw, and Tail":
case "Which of You Burns Brightest":
case "Your Fate Is Thrice Sealed":
case "Your Puny Minds Cannot Fathom":
case "Your Will Is Not Your Own": setCode="OARC"; break;
case "Because I Have Willed It":
case "Behold My Grandeur":
case "Bow to My Command":
case "Choose Your Demise":
case "Delight in the Hunt":
case "Every Dream a Nightmare":
case "For Each of You, a Gift":
case "Know Evil":
case "Make Yourself Useful":
case "My Forces Are Innumerable":
case "My Laughter Echoes":
case "No One Will Hear Your Cries":
case "Pay Tribute to Me":
case "Power Without Equal":
case "The Mighty Will Fall":
case "There Is No Refuge":
case "This World Belongs to Me":
case "What's Yours Is Now Mine":
case "When Will You Learn": setCode="OE01"; break;
case "Bloodhill Bastion":
case "Celestine Reef":
case "Chaotic Aether":
case "Choke":
case "Cliffside Market":
case "Edge of Malacol":
case "Eloren Wilds":
case "Feeding Grounds":
case "Fields of Summer":
case "Furnace Layer":
case "Glimmervoid Basin":
case "Grand Ossuary":
case "Grove of the Dreampods":
case "Hedron Fields of Agadeem":
case "Horizon Boughs":
case "Immersturm":
case "Interplanar Tunnel":
case "Isle of Vesuva":
case "Izzet Steam Maze":
case "Kharasha Foothills":
case "Kilnspire District":
case "Lair of the Ashen Idol":
case "Lethe Lake":
case "Mirrored Depths":
case "Morphic Tide":
case "Mount Keralia":
case "Mutual Epiphany":
case "Norn's Dominion":
case "Onakke Catacomb":
case "Orochi Colony":
case "Panopticon":
case "Planewide Disaster":
case "Pools of Becoming":
case "Quicksilver Sea":
case "Reality Shaping":
case "Sanctum of Serra":
case "Sea of Sand":
case "Selesnya Loft Gardens":
case "Skybreen":
case "Spatial Merging":
case "Stairs to Infinity":
case "Stronghold Furnace":
case "Talon Gates":
case "Tember City":
case "Windriddle Palaces":
case "The Aether Flues":
case "The Dark Barony":
case "The Eon Fog":
case "The Fourth Sphere":
case "The Great Forest":
case "The Hippodrome":
case "The Maelstrom":
case "The Zephyr Maze":
case "Time Distortion":
case "Trail of the Mage-Rings":
case "Truga Jungle":
case "Turri Island":
case "Undercity Reaches": setCode="OPCA"; break;
case "Drench the Soil in Their Blood":
case "Imprison This Insolent Wretch":
case "Perhaps You've Met My Cohort":
case "Plots That Span Centuries":
case "Your Inescapable Doom": setCode="PARC"; break;
case "Stoneforge Mystic": setCode="PGPX"; break;
case "Birds of Paradise Avatar1":
case "Bosh, Iron Golem Avatar":
case "Braids, Conjurer Adept Avatar":
case "Chronatog Avatar":
case "Dakkon Blackblade Avatar":
case "Dauntless Escort Avatar":
case "Diamond Faerie Avatar":
case "Eight-and-a-Half-Tails Avatar":
case "Enigma Sphinx Avatar":
case "Eladamri, Lord of Leaves Avatar":
case "Elvish Champion Avatar":
case "Erhnam Djinn Avatar1":
case "Etched Oracle Avatar":
case "Fallen Angel Avatar":
case "Figure of Destiny Avatar":
case "Flametongue Kavu Avatar":
case "Frenetic Efreet Avatar":
case "Goblin Warchief Avatar1":
case "Grinning Demon Avatar1":
case "Haakon, Stromgald Scourge Avatar":
case "Heartwood Storyteller Avatar":
case "Hell's Caretaker Avatar":
case "Hermit Druid Avatar":
case "Higure, the Still Wind Avatar":
case "Ink-Eyes, Servant of Oni Avatar":
case "Jaya Ballard Avatar":
case "Jhoira of the Ghitu Avatar":
case "Karona, False God Avatar":
case "Kresh the Bloodbraided Avatar":
case "Loxodon Hierarch Avatar":
case "Lyzolda, the Blood Witch Avatar":
case "Malfegor Avatar":
case "Maralen of the Mornsong Avatar":
case "Maro Avatar":
case "Master of the Wild Hunt Avatar":
case "Mayael the Anima Avatar":
case "Mirri the Cursed Avatar":
case "Mirror Entity Avatar":
case "Momir Vig, Simic Visionary Avatar":
case "Morinfen Avatar":
case "Murderous Redcap Avatar":
case "Necropotence Avatar":
case "Nekrataal Avatar":
case "Oni of Wild Places Avatar":
case "Orcish Squatters Avatar":
case "Peacekeeper Avatar":
case "Phage the Untouchable Avatar":
case "Platinum Angel Avatar1":
case "Prodigal Sorcerer Avatar1":
case "Raksha Golden Cub Avatar":
case "Reaper King Avatar":
case "Rith, the Awakener Avatar1":
case "Royal Assassin Avatar1":
case "Rumbling Slum Avatar":
case "Sakashima the Impostor Avatar":
case "Serra Angel Avatar1":
case "Seshiro the Anointed Avatar":
case "Sisters of Stone Death Avatar":
case "Sliver Queen Avatar":
case "Squee, Goblin Nabob Avatar":
case "Stalking Tiger Avatar":
case "Stonehewer Giant Avatar":
case "Stuffy Doll Avatar":
case "Teysa, Orzhov Scion Avatar":
case "Tradewind Rider Avatar1":
case "Two-Headed Giant of Foriys Avatar":
case "Vampire Nocturnus Avatar":
case "Viridian Zealot Avatar": setCode="PMOA"; break;
case "Nalathni Dragon":
case "Sewers of Estark":
case "Windseeker Centaur": setCode="PRM"; break;
case "Lyna":
case "Sliver Queen, Brood Mother":
case "Takara": setCode="PVAN"; break;
case "Goblin Hero": setCode="S99"; break;
case "Pyrostatic Pillar":
case "Weathered Wayfarer": setCode="TD0"; break;
case "Hero's Resolve":
case "Python": setCode="6ED"; break;
}
return setCode;
}
}

View File

@@ -32,6 +32,7 @@ import java.net.URLDecoder;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -272,7 +273,13 @@ public abstract class GuiDownloadService implements Runnable {
URL imageUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection(p);
// don't allow redirections here -- they indicate 'file not found' on the server
conn.setInstanceFollowRedirects(false);
// only allow redirections to consume Scryfall API
if(url.contains("api.scryfall.com")) {
conn.setInstanceFollowRedirects(true);
TimeUnit.MILLISECONDS.sleep(100);
} else {
conn.setInstanceFollowRedirects(false);
}
conn.connect();
// if file is not found and this is a JPG, give PNG a shot...

View File

@@ -60,7 +60,7 @@ public class InputLondonMulligan extends InputSyncronizedBase {
getController().getGui().updateButtons(getOwner(), localizer.getMessage("lblOk"), "", cardsLeft == 0, false, true);
sb.append(String.format(localizer.getMessage("lblReturnForLondon"), selected.size(), toReturn));
sb.append(String.format(localizer.getMessage("lblReturnForLondon"), cardsLeft));
showMessage(sb.toString());
}

View File

@@ -284,6 +284,8 @@ public final class ForgeConstants {
public static final String URL_PIC_DOWNLOAD = URL_CARDFORGE + "/images/cards/";
public static final String URL_TOKEN_DOWNLOAD = URL_CARDFORGE + "/images/tokens/";
public static final String URL_PRICE_DOWNLOAD = URL_CARDFORGE + "/all-prices.txt";
private static final String URL_SCRYFALL = "https://api.scryfall.com";
public static final String URL_PIC_SCRYFALL_DOWNLOAD = URL_SCRYFALL + "/cards/";
// Constants for Display Card Identity game setting
public static final String DISP_CURRENT_COLORS_ALWAYS = "Always";