mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
Implement better in-game localization/translation
This commit is contained in:
@@ -87,7 +87,7 @@ public abstract class SpellAbilityEffect {
|
||||
// by typing "SpellDescription" they want to bypass the Effect's string builder
|
||||
if ("SpellDescription".equalsIgnoreCase(stackDesc)) {
|
||||
if (params.get("SpellDescription") != null) {
|
||||
sb.append(params.get("SpellDescription"));
|
||||
sb.append(CardTranslation.translateSingleDescriptionText(params.get("SpellDescription"), sa.getHostCard().getName()));
|
||||
}
|
||||
if (sa.getTargets() != null && !sa.getTargets().isEmpty()) {
|
||||
sb.append(" (Targeting: ").append(sa.getTargets()).append(")");
|
||||
@@ -98,7 +98,7 @@ public abstract class SpellAbilityEffect {
|
||||
} else {
|
||||
final String conditionDesc = sa.getParam("ConditionDescription");
|
||||
final String afterDesc = sa.getParam("AfterDescription");
|
||||
final String baseDesc = this.getStackDescription(sa);
|
||||
final String baseDesc = CardTranslation.translateSingleDescriptionText(this.getStackDescription(sa), sa.getHostCard().getName());
|
||||
if (conditionDesc != null) {
|
||||
sb.append(conditionDesc).append(" ");
|
||||
}
|
||||
@@ -131,8 +131,8 @@ public abstract class SpellAbilityEffect {
|
||||
}
|
||||
|
||||
String currentName = (sa.getHostCard().getName());
|
||||
String substitutedDesc = TextUtil.fastReplace(sb.toString(), "CARDNAME", currentName);
|
||||
substitutedDesc = TextUtil.fastReplace(substitutedDesc, "NICKNAME", currentName.split(",")[0]);
|
||||
String substitutedDesc = TextUtil.fastReplace(sb.toString(), "CARDNAME", CardTranslation.getTranslatedName(currentName));
|
||||
substitutedDesc = TextUtil.fastReplace(substitutedDesc, "NICKNAME", Lang.getInstance().getNickName(CardTranslation.getTranslatedName(currentName)));
|
||||
return substitutedDesc;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package forge.game.ability.effects;
|
||||
|
||||
import forge.game.card.Card;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.util.CardTranslation;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
@@ -13,6 +14,6 @@ public class PermanentNoncreatureEffect extends PermanentEffect {
|
||||
public String getStackDescription(final SpellAbility sa) {
|
||||
final Card sourceCard = sa.getHostCard();
|
||||
//CardView toString return translated name,don't need call CardTranslation.getTranslatedName in this.
|
||||
return sourceCard.getName();
|
||||
return CardTranslation.getTranslatedName(sourceCard.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2081,7 +2081,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
sbLong.append("\r\n");
|
||||
}
|
||||
sb.append(sbLong);
|
||||
return sb.toString();
|
||||
return CardTranslation.translateMultipleDescriptionText(sb.toString(), getName());
|
||||
}
|
||||
|
||||
private static String getTextForKwCantBeBlockedByAmount(final String keyword) {
|
||||
@@ -2119,7 +2119,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
while (result.endsWith("\r\n")) {
|
||||
result = result.substring(0, result.length() - 2);
|
||||
}
|
||||
return TextUtil.fastReplace(result, "CARDNAME", state.getName());
|
||||
return TextUtil.fastReplace(result, "CARDNAME", CardTranslation.getTranslatedName(state.getName()));
|
||||
}
|
||||
|
||||
if (monstrous) {
|
||||
@@ -2140,7 +2140,9 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
for (final ReplacementEffect replacementEffect : state.getReplacementEffects()) {
|
||||
if (!replacementEffect.isSecondary()) {
|
||||
String text = replacementEffect.getDescription();
|
||||
if (text.contains("enters the battlefield")) {
|
||||
// Get original description since text might be translated
|
||||
if (replacementEffect.hasParam("Description") &&
|
||||
replacementEffect.getParam("Description").contains("enters the battlefield")) {
|
||||
sb.append(text).append("\r\n");
|
||||
} else {
|
||||
replacementEffects.append(text).append("\r\n");
|
||||
@@ -2226,8 +2228,10 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
|
||||
// add Adventure to AbilityText
|
||||
if (sa.isAdventure() && state.getView().getState().equals(CardStateName.Original)) {
|
||||
CardState advState = getState(CardStateName.Adventure);
|
||||
StringBuilder sbSA = new StringBuilder();
|
||||
sbSA.append("Adventure — ").append(getState(CardStateName.Adventure).getName());
|
||||
sbSA.append(Localizer.getInstance().getMessage("lblAdventure"));
|
||||
sbSA.append(" — ").append(CardTranslation.getTranslatedName(advState.getName()));
|
||||
sbSA.append(" ").append(sa.getPayCosts().toSimpleString());
|
||||
sbSA.append(": ");
|
||||
sbSA.append(sAbility);
|
||||
@@ -2299,7 +2303,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
start = sb.lastIndexOf(s);
|
||||
}
|
||||
|
||||
String desc = TextUtil.fastReplace(sb.toString(), "CARDNAME", state.getName());
|
||||
String desc = TextUtil.fastReplace(sb.toString(), "CARDNAME", CardTranslation.getTranslatedName(state.getName()));
|
||||
if (getEffectSource() != null) {
|
||||
desc = TextUtil.fastReplace(desc, "EFFECTSOURCE", getEffectSource().getName());
|
||||
}
|
||||
@@ -2485,7 +2489,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
}
|
||||
}
|
||||
|
||||
sb.append(sbBefore);
|
||||
sb.append(CardTranslation.translateMultipleDescriptionText(sbBefore.toString(), state.getName()));
|
||||
|
||||
// add Spells there to main StringBuilder
|
||||
sb.append(strSpell);
|
||||
@@ -2514,13 +2518,13 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
}
|
||||
}
|
||||
|
||||
sb.append(sbAfter);
|
||||
sb.append(CardTranslation.translateMultipleDescriptionText(sbAfter.toString(), state.getName()));
|
||||
return sb;
|
||||
}
|
||||
|
||||
private String formatSpellAbility(final SpellAbility sa) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(sa.toString()).append("\r\n");
|
||||
sb.append(sa.toString()).append("\r\n\r\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import forge.game.trigger.TriggerHandler;
|
||||
import forge.game.trigger.WrappedAbility;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.item.PaperCard;
|
||||
import forge.util.CardTranslation;
|
||||
import forge.util.TextUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -354,6 +355,10 @@ public class CardFactory {
|
||||
}
|
||||
|
||||
private static void readCardFace(Card c, ICardFace face) {
|
||||
// Build English oracle and translated oracle mapping
|
||||
if (c.getId() >= 0) {
|
||||
CardTranslation.buildOracleMapping(face.getName(), face.getOracleText());
|
||||
}
|
||||
|
||||
// Name first so Senty has the Card name
|
||||
c.setName(face.getName());
|
||||
|
||||
@@ -591,14 +591,8 @@ public class CardView extends GameEntityView {
|
||||
if (translationsText != null) {
|
||||
tname = translationsText.get("name");
|
||||
taltname = translationsText.get("altname");
|
||||
|
||||
// TODO: Translate for cloned or mutated cards
|
||||
// For now, don't translate oracles if the card is a cloned or mutated
|
||||
if (((String) get(TrackableProperty.Cloner)).isEmpty() &&
|
||||
((String) get(TrackableProperty.MergedCards)).isEmpty()) {
|
||||
toracle = translationsText.get("oracle");
|
||||
taltoracle = translationsText.get("altoracle");
|
||||
}
|
||||
toracle = translationsText.get("oracle");
|
||||
taltoracle = translationsText.get("altoracle");
|
||||
}
|
||||
|
||||
if (isSplitCard()) {
|
||||
@@ -629,18 +623,7 @@ public class CardView extends GameEntityView {
|
||||
}
|
||||
|
||||
final String rulesText = state.getRulesText();
|
||||
if (!toracle.isEmpty() && !isFaceDown()) {
|
||||
if (isSplitCard()) {
|
||||
sb.append("(").append(tname).append(") ");
|
||||
sb.append(toracle);
|
||||
sb.append("\r\n\r\n");
|
||||
sb.append("(").append(taltname).append(") ");
|
||||
sb.append(taltoracle);
|
||||
} else {
|
||||
sb.append(toracle);
|
||||
}
|
||||
sb.append("\r\n\r\n");
|
||||
} else if (!rulesText.isEmpty()) {
|
||||
if (!rulesText.isEmpty()) {
|
||||
sb.append(rulesText).append("\r\n\r\n");
|
||||
}
|
||||
if (isCommander()) {
|
||||
@@ -648,15 +631,13 @@ public class CardView extends GameEntityView {
|
||||
sb.append(getOwner().getCommanderInfo(this)).append("\r\n");
|
||||
}
|
||||
|
||||
if (toracle.isEmpty()) {
|
||||
if (isSplitCard() && !isFaceDown() && getZone() != ZoneType.Stack) {
|
||||
sb.append("(").append(getLeftSplitState().getName()).append(") ");
|
||||
sb.append(getLeftSplitState().getAbilityText());
|
||||
sb.append("\r\n\r\n").append("(").append(getRightSplitState().getName()).append(") ");
|
||||
sb.append(getRightSplitState().getAbilityText());
|
||||
} else {
|
||||
sb.append(state.getAbilityText());
|
||||
}
|
||||
if (isSplitCard() && !isFaceDown() && getZone() != ZoneType.Stack) {
|
||||
sb.append("(").append(getLeftSplitState().getName()).append(") ");
|
||||
sb.append(getLeftSplitState().getAbilityText());
|
||||
sb.append("\r\n\r\n").append("(").append(getRightSplitState().getName()).append(") ");
|
||||
sb.append(getRightSplitState().getAbilityText());
|
||||
} else {
|
||||
sb.append(state.getAbilityText());
|
||||
}
|
||||
|
||||
String nonAbilityText = get(TrackableProperty.NonAbilityText);
|
||||
@@ -1093,7 +1074,7 @@ public class CardView extends GameEntityView {
|
||||
return get(TrackableProperty.OracleText);
|
||||
}
|
||||
void updateOracleText(Card c) {
|
||||
set(TrackableProperty.OracleText, c.getOracleText().replace("\\n", "\r\n").trim());
|
||||
set(TrackableProperty.OracleText, c.getOracleText().replace("\\n", "\r\n\r\n").trim());
|
||||
}
|
||||
|
||||
public String getRulesText() {
|
||||
|
||||
@@ -27,7 +27,6 @@ import forge.game.spellability.SpellAbility;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.TextUtil;
|
||||
import forge.util.collect.FCollectionView;
|
||||
import forge.util.Localizer;
|
||||
|
||||
/**
|
||||
* The Class CostExile.
|
||||
@@ -89,32 +88,32 @@ public class CostExile extends CostPartWithList {
|
||||
|
||||
if (this.payCostFromSource()) {
|
||||
if (!this.from.equals(ZoneType.Battlefield)) {
|
||||
return Localizer.getInstance().getMessage("lblExileTargetsFromYourZone", this.getType(), this.from.getTranslatedName());
|
||||
return String.format("Exile %s from your %s", this.getType(), this.from.name());
|
||||
}
|
||||
return Localizer.getInstance().getMessage("lblExileTarget", this.getType());
|
||||
return String.format("Exile %s", this.getType());
|
||||
} else if (this.getType().equals("All")) {
|
||||
return Localizer.getInstance().getMessage("lblExileAllCardsFromYourZone", this.from.getTranslatedName());
|
||||
return String.format("Exile all cards from your %s", this.from.name());
|
||||
}
|
||||
|
||||
if (this.from.equals(ZoneType.Battlefield)) {
|
||||
if (!this.payCostFromSource()) {
|
||||
return Localizer.getInstance().getMessage("lblExileTargetsYourControl", Cost.convertAmountTypeToWords(i, this.getAmount(), desc));
|
||||
return String.format("Exile %s you control", Cost.convertAmountTypeToWords(i, this.getAmount(), desc));
|
||||
}
|
||||
return Localizer.getInstance().getMessage("lblExileTarget", Cost.convertAmountTypeToWords(i, this.getAmount(), desc));
|
||||
return String.format("Exile %s", Cost.convertAmountTypeToWords(i, this.getAmount(), desc));
|
||||
}
|
||||
|
||||
if (!desc.equals("Card") && !desc.endsWith("card")) {
|
||||
if (this.sameZone) {
|
||||
return Localizer.getInstance().getMessage("lblExileNCardFromSameZone", Cost.convertAmountTypeToWords(i, this.getAmount(), desc), this.from.getTranslatedName());
|
||||
return String.format("Exile card %s from the same %s", Cost.convertAmountTypeToWords(i, this.getAmount(), desc), this.from.name());
|
||||
}
|
||||
return Localizer.getInstance().getMessage("lblExileNCardFromYourZone", Cost.convertAmountTypeToWords(i, this.getAmount(), desc), this.from.getTranslatedName());
|
||||
return String.format("Exile card %s from your %s", Cost.convertAmountTypeToWords(i, this.getAmount(), desc), this.from.name());
|
||||
}
|
||||
|
||||
if (this.sameZone) {
|
||||
return Localizer.getInstance().getMessage("lblExileNTargetFromSameZone", Cost.convertAmountTypeToWords(i, this.getAmount(), desc), this.from.getTranslatedName());
|
||||
return String.format("Exile %s from the same %s", Cost.convertAmountTypeToWords(i, this.getAmount(), desc), this.from.name());
|
||||
}
|
||||
|
||||
return Localizer.getInstance().getMessage("lblExileTargetsFromYourZone", Cost.convertAmountTypeToWords(i, this.getAmount(), desc), this.from.getTranslatedName());
|
||||
return String.format("Exile %s from your %s", Cost.convertAmountTypeToWords(i, this.getAmount(), desc), this.from.name());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,6 +25,8 @@ import forge.game.ability.AbilityUtils;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.util.CardTranslation;
|
||||
import forge.util.Lang;
|
||||
import forge.util.TextUtil;
|
||||
|
||||
import java.util.List;
|
||||
@@ -214,15 +216,13 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
|
||||
public String getDescription() {
|
||||
if (hasParam("Description") && !this.isSuppressed()) {
|
||||
String desc = AbilityUtils.applyDescriptionTextChangeEffects(getParam("Description"), this);
|
||||
if (desc.contains("CARDNAME")) {
|
||||
desc = TextUtil.fastReplace(desc, "CARDNAME", getHostCard().toString());
|
||||
}
|
||||
String currentName = getHostCard().getName();
|
||||
desc = CardTranslation.translateSingleDescriptionText(desc, currentName);
|
||||
desc = TextUtil.fastReplace(desc, "CARDNAME", CardTranslation.getTranslatedName(currentName));
|
||||
desc = TextUtil.fastReplace(desc, "NICKNAME", Lang.getInstance().getNickName(CardTranslation.getTranslatedName(currentName)));
|
||||
if (desc.contains("EFFECTSOURCE")) {
|
||||
desc = TextUtil.fastReplace(desc, "EFFECTSOURCE", getHostCard().getEffectSource().toString());
|
||||
}
|
||||
if (desc.contains("NICKNAME")) {
|
||||
desc = TextUtil.fastReplace(desc, "NICKNAME", getHostCard().toString().split(",")[0]);
|
||||
}
|
||||
return desc;
|
||||
} else {
|
||||
return "";
|
||||
|
||||
@@ -54,7 +54,9 @@ import forge.game.trigger.TriggerType;
|
||||
import forge.game.trigger.WrappedAbility;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.Aggregates;
|
||||
import forge.util.CardTranslation;
|
||||
import forge.util.Expressions;
|
||||
import forge.util.Lang;
|
||||
import forge.util.TextUtil;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -822,8 +824,10 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
}
|
||||
String desc = node.getDescription();
|
||||
if (node.getHostCard() != null) {
|
||||
desc = TextUtil.fastReplace(desc, "CARDNAME", node.getHostCard().getName());
|
||||
desc = TextUtil.fastReplace(desc,"NICKNAME",node.getHostCard().getName().split(",")[0]);
|
||||
String currentName = node.getHostCard().getName();
|
||||
desc = CardTranslation.translateMultipleDescriptionText(desc, currentName);
|
||||
desc = TextUtil.fastReplace(desc, "CARDNAME", CardTranslation.getTranslatedName(currentName));
|
||||
desc = TextUtil.fastReplace(desc, "NICKNAME", Lang.getInstance().getNickName(CardTranslation.getTranslatedName(currentName)));
|
||||
if (node.getOriginalHost() != null) {
|
||||
desc = TextUtil.fastReplace(desc, "ORIGINALHOST", node.getOriginalHost().getName());
|
||||
}
|
||||
|
||||
@@ -39,7 +39,9 @@ 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.Lang;
|
||||
import forge.util.TextUtil;
|
||||
|
||||
import java.util.EnumSet;
|
||||
@@ -214,9 +216,10 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
|
||||
@Override
|
||||
public final String toString() {
|
||||
if (hasParam("Description") && !this.isSuppressed()) {
|
||||
String desc = getParam("Description");
|
||||
desc = TextUtil.fastReplace(desc, "CARDNAME", this.hostCard.getName());
|
||||
desc = TextUtil.fastReplace(desc, "NICKNAME", this.hostCard.getName().split(",")[0]);
|
||||
String currentName = this.hostCard.getName();
|
||||
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)));
|
||||
|
||||
return desc;
|
||||
} else {
|
||||
|
||||
@@ -39,6 +39,8 @@ import java.util.*;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import forge.util.CardTranslation;
|
||||
import forge.util.Lang;
|
||||
import forge.util.TextUtil;
|
||||
|
||||
/**
|
||||
@@ -124,9 +126,13 @@ public abstract class Trigger extends TriggerReplacementBase {
|
||||
if (hasParam("TriggerDescription") && !this.isSuppressed()) {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String currentName = (getHostCard().getName());
|
||||
String desc1 = TextUtil.fastReplace(getParam("TriggerDescription"),"CARDNAME", currentName);
|
||||
String desc = TextUtil.fastReplace(desc1,"NICKNAME", currentName.split(",")[0]);
|
||||
String currentName = getHostCard().getName();
|
||||
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)));
|
||||
}
|
||||
if (getHostCard().getEffectSource() != null) {
|
||||
if(active)
|
||||
desc = TextUtil.fastReplace(desc, "EFFECTSOURCE", getHostCard().getEffectSource().toString());
|
||||
@@ -198,6 +204,11 @@ public abstract class Trigger extends TriggerReplacementBase {
|
||||
saDesc = "<take no action>"; // printed in case nothing is chosen for the ability (e.g. Charm with Up to X)
|
||||
}
|
||||
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)));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user