mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
Merge pull request #5991 from Jetz72/fixes20240825
Translation support for functional variants
This commit is contained in:
@@ -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<>();
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
22
forge-core/src/main/java/forge/util/ITranslatable.java
Normal file
22
forge-core/src/main/java/forge/util/ITranslatable.java
Normal 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 "";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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(" ");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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")) {
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user