diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderImpl.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderImpl.java index b418cd22df..2bf644ca6b 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderImpl.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderImpl.java @@ -218,13 +218,15 @@ public class CardPanelRenderImpl extends CardPanel { } } - // Map of generated images private final static Map IMAGE_CACHE = new MapMaker().softValues().makeMap(); // The art image for the card, loaded in from the disk private BufferedImage artImage; + // The faceart image for the card, loaded in from the disk (based on artid from mtgo) + private BufferedImage faceArtImage; + // Factory to generate card appropriate views private CardRendererFactory cardRendererFactory = new CardRendererFactory(); @@ -252,6 +254,8 @@ public class CardPanelRenderImpl extends CardPanel { // Use the art image and current rendered image from the card artImage = impl.artImage; cardRenderer.setArtImage(artImage); + faceArtImage = impl.faceArtImage; + cardRenderer.setFaceArtImage(faceArtImage); cardImage = impl.cardImage; } } @@ -263,8 +267,8 @@ public class CardPanelRenderImpl extends CardPanel { // Try to get card image from cache based on our card characteristics ImageKey key = new ImageKey(gameCard, artImage, - getCardWidth(), getCardHeight(), - isChoosable(), isSelected()); + getCardWidth(), getCardHeight(), + isChoosable(), isSelected()); cardImage = IMAGE_CACHE.computeIfAbsent(key, k -> renderCard()); // No cached copy exists? Render one and cache it @@ -277,7 +281,6 @@ public class CardPanelRenderImpl extends CardPanel { /** * Create an appropriate card renderer for the */ - /** * Render the card to a new BufferedImage at it's current dimensions * @@ -315,6 +318,7 @@ public class CardPanelRenderImpl extends CardPanel { artImage = null; cardImage = null; cardRenderer.setArtImage(null); + cardRenderer.setFaceArtImage(null); // Stop animation tappedAngle = isTapped() ? CardPanel.TAPPED_ANGLE : 0; @@ -332,19 +336,26 @@ public class CardPanelRenderImpl extends CardPanel { Util.threadPool.submit(() -> { try { final BufferedImage srcImage; + final BufferedImage faceArtSrcImage; if (gameCard.isFaceDown()) { // Nothing to do srcImage = null; + faceArtSrcImage = null; } else if (getCardWidth() > THUMBNAIL_SIZE_FULL.width) { srcImage = ImageCache.getImage(gameCard, getCardWidth(), getCardHeight()); + faceArtSrcImage = ImageCache.getFaceImage(gameCard, getCardWidth(), getCardHeight()); } else { srcImage = ImageCache.getThumbnail(gameCard); + faceArtSrcImage = ImageCache.getFaceImage(gameCard, getCardWidth(), getCardHeight()); } UI.invokeLater(() -> { if (stamp == updateArtImageStamp) { artImage = srcImage; cardRenderer.setArtImage(srcImage); + faceArtImage = faceArtSrcImage; + cardRenderer.setFaceArtImage(faceArtSrcImage); + if (srcImage != null) { // Invalidate and repaint cardImage = null; @@ -370,6 +381,7 @@ public class CardPanelRenderImpl extends CardPanel { cardImage = null; cardRenderer = cardRendererFactory.create(gameCard, isTransformed()); cardRenderer.setArtImage(artImage); + cardRenderer.setFaceArtImage(faceArtImage); // Repaint repaint(); diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardRenderer.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardRenderer.java index f28cb134e4..2c0f7cd44b 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/CardRenderer.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardRenderer.java @@ -66,6 +66,9 @@ public abstract class CardRenderer { // The card image protected BufferedImage artImage; + // The face card image + protected BufferedImage faceArtImage; + /////////////////////////////////////////////////////////////////////////// // Common layout metrics between all cards // Polygons for counters @@ -289,8 +292,8 @@ public abstract class CardRenderer { try { BufferedImage subImg = artImage.getSubimage( - (int) (artRect.getX() * fullCardImgWidth), (int) (artRect.getY() * fullCardImgHeight), - (int) artWidth, (int) artHeight); + (int) (artRect.getX() * fullCardImgWidth), (int) (artRect.getY() * fullCardImgHeight), + (int) artWidth, (int) artHeight); g.drawImage(subImg, x, y, (int) targetWidth, (int) targetHeight, @@ -300,6 +303,40 @@ public abstract class CardRenderer { } } + protected void drawFaceArtIntoRect(Graphics2D g, int x, int y, int w, int h, Rectangle2D artRect, boolean shouldPreserveAspect) { + // Perform a process to make sure that the art is scaled uniformly to fill the frame, cutting + // off the minimum amount necessary to make it completely fill the frame without "squashing" it. + double fullCardImgWidth = faceArtImage.getWidth(); + double fullCardImgHeight = faceArtImage.getHeight(); + double artWidth = fullCardImgWidth; + double artHeight = fullCardImgHeight; + double targetWidth = w; + double targetHeight = h; + double targetAspect = targetWidth / targetHeight; + if (!shouldPreserveAspect) { + // No adjustment to art + } else if (targetAspect * artHeight < artWidth) { + // Trim off some width + artWidth = targetAspect * artHeight; + } else { + // Trim off some height + artHeight = artWidth / targetAspect; + } + try { + /*BufferedImage subImg + = faceArtImage.getSubimage( + (int) (artRect.getX() * fullCardImgWidth), (int) (artRect.getY() * fullCardImgHeight), + (int) artWidth, (int) artHeight);*/ + g.drawImage(faceArtImage, + x, y, + (int) targetWidth, (int) targetHeight, + null); + } catch (RasterFormatException e) { + // At very small card sizes we may encounter a problem with rounding error making the rect not fit + System.out.println(e); + } + } + // Draw +1/+1 and other counters protected void drawCounters(Graphics2D g) { int xPos = (int) (0.65 * cardWidth); @@ -442,4 +479,10 @@ public abstract class CardRenderer { public void setArtImage(Image image) { artImage = CardRendererUtils.toBufferedImage(image); } + + // Set the card art image (CardPanel will give it to us when it + // is loaded and ready) + public void setFaceArtImage(Image image) { + faceArtImage = CardRendererUtils.toBufferedImage(image); + } } diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/ModernCardRenderer.java b/Mage.Client/src/main/java/org/mage/card/arcane/ModernCardRenderer.java index a3de811495..e603ac6d1e 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/ModernCardRenderer.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/ModernCardRenderer.java @@ -279,6 +279,8 @@ public class ModernCardRenderer extends CardRenderer { // Just draw a brown rectangle drawCardBack(g); } else { + BufferedImage bufferedImage = new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB); + // Set texture to paint with g.setPaint(getBackgroundPaint(cardView.getColor(), cardView.getCardTypes(), cardView.getSubTypes())); @@ -348,8 +350,15 @@ public class ModernCardRenderer extends CardRenderer { @Override protected void drawArt(Graphics2D g) { if (artImage != null && !cardView.isFaceDown()) { + + boolean useFaceArt = false; + if (faceArtImage != null) { + useFaceArt = true; + } + // Invention rendering, art fills the entire frame if (useInventionFrame()) { + useFaceArt = false; drawArtIntoRect(g, borderWidth, borderWidth, cardWidth - 2 * borderWidth, cardHeight - 2 * borderWidth, @@ -360,6 +369,7 @@ public class ModernCardRenderer extends CardRenderer { Rectangle2D sourceRect = getArtRect(); if (cardView.getMageObjectType() == MageObjectType.SPELL) { + useFaceArt = false; ArtRect rect = cardView.getArtRect(); if (rect == ArtRect.SPLIT_FUSED) { // Special handling for fused, draw the art from both halves stacked on top of one and other @@ -380,10 +390,17 @@ public class ModernCardRenderer extends CardRenderer { } // Normal drawing of art from a source part of the card frame into the rect - drawArtIntoRect(g, - totalContentInset + 1, totalContentInset + boxHeight, - contentWidth - 2, typeLineY - totalContentInset - boxHeight, - sourceRect, shouldPreserveAspect); + if (useFaceArt) { + drawFaceArtIntoRect(g, + totalContentInset + 1, totalContentInset + boxHeight, + contentWidth - 2, typeLineY - totalContentInset - boxHeight, + sourceRect, shouldPreserveAspect); + } else { + drawArtIntoRect(g, + totalContentInset + 1, totalContentInset + boxHeight, + contentWidth - 2, typeLineY - totalContentInset - boxHeight, + sourceRect, shouldPreserveAspect); + } } } @@ -420,6 +437,7 @@ public class ModernCardRenderer extends CardRenderer { g.setPaint(new Color(255, 255, 255, 150)); } else { g.setPaint(textboxPaint); + } g.fillRect( totalContentInset + 1, typeLineY, @@ -476,6 +494,9 @@ public class ModernCardRenderer extends CardRenderer { // Draw the transform circle int nameOffset = drawTransformationCircle(g, borderPaint); + // Draw the transform circle + nameOffset = drawTransformationCircle(g, borderPaint); + // Draw the name line drawNameLine(g, cardView.getDisplayName(), manaCostString, totalContentInset + nameOffset, totalContentInset, diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java index 97cbd4af82..3d9c98d953 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java @@ -44,6 +44,7 @@ public final class ImageCache { private static final Logger LOGGER = Logger.getLogger(ImageCache.class); private static final Map IMAGE_CACHE; + private static final Map FACE_IMAGE_CACHE; /** * Common pattern for keys. Format: "##" @@ -155,6 +156,55 @@ public final class ImageCache { return makeThumbnail(image, thumbnailPath); } }); + + FACE_IMAGE_CACHE = new MapMaker().softValues().makeComputingMap(new Function() { + @Override + public BufferedImage apply(String key) { + try { + + Matcher m = KEY_PATTERN.matcher(key); + + if (m.matches()) { + String name = m.group(1); + String set = m.group(2); + //Integer artid = Integer.parseInt(m.group(2)); + + String path; + path = CardImageUtils.generateFaceImagePath(name, set); + + if (path == null) { + return null; + } + TFile file = getTFile(path); + if (file == null) { + return null; + } + + BufferedImage image = loadImage(file); + return image; + } else { + throw new RuntimeException( + "Requested face image doesn't fit the requirement for key (##: " + key); + } + } catch (Exception ex) { + if (ex instanceof ComputationException) { + throw (ComputationException) ex; + } else { + throw new ComputationException(ex); + } + } + } + + public BufferedImage makeThumbnailByFile(String key, TFile file, String thumbnailPath) { + BufferedImage image = loadImage(file); + image = getWizardsCard(image); + if (image == null) { + return null; + } + LOGGER.debug("creating thumbnail for " + key); + return makeThumbnail(image, thumbnailPath); + } + }); } public static String getFilePath(CardView card, int width) { @@ -263,6 +313,10 @@ public final class ImageCache { return getImage(getKey(card, card.getName(), "")); } + public static BufferedImage getImageFaceOriginal(CardView card) { + return getFaceImage(getFaceKey(card, card.getName(), card.getExpansionSetCode())); + } + public static BufferedImage getImageOriginalAlternateName(CardView card) { return getImage(getKey(card, card.getAlternateName(), "")); } @@ -288,6 +342,27 @@ public final class ImageCache { } } + /** + * Returns the Image corresponding to the key + */ + private static BufferedImage getFaceImage(String key) { + try { + return FACE_IMAGE_CACHE.get(key); + } catch (NullPointerException ex) { + // unfortunately NullOutputException, thrown when apply() returns + // null, is not public + // NullOutputException is a subclass of NullPointerException + // legitimate, happens when a card has no image + return null; + } catch (ComputationException ex) { + if (ex.getCause() instanceof NullPointerException) { + return null; + } + LOGGER.error(ex, ex); + return null; + } + } + /** * Returns the Image corresponding to the key only if it already exists in * the cache. @@ -296,6 +371,14 @@ public final class ImageCache { return IMAGE_CACHE.containsKey(key) ? IMAGE_CACHE.get(key) : null; } + /** + * Returns the Image corresponding to the key only if it already exists in + * the cache. + */ + private static BufferedImage tryGetFaceImage(String key) { + return FACE_IMAGE_CACHE.containsKey(key) ? FACE_IMAGE_CACHE.get(key) : null; + } + /** * Returns the map key for a card, without any suffixes for the image size. */ @@ -307,6 +390,13 @@ public final class ImageCache { + (card.getTokenDescriptor() != null ? '#' + card.getTokenDescriptor() : "#"); } + /** + * Returns the map key for a card, without any suffixes for the image size. + */ + private static String getFaceKey(CardView card, String name, String set) { + return name + '#' + set + "####"; + } + // /** // * Returns the map key for the flip image of a card, without any suffixes for the image size. // */ @@ -409,6 +499,25 @@ public final class ImageCache { return TransformedImageCache.getResizedImage(original, (int) (original.getWidth() * scale), (int) (original.getHeight() * scale)); } + /** + * Returns the image appropriate to display the card in the picture panel + * + * @param card + * @param width + * @param height + * @return + */ + public static BufferedImage getFaceImage(CardView card, int width, int height) { + String key = getFaceKey(card, card.getName(), card.getExpansionSetCode()); + BufferedImage original = getFaceImage(key); + if (original == null) { + LOGGER.debug(key + " (faceimage) not found"); + return null; + } + + return original; + } + /** * Returns the image appropriate to display for a card in a picture panel, * but only it was ALREADY LOADED. That is, the call is immediate and will diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java b/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java index 7cbe1ec9a0..e8611b63e0 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java @@ -48,7 +48,7 @@ public final class CardImageUtils { log.warn("Token image file not found: " + card.getSet() + " - " + card.getTokenSetCode() + " - " + card.getName()); return null; } - + /** * * @param card @@ -204,6 +204,14 @@ public final class CardImageUtils { return imageDir + TFile.separator + imageName; } + public static String generateFaceImagePath(String cardname, String set) { + String useDefault = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_USE_DEFAULT, "true"); + String imagesPath = Objects.equals(useDefault, "true") ? Constants.IO.imageBaseDir : PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PATH, null); + String imageDir = imagesPath; + String imageName = set + TFile.separator + cardname + ".jpg"; + return imageDir + TFile.separator + "FACE" + TFile.separator + imageName; + } + public static String generateTokenDescriptorImagePath(CardDownloadData card) { // String useDefault = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_USE_DEFAULT, "true"); // String imagesPath = Objects.equals(useDefault, "true") ? null : PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PATH, null); diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/CanadianHighlander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/CanadianHighlander.java index 75babb9a1b..9f742d4fbc 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/CanadianHighlander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/CanadianHighlander.java @@ -117,9 +117,9 @@ public class CanadianHighlander extends Constructed { || cn.equals("Mana Crypt") || cn.equals("Mystical Tutor") || cn.equals("Strip Mine") - || cn.equals("Summoner’s Pact") + || cn.equals("Summoner's Pact") || cn.equals("Survival of the Fittest") - || cn.equals("Umezawa’s Jitte")) { + || cn.equals("Umezawa's Jitte")) { totalPoints += 2; invalid.put(entry.getKey(), " 2 points " + cn); } diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianPurge.java b/Mage.Sets/src/mage/cards/p/PhyrexianPurge.java index c0128b767b..1a69e274c6 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianPurge.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianPurge.java @@ -32,6 +32,7 @@ import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.costs.common.PayLifeCost; import mage.abilities.effects.common.DestroyMultiTargetEffect; +import mage.abilities.effects.common.InfoEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -44,17 +45,17 @@ import mage.target.common.TargetCreaturePermanent; * @author escplan9 - Derek Monturo */ public class PhyrexianPurge extends CardImpl { - + public PhyrexianPurge(UUID ownerId, CardSetInfo setInfo) { - - super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}{R}"); + // Destroy any number of target creatures. // Phyrexian Purge costs 3 life more to cast for each target. this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, Integer.MAX_VALUE)); this.getSpellAbility().addEffect(new DestroyMultiTargetEffect()); + this.getSpellAbility().addEffect(new InfoEffect("

{this} costs 3 life more to cast for each target")); } - + @Override public void adjustCosts(Ability ability, Game game) { int numTargets = ability.getTargets().get(0).getTargets().size(); @@ -62,17 +63,17 @@ public class PhyrexianPurge extends CardImpl { ability.getCosts().add(new PayLifeCost(numTargets * 3)); } } - + @Override public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - ability.getTargets().clear(); - Player you = game.getPlayer(ownerId); - int maxTargets = you.getLife() / 3; - ability.addTarget(new TargetCreaturePermanent(0, maxTargets)); - } + if (ability instanceof SpellAbility) { + ability.getTargets().clear(); + Player you = game.getPlayer(ownerId); + int maxTargets = you.getLife() / 3; + ability.addTarget(new TargetCreaturePermanent(0, maxTargets)); + } } - + public PhyrexianPurge(final PhyrexianPurge card) { super(card); } @@ -81,4 +82,4 @@ public class PhyrexianPurge extends CardImpl { public PhyrexianPurge copy() { return new PhyrexianPurge(this); } -} \ No newline at end of file +} diff --git a/Utils/cut.pl b/Utils/cut.pl index 674a7982d1..3b03a0a5b5 100644 --- a/Utils/cut.pl +++ b/Utils/cut.pl @@ -1,6 +1,6 @@ #!/usr/bin/perl ## -# File : get_all.pl +# File : cut.pl # Author : spjspj ## @@ -22,6 +22,7 @@ use POSIX qw(strftime); print (" cut.pl full_text.txt keys 0 filegrep\n"); print (" cut.pl full_text.txt 0 0 make_code_bat\n"); print (" dir /a /b /s *.java | cut.pl stdin 0 0 make_code_bat > bob.bat\n"); + print (" dir /a /b /s *.xml | cut.pl stdin 0 0 make_code_bat > bob_xml.bat\n"); print (" cut.pl d:\\perl_programs output.*txt 7 age_dir | cut.pl list . 0 grep\n"); print (" cut.pl bob.txt 0 0 uniquelines \n"); print (" cut.pl file 0 0 strip_http\n"); @@ -331,16 +332,27 @@ use POSIX qw(strftime); { my $i; { - my $url = $term; - print ("Download :$url:\n"); - my $content = get $url; - print ("Saw " . length ($content) . " bytes!\n"); - print ("Save in $helper\n"); - open OUTPUT, "> " . $helper or die "No dice!"; - binmode (OUTPUT); - print OUTPUT $content; - close OUTPUT; - print $url, " >>> ", $helper, "\n"; + if (!(-f "$helper")) + { + my $url = $term; + print ("Download :$url:\n"); + my $content = get $url; + print ("Saw " . length ($content) . " bytes!\n"); + print ("Save in $helper\n"); + open OUTPUT, "> " . $helper or die "No dice!"; + binmode (OUTPUT); + print OUTPUT $content; + close OUTPUT; + print $url, " >>> ", $helper, "\n"; + } + else + { + print ("Found $helper existed already..\n"); + if (-s "$helper" == 0) + { + `del "$helper"`; + } + } } } if ($operation eq "grep") @@ -898,5 +910,4 @@ use POSIX qw(strftime); } } } - } diff --git a/Utils/get_modo_artids.pl b/Utils/get_modo_artids.pl new file mode 100644 index 0000000000..b55a732b3c --- /dev/null +++ b/Utils/get_modo_artids.pl @@ -0,0 +1,281 @@ +#!/usr/bin/perl +## +# File : get_modo_artids.pl +# Date : 12/Nov/2017 +# Author : spjspj +# Purpose : Get the artid for each face art of each card from modo (mtgo) +# this then goes into some form of image such as: +# http://mtgoclientdepot.onlinegaming.wizards.com/Graphics/Cards/Pics/161922_typ_reg_sty_050.jpg +# "" /00100_typ_reg_sty_001.jpg +# "" /01440_typ_reg_sty_010.jpg +# "" /102392_typ_reg_sty_010.jpg +# "" /400603_typ_reg_sty_050.jpg +# This program expects that you've copied the relevant .xml files from an installation of mtgo +# into the current working directory for this perl script: +# For example: CARDNAME_STRING.xml, client_BNG.xml, +# Also, it expects to be running on windows +## + +use strict; +use LWP::Simple; +use POSIX qw(strftime); + + +# From xmage code - fix from MODO to XMAGE type set codes +my %fix_set_codes; +$fix_set_codes {"2U"} = "2ED"; +$fix_set_codes {"3E"} = "3ED"; +$fix_set_codes {"4E"} = "4ED"; +$fix_set_codes {"5E"} = "5ED"; +$fix_set_codes {"6E"} = "6ED"; +$fix_set_codes {"7E"} = "7ED"; +$fix_set_codes {"AL"} = "ALL"; +$fix_set_codes {"AP"} = "APC"; +$fix_set_codes {"AN"} = "ARN"; +$fix_set_codes {"AQ"} = "ATQ"; +$fix_set_codes {"CM1"} = "CMA"; +$fix_set_codes {"DD3_DVD"} = "DD3DVD"; +$fix_set_codes {"DD3_EVG"} = "DD3EVG"; +$fix_set_codes {"DD3_GLV"} = "DD3GLV"; +$fix_set_codes {"DD3_JVC"} = "DD3JVC"; +$fix_set_codes {"DK"} = "DRK"; +$fix_set_codes {"EX"} = "EXO"; +$fix_set_codes {"FE"} = "FEM"; +$fix_set_codes {"HM"} = "HML"; +$fix_set_codes {"IA"} = "ICE"; +$fix_set_codes {"IN"} = "INV"; +$fix_set_codes {"1E"} = "LEA"; +$fix_set_codes {"2E"} = "LEB"; +$fix_set_codes {"LE"} = "LEG"; +$fix_set_codes {"MI"} = "MIR"; +$fix_set_codes {"MM"} = "MMQ"; +$fix_set_codes {"MPS_KLD"} = "MPS"; +$fix_set_codes {"NE"} = "NEM"; +$fix_set_codes {"NE"} = "NMS"; +$fix_set_codes {"OD"} = "ODY"; +$fix_set_codes {"PR"} = "PCY"; +$fix_set_codes {"PS"} = "PLS"; +$fix_set_codes {"P2"} = "PO2"; +$fix_set_codes {"PO"} = "POR"; +$fix_set_codes {"PK"} = "PTK"; +$fix_set_codes {"ST"} = "STH"; +$fix_set_codes {"TE"} = "TMP"; +$fix_set_codes {"CG"} = "UDS"; +$fix_set_codes {"UD"} = "UDS"; +$fix_set_codes {"GU"} = "ULG"; +$fix_set_codes {"UZ"} = "USG"; +$fix_set_codes {"VI"} = "VIS"; +$fix_set_codes {"WL"} = "WTH"; + +# Main +{ + my $card = $ARGV [0]; + + # Example: Abandoned Sarcophagus + my $vals = `find /I "CARDNAME" *CARDNAME*STR*`; + my %ids; + my %set_names; + my $count = 0; + while ($vals =~ s/^.*CARDNAME_STRING_ITEM id='(.*?)'>(.*?)<\/CARDNAME_STRING.*\n//im) + { + $ids {$1} = $2; + $count++; + } + print ("Finished reading $count names\n"); + + + #$vals = `find /I "<" *lient*`; + $vals = `findstr /I "CARDNAME_STRING DIGITALOBJECT ARTID CLONE FRAMESTYLE " *lient* | find /I /V "_DO.xml"`; + + my $current_artid = ""; + my $current_clone_id = ""; + my $current_doc_id = ""; + my $current_line = ""; + my $current_name = ""; + my $current_set = ""; + my $num_set = 1; + my %docid_to_clone; + + while ($vals =~ s/^(.*)\n//im) + { + my $line = $1; + $line =~ m/^client_(.*)?\.xml/; + $current_set = $1; + +# *** IN +# *** IN +# +# *** IN +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# + + if ($line =~ m/