From bfb97672bbf12a917e41b4701006f404ea2884b4 Mon Sep 17 00:00:00 2001 From: Fenhl Date: Wed, 2 Mar 2016 06:29:03 +0000 Subject: [PATCH 1/6] Implement Wild Pair --- .../src/mage/sets/pdsslivers/WildPair.java | 52 +++++++ .../src/mage/sets/planarchaos/WildPair.java | 139 ++++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/pdsslivers/WildPair.java create mode 100644 Mage.Sets/src/mage/sets/planarchaos/WildPair.java diff --git a/Mage.Sets/src/mage/sets/pdsslivers/WildPair.java b/Mage.Sets/src/mage/sets/pdsslivers/WildPair.java new file mode 100644 index 0000000000..700d6dbf9f --- /dev/null +++ b/Mage.Sets/src/mage/sets/pdsslivers/WildPair.java @@ -0,0 +1,52 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.pdsslivers; + +import java.util.UUID; + +/** + * + * @author fenhl + */ +public class WildPair extends mage.sets.planarchaos.WildPair { + + public WildPair(UUID ownerId) { + super(ownerId); + this.cardNumber = 30; + this.expansionSetCode = "H09"; + } + + public WildPair(final WildPair card) { + super(card); + } + + @Override + public WildPair copy() { + return new WildPair(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/planarchaos/WildPair.java b/Mage.Sets/src/mage/sets/planarchaos/WildPair.java new file mode 100644 index 0000000000..9f47914f80 --- /dev/null +++ b/Mage.Sets/src/mage/sets/planarchaos/WildPair.java @@ -0,0 +1,139 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.planarchaos; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.condition.common.CastFromHandCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +import mage.cards.CardImpl; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.Filter; +import mage.filter.common.FilterCreatureCard; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.IntComparePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author fenhl + */ +public class WildPair extends CardImpl { + + public WildPair(UUID ownerID) { + super(ownerID, 30, "Wild Pair", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{4}{G}{G}"); + this.expansionSetCode = "PLC"; + + // Whenever a creature enters the battlefield, if you cast it from your hand, you may search your library for a creature card with the same total power and toughness and put it onto the battlefield. If you do, shuffle your library. + this.addAbility(new ConditionalTriggeredAbility( + new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new WildPairEffect(), new FilterCreaturePermanent("a creature"), true), + new CastFromHandCondition(), + "Whenever a creature enters the battlefield, if you cast it from your hand, you may search your library for a creature card with the same total power and toughness and put it onto the battlefield. If you do, shuffle your library." + )); + } + + public WildPair(final WildPair card) { + super(card); + } + + @Override + public WildPair copy() { + return new WildPair(this); + } +} + +class WildPairEffect extends OneShotEffect { + + public WildPairEffect() { + super(Outcome.PutCreatureInPlay); + this.staticText = "search your library for a creature card with the same total power and toughness and put it onto the battlefield"; + } + + public WildPairEffect(final WildPairEffect effect) { + super(effect); + } + + @Override + public WildPairEffect copy() { + return new WildPairEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); + if (permanent != null) { + int totalPT = permanent.getPower().getValue() + permanent.getToughness().getValue(); + FilterCreatureCard filter = new FilterCreatureCard("creature card with total power and toughness " + totalPT); + filter.add(new TotalPowerAndToughnessPredicate(Filter.ComparisonType.Equal, totalPT)); + TargetCardInLibrary target = new TargetCardInLibrary(1, filter); + if (controller.searchLibrary(target, game)) { + if (target.getTargets().size() > 0) { + controller.moveCards(new CardsImpl(target.getTargets()), Zone.BATTLEFIELD, source, game); + } + } + controller.shuffleLibrary(game); + return true; + } + } + return false; + } +} + +/** + * + * @author fenhl + */ +class TotalPowerAndToughnessPredicate extends IntComparePredicate { + + public TotalPowerAndToughnessPredicate(Filter.ComparisonType type, int value) { + super(type, value); + } + + @Override + protected int getInputValue(MageObject input) { + return input.getPower().getValue() + input.getToughness().getValue(); + } + + @Override + public String toString() { + return "TotalPowerAndToughness" + super.toString(); + } +} From a5504c1a96d1fff50cc1d80537eb8e970cddccc1 Mon Sep 17 00:00:00 2001 From: GitHubMage <> Date: Wed, 2 Mar 2016 22:29:29 +0100 Subject: [PATCH 2/6] fixed Ali from Cairo the previous implementation did reduce the amount of damage that is being dealt to not reduce life below one. now the damage is untouched but the affected player's life total is set to 1 if the damage would otherwise reduce below 1. --- .../mage/sets/arabiannights/AliFromCairo.java | 17 ++++---- .../test/cards/single/AliFromCairoTest.java | 40 +++++++++++++++++++ 2 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/AliFromCairoTest.java diff --git a/Mage.Sets/src/mage/sets/arabiannights/AliFromCairo.java b/Mage.Sets/src/mage/sets/arabiannights/AliFromCairo.java index 076d03c794..5cc37d20a0 100644 --- a/Mage.Sets/src/mage/sets/arabiannights/AliFromCairo.java +++ b/Mage.Sets/src/mage/sets/arabiannights/AliFromCairo.java @@ -97,11 +97,7 @@ class AliFromCairoReplacementEffect extends ReplacementEffectImpl { && (controller.getLife() > 0) &&(controller.getLife() - event.getAmount()) < 1 && event.getPlayerId().equals(controller.getId()) ) { - return true; - //unsure how to make this comply with - // 10/1/2008: The ability doesn't change how much damage is dealt; - // it just changes how much life that damage makes you lose. - // An effect such as Spirit Link will see the full amount of damage being dealt. + return true; } } return false; @@ -110,10 +106,17 @@ class AliFromCairoReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { Player controller = game.getPlayer(source.getControllerId()); + + // 10/1/2008: The ability doesn't change how much damage is dealt; + // it just changes how much life that damage makes you lose. + // An effect such as Spirit Link will see the full amount of damage being dealt. + game.fireEvent(event); + if (controller != null) { - event.setAmount(controller.getLife() - 1); + controller.setLife(1, game); } - return false; + + return true; } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/AliFromCairoTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/AliFromCairoTest.java new file mode 100644 index 0000000000..fefd0c65d2 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/AliFromCairoTest.java @@ -0,0 +1,40 @@ +package org.mage.test.cards.single; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author BetaSteward + */ +public class AliFromCairoTest extends CardTestPlayerBase { + + @Test + public void testCard() { + addCard(Zone.BATTLEFIELD, playerA, "Ali from Cairo", 1); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 12); + addCard(Zone.BATTLEFIELD, playerB, "Soulfire Grand Master", 1); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 12); + addCard(Zone.HAND, playerA, "Lightning Bolt", 7); + addCard(Zone.HAND, playerB, "Lightning Bolt", 7); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerA); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerA); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerA); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerA); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerA); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerA); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerA); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerA); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", playerA); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertLife(playerA, 1); + assertLife(playerB, 23); + } +} \ No newline at end of file From b46c2d5b4561531b67e103695455169223017240 Mon Sep 17 00:00:00 2001 From: drmDev Date: Thu, 3 Mar 2016 14:50:00 -0500 Subject: [PATCH 3/6] testReflectorMageBouncesFaceupCreatureReplayAsMorph fails due to bug reported --- .../cards/abilities/keywords/MorphTest.java | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/MorphTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/MorphTest.java index 7b35f5ef6a..00f770a05f 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/MorphTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/MorphTest.java @@ -640,6 +640,91 @@ public class MorphTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Pine Walker", 1); assertPowerToughness(playerA, "Pine Walker", 5, 5); assertTapped("Pine Walker", false); + } + + /** + * Reflector Mage bouncing a creature that can be played as a morph should not prevent the card + * from being replayed as a morph. Morph creatures are nameless. + * + * Reported bug: + * Face-up morph creatures that are bounced by Reflector Mage should be able to be replayed as morphs + * without the "until the next turn" restriction." + */ + @Test + public void testReflectorMageBouncesFaceupCreatureReplayAsMorph() { + + // {1}{W}{U} When Reflector Mage enters the battlefield, return target creature an opponent controls to its owner's hand. + // That creature's owner can't cast spells with the same name as that creature until your next turn. + addCard(Zone.HAND, playerA, "Reflector Mage"); // 2/3 + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + addCard(Zone.BATTLEFIELD, playerA, "Island", 2); + + //Tap: Add {G}, {U}, or {R} to your mana pool. + // Morph 2 (You may cast this card face down as a 2/2 creature for 3. Turn it face up any time for its morph cost.) + // When Rattleclaw Mystic is turned face up, add {G}{U}{R} to your mana pool. + addCard(Zone.BATTLEFIELD, playerB, "Rattleclaw Mystic"); // 2/1 + addCard(Zone.BATTLEFIELD, playerB, "Forest"); + addCard(Zone.BATTLEFIELD, playerB, "Island"); + addCard(Zone.BATTLEFIELD, playerB, "Mountain"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reflector Mage"); + addTarget(playerA, "Rattleclaw Mystic"); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Rattleclaw Mystic"); + setChoice(playerB, "Yes"); // cast it face down as 2/2 creature + setStopAt(2, PhaseStep.BEGIN_COMBAT); + + execute(); + + assertPermanentCount(playerA, "Reflector Mage", 1); + assertPermanentCount(playerB, "Rattleclaw Mystic", 0); + assertHandCount(playerB, "Rattleclaw Mystic", 0); // should have been replayed + assertPermanentCount(playerB, "", 1); // Rattleclaw played as a morph + } + + /** + * Reflector Mage bouncing a creature that can be played as a morph should not prevent the card + * from being replayed as a morph. Morph creatures are nameless. + * + * Reported bug: + * Face-up morph creatures that are bounced by Reflector Mage should be able to be replayed as morphs + * without the "until the next turn" restriction." + * + * Testing bouncing a face-down creature played next turn face-up. + */ + @Test + public void testReflectorMageBouncesMorphCreatureReplayAsFaceup() { + + //Tap: Add {G}, {U}, or {R} to your mana pool. + // Morph 2 (You may cast this card face down as a 2/2 creature for 3. Turn it face up any time for its morph cost.) + // When Rattleclaw Mystic is turned face up, add {G}{U}{R} to your mana pool. + addCard(Zone.HAND, playerA, "Rattleclaw Mystic"); // 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Forest"); + addCard(Zone.BATTLEFIELD, playerA, "Island"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + + // {1}{W}{U} When Reflector Mage enters the battlefield, return target creature an opponent controls to its owner's hand. + // That creature's owner can't cast spells with the same name as that creature until your next turn. + addCard(Zone.HAND, playerB, "Reflector Mage"); // 2/3 + addCard(Zone.BATTLEFIELD, playerB, "Plains", 2); + addCard(Zone.BATTLEFIELD, playerB, "Island", 2); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rattleclaw Mystic"); + setChoice(playerA, "Yes"); // cast it face down as 2/2 creature + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Reflector Mage"); + addTarget(playerB, ""); + + castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Rattleclaw Mystic"); + setChoice(playerA, "No"); // cast it face down as 2/2 creature + + setStopAt(3, PhaseStep.BEGIN_COMBAT); + + execute(); + + assertPermanentCount(playerB, "Reflector Mage", 1); + assertPermanentCount(playerA, "Rattleclaw Mystic", 1); + assertHandCount(playerA, "Rattleclaw Mystic", 0); // should have been replayed faceup } } From 95d91912360a9e17424125db1c76a53495c31941 Mon Sep 17 00:00:00 2001 From: drmDev Date: Thu, 3 Mar 2016 14:50:10 -0500 Subject: [PATCH 4/6] Fixed SkylineCascade Test usage of addTarget --- .../cards/abilities/enters/SkylineCascadeTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/SkylineCascadeTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/SkylineCascadeTest.java index 8703d86878..2dad85bb0a 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/SkylineCascadeTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/SkylineCascadeTest.java @@ -29,14 +29,14 @@ public class SkylineCascadeTest extends CardTestPlayerBase { /** * Skyline Cascade enters the battlefield tapped. * When Skyline Cascade enters the battlefield, target creature an opponent controls doesn't untap during its controller's next untap step. - * Tap: Add {B} to your mana pool. + * Tap: Add {U} to your mana pool. */ addCard(Zone.HAND, playerB, "Skyline Cascade"); attack(1, playerA, "Savannah Lions"); playLand(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Skyline Cascade"); - addTarget(playerA, "Savannah Lions"); + addTarget(playerB, "Savannah Lions"); setStopAt(3, PhaseStep.PRECOMBAT_MAIN); @@ -64,12 +64,12 @@ public class SkylineCascadeTest extends CardTestPlayerBase { /** * Skyline Cascade enters the battlefield tapped. * When Skyline Cascade enters the battlefield, target creature an opponent controls doesn't untap during its controller's next untap step. - * Tap: Add {B} to your mana pool. + * Tap: Add {U} to your mana pool. */ addCard(Zone.HAND, playerB, "Skyline Cascade"); playLand(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Skyline Cascade"); - addTarget(playerA, "Savannah Lions"); + addTarget(playerB, "Savannah Lions"); setStopAt(3, PhaseStep.PRECOMBAT_MAIN); @@ -78,4 +78,4 @@ public class SkylineCascadeTest extends CardTestPlayerBase { assertTapped("Savannah Lions", false); assertTapped("Skyline Cascade", true); } -} +} \ No newline at end of file From b9bbf9ccec5d82d2034e4a376034051e6893e821 Mon Sep 17 00:00:00 2001 From: rkfg Date: Fri, 4 Mar 2016 00:59:12 +0300 Subject: [PATCH 5/6] Store symbols as .gif instead of .jpg, rename already downloaded ones on start, fixes #98. --- .../org/mage/card/arcane/ManaSymbols.java | 593 +++++++++--------- .../card/dl/sources/GathererSymbols.java | 2 +- 2 files changed, 312 insertions(+), 283 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java b/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java index 7aa3ef492a..2921db77a3 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java @@ -1,282 +1,311 @@ -package org.mage.card.arcane; - -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Image; -import java.awt.Rectangle; -import java.awt.image.BufferedImage; -import java.io.File; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; -import java.util.regex.Pattern; -import javax.imageio.ImageIO; -import mage.cards.repository.ExpansionRepository; -import mage.client.dialog.PreferencesDialog; -import mage.client.util.GUISizeHelper; -import mage.client.util.ImageHelper; -import mage.client.util.gui.BufferedImageBuilder; -import org.apache.log4j.Logger; -import org.mage.plugins.card.constants.Constants; - -public class ManaSymbols { - - private static final Logger LOGGER = Logger.getLogger(ManaSymbols.class); - private static final Map> manaImages = new HashMap<>(); - private static boolean smallSymbolsFound = false; - private static boolean mediumSymbolsFound = false; - - private static final Map setImages = new HashMap<>(); - private static final Map setImagesExist = new HashMap<>(); - private static final Pattern REPLACE_SYMBOLS_PATTERN = Pattern.compile("\\{([^}/]*)/?([^}]*)\\}"); - private static String cachedPath; - private static final String[] symbols = new String[]{"0", "1", "10", "11", "12", "15", "16", "2", "3", "4", "5", "6", "7", "8", "9", "B", "BG", - "BR", "G", "GU", "GW", "R", "RG", "RW", "S", "T", "U", "UB", "UR", "W", "WB", "WU", - "WP", "UP", "BP", "RP", "GP", "X", "C"}; - - public static void loadImages() { - smallSymbolsFound = loadSymbolsImages(15); - mediumSymbolsFound = loadSymbolsImages(25); - - List setCodes = ExpansionRepository.instance.getSetCodes(); - if (setCodes == null) { - // the cards db file is probaly not included in the client. It will be created after the first connect to a server. - LOGGER.warn("No db information for sets found. Connect to a server to create database file on client side. Then try to restart the client."); - return; - } - for (String set : setCodes) { - File file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET + set + "-C.jpg"); - try { - Image image = UI.getImageIcon(file.getAbsolutePath()).getImage(); - int width = image.getWidth(null); - if (width > 21) { - int h = image.getHeight(null); - if (h > 0) { - Rectangle r = new Rectangle(21, (int) (h * 21.0f / width)); - BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r); - setImages.put(set, resized); - } - } else { - setImages.put(set, image); - } - } catch (Exception e) { - } - String[] codes = new String[]{"C", "U", "R", "M"}; - try { - file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL); - if (!file.exists()) { - file.mkdirs(); - } - - for (String code : codes) { - file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL + set + "-" + code + ".png"); - if (file.exists()) { - continue; - } - file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET + set + "-" + code + ".jpg"); - Image image = UI.getImageIcon(file.getAbsolutePath()).getImage(); - try { - int width = image.getWidth(null); - int height = image.getHeight(null); - if (height > 0) { - int dx = 0; - if (set.equals("M10") || set.equals("M11") || set.equals("M12")) { - dx = 6; - } - Rectangle r = new Rectangle(15 + dx, (int) (height * (15.0f + dx) / width)); - BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r); - File newFile = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL + File.separator + set + "-" + code + ".png"); - ImageIO.write(resized, "png", newFile); - } - } catch (Exception e) { - if (file.exists()) { - file.delete(); - } - } - } - - } catch (Exception e) { - } - } - - File file; - for (String set : ExpansionRepository.instance.getSetCodes()) { - file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL); - if (!file.exists()) { - break; - } - file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL + set + "-C.png"); - try { - Image image = UI.getImageIcon(file.getAbsolutePath()).getImage(); - int width = image.getWidth(null); - int height = image.getHeight(null); - setImagesExist.put(set, new Dimension(width, height)); - } catch (Exception e) { - } - } - } - - private static boolean loadSymbolsImages(int size) { - boolean fileErrors = false; - HashMap sizedSymbols = new HashMap<>(); - String resourcePath = Constants.RESOURCE_PATH_MANA_SMALL; - if (size > 25) { - resourcePath = Constants.RESOURCE_PATH_MANA_LARGE; - } else if (size > 15) { - resourcePath = Constants.RESOURCE_PATH_MANA_MEDIUM; - } - for (String symbol : symbols) { - File file = new File(getSymbolsPath() + resourcePath + "/" + symbol + ".gif"); - try { - - if (size == 15 || size == 25) { - BufferedImage notResized = ImageIO.read(file); - sizedSymbols.put(symbol, notResized); - } else { - Rectangle r = new Rectangle(size, size); - Image image = UI.getImageIcon(file.getAbsolutePath()).getImage(); - BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r); - sizedSymbols.put(symbol, resized); - } - } catch (Exception e) { - LOGGER.error("Error for symbol:" + symbol); - fileErrors = true; - } - } - manaImages.put(size, sizedSymbols); - return !fileErrors; - } - - private static String getSymbolsPath() { - return getSymbolsPath(false); - } - - private static String getSymbolsPath(boolean forHtmlCode) { - String useDefault = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_USE_DEFAULT, "true"); - String path = useDefault.equals("true") ? null : PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PATH, null); - if (path == null) { - if (forHtmlCode) { - // for html code we need to use double '//' symbols - // and seems it should be hard coded - as it is not the same as using File.separator - return "plugins/images/"; - } else { - return mage.client.constants.Constants.IO.imageBaseDir; - } - } - if (forHtmlCode) { - if (cachedPath != null) { - return cachedPath; - } - if (path.contains("\\")) { - cachedPath = path.replaceAll("[\\\\]", "/"); - return cachedPath; - } - } - return path; - } - - public static void draw(Graphics g, String manaCost, int x, int y, int symbolWidth) { - if (!manaImages.containsKey(symbolWidth)) { - loadSymbolsImages(symbolWidth); - } - Map sizedSymbols = manaImages.get(symbolWidth); - if (manaCost.length() == 0) { - return; - } - manaCost = manaCost.replace("\\", ""); - manaCost = UI.getDisplayManaCost(manaCost); - StringTokenizer tok = new StringTokenizer(manaCost, " "); - while (tok.hasMoreTokens()) { - String symbol = tok.nextToken().substring(0); - // Check and load symbol in the width - Image image = sizedSymbols.get(symbol); - if (image == null) { - //log.error("Symbol not recognized \"" + symbol + "\" in mana cost: " + manaCost); - continue; - } - g.drawImage(image, x, y, null); - x += symbolWidth; - } - } - - public static String getStringManaCost(List manaCost) { - StringBuilder sb = new StringBuilder(); - for (String s : manaCost) { - sb.append(s); - } - return sb.toString().replace("{", "").replace("}", " ").trim(); - } - - public enum Type { - TABLE, - CHAT, - DIALOG, - TOOLTIP, - } - - public static synchronized String replaceSymbolsWithHTML(String value, Type type) { - value = value.replace("{source}", "|source|"); - value = value.replace("{this}", "|this|"); - String replaced = value; - boolean symbolFilesFound; - int symbolSize; - switch (type) { - case TABLE: - symbolSize = GUISizeHelper.symbolTableSize; - break; - case CHAT: - symbolSize = GUISizeHelper.symbolChatSize; - break; - case DIALOG: - symbolSize = GUISizeHelper.symbolDialogSize; - break; - case TOOLTIP: - symbolSize = GUISizeHelper.symbolTooltipSize; - break; - default: - symbolSize = 11; - break; - } - String resourcePath = "small"; - symbolFilesFound = smallSymbolsFound; - if (symbolSize > 25) { - resourcePath = "large"; - } else if (symbolSize > 15) { - resourcePath = "medium"; - symbolFilesFound = mediumSymbolsFound; - } - if (symbolFilesFound) { - replaced = REPLACE_SYMBOLS_PATTERN.matcher(value).replaceAll("$1$2"); - } - replaced = replaced.replace("|source|", "{source}"); - replaced = replaced.replace("|this|", "{this}"); - return replaced; - } - - public static String replaceSetCodeWithHTML(String set, String rarity, int size) { - String _set = set; - if (setImagesExist.containsKey(_set)) { - int factor = size / 15 + 1; - Integer width = setImagesExist.get(_set).width * factor; - Integer height = setImagesExist.get(_set).height * factor; - return "" + rarity + ""; - } else { - return set; - } - } - - public static Image getSetSymbolImage(String set) { - return setImages.get(set); - } - - public static BufferedImage getSizedManaSymbol(String symbol) { - if (!manaImages.containsKey(GUISizeHelper.symbolDialogSize)) { - loadSymbolsImages(GUISizeHelper.symbolDialogSize); - } - Map sizedSymbols = manaImages.get(GUISizeHelper.symbolDialogSize); - return sizedSymbols.get(symbol); - } -} +package org.mage.card.arcane; + +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.regex.Pattern; +import javax.imageio.ImageIO; +import mage.cards.repository.ExpansionRepository; +import mage.client.dialog.PreferencesDialog; +import mage.client.util.GUISizeHelper; +import mage.client.util.ImageHelper; +import mage.client.util.gui.BufferedImageBuilder; +import org.apache.log4j.Logger; +import org.mage.plugins.card.constants.Constants; + +public class ManaSymbols { + + private static final Logger LOGGER = Logger.getLogger(ManaSymbols.class); + private static final Map> manaImages = new HashMap<>(); + private static boolean smallSymbolsFound = false; + private static boolean mediumSymbolsFound = false; + + private static final Map setImages = new HashMap<>(); + private static final Map setImagesExist = new HashMap<>(); + private static final Pattern REPLACE_SYMBOLS_PATTERN = Pattern.compile("\\{([^}/]*)/?([^}]*)\\}"); + private static String cachedPath; + private static final String[] symbols = new String[]{"0", "1", "10", "11", "12", "15", "16", "2", "3", "4", "5", "6", "7", "8", "9", "B", "BG", + "BR", "G", "GU", "GW", "R", "RG", "RW", "S", "T", "U", "UB", "UR", "W", "WB", "WU", + "WP", "UP", "BP", "RP", "GP", "X", "C"}; + + public static void loadImages() { + renameSymbols(getSymbolsPath() + File.separator + "symbols"); + smallSymbolsFound = loadSymbolsImages(15); + mediumSymbolsFound = loadSymbolsImages(25); + + List setCodes = ExpansionRepository.instance.getSetCodes(); + if (setCodes == null) { + // the cards db file is probaly not included in the client. It will be created after the first connect to a server. + LOGGER.warn("No db information for sets found. Connect to a server to create database file on client side. Then try to restart the client."); + return; + } + for (String set : setCodes) { + File file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET + set + "-C.jpg"); + try { + Image image = UI.getImageIcon(file.getAbsolutePath()).getImage(); + int width = image.getWidth(null); + if (width > 21) { + int h = image.getHeight(null); + if (h > 0) { + Rectangle r = new Rectangle(21, (int) (h * 21.0f / width)); + BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r); + setImages.put(set, resized); + } + } else { + setImages.put(set, image); + } + } catch (Exception e) { + } + String[] codes = new String[]{"C", "U", "R", "M"}; + try { + file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL); + if (!file.exists()) { + file.mkdirs(); + } + + for (String code : codes) { + file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL + set + "-" + code + ".png"); + if (file.exists()) { + continue; + } + file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET + set + "-" + code + ".jpg"); + Image image = UI.getImageIcon(file.getAbsolutePath()).getImage(); + try { + int width = image.getWidth(null); + int height = image.getHeight(null); + if (height > 0) { + int dx = 0; + if (set.equals("M10") || set.equals("M11") || set.equals("M12")) { + dx = 6; + } + Rectangle r = new Rectangle(15 + dx, (int) (height * (15.0f + dx) / width)); + BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r); + File newFile = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL + File.separator + set + "-" + code + ".png"); + ImageIO.write(resized, "png", newFile); + } + } catch (Exception e) { + if (file.exists()) { + file.delete(); + } + } + } + + } catch (Exception e) { + } + } + + File file; + for (String set : ExpansionRepository.instance.getSetCodes()) { + file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL); + if (!file.exists()) { + break; + } + file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL + set + "-C.png"); + try { + Image image = UI.getImageIcon(file.getAbsolutePath()).getImage(); + int width = image.getWidth(null); + int height = image.getHeight(null); + setImagesExist.put(set, new Dimension(width, height)); + } catch (Exception e) { + } + } + } + + private static boolean loadSymbolsImages(int size) { + boolean fileErrors = false; + HashMap sizedSymbols = new HashMap<>(); + String resourcePath = Constants.RESOURCE_PATH_MANA_SMALL; + if (size > 25) { + resourcePath = Constants.RESOURCE_PATH_MANA_LARGE; + } else if (size > 15) { + resourcePath = Constants.RESOURCE_PATH_MANA_MEDIUM; + } + for (String symbol : symbols) { + File file = new File(getSymbolsPath() + resourcePath + "/" + symbol + ".gif"); + try { + + if (size == 15 || size == 25) { + BufferedImage notResized = ImageIO.read(file); + sizedSymbols.put(symbol, notResized); + } else { + Rectangle r = new Rectangle(size, size); + Image image = UI.getImageIcon(file.getAbsolutePath()).getImage(); + BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r); + sizedSymbols.put(symbol, resized); + } + } catch (Exception e) { + LOGGER.error("Error for symbol:" + symbol); + fileErrors = true; + } + } + manaImages.put(size, sizedSymbols); + return !fileErrors; + } + + private static void renameSymbols(String path) { + final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**/*.jpg"); + try { + Files.walkFileTree(Paths.get(path), new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + if (matcher.matches(file)) { + Path gifPath = file.resolveSibling(file.getFileName().toString().replaceAll("\\.jpg$", ".gif")); + Files.move(file, gifPath, StandardCopyOption.REPLACE_EXISTING); + } + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + LOGGER.error("Couldn't rename mana symbols!"); + } + } + + private static String getSymbolsPath() { + return getSymbolsPath(false); + } + + private static String getSymbolsPath(boolean forHtmlCode) { + String useDefault = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_USE_DEFAULT, "true"); + String path = useDefault.equals("true") ? null : PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PATH, null); + if (path == null) { + if (forHtmlCode) { + // for html code we need to use double '//' symbols + // and seems it should be hard coded - as it is not the same as using File.separator + return "plugins/images/"; + } else { + return mage.client.constants.Constants.IO.imageBaseDir; + } + } + if (forHtmlCode) { + if (cachedPath != null) { + return cachedPath; + } + if (path.contains("\\")) { + cachedPath = path.replaceAll("[\\\\]", "/"); + return cachedPath; + } + } + return path; + } + + public static void draw(Graphics g, String manaCost, int x, int y, int symbolWidth) { + if (!manaImages.containsKey(symbolWidth)) { + loadSymbolsImages(symbolWidth); + } + Map sizedSymbols = manaImages.get(symbolWidth); + if (manaCost.length() == 0) { + return; + } + manaCost = manaCost.replace("\\", ""); + manaCost = UI.getDisplayManaCost(manaCost); + StringTokenizer tok = new StringTokenizer(manaCost, " "); + while (tok.hasMoreTokens()) { + String symbol = tok.nextToken().substring(0); + // Check and load symbol in the width + Image image = sizedSymbols.get(symbol); + if (image == null) { + //log.error("Symbol not recognized \"" + symbol + "\" in mana cost: " + manaCost); + continue; + } + g.drawImage(image, x, y, null); + x += symbolWidth; + } + } + + public static String getStringManaCost(List manaCost) { + StringBuilder sb = new StringBuilder(); + for (String s : manaCost) { + sb.append(s); + } + return sb.toString().replace("{", "").replace("}", " ").trim(); + } + + public enum Type { + TABLE, + CHAT, + DIALOG, + TOOLTIP, + } + + public static synchronized String replaceSymbolsWithHTML(String value, Type type) { + value = value.replace("{source}", "|source|"); + value = value.replace("{this}", "|this|"); + String replaced = value; + boolean symbolFilesFound; + int symbolSize; + switch (type) { + case TABLE: + symbolSize = GUISizeHelper.symbolTableSize; + break; + case CHAT: + symbolSize = GUISizeHelper.symbolChatSize; + break; + case DIALOG: + symbolSize = GUISizeHelper.symbolDialogSize; + break; + case TOOLTIP: + symbolSize = GUISizeHelper.symbolTooltipSize; + break; + default: + symbolSize = 11; + break; + } + String resourcePath = "small"; + symbolFilesFound = smallSymbolsFound; + if (symbolSize > 25) { + resourcePath = "large"; + } else if (symbolSize > 15) { + resourcePath = "medium"; + symbolFilesFound = mediumSymbolsFound; + } + if (symbolFilesFound) { + replaced = REPLACE_SYMBOLS_PATTERN.matcher(value).replaceAll( + "$1$2"); + } + replaced = replaced.replace("|source|", "{source}"); + replaced = replaced.replace("|this|", "{this}"); + return replaced; + } + + public static String replaceSetCodeWithHTML(String set, String rarity, int size) { + String _set = set; + if (setImagesExist.containsKey(_set)) { + int factor = size / 15 + 1; + Integer width = setImagesExist.get(_set).width * factor; + Integer height = setImagesExist.get(_set).height * factor; + return "" + rarity + ""; + } else { + return set; + } + } + + public static Image getSetSymbolImage(String set) { + return setImages.get(set); + } + + public static BufferedImage getSizedManaSymbol(String symbol) { + if (!manaImages.containsKey(GUISizeHelper.symbolDialogSize)) { + loadSymbolsImages(GUISizeHelper.symbolDialogSize); + } + Map sizedSymbols = manaImages.get(GUISizeHelper.symbolDialogSize); + return sizedSymbols.get(symbol); + } +} diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GathererSymbols.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GathererSymbols.java index bd25bd0059..10bd03ff7a 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GathererSymbols.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GathererSymbols.java @@ -71,7 +71,7 @@ public class GathererSymbols implements Iterable { return computeNext(); } String symbol = sym.replaceAll("/", ""); - File dst = new File(dir, symbol + ".jpg"); + File dst = new File(dir, symbol + ".gif"); switch (symbol) { case "T": From e8091daea5f452ad7a27e8c4fb356ee104c567e5 Mon Sep 17 00:00:00 2001 From: rkfg Date: Fri, 4 Mar 2016 01:09:45 +0300 Subject: [PATCH 6/6] Reverted crlf's back. --- .../org/mage/card/arcane/ManaSymbols.java | 622 +++++++++--------- 1 file changed, 311 insertions(+), 311 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java b/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java index 2921db77a3..89843310e5 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java @@ -1,311 +1,311 @@ -package org.mage.card.arcane; - -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Image; -import java.awt.Rectangle; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.nio.file.FileSystems; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.PathMatcher; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.StandardCopyOption; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; -import java.util.regex.Pattern; -import javax.imageio.ImageIO; -import mage.cards.repository.ExpansionRepository; -import mage.client.dialog.PreferencesDialog; -import mage.client.util.GUISizeHelper; -import mage.client.util.ImageHelper; -import mage.client.util.gui.BufferedImageBuilder; -import org.apache.log4j.Logger; -import org.mage.plugins.card.constants.Constants; - -public class ManaSymbols { - - private static final Logger LOGGER = Logger.getLogger(ManaSymbols.class); - private static final Map> manaImages = new HashMap<>(); - private static boolean smallSymbolsFound = false; - private static boolean mediumSymbolsFound = false; - - private static final Map setImages = new HashMap<>(); - private static final Map setImagesExist = new HashMap<>(); - private static final Pattern REPLACE_SYMBOLS_PATTERN = Pattern.compile("\\{([^}/]*)/?([^}]*)\\}"); - private static String cachedPath; - private static final String[] symbols = new String[]{"0", "1", "10", "11", "12", "15", "16", "2", "3", "4", "5", "6", "7", "8", "9", "B", "BG", - "BR", "G", "GU", "GW", "R", "RG", "RW", "S", "T", "U", "UB", "UR", "W", "WB", "WU", - "WP", "UP", "BP", "RP", "GP", "X", "C"}; - - public static void loadImages() { - renameSymbols(getSymbolsPath() + File.separator + "symbols"); - smallSymbolsFound = loadSymbolsImages(15); - mediumSymbolsFound = loadSymbolsImages(25); - - List setCodes = ExpansionRepository.instance.getSetCodes(); - if (setCodes == null) { - // the cards db file is probaly not included in the client. It will be created after the first connect to a server. - LOGGER.warn("No db information for sets found. Connect to a server to create database file on client side. Then try to restart the client."); - return; - } - for (String set : setCodes) { - File file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET + set + "-C.jpg"); - try { - Image image = UI.getImageIcon(file.getAbsolutePath()).getImage(); - int width = image.getWidth(null); - if (width > 21) { - int h = image.getHeight(null); - if (h > 0) { - Rectangle r = new Rectangle(21, (int) (h * 21.0f / width)); - BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r); - setImages.put(set, resized); - } - } else { - setImages.put(set, image); - } - } catch (Exception e) { - } - String[] codes = new String[]{"C", "U", "R", "M"}; - try { - file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL); - if (!file.exists()) { - file.mkdirs(); - } - - for (String code : codes) { - file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL + set + "-" + code + ".png"); - if (file.exists()) { - continue; - } - file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET + set + "-" + code + ".jpg"); - Image image = UI.getImageIcon(file.getAbsolutePath()).getImage(); - try { - int width = image.getWidth(null); - int height = image.getHeight(null); - if (height > 0) { - int dx = 0; - if (set.equals("M10") || set.equals("M11") || set.equals("M12")) { - dx = 6; - } - Rectangle r = new Rectangle(15 + dx, (int) (height * (15.0f + dx) / width)); - BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r); - File newFile = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL + File.separator + set + "-" + code + ".png"); - ImageIO.write(resized, "png", newFile); - } - } catch (Exception e) { - if (file.exists()) { - file.delete(); - } - } - } - - } catch (Exception e) { - } - } - - File file; - for (String set : ExpansionRepository.instance.getSetCodes()) { - file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL); - if (!file.exists()) { - break; - } - file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL + set + "-C.png"); - try { - Image image = UI.getImageIcon(file.getAbsolutePath()).getImage(); - int width = image.getWidth(null); - int height = image.getHeight(null); - setImagesExist.put(set, new Dimension(width, height)); - } catch (Exception e) { - } - } - } - - private static boolean loadSymbolsImages(int size) { - boolean fileErrors = false; - HashMap sizedSymbols = new HashMap<>(); - String resourcePath = Constants.RESOURCE_PATH_MANA_SMALL; - if (size > 25) { - resourcePath = Constants.RESOURCE_PATH_MANA_LARGE; - } else if (size > 15) { - resourcePath = Constants.RESOURCE_PATH_MANA_MEDIUM; - } - for (String symbol : symbols) { - File file = new File(getSymbolsPath() + resourcePath + "/" + symbol + ".gif"); - try { - - if (size == 15 || size == 25) { - BufferedImage notResized = ImageIO.read(file); - sizedSymbols.put(symbol, notResized); - } else { - Rectangle r = new Rectangle(size, size); - Image image = UI.getImageIcon(file.getAbsolutePath()).getImage(); - BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r); - sizedSymbols.put(symbol, resized); - } - } catch (Exception e) { - LOGGER.error("Error for symbol:" + symbol); - fileErrors = true; - } - } - manaImages.put(size, sizedSymbols); - return !fileErrors; - } - - private static void renameSymbols(String path) { - final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**/*.jpg"); - try { - Files.walkFileTree(Paths.get(path), new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - if (matcher.matches(file)) { - Path gifPath = file.resolveSibling(file.getFileName().toString().replaceAll("\\.jpg$", ".gif")); - Files.move(file, gifPath, StandardCopyOption.REPLACE_EXISTING); - } - return FileVisitResult.CONTINUE; - } - }); - } catch (IOException e) { - LOGGER.error("Couldn't rename mana symbols!"); - } - } - - private static String getSymbolsPath() { - return getSymbolsPath(false); - } - - private static String getSymbolsPath(boolean forHtmlCode) { - String useDefault = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_USE_DEFAULT, "true"); - String path = useDefault.equals("true") ? null : PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PATH, null); - if (path == null) { - if (forHtmlCode) { - // for html code we need to use double '//' symbols - // and seems it should be hard coded - as it is not the same as using File.separator - return "plugins/images/"; - } else { - return mage.client.constants.Constants.IO.imageBaseDir; - } - } - if (forHtmlCode) { - if (cachedPath != null) { - return cachedPath; - } - if (path.contains("\\")) { - cachedPath = path.replaceAll("[\\\\]", "/"); - return cachedPath; - } - } - return path; - } - - public static void draw(Graphics g, String manaCost, int x, int y, int symbolWidth) { - if (!manaImages.containsKey(symbolWidth)) { - loadSymbolsImages(symbolWidth); - } - Map sizedSymbols = manaImages.get(symbolWidth); - if (manaCost.length() == 0) { - return; - } - manaCost = manaCost.replace("\\", ""); - manaCost = UI.getDisplayManaCost(manaCost); - StringTokenizer tok = new StringTokenizer(manaCost, " "); - while (tok.hasMoreTokens()) { - String symbol = tok.nextToken().substring(0); - // Check and load symbol in the width - Image image = sizedSymbols.get(symbol); - if (image == null) { - //log.error("Symbol not recognized \"" + symbol + "\" in mana cost: " + manaCost); - continue; - } - g.drawImage(image, x, y, null); - x += symbolWidth; - } - } - - public static String getStringManaCost(List manaCost) { - StringBuilder sb = new StringBuilder(); - for (String s : manaCost) { - sb.append(s); - } - return sb.toString().replace("{", "").replace("}", " ").trim(); - } - - public enum Type { - TABLE, - CHAT, - DIALOG, - TOOLTIP, - } - - public static synchronized String replaceSymbolsWithHTML(String value, Type type) { - value = value.replace("{source}", "|source|"); - value = value.replace("{this}", "|this|"); - String replaced = value; - boolean symbolFilesFound; - int symbolSize; - switch (type) { - case TABLE: - symbolSize = GUISizeHelper.symbolTableSize; - break; - case CHAT: - symbolSize = GUISizeHelper.symbolChatSize; - break; - case DIALOG: - symbolSize = GUISizeHelper.symbolDialogSize; - break; - case TOOLTIP: - symbolSize = GUISizeHelper.symbolTooltipSize; - break; - default: - symbolSize = 11; - break; - } - String resourcePath = "small"; - symbolFilesFound = smallSymbolsFound; - if (symbolSize > 25) { - resourcePath = "large"; - } else if (symbolSize > 15) { - resourcePath = "medium"; - symbolFilesFound = mediumSymbolsFound; - } - if (symbolFilesFound) { - replaced = REPLACE_SYMBOLS_PATTERN.matcher(value).replaceAll( - "$1$2"); - } - replaced = replaced.replace("|source|", "{source}"); - replaced = replaced.replace("|this|", "{this}"); - return replaced; - } - - public static String replaceSetCodeWithHTML(String set, String rarity, int size) { - String _set = set; - if (setImagesExist.containsKey(_set)) { - int factor = size / 15 + 1; - Integer width = setImagesExist.get(_set).width * factor; - Integer height = setImagesExist.get(_set).height * factor; - return "" + rarity + ""; - } else { - return set; - } - } - - public static Image getSetSymbolImage(String set) { - return setImages.get(set); - } - - public static BufferedImage getSizedManaSymbol(String symbol) { - if (!manaImages.containsKey(GUISizeHelper.symbolDialogSize)) { - loadSymbolsImages(GUISizeHelper.symbolDialogSize); - } - Map sizedSymbols = manaImages.get(GUISizeHelper.symbolDialogSize); - return sizedSymbols.get(symbol); - } -} +package org.mage.card.arcane; + +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.regex.Pattern; +import javax.imageio.ImageIO; +import mage.cards.repository.ExpansionRepository; +import mage.client.dialog.PreferencesDialog; +import mage.client.util.GUISizeHelper; +import mage.client.util.ImageHelper; +import mage.client.util.gui.BufferedImageBuilder; +import org.apache.log4j.Logger; +import org.mage.plugins.card.constants.Constants; + +public class ManaSymbols { + + private static final Logger LOGGER = Logger.getLogger(ManaSymbols.class); + private static final Map> manaImages = new HashMap<>(); + private static boolean smallSymbolsFound = false; + private static boolean mediumSymbolsFound = false; + + private static final Map setImages = new HashMap<>(); + private static final Map setImagesExist = new HashMap<>(); + private static final Pattern REPLACE_SYMBOLS_PATTERN = Pattern.compile("\\{([^}/]*)/?([^}]*)\\}"); + private static String cachedPath; + private static final String[] symbols = new String[]{"0", "1", "10", "11", "12", "15", "16", "2", "3", "4", "5", "6", "7", "8", "9", "B", "BG", + "BR", "G", "GU", "GW", "R", "RG", "RW", "S", "T", "U", "UB", "UR", "W", "WB", "WU", + "WP", "UP", "BP", "RP", "GP", "X", "C"}; + + public static void loadImages() { + renameSymbols(getSymbolsPath() + File.separator + "symbols"); + smallSymbolsFound = loadSymbolsImages(15); + mediumSymbolsFound = loadSymbolsImages(25); + + List setCodes = ExpansionRepository.instance.getSetCodes(); + if (setCodes == null) { + // the cards db file is probaly not included in the client. It will be created after the first connect to a server. + LOGGER.warn("No db information for sets found. Connect to a server to create database file on client side. Then try to restart the client."); + return; + } + for (String set : setCodes) { + File file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET + set + "-C.jpg"); + try { + Image image = UI.getImageIcon(file.getAbsolutePath()).getImage(); + int width = image.getWidth(null); + if (width > 21) { + int h = image.getHeight(null); + if (h > 0) { + Rectangle r = new Rectangle(21, (int) (h * 21.0f / width)); + BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r); + setImages.put(set, resized); + } + } else { + setImages.put(set, image); + } + } catch (Exception e) { + } + String[] codes = new String[]{"C", "U", "R", "M"}; + try { + file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL); + if (!file.exists()) { + file.mkdirs(); + } + + for (String code : codes) { + file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL + set + "-" + code + ".png"); + if (file.exists()) { + continue; + } + file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET + set + "-" + code + ".jpg"); + Image image = UI.getImageIcon(file.getAbsolutePath()).getImage(); + try { + int width = image.getWidth(null); + int height = image.getHeight(null); + if (height > 0) { + int dx = 0; + if (set.equals("M10") || set.equals("M11") || set.equals("M12")) { + dx = 6; + } + Rectangle r = new Rectangle(15 + dx, (int) (height * (15.0f + dx) / width)); + BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r); + File newFile = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL + File.separator + set + "-" + code + ".png"); + ImageIO.write(resized, "png", newFile); + } + } catch (Exception e) { + if (file.exists()) { + file.delete(); + } + } + } + + } catch (Exception e) { + } + } + + File file; + for (String set : ExpansionRepository.instance.getSetCodes()) { + file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL); + if (!file.exists()) { + break; + } + file = new File(getSymbolsPath() + Constants.RESOURCE_PATH_SET_SMALL + set + "-C.png"); + try { + Image image = UI.getImageIcon(file.getAbsolutePath()).getImage(); + int width = image.getWidth(null); + int height = image.getHeight(null); + setImagesExist.put(set, new Dimension(width, height)); + } catch (Exception e) { + } + } + } + + private static boolean loadSymbolsImages(int size) { + boolean fileErrors = false; + HashMap sizedSymbols = new HashMap<>(); + String resourcePath = Constants.RESOURCE_PATH_MANA_SMALL; + if (size > 25) { + resourcePath = Constants.RESOURCE_PATH_MANA_LARGE; + } else if (size > 15) { + resourcePath = Constants.RESOURCE_PATH_MANA_MEDIUM; + } + for (String symbol : symbols) { + File file = new File(getSymbolsPath() + resourcePath + "/" + symbol + ".gif"); + try { + + if (size == 15 || size == 25) { + BufferedImage notResized = ImageIO.read(file); + sizedSymbols.put(symbol, notResized); + } else { + Rectangle r = new Rectangle(size, size); + Image image = UI.getImageIcon(file.getAbsolutePath()).getImage(); + BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r); + sizedSymbols.put(symbol, resized); + } + } catch (Exception e) { + LOGGER.error("Error for symbol:" + symbol); + fileErrors = true; + } + } + manaImages.put(size, sizedSymbols); + return !fileErrors; + } + + private static void renameSymbols(String path) { + final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**/*.jpg"); + try { + Files.walkFileTree(Paths.get(path), new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + if (matcher.matches(file)) { + Path gifPath = file.resolveSibling(file.getFileName().toString().replaceAll("\\.jpg$", ".gif")); + Files.move(file, gifPath, StandardCopyOption.REPLACE_EXISTING); + } + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + LOGGER.error("Couldn't rename mana symbols!"); + } + } + + private static String getSymbolsPath() { + return getSymbolsPath(false); + } + + private static String getSymbolsPath(boolean forHtmlCode) { + String useDefault = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_USE_DEFAULT, "true"); + String path = useDefault.equals("true") ? null : PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PATH, null); + if (path == null) { + if (forHtmlCode) { + // for html code we need to use double '//' symbols + // and seems it should be hard coded - as it is not the same as using File.separator + return "plugins/images/"; + } else { + return mage.client.constants.Constants.IO.imageBaseDir; + } + } + if (forHtmlCode) { + if (cachedPath != null) { + return cachedPath; + } + if (path.contains("\\")) { + cachedPath = path.replaceAll("[\\\\]", "/"); + return cachedPath; + } + } + return path; + } + + public static void draw(Graphics g, String manaCost, int x, int y, int symbolWidth) { + if (!manaImages.containsKey(symbolWidth)) { + loadSymbolsImages(symbolWidth); + } + Map sizedSymbols = manaImages.get(symbolWidth); + if (manaCost.length() == 0) { + return; + } + manaCost = manaCost.replace("\\", ""); + manaCost = UI.getDisplayManaCost(manaCost); + StringTokenizer tok = new StringTokenizer(manaCost, " "); + while (tok.hasMoreTokens()) { + String symbol = tok.nextToken().substring(0); + // Check and load symbol in the width + Image image = sizedSymbols.get(symbol); + if (image == null) { + //log.error("Symbol not recognized \"" + symbol + "\" in mana cost: " + manaCost); + continue; + } + g.drawImage(image, x, y, null); + x += symbolWidth; + } + } + + public static String getStringManaCost(List manaCost) { + StringBuilder sb = new StringBuilder(); + for (String s : manaCost) { + sb.append(s); + } + return sb.toString().replace("{", "").replace("}", " ").trim(); + } + + public enum Type { + TABLE, + CHAT, + DIALOG, + TOOLTIP, + } + + public static synchronized String replaceSymbolsWithHTML(String value, Type type) { + value = value.replace("{source}", "|source|"); + value = value.replace("{this}", "|this|"); + String replaced = value; + boolean symbolFilesFound; + int symbolSize; + switch (type) { + case TABLE: + symbolSize = GUISizeHelper.symbolTableSize; + break; + case CHAT: + symbolSize = GUISizeHelper.symbolChatSize; + break; + case DIALOG: + symbolSize = GUISizeHelper.symbolDialogSize; + break; + case TOOLTIP: + symbolSize = GUISizeHelper.symbolTooltipSize; + break; + default: + symbolSize = 11; + break; + } + String resourcePath = "small"; + symbolFilesFound = smallSymbolsFound; + if (symbolSize > 25) { + resourcePath = "large"; + } else if (symbolSize > 15) { + resourcePath = "medium"; + symbolFilesFound = mediumSymbolsFound; + } + if (symbolFilesFound) { + replaced = REPLACE_SYMBOLS_PATTERN.matcher(value).replaceAll("$1$2"); + } + replaced = replaced.replace("|source|", "{source}"); + replaced = replaced.replace("|this|", "{this}"); + return replaced; + } + + public static String replaceSetCodeWithHTML(String set, String rarity, int size) { + String _set = set; + if (setImagesExist.containsKey(_set)) { + int factor = size / 15 + 1; + Integer width = setImagesExist.get(_set).width * factor; + Integer height = setImagesExist.get(_set).height * factor; + return "" + rarity + ""; + } else { + return set; + } + } + + public static Image getSetSymbolImage(String set) { + return setImages.get(set); + } + + public static BufferedImage getSizedManaSymbol(String symbol) { + if (!manaImages.containsKey(GUISizeHelper.symbolDialogSize)) { + loadSymbolsImages(GUISizeHelper.symbolDialogSize); + } + Map sizedSymbols = manaImages.get(GUISizeHelper.symbolDialogSize); + return sizedSymbols.get(symbol); + } +}