mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 20:58:03 +00:00
Support functional variants in translations
This commit is contained in:
@@ -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.
|
||||
@@ -7558,6 +7560,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),
|
||||
|
||||
Reference in New Issue
Block a user