Merge pull request #5991 from Jetz72/fixes20240825

Translation support for functional variants
This commit is contained in:
kevlahnota
2024-08-27 12:43:35 +08:00
committed by GitHub
22 changed files with 282 additions and 99 deletions

View File

@@ -156,6 +156,9 @@ final class CardFace implements ICardFace, Cloneable {
return null;
return this.functionalVariants.get(variant);
}
@Override public Map<String, ? extends ICardFace> getFunctionalVariants() {
return this.functionalVariants;
}
CardFace getOrCreateFunctionalVariant(String variant) {
if (this.functionalVariants == null) {
this.functionalVariants = new HashMap<>();

View File

@@ -334,6 +334,17 @@ public final class CardRulesPredicates {
if (face == null) {
return false;
}
if (face.hasFunctionalVariants()) {
for (Map.Entry<String, ? extends ICardFace> v : face.getFunctionalVariants().entrySet()) {
//Not a very pretty implementation, but an ICardFace doesn't have a specific variant, so they all need to be checked.
String origOracle = v.getValue().getOracleText();
if(op(origOracle, operand))
return true;
String name = v.getValue().getName() + " $" + v.getKey();
if(op(CardTranslation.getTranslatedOracle(name), operand))
return true;
}
}
if (op(face.getOracleText(), operand) || op(CardTranslation.getTranslatedOracle(face.getName()), operand)) {
return true;
}
@@ -343,6 +354,16 @@ public final class CardRulesPredicates {
if (face == null) {
return false;
}
if (face.hasFunctionalVariants()) {
for (Map.Entry<String, ? extends ICardFace> v : face.getFunctionalVariants().entrySet()) {
String origType = v.getValue().getType().toString();
if(op(origType, operand))
return true;
String name = v.getValue().getName() + " $" + v.getKey();
if(op(CardTranslation.getTranslatedType(name, origType), operand))
return true;
}
}
return (op(CardTranslation.getTranslatedType(face.getName(), face.getType().toString()), operand) || op(face.getType().toString(), operand));
}

View File

@@ -1,5 +1,7 @@
package forge.card;
import java.util.Map;
/**
* TODO: Write javadoc for this type.
*
@@ -9,4 +11,5 @@ public interface ICardFace extends ICardCharacteristics, ICardRawAbilites, Compa
boolean hasFunctionalVariants();
ICardFace getFunctionalVariant(String variant);
Map<String, ? extends ICardFace> getFunctionalVariants();
}

View File

@@ -253,5 +253,22 @@ public interface IPaperCard extends InventoryItem, Serializable {
String getCardRSpecImageKey();
String getCardGSpecImageKey();
public boolean isRebalanced();
boolean isRebalanced();
@Override
default String getTranslationKey() {
if(!NO_FUNCTIONAL_VARIANT.equals(getFunctionalVariant()))
return getName() + " $" + getFunctionalVariant();
return getName();
}
@Override
default String getUntranslatedType() {
return getRules().getType().toString();
}
@Override
default String getUntranslatedOracle() {
return getRules().getOracleText();
}
}

View File

@@ -17,13 +17,18 @@
*/
package forge.item;
import forge.util.IHasName;
import forge.util.ITranslatable;
/**
* Interface to define a player's inventory may hold. Should include
* CardPrinted, Booster, Pets, Plants... etc
*/
public interface InventoryItem extends IHasName {
public interface InventoryItem extends ITranslatable {
String getItemType();
String getImageKey(boolean altState);
@Override
default String getUntranslatedType() {
return getItemType();
}
}

View File

@@ -28,6 +28,15 @@ public class CardTranslation {
for (String line : translationFile.readLines()) {
String[] matches = line.split("\\|");
if (matches.length >= 2) {
if (matches[0].indexOf('$') > 0) {
//Functional variant, e.g. "Garbage Elemental $C"
String[] variantSplit = matches[0].split("\\s*\\$", 2);
if(variantSplit.length > 1) {
//Add the base name to the translated names.
translatednames.put(variantSplit[0], matches[1]);
matches[0] = variantSplit[0] + " $" + variantSplit[1]; //Standardize storage.
}
}
translatednames.put(matches[0], matches[1]);
}
if (matches.length >= 3) {
@@ -53,7 +62,7 @@ public class CardTranslation {
if (name.contains(" // ")) {
int splitIndex = name.indexOf(" // ");
String leftname = name.substring(0, splitIndex);
String rightname = name.substring(splitIndex + 4, name.length());
String rightname = name.substring(splitIndex + 4);
return translatednames.getOrDefault(leftname, leftname) + " // " + translatednames.getOrDefault(rightname, rightname);
}
try {
@@ -74,6 +83,10 @@ public class CardTranslation {
return name;
}
public static String getTranslatedName(ITranslatable card) {
return getTranslatedName(card.getUntranslatedName());
}
private static String translateTokenName(String name) {
if (translatedTokenNames == null)
translatedTokenNames = new HashMap<>();
@@ -203,6 +216,12 @@ public class CardTranslation {
return originaltype;
}
public static String getTranslatedType(ITranslatable item) {
if (!needsTranslation())
return item.getUntranslatedType();
return translatedtypes.getOrDefault(item.getTranslationKey(), item.getUntranslatedType());
}
public static String getTranslatedOracle(String name) {
if (needsTranslation()) {
String toracle = translatedoracles.get(name);
@@ -212,13 +231,30 @@ public class CardTranslation {
return "";
}
public static HashMap<String, String> getTranslationTexts(String cardname, String altcardname) {
if (!needsTranslation()) return null;
public static String getTranslatedOracle(ITranslatable card) {
if(!needsTranslation())
return ""; //card.getUntranslatedOracle();
//Fallbacks and english versions of oracle texts are handled elsewhere.
return translatedoracles.getOrDefault(card.getTranslationKey(), "");
}
public static HashMap<String, String> getTranslationTexts(ITranslatable card) {
return getTranslationTexts(card, null);
}
public static HashMap<String, String> getTranslationTexts(ITranslatable cardMain, ITranslatable cardOther) {
if(!needsTranslation()) return null;
HashMap<String, String> translations = new HashMap<>();
translations.put("name", getTranslatedName(cardname));
translations.put("oracle", getTranslatedOracle(cardname));
translations.put("altname", getTranslatedName(altcardname));
translations.put("altoracle", getTranslatedOracle(altcardname));
translations.put("name", getTranslatedName(cardMain));
translations.put("oracle", getTranslatedOracle(cardMain));
if(cardOther == null) {
translations.put("altname", "");
translations.put("altoracle", "");
}
else {
translations.put("altname", getTranslatedName(cardOther));
translations.put("altoracle", getTranslatedOracle(cardOther));
}
return translations;
}
@@ -248,14 +284,17 @@ public class CardTranslation {
return result;
}
public static void buildOracleMapping(String faceName, String oracleText) {
if (!needsTranslation() || oracleMappings.containsKey(faceName)) return;
String translatedText = getTranslatedOracle(faceName);
public static void buildOracleMapping(String faceName, String oracleText, String variantName) {
String translationKey = faceName;
if(variantName != null)
translationKey = faceName + " $" + variantName;
if (!needsTranslation() || oracleMappings.containsKey(translationKey)) return;
String translatedText = getTranslatedOracle(translationKey);
if (translatedText.isEmpty()) {
// english card only, fall back
return;
}
String translatedName = getTranslatedName(faceName);
String translatedName = getTranslatedName(translationKey);
List <Pair <String, String> > mapping = new ArrayList<>();
String [] splitOracleText = oracleText.split("\\\\n");
String [] splitTranslatedText = translatedText.split("\r\n\r\n");
@@ -269,17 +308,17 @@ public class CardTranslation {
}
mapping.add(Pair.of(toracle, ttranslated));
}
oracleMappings.put(faceName, mapping);
oracleMappings.put(translationKey, mapping);
}
public static String translateMultipleDescriptionText(String descText, String cardName) {
public static String translateMultipleDescriptionText(String descText, ITranslatable card) {
if (!needsTranslation()) return descText;
String [] splitDescText = descText.split("\n");
String result = descText;
for (String text : splitDescText) {
text = text.trim();
if (text.isEmpty()) continue;
String translated = translateSingleDescriptionText(text, cardName);
String translated = translateSingleDescriptionText(text, card);
if (!text.equals(translated)) {
result = TextUtil.fastReplace(result, text, translated);
} else {
@@ -288,7 +327,7 @@ public class CardTranslation {
if (splitKeywords.length <= 1) continue;
for (String keyword : splitKeywords) {
if (keyword.contains(" ")) continue;
translated = translateSingleDescriptionText(keyword, cardName);
translated = translateSingleDescriptionText(keyword, card);
if (!keyword.equals(translated)) {
result = TextUtil.fastReplace(result, keyword, translated);
}
@@ -298,13 +337,13 @@ public class CardTranslation {
return result;
}
public static String translateSingleDescriptionText(String descText, String cardName) {
public static String translateSingleDescriptionText(String descText, ITranslatable card) {
if (descText == null)
return "";
if (!needsTranslation()) return descText;
if (translatedCaches.containsKey(descText)) return translatedCaches.get(descText);
List <Pair <String, String> > mapping = oracleMappings.get(cardName);
List <Pair <String, String> > mapping = oracleMappings.get(card.getTranslationKey());
if (mapping == null) return descText;
String result = descText;
if (!mapping.isEmpty()) {

View File

@@ -0,0 +1,22 @@
package forge.util;
public interface ITranslatable extends IHasName {
default String getTranslationKey() {
return getName();
}
//Fallback methods - used if no translation is found for the given key.
default String getUntranslatedName() {
return getName();
}
default String getUntranslatedType() {
return "";
}
default String getUntranslatedOracle() {
return "";
}
}

View File

@@ -82,8 +82,7 @@ public abstract class SpellAbilityEffect {
if (params.containsKey("SpellDescription")) {
if (rawSDesc.contains(",,,,,,")) rawSDesc = rawSDesc.replaceAll(",,,,,,", " ");
if (rawSDesc.contains(",,,")) rawSDesc = rawSDesc.replaceAll(",,,", " ");
String spellDesc = CardTranslation.translateSingleDescriptionText(rawSDesc,
sa.getHostCard().getName());
String spellDesc = CardTranslation.translateSingleDescriptionText(rawSDesc, sa.getHostCard());
//trim reminder text from StackDesc
int idxL = spellDesc.indexOf(" (");
@@ -113,7 +112,7 @@ public abstract class SpellAbilityEffect {
} else {
final String condDesc = sa.getParam("ConditionDescription");
final String afterDesc = sa.getParam("AfterDescription");
final String baseDesc = CardTranslation.translateSingleDescriptionText(this.getStackDescription(sa), sa.getHostCard().getName());
final String baseDesc = CardTranslation.translateSingleDescriptionText(this.getStackDescription(sa), sa.getHostCard());
if (condDesc != null) {
sb.append(condDesc).append(" ");
}

View File

@@ -76,7 +76,7 @@ import java.util.Map.Entry;
* @author Forge
* @version $Id$
*/
public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITranslatable {
private Game game;
private final IPaperCard paperCard;
@@ -2227,7 +2227,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
sbLong.append("\r\n");
}
sb.append(sbLong);
return CardTranslation.translateMultipleDescriptionText(sb.toString(), getName());
return CardTranslation.translateMultipleDescriptionText(sb.toString(), this);
}
// convert a keyword list to the String that should be displayed in game
@@ -2632,7 +2632,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
sbLong.append("\r\n");
}
sb.append(sbLong);
return CardTranslation.translateMultipleDescriptionText(sb.toString(), getName());
return CardTranslation.translateMultipleDescriptionText(sb.toString(), this);
}
private String kickerDesc(String keyword, String remText) {
@@ -3194,7 +3194,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
}
}
sb.append(CardTranslation.translateMultipleDescriptionText(sbBefore.toString(), state.getName()));
sb.append(CardTranslation.translateMultipleDescriptionText(sbBefore.toString(), state));
// add Spells there to main StringBuilder
sb.append(strSpell);
@@ -3223,7 +3223,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
}
}
sb.append(CardTranslation.translateMultipleDescriptionText(sbAfter.toString(), state.getName()));
sb.append(CardTranslation.translateMultipleDescriptionText(sbAfter.toString(), state));
return sb;
}
@@ -3553,8 +3553,10 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
public final void setCopiedPermanent(final Card c) {
if (copiedPermanent == c) { return; }
copiedPermanent = c;
if(c != null)
if(c != null) {
currentState.setOracleText(c.getOracleText());
currentState.setFunctionalVariantName(c.getCurrentState().getFunctionalVariantName());
}
//Could fetch the card rules oracle text in an "else" clause here,
//but CardRules isn't aware of the card's state. May be better to
//just stash the original oracle text if this comes up.
@@ -7560,6 +7562,23 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
currentState.setOracleText(oracleText);
}
@Override
public String getTranslationKey() {
return currentState.getTranslationKey();
}
@Override
public String getUntranslatedName() {
return this.getName();
}
@Override
public String getUntranslatedType() {
return currentState.getUntranslatedType();
}
@Override
public String getUntranslatedOracle() {
return currentState.getUntranslatedOracle();
}
@Override
public CardView getView() {
return view;

View File

@@ -355,13 +355,16 @@ public class CardFactory {
}
private static void readCardFace(Card c, ICardFace face) {
String variantName = null;
//If it's a functional variant card, switch to that first.
if(face.hasFunctionalVariants()) {
String variantName = c.getPaperCard().getFunctionalVariant();
variantName = c.getPaperCard().getFunctionalVariant();
if (!IPaperCard.NO_FUNCTIONAL_VARIANT.equals(variantName)) {
ICardFace variant = face.getFunctionalVariant(variantName);
if (variant != null)
if (variant != null) {
face = variant;
c.getCurrentState().setFunctionalVariantName(variantName);
}
else
System.err.printf("Tried to apply unknown or unsupported variant - Card: \"%s\"; Variant: %s\n", face.getName(), variantName);
}
@@ -369,7 +372,7 @@ public class CardFactory {
// Build English oracle and translated oracle mapping
if (c.getId() >= 0) {
CardTranslation.buildOracleMapping(face.getName(), face.getOracleText());
CardTranslation.buildOracleMapping(face.getName(), face.getOracleText(), variantName);
}
// Name first so Senty has the Card name

View File

@@ -47,17 +47,20 @@ import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityPredicates;
import forge.game.staticability.StaticAbility;
import forge.game.trigger.Trigger;
import forge.util.ITranslatable;
import forge.util.collect.FCollection;
import forge.util.collect.FCollectionView;
import io.sentry.Breadcrumb;
import io.sentry.Sentry;
import org.apache.commons.lang3.StringUtils;
public class CardState extends GameObject implements IHasSVars {
public class CardState extends GameObject implements IHasSVars, ITranslatable {
private String name = "";
private CardType type = new CardType(false);
private ManaCost manaCost = ManaCost.NO_COST;
private byte color = MagicColor.COLORLESS;
private String oracleText = "";
private String functionalVariantName = null;
private int basePower = 0;
private int baseToughness = 0;
private String basePowerString = null;
@@ -202,6 +205,16 @@ public class CardState extends GameObject implements IHasSVars {
view.setOracleText(oracleText);
}
public String getFunctionalVariantName() {
return functionalVariantName;
}
public void setFunctionalVariantName(String functionalVariantName) {
if(functionalVariantName != null && functionalVariantName.isEmpty())
functionalVariantName = null;
this.functionalVariantName = functionalVariantName;
view.setFunctionalVariantName(functionalVariantName);
}
public final int getBasePower() {
return basePower;
@@ -605,6 +618,7 @@ public class CardState extends GameObject implements IHasSVars {
setManaCost(source.getManaCost());
setColor(source.getColor());
setOracleText(source.getOracleText());
setFunctionalVariantName(source.getFunctionalVariantName());
setBasePower(source.getBasePower());
setBaseToughness(source.getBaseToughness());
setBaseLoyalty(source.getBaseLoyalty());
@@ -804,4 +818,21 @@ public class CardState extends GameObject implements IHasSVars {
}
return cloakUp;
}
@Override
public String getTranslationKey() {
if(StringUtils.isNotEmpty(functionalVariantName))
return name + " $" + functionalVariantName;
return name;
}
@Override
public String getUntranslatedType() {
return getType().toString();
}
@Override
public String getUntranslatedOracle() {
return getOracleText();
}
}

View File

@@ -22,10 +22,7 @@ import forge.trackable.TrackableCollection;
import forge.trackable.TrackableObject;
import forge.trackable.TrackableProperty;
import forge.trackable.Tracker;
import forge.util.CardTranslation;
import forge.util.Lang;
import forge.util.Localizer;
import forge.util.TextUtil;
import forge.util.*;
import forge.util.collect.FCollectionView;
import org.apache.commons.lang3.StringUtils;
@@ -1165,7 +1162,7 @@ public class CardView extends GameEntityView {
return (zone + ' ' + CardTranslation.getTranslatedName(name) + " (" + getId() + ")").trim();
}
public class CardStateView extends TrackableObject {
public class CardStateView extends TrackableObject implements ITranslatable {
private static final long serialVersionUID = 6673944200513430607L;
private final CardStateName state;
@@ -1318,6 +1315,13 @@ public class CardView extends GameEntityView {
set(TrackableProperty.OracleText, oracleText.replace("\\n", "\r\n\r\n").trim());
}
public String getFunctionalVariantName() {
return get(TrackableProperty.FunctionalVariant);
}
void setFunctionalVariantName(String functionalVariant) {
set(TrackableProperty.FunctionalVariant, functionalVariant);
}
public String getRulesText() {
return get(TrackableProperty.RulesText);
}
@@ -1741,6 +1745,25 @@ public class CardView extends GameEntityView {
public boolean isAttraction() {
return getType().isAttraction();
}
@Override
public String getTranslationKey() {
String key = getName();
String variant = getFunctionalVariantName();
if(StringUtils.isNotEmpty(variant))
key = key + " $" + variant;
return key;
}
@Override
public String getUntranslatedType() {
return getType().toString();
}
@Override
public String getUntranslatedOracle() {
return getOracleText();
}
}
//special methods for updating card and player properties as needed and returning the new collection

View File

@@ -23,6 +23,7 @@ import java.util.Objects;
import com.google.common.collect.*;
import forge.util.ITranslatable;
import org.apache.commons.lang3.StringUtils;
import forge.game.Game;
@@ -221,15 +222,16 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
public String getDescription() {
if (hasParam("Description") && !this.isSuppressed()) {
String desc = AbilityUtils.applyDescriptionTextChangeEffects(getParam("Description"), this);
String currentName;
ITranslatable nameSource;
if (this.isIntrinsic() && cardState != null && cardState.getCard() == getHostCard()) {
currentName = cardState.getName();
nameSource = cardState;
} else {
currentName = getHostCard().getName();
nameSource = getHostCard();
}
desc = CardTranslation.translateSingleDescriptionText(desc, currentName);
desc = TextUtil.fastReplace(desc, "CARDNAME", CardTranslation.getTranslatedName(currentName));
desc = TextUtil.fastReplace(desc, "NICKNAME", Lang.getInstance().getNickName(CardTranslation.getTranslatedName(currentName)));
desc = CardTranslation.translateMultipleDescriptionText(desc, nameSource);
String translatedName = CardTranslation.getTranslatedName(nameSource);
desc = TextUtil.fastReplace(desc, "CARDNAME", translatedName);
desc = TextUtil.fastReplace(desc, "NICKNAME", Lang.getInstance().getNickName(translatedName));
if (desc.contains("EFFECTSOURCE")) {
desc = TextUtil.fastReplace(desc, "EFFECTSOURCE", getHostCard().getEffectSource().toString());
}

View File

@@ -20,6 +20,7 @@ package forge.game.spellability;
import java.util.*;
import forge.game.cost.CostSacrifice;
import forge.util.*;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
@@ -68,11 +69,6 @@ import forge.game.staticability.StaticAbilityMustTarget;
import forge.game.trigger.Trigger;
import forge.game.trigger.TriggerType;
import forge.game.zone.ZoneType;
import forge.util.Aggregates;
import forge.util.CardTranslation;
import forge.util.Lang;
import forge.util.Localizer;
import forge.util.TextUtil;
//only SpellAbility can go on the stack
//override any methods as needed
@@ -988,16 +984,17 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
}
String desc = node.getDescription();
if (node.getHostCard() != null) {
String currentName;
ITranslatable nameSource;
// if alternate state is viewed while card uses original
if (node.isIntrinsic() && node.cardState != null && node.cardState.getCard() == node.getHostCard()) {
currentName = node.cardState.getName();
nameSource = node.cardState;
} else {
currentName = node.getHostCard().getName();
nameSource = node.getHostCard();
}
desc = CardTranslation.translateMultipleDescriptionText(desc, currentName);
desc = TextUtil.fastReplace(desc, "CARDNAME", CardTranslation.getTranslatedName(currentName));
desc = TextUtil.fastReplace(desc, "NICKNAME", Lang.getInstance().getNickName(CardTranslation.getTranslatedName(currentName)));
desc = CardTranslation.translateMultipleDescriptionText(desc, nameSource);
String translatedName = CardTranslation.getTranslatedName(nameSource);
desc = TextUtil.fastReplace(desc, "CARDNAME", translatedName);
desc = TextUtil.fastReplace(desc, "NICKNAME", Lang.getInstance().getNickName(translatedName));
if (node.getOriginalHost() != null) {
desc = TextUtil.fastReplace(desc, "ORIGINALHOST", node.getOriginalHost().getName());
}

View File

@@ -45,11 +45,7 @@ import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.zone.Zone;
import forge.game.zone.ZoneType;
import forge.util.CardTranslation;
import forge.util.Expressions;
import forge.util.FileSection;
import forge.util.Lang;
import forge.util.TextUtil;
import forge.util.*;
/**
* The Class StaticAbility.
@@ -187,15 +183,16 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
@Override
public final String toString() {
if (hasParam("Description") && !this.isSuppressed()) {
String currentName;
ITranslatable nameSource;
if (this.isIntrinsic() && cardState != null && cardState.getCard() == getHostCard()) {
currentName = cardState.getName();
nameSource = cardState;
} else {
currentName = getHostCard().getName();
nameSource = getHostCard();
}
String desc = CardTranslation.translateSingleDescriptionText(getParam("Description"), currentName);
desc = TextUtil.fastReplace(desc, "CARDNAME", CardTranslation.getTranslatedName(currentName));
desc = TextUtil.fastReplace(desc, "NICKNAME", Lang.getInstance().getNickName(CardTranslation.getTranslatedName(currentName)));
String desc = CardTranslation.translateSingleDescriptionText(getParam("Description"), nameSource);
String translatedName = CardTranslation.getTranslatedName(nameSource);
desc = TextUtil.fastReplace(desc, "CARDNAME", translatedName);
desc = TextUtil.fastReplace(desc, "NICKNAME", Lang.getInstance().getNickName(translatedName));
return desc;
} else {

View File

@@ -36,6 +36,7 @@ import forge.game.spellability.SpellAbility;
import forge.game.zone.CostPaymentStack;
import forge.game.zone.ZoneType;
import forge.util.CardTranslation;
import forge.util.ITranslatable;
import forge.util.Lang;
import forge.util.TextUtil;
@@ -119,17 +120,18 @@ public abstract class Trigger extends TriggerReplacementBase {
public String toString(boolean active) {
if (hasParam("TriggerDescription") && !this.isSuppressed()) {
StringBuilder sb = new StringBuilder();
String currentName;
ITranslatable nameSource;
if (this.isIntrinsic() && cardState != null && cardState.getCard() == getHostCard()) {
currentName = cardState.getName();
nameSource = cardState;
} else {
currentName = getHostCard().getName();
nameSource = getHostCard();
}
String desc = getParam("TriggerDescription");
if (!desc.contains("ABILITY")) {
desc = CardTranslation.translateSingleDescriptionText(getParam("TriggerDescription"), currentName);
desc = TextUtil.fastReplace(desc,"CARDNAME", CardTranslation.getTranslatedName(currentName));
desc = TextUtil.fastReplace(desc,"NICKNAME", Lang.getInstance().getNickName(CardTranslation.getTranslatedName(currentName)));
desc = CardTranslation.translateSingleDescriptionText(getParam("TriggerDescription"), nameSource);
String translatedName = CardTranslation.getTranslatedName(nameSource);
desc = TextUtil.fastReplace(desc,"CARDNAME", translatedName);
desc = TextUtil.fastReplace(desc,"NICKNAME", Lang.getInstance().getNickName(translatedName));
if (desc.contains("ORIGINALHOST") && this.getOriginalHost() != null) {
desc = TextUtil.fastReplace(desc, "ORIGINALHOST", this.getOriginalHost().getName());
}
@@ -220,10 +222,10 @@ public abstract class Trigger extends TriggerReplacementBase {
}
result = TextUtil.fastReplace(result, "ABILITY", saDesc);
String currentName = sa.getHostCard().getName();
result = CardTranslation.translateMultipleDescriptionText(result, currentName);
result = TextUtil.fastReplace(result,"CARDNAME", CardTranslation.getTranslatedName(currentName));
result = TextUtil.fastReplace(result,"NICKNAME", Lang.getInstance().getNickName(CardTranslation.getTranslatedName(currentName)));
result = CardTranslation.translateMultipleDescriptionText(result, sa.getHostCard());
String translatedName = CardTranslation.getTranslatedName(sa.getHostCard());
result = TextUtil.fastReplace(result,"CARDNAME", translatedName);
result = TextUtil.fastReplace(result,"NICKNAME", Lang.getInstance().getNickName(translatedName));
}
return result;

View File

@@ -123,6 +123,7 @@ public enum TrackableProperty {
ManaCost(TrackableTypes.ManaCostType),
SetCode(TrackableTypes.StringType),
Rarity(TrackableTypes.EnumType(CardRarity.class)),
FunctionalVariant(TrackableTypes.StringType),
OracleText(TrackableTypes.StringType),
RulesText(TrackableTypes.StringType),
Power(TrackableTypes.IntegerType),

View File

@@ -203,9 +203,9 @@ public class FCardImageRenderer {
if (card.isSplitCard()) {
boolean needTranslation = !"en-US".equals(FModel.getPreferences().getPref(FPref.UI_LANGUAGE));
final CardStateView leftState = card.getLeftSplitState();
final String leftText = needTranslation ? CardTranslation.getTranslatedOracle(leftState.getName()) : leftState.getOracleText();
final String leftText = needTranslation ? CardTranslation.getTranslatedOracle(leftState) : leftState.getOracleText();
final CardStateView rightState = card.getRightSplitState();
String rightText = needTranslation ? CardTranslation.getTranslatedOracle(rightState.getName()) : rightState.getOracleText();
String rightText = needTranslation ? CardTranslation.getTranslatedOracle(rightState) : rightState.getOracleText();
boolean isAftermath = (rightState.getKeywordKey().contains("Aftermath"));
BufferedImage leftArt = null;
BufferedImage rightArt = null;
@@ -247,9 +247,9 @@ public class FCardImageRenderer {
} else if (card.isFlipCard()) {
boolean needTranslation = !card.isToken() || !(card.getCloneOrigin() == null);
final CardStateView state = card.getState(false);
final String text = card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(state.getName(), "") : null);
final String text = card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(state) : null);
final CardStateView flipState = card.getState(true);
final String flipText = card.getText(flipState, needTranslation ? CardTranslation.getTranslationTexts(flipState.getName(), "") : null);
final String flipText = card.getText(flipState, needTranslation ? CardTranslation.getTranslationTexts(flipState) : null);
CARD_ART_RATIO = 1.728f;
updateAreaSizes(ratio, ratio);
int heightAdjust = OUTER_BORDER_THICKNESS + PT_SIZE / 2;
@@ -261,16 +261,16 @@ public class FCardImageRenderer {
} else if (card.isAdventureCard()) {
boolean needTranslation = !card.isToken() || !(card.getCloneOrigin() == null);
final CardStateView state = card.getState(false);
final String text = card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(state.getName(), "") : null);
final String text = card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(state) : null);
final CardStateView advState = card.getState(true);
final String advText = card.getText(advState, needTranslation ? CardTranslation.getTranslationTexts(advState.getName(), "") : null);
final String advText = card.getText(advState, needTranslation ? CardTranslation.getTranslationTexts(advState) : null);
CARD_ART_RATIO = 1.37f;
updateAreaSizes(ratio, ratio);
drawAdvCardImage(g, state, text, advState, advText, width, height, art);
} else {
boolean needTranslation = !card.isToken() || !(card.getCloneOrigin() == null);
final CardStateView state = card.getState(altState);
final String text = card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(state.getName(), "") : null);
final String text = card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(state) : null);
CARD_ART_RATIO = 1.37f;
if (art != null && Math.abs((float)art.getWidth() / (float)art.getHeight() - CARD_ART_RATIO) > 0.1f) {
CARD_ART_RATIO = (float)art.getWidth() / (float)art.getHeight();

View File

@@ -670,12 +670,13 @@ public class CardImageRenderer {
CardView cv = card.getBackup();
if (cv == null || isFaceDown)
cv = card;
text = cv.getText(cv.getState(true), needTranslation ? CardTranslation.getTranslationTexts(cv.getName(), "") : null);
CardStateView csv = cv.getState(true);
text = cv.getText(csv, needTranslation ? CardTranslation.getTranslationTexts(csv) : null);
} else {
text = !card.isSplitCard() ?
card.getText(state, needTranslation ? state == null ? null : CardTranslation.getTranslationTexts(state.getName(), "") : null) :
card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(card.getLeftSplitState().getName(), card.getRightSplitState().getName()) : null);
card.getText(state, needTranslation ? state == null ? null : CardTranslation.getTranslationTexts(state) : null) :
card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(card.getLeftSplitState(), card.getRightSplitState()) : null);
}
} else {
if (noText)
@@ -684,12 +685,13 @@ public class CardImageRenderer {
CardView cv = card.getBackup();
if (cv == null || isFaceDown)
cv = card;
text = cv.getText(cv.getState(false), needTranslation ? CardTranslation.getTranslationTexts(cv.getName(), "") : null);
CardStateView csv = cv.getState(false);
text = cv.getText(csv, needTranslation ? CardTranslation.getTranslationTexts(csv) : null);
} else {
text = !card.isSplitCard() ?
card.getText(state, needTranslation ? state == null ? null : CardTranslation.getTranslationTexts(state.getName(), "") : null) :
card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(card.getLeftSplitState().getName(), card.getRightSplitState().getName()) : null);
card.getText(state, needTranslation ? state == null ? null : CardTranslation.getTranslationTexts(state) : null) :
card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(card.getLeftSplitState(), card.getRightSplitState()) : null);
}
}
if (StringUtils.isEmpty(text)) {

View File

@@ -178,7 +178,7 @@ public class CardDetailUtil {
public static String formatCardType(final CardStateView card, final boolean canShow) {
boolean isInPlay = card.getCard() != null && ZoneType.Battlefield.equals(card.getCard().getZone());
String translatedtype = CardTranslation.getTranslatedType(card.getName(), card.getType().toString());
String translatedtype = CardTranslation.getTranslatedType(card);
return canShow ? translatedtype : (card.getState() == CardStateName.FaceDown && isInPlay ? "Creature" : "");
}
@@ -319,8 +319,8 @@ public class CardDetailUtil {
needTranslation = false;
}
String text = !card.isSplitCard() ?
card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(state.getName(), "") : null) :
card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(card.getLeftSplitState().getName(), card.getRightSplitState().getName()) : null );
card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(state) : null) :
card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(card.getLeftSplitState(), card.getRightSplitState()) : null );
// Bracket P/T for Level up
if (text.contains("LEVEL")) {

View File

@@ -82,11 +82,12 @@ public class AdvancedSearch {
protected Set<String> getItemValues(PaperCard input) {
Set<String> names = new HashSet<>();
names.add(input.getRules().getOracleText());
names.add(CardTranslation.getTranslatedOracle(input.getName()));
names.add(CardTranslation.getTranslatedOracle(input));
CardSplitType cardSplitType = input.getRules().getSplitType();
if (cardSplitType != CardSplitType.None && cardSplitType != CardSplitType.Split) {
if (input.getRules().getOtherPart() != null) {
names.add(input.getRules().getOtherPart().getOracleText());
//Doesn't support a combination of functional variant + split card, but none of those exist yet.
names.add(CardTranslation.getTranslatedOracle(input.getRules().getOtherPart().getName()));
}
}

View File

@@ -81,8 +81,8 @@ public enum ColumnDef {
* The type column.
*/
TYPE("lblType", "ttType", 100, false, SortState.ASC,
from -> CardTranslation.getTranslatedType(from.getKey().getName(), toType(from.getKey())),
from -> CardTranslation.getTranslatedType(from.getKey().getName(), toType(from.getKey()))),
from -> CardTranslation.getTranslatedType(from.getKey()),
from -> CardTranslation.getTranslatedType(from.getKey())),
/**
* The mana cost column.
*/
@@ -357,10 +357,6 @@ public enum ColumnDef {
return this.longName;
}
private static String toType(final InventoryItem i) {
return i instanceof IPaperCard ? ((IPaperCard) i).getRules().getType().toString() : i.getItemType();
}
private static IPaperCard toCard(final InventoryItem i) {
return i instanceof IPaperCard ? ((IPaperCard) i) : null;
}