mirror of
https://github.com/magefree/mage.git
synced 2026-01-26 21:29:17 -08:00
* Textual set symbols no longer displayed if set symbol image doesn't exist.
* Fixed a small graphical mispositioning in rendering of keyword abilities. * Added an option to hide set symbols entirely when rendering. * Fixed flip walkers like Arlin Kord showing a "0" loyalty on their back face (when they should have no loyalty there). * Removed some log files I accidentally committed. * Fixed a bug in tokens, where they are missing their expansion symbol of they are created by another token * Fixed the the new Rendering based CardPanel not returning the correct Image through getImage (resulting in a poor quality image in the card preview window)
This commit is contained in:
parent
d33f8a636e
commit
818efb8535
10 changed files with 119 additions and 11253 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
|
|
@ -4156,10 +4156,7 @@
|
|||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="panelCardImages" max="32767" attributes="0"/>
|
||||
<Component id="jPanel1" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="panelBackgroundImages" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="panelBackgroundImages" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
|
|
@ -4174,7 +4171,7 @@
|
|||
<Component id="panelCardImages" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="panelBackgroundImages" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<EmptySpace pref="53" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
|
@ -4506,6 +4503,7 @@
|
|||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="cbCardRenderImageFallback" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cbCardRenderShowReminderText" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cbCardRenderHideSetSymbol" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
|
|
@ -4517,7 +4515,9 @@
|
|||
<Component id="cbCardRenderImageFallback" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cbCardRenderShowReminderText" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="7" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cbCardRenderHideSetSymbol" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
|
@ -4539,6 +4539,14 @@
|
|||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbCardRenderShowReminderTextActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="cbCardRenderHideSetSymbol">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Hide set symbols on cards (more space on the type line for card types)"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbCardRenderHideSetSymbolActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
|
|
|
|||
|
|
@ -120,7 +120,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
|
||||
public static final String KEY_CARD_RENDERING_FALLBACK = "cardRenderingFallback";
|
||||
public static final String KEY_CARD_RENDERING_REMINDER_TEXT = "cardRenderingReminderText";
|
||||
|
||||
public static final String KEY_CARD_RENDERING_SET_SYMBOL = "cardRenderingSetSymbol";
|
||||
|
||||
public static final String KEY_BACKGROUND_IMAGE = "backgroundImage";
|
||||
public static final String KEY_BATTLEFIELD_IMAGE = "battlefieldImage";
|
||||
public static final String KEY_BACKGROUND_IMAGE_DEFAULT = "backgroundImagedDefault";
|
||||
|
|
@ -470,6 +471,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
jPanel1 = new javax.swing.JPanel();
|
||||
cbCardRenderImageFallback = new javax.swing.JCheckBox();
|
||||
cbCardRenderShowReminderText = new javax.swing.JCheckBox();
|
||||
cbCardRenderHideSetSymbol = new javax.swing.JCheckBox();
|
||||
tabSounds = new javax.swing.JPanel();
|
||||
sounds_clips = new javax.swing.JPanel();
|
||||
cbEnableGameSounds = new javax.swing.JCheckBox();
|
||||
|
|
@ -1615,6 +1617,13 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
}
|
||||
});
|
||||
|
||||
cbCardRenderHideSetSymbol.setText("Hide set symbols on cards (more space on the type line for card types)");
|
||||
cbCardRenderHideSetSymbol.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cbCardRenderHideSetSymbolActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
|
||||
jPanel1.setLayout(jPanel1Layout);
|
||||
jPanel1Layout.setHorizontalGroup(
|
||||
|
|
@ -1622,7 +1631,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
.add(jPanel1Layout.createSequentialGroup()
|
||||
.add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
|
||||
.add(cbCardRenderImageFallback)
|
||||
.add(cbCardRenderShowReminderText))
|
||||
.add(cbCardRenderShowReminderText)
|
||||
.add(cbCardRenderHideSetSymbol))
|
||||
.add(0, 0, Short.MAX_VALUE))
|
||||
);
|
||||
jPanel1Layout.setVerticalGroup(
|
||||
|
|
@ -1631,7 +1641,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
.add(cbCardRenderImageFallback)
|
||||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
|
||||
.add(cbCardRenderShowReminderText)
|
||||
.add(0, 7, Short.MAX_VALUE))
|
||||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
|
||||
.add(cbCardRenderHideSetSymbol)
|
||||
.add(0, 0, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
org.jdesktop.layout.GroupLayout tabImagesLayout = new org.jdesktop.layout.GroupLayout(tabImages);
|
||||
|
|
@ -1643,9 +1655,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
.add(tabImagesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
|
||||
.add(panelCardImages, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(tabImagesLayout.createSequentialGroup()
|
||||
.add(0, 0, 0)
|
||||
.add(panelBackgroundImages, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||
.add(panelBackgroundImages, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
tabImagesLayout.setVerticalGroup(
|
||||
|
|
@ -1657,7 +1667,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
.add(panelCardImages, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
|
||||
.add(panelBackgroundImages, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap(53, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
tabsPanel.addTab("Images", tabImages);
|
||||
|
|
@ -2586,6 +2596,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
|
||||
// rendering
|
||||
save(prefs, dialog.cbCardRenderImageFallback, KEY_CARD_RENDERING_FALLBACK, "true", "false", UPDATE_CACHE_POLICY);
|
||||
save(prefs, dialog.cbCardRenderHideSetSymbol, KEY_CARD_RENDERING_SET_SYMBOL, "true", "false", UPDATE_CACHE_POLICY);
|
||||
save(prefs, dialog.cbCardRenderShowReminderText, KEY_CARD_RENDERING_REMINDER_TEXT, "true", "false", UPDATE_CACHE_POLICY);
|
||||
|
||||
// sounds
|
||||
|
|
@ -2893,6 +2904,10 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
}
|
||||
}//GEN-LAST:event_cbUseDefaultImageFolderActionPerformed
|
||||
|
||||
private void cbCardRenderHideSetSymbolActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbCardRenderHideSetSymbolActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_cbCardRenderHideSetSymbolActionPerformed
|
||||
|
||||
private void showProxySettings() {
|
||||
Connection.ProxyType proxyType = (Connection.ProxyType) cbProxyType.getSelectedItem();
|
||||
switch (proxyType) {
|
||||
|
|
@ -3068,6 +3083,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
|
||||
// rendering settings
|
||||
load(prefs, dialog.cbCardRenderImageFallback, KEY_CARD_RENDERING_FALLBACK, "true");
|
||||
load(prefs, dialog.cbCardRenderHideSetSymbol, KEY_CARD_RENDERING_SET_SYMBOL, "true");
|
||||
load(prefs, dialog.cbCardRenderShowReminderText, KEY_CARD_RENDERING_REMINDER_TEXT, "true");
|
||||
|
||||
//add background load precedure
|
||||
|
|
@ -3450,6 +3466,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
private javax.swing.JCheckBox cbAllowRequestToShowHandCards;
|
||||
private javax.swing.JCheckBox cbAskMoveToGraveOrder;
|
||||
private javax.swing.JCheckBox cbAutoOrderTrigger;
|
||||
private javax.swing.JCheckBox cbCardRenderHideSetSymbol;
|
||||
private javax.swing.JCheckBox cbCardRenderImageFallback;
|
||||
private javax.swing.JCheckBox cbCardRenderShowReminderText;
|
||||
private javax.swing.JCheckBox cbCheckForNewImages;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import java.awt.Graphics2D;
|
|||
import java.awt.Image;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import mage.cards.action.ActionCallback;
|
||||
|
|
@ -16,9 +17,12 @@ import mage.constants.CardType;
|
|||
import mage.view.CardView;
|
||||
import mage.view.CounterView;
|
||||
import mage.view.PermanentView;
|
||||
import mage.view.StackAbilityView;
|
||||
import net.java.truevfs.access.TFile;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.jdesktop.swingx.graphics.GraphicsUtilities;
|
||||
import static org.mage.plugins.card.constants.Constants.THUMBNAIL_SIZE_FULL;
|
||||
import org.mage.plugins.card.dl.sources.DirectLinksForDownload;
|
||||
import org.mage.plugins.card.images.ImageCache;
|
||||
|
||||
public class CardPanelRenderImpl extends CardPanel {
|
||||
|
|
@ -360,11 +364,31 @@ public class CardPanelRenderImpl extends CardPanel {
|
|||
cardImage = null;
|
||||
}
|
||||
}
|
||||
|
||||
private BufferedImage getFaceDownImage() {
|
||||
if (isPermanent()) {
|
||||
if (((PermanentView) gameCard).isMorphed()) {
|
||||
return ImageCache.getMorphImage();
|
||||
} else {
|
||||
return ImageCache.getManifestImage();
|
||||
}
|
||||
} else if (this.gameCard instanceof StackAbilityView) {
|
||||
return ImageCache.getMorphImage();
|
||||
} else {
|
||||
return ImageCache.loadImage(new TFile(DirectLinksForDownload.outDir + File.separator + DirectLinksForDownload.cardbackFilename));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image getImage() {
|
||||
// Render impl never returns a card image
|
||||
return artImage;
|
||||
if (artImage != null) {
|
||||
if (gameCard.isFaceDown()) {
|
||||
return getFaceDownImage();
|
||||
} else {
|
||||
return ImageCache.getImageOriginal(gameCard);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import java.awt.image.BufferedImage;
|
|||
import java.text.AttributedString;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import mage.client.dialog.PreferencesDialog;
|
||||
import mage.constants.AbilityType;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Rarity;
|
||||
|
|
@ -140,11 +141,19 @@ public abstract class CardRenderer {
|
|||
|
||||
// Translate the textbox text
|
||||
for (String rule: card.getRules()) {
|
||||
TextboxRule tbRule = TextboxRuleParser.parse(card, rule);
|
||||
if (tbRule.type == TextboxRuleType.SIMPLE_KEYWORD) {
|
||||
textboxKeywords.add(tbRule);
|
||||
} else {
|
||||
textboxRules.add(tbRule);
|
||||
// Kill reminder text
|
||||
if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_RENDERING_REMINDER_TEXT, "false").equals("false")) {
|
||||
rule = CardRendererUtils.killReminderText(rule).trim();
|
||||
}
|
||||
if (!rule.isEmpty()) {
|
||||
TextboxRule tbRule = TextboxRuleParser.parse(card, rule);
|
||||
if (tbRule.type == TextboxRuleType.SIMPLE_KEYWORD) {
|
||||
textboxKeywords.add(tbRule);
|
||||
} else if (tbRule.text.isEmpty()) {
|
||||
// Nothing to do, rule is empty
|
||||
} else {
|
||||
textboxRules.add(tbRule);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -281,8 +290,12 @@ public abstract class CardRenderer {
|
|||
Image setSymbol = ManaSymbols.getSetSymbolImage(cardView.getExpansionSetCode(), cardView.getRarity().getCode());
|
||||
int setSymbolWidth;
|
||||
if (setSymbol == null) {
|
||||
// Don't draw anything when we don't have a set symbol
|
||||
return 0;
|
||||
/*
|
||||
// Just draw the as a code
|
||||
String code = cardView.getExpansionSetCode().toUpperCase();
|
||||
String code = cardView.getExpansionSetCode();
|
||||
code = (code != null) ? code.toUpperCase() : "";
|
||||
FontMetrics metrics = g.getFontMetrics();
|
||||
setSymbolWidth = metrics.stringWidth(code);
|
||||
if (cardView.getRarity() == Rarity.COMMON) {
|
||||
|
|
@ -296,6 +309,7 @@ public abstract class CardRenderer {
|
|||
5, 5);
|
||||
g.setColor(getRarityColor());
|
||||
g.drawString(code, x + w - setSymbolWidth, y + h - 3);
|
||||
*/
|
||||
} else {
|
||||
// Draw the set symbol
|
||||
int height = setSymbol.getHeight(null);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import java.util.Collection;
|
|||
import java.util.List;
|
||||
import javax.swing.ImageIcon;
|
||||
import mage.ObjectColor;
|
||||
import mage.client.dialog.PreferencesDialog;
|
||||
import mage.constants.CardType;
|
||||
import mage.view.CardView;
|
||||
import mage.view.PermanentView;
|
||||
|
|
@ -444,10 +445,14 @@ public class ModernCardRenderer extends CardRenderer {
|
|||
protected void drawTypeLine(Graphics2D g, int x, int y, int w, int h) {
|
||||
// Draw expansion symbol
|
||||
int expansionSymbolWidth;
|
||||
if (cardView.isAbility()) {
|
||||
expansionSymbolWidth = 0;
|
||||
if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_RENDERING_SET_SYMBOL, "false").equals("false")) {
|
||||
if (cardView.isAbility()) {
|
||||
expansionSymbolWidth = 0;
|
||||
} else {
|
||||
expansionSymbolWidth = drawExpansionSymbol(g, x, y, w, h);
|
||||
}
|
||||
} else {
|
||||
expansionSymbolWidth = drawExpansionSymbol(g, x, y, w, h);
|
||||
expansionSymbolWidth = 0;
|
||||
}
|
||||
|
||||
// Draw type line text
|
||||
|
|
@ -518,8 +523,10 @@ public class ModernCardRenderer extends CardRenderer {
|
|||
curY -= boxHeight;
|
||||
}
|
||||
|
||||
// Is it a walker?
|
||||
if (cardView.getCardTypes().contains(CardType.PLANESWALKER)) {
|
||||
// Is it a walker? (But don't draw the box if it's a non-permanent view
|
||||
// of a walker without a starting loyalty (EG: Arlin Kord's flipped side).
|
||||
if (cardView.getCardTypes().contains(CardType.PLANESWALKER)
|
||||
&& (cardView instanceof PermanentView || !cardView.getStartingLoyalty().equals("0"))) {
|
||||
// Draw the PW loyalty box
|
||||
int w = partWidth;
|
||||
int h = partWidth/2;
|
||||
|
|
@ -638,23 +645,36 @@ public class ModernCardRenderer extends CardRenderer {
|
|||
AttributedString attributed = rule.generateAttributedString(font, fontItalic);
|
||||
attributedRules.add(attributed);
|
||||
}
|
||||
|
||||
// Get the new spacing for the small text
|
||||
remaining = h;
|
||||
if (hasKeywords) {
|
||||
remaining -= drawSingleRule(g, keywordRulesAttributed, null, 0, 0, w, remaining, false);
|
||||
}
|
||||
for (TextboxRule rule: textboxRules) {
|
||||
AttributedString attributed = rule.generateAttributedString(font, fontItalic);
|
||||
attributedRules.add(attributed);
|
||||
remaining -= drawSingleRule(g, attributed, rule, 0, 0, w, remaining, false);
|
||||
if (remaining < 0) {
|
||||
useSmallFont = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do we have room for additional spacing between the parts of text?
|
||||
// If so, calculate the spacing based on how much space was left over
|
||||
int spacing;
|
||||
if (useSmallFont) {
|
||||
spacing = 0;
|
||||
} else {
|
||||
spacing = (int)(remaining / (hasKeywords ? (textboxRules.size() + 2) : (textboxRules.size() + 1)));
|
||||
}
|
||||
int spacing =
|
||||
(int)(remaining / (hasKeywords ?
|
||||
(textboxRules.size() + 2) :
|
||||
(textboxRules.size() + 1)));
|
||||
|
||||
// Do the actual draw
|
||||
loyaltyAbilityColorToggle = false;
|
||||
g.setColor(Color.black);
|
||||
int curY = y + spacing;
|
||||
if (hasKeywords) {
|
||||
int adv = drawSingleRule(g, keywordRulesAttributed, null, x, y, w, h, true);
|
||||
int adv = drawSingleRule(g, keywordRulesAttributed, null, x, curY, w, h, true);
|
||||
curY += adv + spacing;
|
||||
h -= adv;
|
||||
}
|
||||
|
|
@ -685,7 +705,7 @@ public class ModernCardRenderer extends CardRenderer {
|
|||
// Draw a single rule and returns the amount vertically advanced by, but
|
||||
// only if doDraw is true. If doDraw is false, just returns the vertical
|
||||
// advance if the rule were to be drawn.
|
||||
private int drawSingleRule(Graphics2D g, AttributedString text, TextboxRule rule, int x, int y, int w, int h, boolean doDraw) {
|
||||
private int drawSingleRule(Graphics2D g, AttributedString text, TextboxRule rule, int x, int y, int w, int h, boolean doDraw) {
|
||||
// Inset, in case we are a leveler or loyalty ability
|
||||
int inset = 0;
|
||||
if (rule != null && rule.type == TextboxRuleType.LOYALTY) {
|
||||
|
|
|
|||
|
|
@ -37,12 +37,7 @@ public class TextboxRuleParser {
|
|||
// if the ability is a loyalty ability, and returning an TextboxRule
|
||||
// representing that information, which can be used to render the rule in
|
||||
// the textbox of a card.
|
||||
public static TextboxRule parse(CardView source, String rule) {
|
||||
// Kill reminder text
|
||||
if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_RENDERING_REMINDER_TEXT, "false").equals("false")) {
|
||||
rule = CardRendererUtils.killReminderText(rule);
|
||||
}
|
||||
|
||||
public static TextboxRule parse(CardView source, String rule) {
|
||||
// List of regions to apply
|
||||
ArrayList<TextboxRule.AttributeRegion> regions = new ArrayList<>();
|
||||
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ public class Token extends MageObjectImpl {
|
|||
} else {
|
||||
MageObject object = game.getObject(sourceId);
|
||||
if (object instanceof PermanentToken) {
|
||||
((PermanentToken) object).getExpansionSetCode();
|
||||
setCode = ((PermanentToken) object).getExpansionSetCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue