Merge remote-tracking branch 'upstream/master' into display_localization_cardname

This commit is contained in:
CCTV-1
2020-01-28 09:20:28 +08:00
613 changed files with 31525 additions and 3770 deletions

View File

@@ -6,7 +6,7 @@
<parent>
<artifactId>forge</artifactId>
<groupId>forge</groupId>
<version>1.6.31-SNAPSHOT</version>
<version>1.6.33-SNAPSHOT</version>
</parent>
<artifactId>forge-ai</artifactId>

View File

@@ -579,7 +579,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
@Override
public PaymentDecision visit(CostReveal cost) {
final String type = cost.getType();
CardCollectionView hand = player.getCardsIn(ZoneType.Hand);
CardCollectionView hand = player.getCardsIn(cost.getRevealFrom());
if (cost.payCostFromSource()) {
if (!hand.contains(source)) {

View File

@@ -109,7 +109,7 @@ public class ComputerUtil {
if (chooseTargets != null) {
chooseTargets.run();
}
if (sa.hasParam("Bestow")) {
if (sa.isBestow()) {
sa.getHostCard().animateBestow();
}

View File

@@ -643,7 +643,7 @@ public class ComputerUtilCard {
return getMostProminentType(list, CardType.getAllCreatureTypes());
}
public static String getMostProminentType(final CardCollectionView list, final List<String> valid) {
public static String getMostProminentType(final CardCollectionView list, final Collection<String> valid) {
if (list.size() == 0) {
return "";
}
@@ -964,6 +964,22 @@ public class ComputerUtilCard {
}
chosen.add(chosenColor);
}
else if (logic.equals("HighestDevotionToColor")) {
int curDevotion = 0;
String chosenColor = MagicColor.Constant.WHITE;
CardCollectionView hand = ai.getCardsIn(ZoneType.Hand);
for(byte c : MagicColor.WUBRG) {
String devotionCode = "Count$Devotion." + MagicColor.toLongString(c);
int devotion = CardFactoryUtil.xCount(sa.getHostCard(), devotionCode);
if (devotion > curDevotion && !CardLists.filter(hand, CardPredicates.isColor(c)).isEmpty()) {
curDevotion = devotion;
chosenColor = MagicColor.toLongString(c);
}
}
chosen.add(chosenColor);
}
}
if (chosen.isEmpty()) {
chosen.add(MagicColor.Constant.GREEN);

View File

@@ -2389,7 +2389,7 @@ public class ComputerUtilCombat {
restDamage = target.staticReplaceDamage(restDamage, source, isCombat);
// Predict replacement effects
for (final Card ca : game.getCardsIn(ZoneType.listValueOf("Battlefield,Command"))) {
for (final Card ca : game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) {
for (final ReplacementEffect re : ca.getReplacementEffects()) {
Map<String, String> params = re.getMapParams();
if (!re.getMode().equals(ReplacementType.DamageDone) || !params.containsKey("PreventionEffect")) {

View File

@@ -242,7 +242,7 @@ public abstract class GameState {
if (card instanceof DetachedCardEffect) {
continue;
}
addCard(zone, card.getOwner() == ai ? aiCardTexts : humanCardTexts, card);
addCard(zone, card.getController() == ai ? aiCardTexts : humanCardTexts, card);
}
}
}
@@ -269,6 +269,10 @@ public abstract class GameState {
}
if (zoneType == ZoneType.Battlefield) {
if (c.getOwner() != c.getController()) {
// TODO: Handle more than 2-player games.
newText.append("|Owner:" + (c.getOwner().isAI() ? "AI" : "Human"));
}
if (c.isTapped()) {
newText.append("|Tapped");
}

View File

@@ -502,12 +502,11 @@ public class PlayerControllerAi extends PlayerController {
}
@Override
public String chooseSomeType(String kindOfType, SpellAbility sa, List<String> validTypes, List<String> invalidTypes, boolean isOptional) {
public String chooseSomeType(String kindOfType, SpellAbility sa, Collection<String> validTypes, List<String> invalidTypes, boolean isOptional) {
String chosen = ComputerUtil.chooseSomeType(player, kindOfType, sa.getParam("AILogic"), invalidTypes);
if (StringUtils.isBlank(chosen) && !validTypes.isEmpty())
{
chosen = validTypes.get(0);
System.err.println("AI has no idea how to choose " + kindOfType +", defaulting to 1st element: chosen");
if (StringUtils.isBlank(chosen) && !validTypes.isEmpty()) {
chosen = validTypes.iterator().next();
System.err.println("AI has no idea how to choose " + kindOfType +", defaulting to arbitrary element: chosen");
}
game.getAction().nofityOfValue(sa, player, chosen, player);
return chosen;

View File

@@ -1031,7 +1031,7 @@ public class AttachAi extends SpellAbilityAi {
Card c = null;
List<Card> magnetList = null;
String stCheck = null;
if (attachSource.isAura() || sa.hasParam("Bestow")) {
if (attachSource.isAura() || sa.isBestow()) {
stCheck = "EnchantedBy";
magnetList = CardLists.filter(list, new Predicate<Card>() {
@Override

View File

@@ -8,10 +8,7 @@ import forge.ai.SpecialCardAi;
import forge.ai.SpellAbilityAi;
import forge.card.MagicColor;
import forge.game.Game;
import forge.game.card.Card;
import forge.game.card.CardCollectionView;
import forge.game.card.CardLists;
import forge.game.card.CardPredicates;
import forge.game.card.*;
import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType;
import forge.game.player.Player;
@@ -69,9 +66,7 @@ public class ChooseColorAi extends SpellAbilityAi {
}
}
return false;
}
if (logic.equals("MostProminentInComputerDeck")) {
} else if (logic.equals("MostProminentInComputerDeck")) {
if ("Astral Cornucopia".equals(sourceName)) {
// activate in Main 2 hoping that the extra mana surplus will make a difference
// if there are some nonland permanents in hand
@@ -80,6 +75,11 @@ public class ChooseColorAi extends SpellAbilityAi {
return permanents.size() > 0 && ph.is(PhaseType.MAIN2, ai);
}
} else if (logic.equals("HighestDevotionToColor")) {
// currently only works more or less reliably in Main2 to cast own spells
if (!ph.is(PhaseType.MAIN2, ai)) {
return false;
}
}
boolean chance = MyRandom.getRandom().nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn());

View File

@@ -5,6 +5,7 @@ import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import forge.ai.*;
import forge.game.Game;
import forge.game.ability.AbilityKey;
import forge.game.ability.AbilityUtils;
import forge.game.card.*;
import forge.game.card.CardPredicates.Presets;
@@ -180,6 +181,13 @@ public class CopyPermanentAi extends SpellAbilityAi {
// if no targeting, it should always be ok
}
if ("TriggeredCardController".equals(sa.getParam("Controller"))) {
Card trigCard = (Card)sa.getTriggeringObject(AbilityKey.Card);
if (!mandatory && trigCard != null && trigCard.getController().isOpponentOf(aiPlayer)) {
return false;
}
}
return true;
}

View File

@@ -23,6 +23,14 @@ import java.util.Map;
public class CountersRemoveAi extends SpellAbilityAi {
@Override
protected boolean canPlayWithoutRestrict(final Player ai, final SpellAbility sa) {
if ("Always".equals(sa.getParam("AILogic"))) {
return true;
}
return super.canPlayWithoutRestrict(ai, sa);
}
/*
* (non-Javadoc)
*

View File

@@ -1,6 +1,8 @@
package forge.ai.ability;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import forge.ai.*;
import forge.game.Game;
import forge.game.ability.AbilityUtils;
@@ -157,6 +159,15 @@ public class DigAi extends SpellAbilityAi {
}
}
/* (non-Javadoc)
* @see forge.card.ability.SpellAbilityAi#chooseSinglePlayer(forge.game.player.Player, forge.card.spellability.SpellAbility, java.util.List)
*/
@Override
public Player chooseSinglePlayer(Player ai, SpellAbility sa, Iterable<Player> options) {
// an opponent choose a card from
return Iterables.getFirst(options, null);
}
/* (non-Javadoc)
* @see forge.card.ability.SpellAbilityAi#confirmAction(forge.card.spellability.SpellAbility, forge.game.player.PlayerActionConfirmMode, java.lang.String)
*/

View File

@@ -5,11 +5,7 @@ import java.util.List;
import com.google.common.base.Predicate;
import forge.ai.AiAttackController;
import forge.ai.ComputerUtil;
import forge.ai.ComputerUtilCard;
import forge.ai.ComputerUtilCombat;
import forge.ai.SpellAbilityAi;
import forge.ai.*;
import forge.card.MagicColor;
import forge.game.Game;
import forge.game.GameObject;
@@ -221,6 +217,11 @@ public class ProtectAi extends SpellAbilityAi {
// Don't target cards that will die.
list = ComputerUtil.getSafeTargets(ai, sa, list);
// Don't target self if the cost includes sacrificing itself
if (ComputerUtilCost.isSacrificeSelfCost(sa.getPayCosts())) {
list.remove(source);
}
if (list.isEmpty()) {
return mandatory && protectMandatoryTarget(ai, sa, mandatory);
}

View File

@@ -29,6 +29,13 @@ public class GameStateEvaluator {
if (phase.isAfter(PhaseType.COMBAT_DAMAGE) || evalGame.isGameOver()) {
return null;
}
// If the current player has no creatures in play, there won't be any combat. This avoids
// an expensive game copy operation.
// Note: This is is safe to do because the simulation is based on the current game state,
// so there isn't a chance to play creatures in between.
if (evalGame.getPhaseHandler().getPlayerTurn().getCreaturesInPlay().isEmpty()) {
return null;
}
GameCopier copier = new GameCopier(evalGame);
Game gameCopy = copier.makeCopy();
gameCopy.getPhaseHandler().devAdvanceToPhase(PhaseType.COMBAT_DAMAGE);

View File

@@ -23,6 +23,7 @@ import forge.util.TextUtil;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
public class SpellAbilityPicker {
private Game game;
@@ -307,7 +308,7 @@ public class SpellAbilityPicker {
if (conditions == null) {
return true;
}
List<PhaseType> phases = conditions.getPhases();
Set<PhaseType> phases = conditions.getPhases();
return phases.isEmpty() || phases.contains(PhaseType.MAIN1);
}

View File

@@ -6,7 +6,7 @@
<parent>
<artifactId>forge</artifactId>
<groupId>forge</groupId>
<version>1.6.31-SNAPSHOT</version>
<version>1.6.33-SNAPSHOT</version>
</parent>
<artifactId>forge-core</artifactId>

View File

@@ -553,6 +553,23 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
return Lists.newArrayList(Iterables.filter(this.roAllCards, predicate));
}
// Do I want a foiled version of these cards?
@Override
public List<PaperCard> getAllCardsFromEdition(CardEdition edition) {
List<PaperCard> cards = Lists.newArrayList();
for(CardInSet cis : edition.getCards()) {
PaperCard card = this.getCard(cis.name, edition.getCode());
if (card == null) {
// Just in case the card is listed in the edition file but Forge doesn't support it
continue;
}
cards.add(card);
}
return cards;
}
@Override
public boolean contains(String name) {
return allCardsByName.containsKey(getName(name));

View File

@@ -110,6 +110,7 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
private Type type;
private String name;
private String alias = null;
private String prerelease = null;
private boolean whiteBorder = false;
private FoilType foilType = FoilType.NOT_SUPPORTED;
private double foilChanceInBooster = 0;
@@ -178,6 +179,7 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
public Type getType() { return type; }
public String getName() { return name; }
public String getAlias() { return alias; }
public String getPrerelease() { return prerelease; }
public FoilType getFoilType() { return foilType; }
public double getFoilChanceInBooster() { return foilChanceInBooster; }
public boolean getFoilAlwaysInCommonSlot() { return foilAlwaysInCommonSlot; }
@@ -303,7 +305,7 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
tokenNormalized
);
FileSection section = FileSection.parse(contents.get("metadata"), "=");
FileSection section = FileSection.parse(contents.get("metadata"), FileSection.EQUALS_KV_SEPARATOR);
res.name = section.get("name");
res.date = parseDate(section.get("date"));
res.code = section.get("code");
@@ -333,6 +335,7 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
}
}
res.type = enumType;
res.prerelease = section.get("Prerelease", null);
switch(section.get("foil", "newstyle").toLowerCase()) {
case "notsupported":
@@ -413,6 +416,16 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
return res;
}
public Iterable<CardEdition> getPrereleaseEditions() {
List<CardEdition> res = Lists.newArrayList(this);
return Iterables.filter(res, new Predicate<CardEdition>() {
@Override
public boolean apply(final CardEdition edition) {
return edition.getPrerelease() != null;
}
});
}
public CardEdition getEditionByCodeOrThrow(final String code) {
final CardEdition set = this.get(code);
if (null == set) {

View File

@@ -606,13 +606,13 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
public static class Constant {
public static final Settable LOADED = new Settable();
public static final List<String> BASIC_TYPES = Lists.newArrayList();
public static final List<String> LAND_TYPES = Lists.newArrayList();
public static final List<String> CREATURE_TYPES = Lists.newArrayList();
public static final List<String> SPELL_TYPES = Lists.newArrayList();
public static final List<String> ENCHANTMENT_TYPES = Lists.newArrayList();
public static final List<String> ARTIFACT_TYPES = Lists.newArrayList();
public static final List<String> WALKER_TYPES = Lists.newArrayList();
public static final Set<String> BASIC_TYPES = Sets.newHashSet();
public static final Set<String> LAND_TYPES = Sets.newHashSet();
public static final Set<String> CREATURE_TYPES = Sets.newHashSet();
public static final Set<String> SPELL_TYPES = Sets.newHashSet();
public static final Set<String> ENCHANTMENT_TYPES = Sets.newHashSet();
public static final Set<String> ARTIFACT_TYPES = Sets.newHashSet();
public static final Set<String> WALKER_TYPES = Sets.newHashSet();
// singular -> plural
public static final BiMap<String,String> pluralTypes = HashBiMap.create();
@@ -699,12 +699,12 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
return sortedSubTypes;
}
public static List<String> getBasicTypes() {
return Collections.unmodifiableList(Constant.BASIC_TYPES);
public static Collection<String> getBasicTypes() {
return Collections.unmodifiableCollection(Constant.BASIC_TYPES);
}
public static List<String> getAllCreatureTypes() {
return Collections.unmodifiableList(Constant.CREATURE_TYPES);
public static Collection<String> getAllCreatureTypes() {
return Collections.unmodifiableCollection(Constant.CREATURE_TYPES);
}
public static List<String> getAllLandTypes() {
return ImmutableList.<String>builder()

View File

@@ -28,6 +28,8 @@ public interface ICardDatabase extends Iterable<PaperCard> {
List<PaperCard> getAllCards(String cardName);
List<PaperCard> getAllCards(Predicate<PaperCard> predicate);
List<PaperCard> getAllCardsFromEdition(CardEdition edition);
Predicate<? super PaperCard> wasPrintedInSets(List<String> allowedSetCodes);
}

View File

@@ -27,7 +27,7 @@ public class DeckSerializer {
}
final List<String> metadata = map.get("metadata");
if (metadata != null) {
return new DeckFileHeader(FileSection.parse(metadata, "="));
return new DeckFileHeader(FileSection.parse(metadata, FileSection.EQUALS_KV_SEPARATOR));
}
final List<String> general = map.get("general");
if (general != null) {

View File

@@ -108,7 +108,7 @@ public class PreconDeck implements InventoryItemFromSet {
// To be able to read "shops" section in overloads
protected PreconDeck getPreconDeckFromSections(final Map<String, List<String>> sections) {
FileSection kv = FileSection.parse(sections.get("metadata"), "=");
FileSection kv = FileSection.parse(sections.get("metadata"), FileSection.EQUALS_KV_SEPARATOR);
String imageFilename = kv.get("Image");
String description = kv.get("Description");
String deckEdition = kv.get("set");

View File

@@ -17,9 +17,12 @@
*/
package forge.util;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -57,31 +60,37 @@ public class FileSection {
lines = lines0;
}
/**
* Parses the.
*
* @param line the line
* @param kvSeparator the kv separator
* @param pairSeparator the pair separator
* @return the file section
*/
public static FileSection parse(final String line, final String kvSeparator, final String pairSeparator) {
Map<String, String> map = parseToMap(line, kvSeparator, pairSeparator);
return new FileSection(map);
public static final Pattern DOLLAR_SIGN_KV_SEPARATOR = Pattern.compile(Pattern.quote("$"));
public static final Pattern ARROW_KV_SEPARATOR = Pattern.compile(Pattern.quote("->"));
public static final Pattern EQUALS_KV_SEPARATOR = Pattern.compile(Pattern.quote("="));
public static final Pattern COLON_KV_SEPARATOR = Pattern.compile(Pattern.quote(":"));
private static final String BAR_PAIR_SPLITTER = Pattern.quote("|");
private static Table<String, Pattern, Map<String, String>> parseToMapCache = HashBasedTable.create();
public static Map<String, String> parseToMap(final String line, final Pattern kvSeparator) {
Map<String, String> result = parseToMapCache.get(line, kvSeparator);
if (result != null) {
return result;
}
result = parseToMapImpl(line, kvSeparator);
parseToMapCache.put(line, kvSeparator, result);
return result;
}
public static Map<String, String> parseToMap(final String line, final String kvSeparator, final String pairSeparator) {
Map<String, String> result = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
if (!StringUtils.isEmpty(line)) {
final String[] pairs = line.split(Pattern.quote(pairSeparator));
final Pattern splitter = Pattern.compile(Pattern.quote(kvSeparator));
private static Map<String, String> parseToMapImpl(final String line, final Pattern kvSeparator) {
if (StringUtils.isEmpty(line)) {
return Collections.emptyMap();
}
final Map<String, String> result = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
final String[] pairs = line.split(BAR_PAIR_SPLITTER);
for (final String dd : pairs) {
final String[] v = splitter.split(dd, 2);
final String[] v = kvSeparator.split(dd, 2);
result.put(v[0].trim(), v.length > 1 ? v[1].trim() : "");
}
}
return result;
return Collections.unmodifiableMap(result);
}
/**
@@ -91,11 +100,10 @@ public class FileSection {
* @param kvSeparator the kv separator
* @return the file section
*/
public static FileSection parse(final Iterable<String> lines, final String kvSeparator) {
public static FileSection parse(final Iterable<String> lines, final Pattern kvSeparator) {
final FileSection result = new FileSection();
final Pattern splitter = Pattern.compile(Pattern.quote(kvSeparator));
for (final String dd : lines) {
final String[] v = splitter.split(dd, 2);
final String[] v = kvSeparator.split(dd, 2);
result.lines.put(v[0].trim(), v.length > 1 ? v[1].trim() : "");
}

View File

@@ -6,7 +6,7 @@
<parent>
<artifactId>forge</artifactId>
<groupId>forge</groupId>
<version>1.6.31-SNAPSHOT</version>
<version>1.6.33-SNAPSHOT</version>
</parent>
<artifactId>forge-game</artifactId>

View File

@@ -72,8 +72,9 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView {
return this.mapParams;
}
public final String getParamOrDefault(String key, String defaultValue) {
return hasParam(key) ? getParam(key) : defaultValue;
public String getParamOrDefault(String key, String defaultValue) {
String param = mapParams.get(key);
return param != null ? param : defaultValue;
}
public String getParam(String key) {

View File

@@ -168,6 +168,8 @@ public class ForgeScript {
return found;
} else if (property.equals("YouCtrl")) {
return sa.getActivatingPlayer().equals(sourceController);
} else if (property.equals("OppCtrl")) {
return sa.getActivatingPlayer().isOpponentOf(sourceController);
} else if (sa.getHostCard() != null) {
return sa.getHostCard().hasProperty(property, sourceController, source, spellAbility);
}

View File

@@ -514,6 +514,11 @@ public class GameAction {
}
}
// Cards not on the battlefield / stack should not have controller
if (!zoneTo.is(ZoneType.Battlefield) && !zoneTo.is(ZoneType.Stack)) {
c.clearControllers();
}
return copied;
}
@@ -1553,8 +1558,7 @@ public class GameAction {
// Where there are none, it should bring up speed controls
game.fireEvent(new GameEventGameStarted(gameType, first, game.getPlayers()));
// Emissary's Plot
// runPreOpeningHandActions(first);
runPreOpeningHandActions(first);
game.setAge(GameStage.Mulligan);
for (final Player p1 : game.getPlayers()) {

View File

@@ -75,7 +75,7 @@ public final class GameActionUtil {
Card source = sa.getHostCard();
final Game game = source.getGame();
if (sa.isSpell()) {
if (sa.isSpell() && !source.isInZone(ZoneType.Battlefield)) {
boolean lkicheck = false;
// need to be done before so it works with Vivien and Zoetic Cavern
@@ -88,7 +88,7 @@ public final class GameActionUtil {
lkicheck = true;
}
if (sa.hasParam("Bestow") && !source.isBestowed() && !source.isInZone(ZoneType.Battlefield)) {
if (sa.isBestow() && !source.isBestowed() && !source.isInZone(ZoneType.Battlefield)) {
if (!source.isLKI()) {
source = CardUtil.getLKICopy(source);
}
@@ -102,7 +102,7 @@ public final class GameActionUtil {
}
source.turnFaceDownNoUpdate();
lkicheck = true;
} else if (sa.isAdventure() && !source.isInZone(ZoneType.Battlefield)) {
} else if (sa.isAdventure()) {
if (!source.isLKI()) {
source = CardUtil.getLKICopy(source);
}
@@ -146,6 +146,7 @@ public final class GameActionUtil {
if (lkicheck) {
// double freeze tracker, so it doesn't update view
game.getTracker().freeze();
source.clearChangedCardKeywords(false);
CardCollection preList = new CardCollection(source);
game.getAction().checkStaticAbilities(false, Sets.newHashSet(source), preList);
}
@@ -207,6 +208,57 @@ public final class GameActionUtil {
alternatives.add(newSA);
}
// need to be done there before static abilities does reset the card
if (sa.isBasicSpell()) {
for (final KeywordInterface inst : source.getKeywords()) {
final String keyword = inst.getOriginal();
if (keyword.startsWith("Escape")) {
final String[] k = keyword.split(":");
final Cost escapeCost = new Cost(k[1], true);
final SpellAbility newSA = sa.copyWithDefinedCost(escapeCost);
newSA.getMapParams().put("PrecostDesc", "Escape—");
newSA.getMapParams().put("CostDesc", escapeCost.toString());
// makes new SpellDescription
final StringBuilder desc = new StringBuilder();
desc.append(newSA.getCostDescription());
desc.append("(").append(inst.getReminderText()).append(")");
newSA.setDescription(desc.toString());
// Stack Description only for Permanent or it might crash
if (source.isPermanent()) {
final StringBuilder sbStack = new StringBuilder();
sbStack.append(sa.getStackDescription()).append(" (Escaped)");
newSA.setStackDescription(sbStack.toString());
}
newSA.setAlternativeCost(AlternativeCost.Escape);
newSA.getRestrictions().setZone(ZoneType.Graveyard);
alternatives.add(newSA);
} else if (keyword.startsWith("Flashback")) {
// if source has No Mana cost, and flashback doesn't have own one,
// flashback can't work
if (keyword.equals("Flashback") && source.getManaCost().isNoCost()) {
continue;
}
final SpellAbility flashback = sa.copy(activator);
flashback.setAlternativeCost(AlternativeCost.Flashback);
flashback.getRestrictions().setZone(ZoneType.Graveyard);
// there is a flashback cost (and not the cards cost)
if (keyword.contains(":")) {
final String[] k = keyword.split(":");
flashback.setPayCosts(new Cost(k[1], false));
}
alternatives.add(flashback);
}
}
}
// reset static abilities
if (lkicheck) {
game.getAction().checkStaticAbilities(false);
@@ -244,28 +296,6 @@ public final class GameActionUtil {
alternatives.add(newSA);
}
for (final KeywordInterface inst : source.getKeywords()) {
final String keyword = inst.getOriginal();
if (sa.isSpell() && keyword.startsWith("Flashback")) {
// if source has No Mana cost, and flashback doesn't have own one,
// flashback can't work
if (keyword.equals("Flashback") && source.getManaCost().isNoCost()) {
continue;
}
final SpellAbility flashback = sa.copy(activator);
flashback.setFlashBackAbility(true);
flashback.getRestrictions().setZone(ZoneType.Graveyard);
// there is a flashback cost (and not the cards cost)
if (keyword.contains(":")) {
final String[] k = keyword.split(":");
flashback.setPayCosts(new Cost(k[1], false));
}
alternatives.add(flashback);
}
}
return alternatives;
}

View File

@@ -385,7 +385,7 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
}
// CantTarget static abilities
for (final Card ca : getGame().getCardsIn(ZoneType.listValueOf("Battlefield,Command"))) {
for (final Card ca : getGame().getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) {
for (final StaticAbility stAb : ca.getStaticAbilities()) {
if (stAb.applyAbility("CantAttach", attach, this)) {
return false;

View File

@@ -321,7 +321,7 @@ public class GameFormat implements Comparable<GameFormat> {
if (formatStrings == null){
return null;
}
FileSection section = FileSection.parse(formatStrings, ":");
FileSection section = FileSection.parse(formatStrings, FileSection.COLON_KV_SEPARATOR);
String title = section.get("name");
FormatType formatType;
try {

View File

@@ -1,5 +1,9 @@
package forge.game;
import java.util.EnumSet;
import java.util.Set;
import com.google.common.base.Enums;
import com.google.common.base.Function;
import forge.StaticData;
import forge.deck.CardPool;
@@ -144,4 +148,19 @@ public enum GameType {
public String getDescription() {
return description;
}
public static GameType smartValueOf(String name) {
return Enums.getIfPresent(GameType.class, name).orNull();
}
public static Set<GameType> listValueOf(final String values) {
final Set<GameType> result = EnumSet.noneOf(GameType.class);
for (final String s : values.split(",")) {
GameType g = GameType.smartValueOf(s);
if (g != null) {
result.add(g);
}
}
return result;
}
}

View File

@@ -25,7 +25,6 @@ public enum GlobalRuleChange {
alwaysWither ("All damage is dealt as though it's source had wither."),
attackerChoosesBlockers ("The attacking player chooses how each creature blocks each turn."),
manapoolsDontEmpty ("Mana pools don't empty as steps and phases end."),
noCycling ("Players can't cycle cards."),
noCreatureETBTriggers ("Creatures entering the battlefield don't cause abilities to trigger."),
noCreatureDyingTriggers ("Creatures dying don't cause abilities to trigger."),
noLegendRule ("The legend rule doesn't apply."),

View File

@@ -19,6 +19,7 @@ import forge.game.zone.ZoneType;
import forge.item.PaperCard;
import forge.util.MyRandom;
import forge.util.collect.FCollectionView;
import forge.util.Localizer;
import java.util.*;
import java.util.Map.Entry;
@@ -291,12 +292,13 @@ public class Match {
}
}
final Localizer localizer = Localizer.getInstance();
if (!rAICards.isEmpty() && !rules.getGameType().isCardPoolLimited()) {
game.getAction().revealAnte("AI can't play these cards well", rAICards);
game.getAction().revealAnte(localizer.getMessage("lblAICantPlayCards"), rAICards);
}
if (!removedAnteCards.isEmpty()) {
game.getAction().revealAnte("These ante cards were removed", removedAnteCards);
game.getAction().revealAnte(localizer.getMessage("lblAnteCardsRemoved"), removedAnteCards);
}
}

View File

@@ -382,21 +382,10 @@ public final class AbilityFactory {
* @param mapParams
*/
private static final void initializeParams(final SpellAbility sa, Map<String, String> mapParams) {
if (mapParams.containsKey("Flashback")) {
sa.setFlashBackAbility(true);
}
if (mapParams.containsKey("NonBasicSpell")) {
sa.setBasicSpell(false);
}
if (mapParams.containsKey("Dash")) {
sa.setDash(true);
}
if (mapParams.containsKey("Outlast")) {
sa.setOutlast(true);
}
}
/**
@@ -449,7 +438,7 @@ public final class AbilityFactory {
}
public static final Map<String, String> getMapParams(final String abString) {
return FileSection.parseToMap(abString, "$", "|");
return FileSection.parseToMap(abString, FileSection.DOLLAR_SIGN_KV_SEPARATOR);
}
public static final void adjustChangeZoneTarget(final Map<String, String> params, final SpellAbility sa) {

View File

@@ -260,6 +260,8 @@ public class AbilityUtils {
list = sa.getRootAbility().getPaidList("SacrificedCards");
} else if (defined.startsWith("Sacrificed")) {
list = sa.getRootAbility().getPaidList("Sacrificed");
} else if (defined.startsWith("Revealed")) {
list = sa.getRootAbility().getPaidList("Revealed");
} else if (defined.startsWith("DiscardedCards")) {
list = sa.getRootAbility().getPaidList("DiscardedCards");
} else if (defined.startsWith("Discarded")) {
@@ -1279,6 +1281,8 @@ public class AbilityUtils {
if (o instanceof Card) {
final Card rem = (Card) o;
sas.addAll(game.getCardState(rem).getSpellAbilities());
} else if (o instanceof SpellAbility) {
sas.add((SpellAbility) o);
}
}
}
@@ -1617,7 +1621,19 @@ public class AbilityUtils {
}
return count;
}
// Count$AttachedTo <DefinedCards related to spellability> <restriction>
if (sq[0].startsWith("AttachedTo")) {
final String[] k = l[0].split(" ");
int sum = 0;
for (Card card : AbilityUtils.getDefinedCards(sa.getHostCard(), k[1], sa)) {
// Hateful Eidolon: the script uses LKI so that the attached cards have to be defined
// This card needs the spellability ("Auras You control", you refers to the activating player)
// CardFactoryUtils.xCount doesn't have the sa parameter, SVar:X:TriggeredCard$Valid <restriction> cannot handle this
CardCollection list = CardLists.getValidCards(card.getAttachedCards(), k[2].split(","), sa.getActivatingPlayer(), c, sa);
sum += list.size();
}
return sum;
}
// Count$Adamant.<Color>.<True>.<False>
if (sq[0].startsWith("Adamant")) {
final String payingMana = StringUtils.join(sa.getRootAbility().getPayingMana());
@@ -1708,7 +1724,7 @@ public class AbilityUtils {
if (res.checkTimingRestrictions(tgtCard, newSA)
// still need to check the other restrictions like Aftermath
&& res.checkOtherRestrictions(tgtCard, newSA, controller)
&& newSA.checkOtherRestrictions()) {
&& newSA.checkOtherRestrictions(tgtCard)) {
sas.add(newSA);
}
}
@@ -1836,6 +1852,11 @@ public class AbilityUtils {
} else if (def.endsWith("Owner")) {
players.add(c.getOwner());
}
} else if (o instanceof SpellAbility) {
final SpellAbility c = (SpellAbility) o;
if (def.endsWith("Controller")) {
players.add(c.getHostCard().getController());
}
}
}
}

View File

@@ -8,6 +8,8 @@ import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.trigger.TriggerType;
import forge.game.zone.ZoneType;
import forge.util.Localizer;
import forge.util.CardTranslation;
import java.util.Map;
@@ -23,7 +25,7 @@ public class AbandonEffect extends SpellAbilityEffect {
Player controller = source.getController();
boolean isOptional = sa.hasParam("Optional");
if (isOptional && !controller.getController().confirmAction(sa, null, "Would you like to abandon the scheme " + source + "?")) {
if (isOptional && !controller.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblWouldYouLikeAbandonSource", CardTranslation.getTranslatedName(source.getName())))) {
return;
}

View File

@@ -9,6 +9,7 @@ import forge.game.spellability.TargetRestrictions;
import forge.game.zone.ZoneType;
import forge.util.collect.FCollection;
import forge.util.Lang;
import forge.util.Localizer;
import org.apache.commons.lang3.StringUtils;
@@ -51,7 +52,7 @@ public class ActivateAbilityEffect extends SpellAbilityEffect {
continue;
}
SpellAbility manaAb = p.getController().chooseSingleSpellForEffect(
possibleAb, sa, "Choose a mana ability:", ImmutableMap.of());
possibleAb, sa, Localizer.getInstance().getMessage("lblChooseManaAbility"), ImmutableMap.of());
p.getController().playChosenSpellAbility(manaAb);
}
}

View File

@@ -8,6 +8,7 @@ import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.trigger.Trigger;
import forge.game.trigger.TriggerHandler;
import forge.util.Localizer;
import java.util.List;
@@ -61,7 +62,7 @@ public class AddTurnEffect extends SpellAbilityEffect {
extra.setCantSetSchemesInMotion(true);
}
if (sa.hasParam("ShowMessage")) {
p.getGame().getAction().nofityOfValue(sa, p, p + " takes an extra turn.", null);
p.getGame().getAction().nofityOfValue(sa, p, Localizer.getInstance().getMessage("lblPlayerTakesExtraTurn", p.toString()), null);
}
}
}

View File

@@ -17,6 +17,7 @@ import forge.game.player.PlayerController;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.Lang;
import forge.util.Localizer;
public class AmassEffect extends SpellAbilityEffect {
@@ -80,7 +81,7 @@ public class AmassEffect extends SpellAbilityEffect {
}
CardCollectionView tgtCards = CardLists.getType(activator.getCardsIn(ZoneType.Battlefield), "Army");
tgtCards = pc.chooseCardsForEffect(tgtCards, sa, "Choose an army to put counters on", 1, 1, false);
tgtCards = pc.chooseCardsForEffect(tgtCards, sa, Localizer.getInstance().getMessage("lblChooseAnArmy"), 1, 1, false);
GameEntityCounterTable table = new GameEntityCounterTable();
for(final Card tgtCard : tgtCards) {

View File

@@ -16,6 +16,7 @@ import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.util.Localizer;
public class AssignGroupEffect extends SpellAbilityEffect {
@@ -49,7 +50,7 @@ public class AssignGroupEffect extends SpellAbilityEffect {
Multimap<SpellAbility, GameObject> result = ArrayListMultimap.create();
for (GameObject g : defined) {
final String title = "Choose ability for " + g.toString();
final String title = Localizer.getInstance().getMessage("lblChooseAbilityForObject", g.toString());
Map<String, Object> params = Maps.newHashMap();
params.put("Affected", g);

View File

@@ -16,6 +16,8 @@ import forge.game.spellability.TargetRestrictions;
import forge.game.zone.ZoneType;
import forge.util.collect.FCollection;
import forge.util.Lang;
import forge.util.Localizer;
import forge.util.CardTranslation;
import java.util.List;
@@ -45,6 +47,14 @@ public class AttachEffect extends SpellAbilityEffect {
attachTo = targets.get(0);
}
String attachToName = null;
if (attachTo instanceof Card) {
attachToName = CardTranslation.getTranslatedName(((Card)attachTo).getName());
}
else {
attachToName = attachTo.toString();
}
final Player p = sa.getActivatingPlayer();
if (sa.hasParam("Object")) {
@@ -60,7 +70,7 @@ public class AttachEffect extends SpellAbilityEffect {
// If Cast Targets will be checked on the Stack
for (final Card attachment : attachments) {
String message = "Do you want to attach " + attachment + " to " + attachTo + "?";
String message = Localizer.getInstance().getMessage("lblDoYouWantAttachSourceToTarget", CardTranslation.getTranslatedName(attachment.getName()), attachToName);
if ( sa.hasParam("Optional") && !p.getController().confirmAction(sa, null, message) )
continue;
handleAttachment(attachment, attachTo, sa);
@@ -173,7 +183,7 @@ public class AttachEffect extends SpellAbilityEffect {
players.add(player);
}
}
final Player pa = p.getController().chooseSingleEntityForEffect(players, aura, source + " - Select a player to attach to.");
final Player pa = p.getController().chooseSingleEntityForEffect(players, aura, Localizer.getInstance().getMessage("lblSelectAPlayerAttachSourceTo", CardTranslation.getTranslatedName(source.getName())));
if (pa != null) {
handleAura(source, pa);
return true;
@@ -186,7 +196,7 @@ public class AttachEffect extends SpellAbilityEffect {
return false;
}
final Card o = p.getController().chooseSingleEntityForEffect(list, aura, source + " - Select a card to attach to.");
final Card o = p.getController().chooseSingleEntityForEffect(list, aura, Localizer.getInstance().getMessage("lblSelectACardAttachSourceTo", CardTranslation.getTranslatedName(source.getName())));
if (o != null) {
handleAura(source, o);
//source.enchantEntity((Card) o);

View File

@@ -11,6 +11,7 @@ import forge.game.player.PlayerActionConfirmMode;
import forge.game.spellability.AbilitySub;
import forge.game.spellability.SpellAbility;
import forge.util.collect.FCollection;
import forge.util.Localizer;
public class BidLifeEffect extends SpellAbilityEffect {
@Override
@@ -27,7 +28,7 @@ public class BidLifeEffect extends SpellAbilityEffect {
if (sa.hasParam("StartBidding")) {
String start = sa.getParam("StartBidding");
if ("Any".equals(start)) {
startBidding = activator.getController().announceRequirements(sa, "Choose a starting bid", true);
startBidding = activator.getController().announceRequirements(sa, Localizer.getInstance().getMessage("lblChooseStartingBid"), true);
} else {
startBidding = AbilityUtils.calculateAmount(host, start, sa);
}
@@ -54,12 +55,12 @@ public class BidLifeEffect extends SpellAbilityEffect {
willBid = false;
for (final Player p : bidPlayers) {
final boolean result = p.getController().confirmBidAction(sa, PlayerActionConfirmMode.BidLife,
"Do you want to top bid? Current Bid =" + bid, bid, winner);
Localizer.getInstance().getMessage("lblDoYouWantTopBid") + bid, bid, winner);
willBid |= result;
if (result) { // a different choose number
bid += p.getController().chooseNumber(sa, "Bid life:", 1, 9);
bid += p.getController().chooseNumber(sa, Localizer.getInstance().getMessage("lblBidLife") + ":", 1, 9);
winner = p;
host.getGame().getAction().nofityOfValue(sa, p, "topped bid with " + bid + " life", p);
host.getGame().getAction().nofityOfValue(sa, p, Localizer.getInstance().getMessage("lblTopBidWithValueLife", String.valueOf(bid)), p);
}
}
}

View File

@@ -6,6 +6,7 @@ import forge.game.card.Card;
import forge.game.card.CardCollectionView;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.Localizer;
import java.util.List;
@@ -30,7 +31,7 @@ public class BondEffect extends SpellAbilityEffect {
Card partner = cards.getFirst();
// skip choice if only one card on list
if (cards.size() > 1) {
partner = sa.getActivatingPlayer().getController().chooseSingleEntityForEffect(cards, sa, "Select a card to pair with");
partner = sa.getActivatingPlayer().getController().chooseSingleEntityForEffect(cards, sa, Localizer.getInstance().getMessage("lblSelectACardPair"));
}
// pair choices together

View File

@@ -13,6 +13,8 @@ import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityStackInstance;
import forge.game.spellability.TargetRestrictions;
import forge.util.collect.FCollectionView;
import forge.util.Localizer;
import forge.util.CardTranslation;
import org.apache.commons.lang3.StringUtils;
@@ -44,7 +46,7 @@ public class ChangeCombatantsEffect extends SpellAbilityEffect {
final GameEntity originalDefender = combat.getDefenderByAttacker(c);
final FCollectionView<GameEntity> defs = combat.getDefenders();
final GameEntity defender = sa.getActivatingPlayer().getController().chooseSingleEntityForEffect(defs, sa,
"Choose which defender to attack with " + c, false);
Localizer.getInstance().getMessage("lblChooseDefenderToAttackWithCard", CardTranslation.getTranslatedName(c.getName())), false);
if (originalDefender != null && !originalDefender.equals(defender)) {
AttackingBand ab = combat.getBandOfAttacker(c);
if (ab != null) {

View File

@@ -11,6 +11,7 @@ import forge.game.spellability.SpellAbilityStackInstance;
import forge.game.spellability.TargetChoices;
import forge.game.zone.MagicStack;
import forge.util.Aggregates;
import forge.util.Localizer;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
@@ -50,7 +51,7 @@ public class ChangeTargetsEffect extends SpellAbilityEffect {
// Redirect rules read 'you MAY choose new targets' ... okay!
// TODO: Don't even ask to change targets, if the SA and subs don't actually have targets
boolean isOptional = sa.hasParam("Optional");
if (isOptional && !chooser.getController().confirmAction(sa, null, "Do you want to change targets of " + tgtSA.getHostCard() + "?")) {
if (isOptional && !chooser.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantChangeAbilityTargets", tgtSA.getHostCard().toString()))) {
continue;
}
if (changesOneTarget) {

View File

@@ -14,6 +14,7 @@ import forge.game.card.Card;
import forge.game.event.GameEventCardStatsChanged;
import forge.game.spellability.SpellAbility;
import forge.util.TextUtil;
import forge.util.Localizer;
public class ChangeTextEffect extends SpellAbilityEffect {
@@ -33,7 +34,7 @@ public class ChangeTextEffect extends SpellAbilityEffect {
final String[] changedColorWordsArray = sa.getParam("ChangeColorWord").split(" ");
if (changedColorWordsArray[0].equals("Choose")) {
originalColor = sa.getActivatingPlayer().getController().chooseColor(
"Choose a color word to replace", sa, ColorSet.ALL_COLORS);
Localizer.getInstance().getMessage("lblChooseColorReplace"), sa, ColorSet.ALL_COLORS);
changedColorWordOriginal = TextUtil.capitalize(MagicColor.toLongString(originalColor));
} else {
changedColorWordOriginal = changedColorWordsArray[0];
@@ -48,7 +49,7 @@ public class ChangeTextEffect extends SpellAbilityEffect {
possibleNewColors = ColorSet.fromMask(originalColor).inverse();
}
final byte newColor = sa.getActivatingPlayer().getController().chooseColor(
"Choose a new color word", sa, possibleNewColors);
Localizer.getInstance().getMessage("lblChooseNewColor"), sa, possibleNewColors);
changedColorWordNew = TextUtil.capitalize(MagicColor.toLongString(newColor));
} else {
changedColorWordNew = changedColorWordsArray[1];

View File

@@ -14,6 +14,7 @@ import forge.game.zone.Zone;
import forge.game.zone.ZoneType;
import forge.util.Lang;
import forge.util.TextUtil;
import forge.util.Localizer;
import java.util.List;
import java.util.Map;
@@ -100,17 +101,7 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect {
if (sa.hasParam("OptionQuestion")) {
message = TextUtil.fastReplace(sa.getParam("OptionQuestion"), "TARGETS", targets);
} else {
final StringBuilder sb = new StringBuilder();
sb.append("Move ");
sb.append(targets);
sb.append(" from ");
sb.append(Lang.joinHomogenous(origin));
sb.append(" to ");
sb.append(destination);
sb.append("?");
message = sb.toString();
message = Localizer.getInstance().getMessage("lblMoveTargetFromOriginToDestination", targets, Lang.joinHomogenous(origin, ZoneType.Accessors.GET_TRANSLATED_NAME), destination.getTranslatedName());
}
if (!sa.getActivatingPlayer().getController().confirmAction(sa, null, message)) {

View File

@@ -32,6 +32,8 @@ import forge.util.MessageUtil;
import forge.util.TextUtil;
import forge.util.collect.FCollection;
import forge.util.collect.FCollectionView;
import forge.util.Localizer;
import forge.util.CardTranslation;
import java.util.List;
import java.util.Map;
@@ -439,7 +441,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
hostCard.addRemembered(CardUtil.getLKICopy(tgtC));
}
final String prompt = TextUtil.concatWithSpace("Do you want to move", tgtC.toString(), "from", origin.toString(), "to", TextUtil.addSuffix(destination.toString(),"?"));
final String prompt = TextUtil.concatWithSpace(Localizer.getInstance().getMessage("lblDoYouWantMoveTargetFromOriToDest", CardTranslation.getTranslatedName(tgtC.getName()), Lang.joinHomogenous(origin, ZoneType.Accessors.GET_TRANSLATED_NAME), destination.getTranslatedName()));
if (optional && !player.getController().confirmAction(sa, null, prompt) )
continue;
@@ -503,7 +505,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), sa.getParam("AttachedTo"), tgtC.getController(), tgtC);
}
if (!list.isEmpty()) {
Card attachedTo = player.getController().chooseSingleEntityForEffect(list, sa, tgtC + " - Select a card to attach to.");
Card attachedTo = player.getController().chooseSingleEntityForEffect(list, sa, Localizer.getInstance().getMessage("lblSelectACardAttachSourceTo", tgtC.toString()));
tgtC.attachToEntity(attachedTo);
} else { // When it should enter the battlefield attached to an illegal permanent it fails
continue;
@@ -513,7 +515,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
if (sa.hasParam("AttachedToPlayer")) {
FCollectionView<Player> list = AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("AttachedToPlayer"), sa);
if (!list.isEmpty()) {
Player attachedTo = player.getController().chooseSingleEntityForEffect(list, sa, tgtC + " - Select a player to attach to.");
Player attachedTo = player.getController().chooseSingleEntityForEffect(list, sa, Localizer.getInstance().getMessage("lblSelectAPlayerAttachSourceTo", tgtC.toString()));
tgtC.attachToEntity(attachedTo);
}
else { // When it should enter the battlefield attached to an illegal player it fails
@@ -560,7 +562,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
}
}
} else {
defender = player.getController().chooseSingleEntityForEffect(e, sa, "Declare a defender for " + movedCard );
defender = player.getController().chooseSingleEntityForEffect(e, sa, Localizer.getInstance().getMessage("lblChooseDefenderToAttackWithCard", CardTranslation.getTranslatedName(movedCard.getName())));
}
if (defender != null) {
combat.addAttacker(movedCard, defender);
@@ -727,7 +729,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
final StringBuilder sb = new StringBuilder();
sb.append(sa.getParam("AlternativeMessage")).append(" ");
sb.append(altFetchList.size()).append(" cards match your searching type in Alternate Zones.");
sb.append(altFetchList.size()).append(" " + Localizer.getInstance().getMessage("lblCardMatchSearchingTypeInAlternateZones"));
if (!decider.getController().confirmAction(sa, PlayerActionConfirmMode.ChangeZoneFromAltSource, sb.toString())) {
origin = alt;
@@ -749,7 +751,14 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
final boolean optional = sa.hasParam("Optional");
if (optional) {
String message = MessageUtil.formatMessage(defined ? "Put that card from {player's} " + Lang.joinHomogenous(origin).toLowerCase() + " to " + destination.name().toLowerCase() : "Search {player's} " + Lang.joinHomogenous(origin).toLowerCase() + "?", decider, player);
String prompt;
if (defined) {
prompt = Localizer.getInstance().getMessage("lblPutThatCardFromPlayerOriginToDestination", "{player's}", Lang.joinHomogenous(origin, ZoneType.Accessors.GET_TRANSLATED_NAME).toLowerCase(), destination.getTranslatedName().toLowerCase());
}
else {
prompt = Localizer.getInstance().getMessage("lblSearchPlayerZoneConfirm", "{player's}", Lang.joinHomogenous(origin, ZoneType.Accessors.GET_TRANSLATED_NAME).toLowerCase());
}
String message = MessageUtil.formatMessage(prompt , decider, player);
if (!decider.getController().confirmAction(sa, PlayerActionConfirmMode.ChangeZoneGeneral, message)) {
return;
}
@@ -801,10 +810,10 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
final int fetchNum = Math.min(player.getCardsIn(ZoneType.Library).size(), 4);
CardCollectionView shown = !decider.hasKeyword("LimitSearchLibrary") ? player.getCardsIn(ZoneType.Library) : player.getCardsIn(ZoneType.Library, fetchNum);
// Look at whole library before moving onto choosing a card
delayedReveal = new DelayedReveal(shown, ZoneType.Library, PlayerView.get(player), source.getName() + " - Looking at cards in ");
delayedReveal = new DelayedReveal(shown, ZoneType.Library, PlayerView.get(player), CardTranslation.getTranslatedName(source.getName()) + " - " + Localizer.getInstance().getMessage("lblLookingCardIn") + " ");
}
else if (origin.contains(ZoneType.Hand) && player.isOpponentOf(decider)) {
delayedReveal = new DelayedReveal(player.getCardsIn(ZoneType.Hand), ZoneType.Hand, PlayerView.get(player), source.getName() + " - Looking at cards in ");
delayedReveal = new DelayedReveal(player.getCardsIn(ZoneType.Hand), ZoneType.Hand, PlayerView.get(player), CardTranslation.getTranslatedName(source.getName()) + " - " + Localizer.getInstance().getMessage("lblLookingCardIn") + " ");
}
}
@@ -821,7 +830,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
continue;
}
SpellAbility tgtSA = decider.getController().getAbilityToPlay(tgtCard, sas);
if (!decider.getController().confirmAction(tgtSA, null, "Do you want to play " + tgtCard + "?")) {
if (!decider.getController().confirmAction(tgtSA, null, Localizer.getInstance().getMessage("lblDoYouWantPlayCard", CardTranslation.getTranslatedName(tgtCard.getName())))) {
continue;
}
// if played, that card cannot be found
@@ -853,7 +862,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
final boolean champion = sa.hasParam("Champion");
final boolean forget = sa.hasParam("ForgetChanged");
final boolean imprint = sa.hasParam("Imprint");
String selectPrompt = sa.hasParam("SelectPrompt") ? sa.getParam("SelectPrompt") : MessageUtil.formatMessage("Select a card from {player's} " + Lang.joinHomogenous(origin).toLowerCase(), decider, player);
String selectPrompt = sa.hasParam("SelectPrompt") ? sa.getParam("SelectPrompt") : MessageUtil.formatMessage(Localizer.getInstance().getMessage("lblSelectCardFromPlayerZone", "{player's}", Lang.joinHomogenous(origin, ZoneType.Accessors.GET_TRANSLATED_NAME).toLowerCase()), decider, player);
final String totalcmc = sa.getParam("WithTotalCMC");
int totcmc = AbilityUtils.calculateAmount(source, totalcmc, sa);
@@ -866,9 +875,10 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
if (! sa.hasParam("SelectPrompt")) {
// new default messaging for multi select
if (fetchList.size() > changeNum) {
selectPrompt = MessageUtil.formatMessage("Select up to " + changeNum + " cards from {player's} " + Lang.joinHomogenous(origin).toLowerCase(), decider, player);
//Select up to %changeNum cards from %players %origin
selectPrompt = MessageUtil.formatMessage(Localizer.getInstance().getMessage("lblSelectUpToNumCardFromPlayerZone", String.valueOf(changeNum), "{player's}", Lang.joinHomogenous(origin, ZoneType.Accessors.GET_TRANSLATED_NAME).toLowerCase()), decider, player);
} else {
selectPrompt = MessageUtil.formatMessage("Select cards from {player's} " + Lang.joinHomogenous(origin).toLowerCase(), decider, player);
selectPrompt = MessageUtil.formatMessage(Localizer.getInstance().getMessage("lblSelectCardsFromPlayerZone", "{player's}", Lang.joinHomogenous(origin, ZoneType.Accessors.GET_TRANSLATED_NAME).toLowerCase()), decider, player);
}
}
// ensure that selection is within maximum allowed changeNum
@@ -930,7 +940,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
if (c == null) {
final int num = Math.min(fetchList.size(), changeNum - i);
String message = "Cancel Search? Up to " + num + " more card" + (num != 1 ? "s" : "") + " can be selected.";
String message = Localizer.getInstance().getMessage("lblCancelSearchUpToSelectNumCards", String.valueOf(num));
if (fetchList.isEmpty() || decider.getController().confirmAction(sa, PlayerActionConfirmMode.ChangeZoneGeneral, message)) {
break;
@@ -1001,7 +1011,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
if (!list.isEmpty()) {
Card attachedTo = null;
if (list.size() > 1) {
attachedTo = decider.getController().chooseSingleEntityForEffect(list, sa, c + " - Select a card to attach to.");
attachedTo = decider.getController().chooseSingleEntityForEffect(list, sa, Localizer.getInstance().getMessage("lblSelectACardAttachSourceTo", CardTranslation.getTranslatedName(c.getName())));
}
else {
attachedTo = list.get(0);
@@ -1019,7 +1029,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
if (sa.hasParam("AttachedToPlayer")) {
FCollectionView<Player> list = AbilityUtils.getDefinedPlayers(source, sa.getParam("AttachedToPlayer"), sa);
if (!list.isEmpty()) {
Player attachedTo = player.getController().chooseSingleEntityForEffect(list, sa, c + " - Select a player to attach to.");
Player attachedTo = player.getController().chooseSingleEntityForEffect(list, sa, Localizer.getInstance().getMessage("lblSelectACardAttachSourceTo", CardTranslation.getTranslatedName(c.getName())));
c.attachToEntity(attachedTo);
}
else { // When it should enter the battlefield attached to an illegal permanent it fails
@@ -1042,7 +1052,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
}
}
} else {
defender = player.getController().chooseSingleEntityForEffect(e, sa, "Declare a defender for " + c );
defender = player.getController().chooseSingleEntityForEffect(e, sa, Localizer.getInstance().getMessage("lblChooseDefenderToAttackWithCard", CardTranslation.getTranslatedName(c.getName())));
}
if (defender != null) {
combat.addAttacker(c, defender);

View File

@@ -18,6 +18,7 @@ import forge.game.spellability.TargetRestrictions;
import forge.game.zone.ZoneType;
import forge.util.Aggregates;
import forge.util.Lang;
import forge.util.Localizer;
import org.apache.commons.lang3.StringUtils;
@@ -82,7 +83,7 @@ public class ChooseCardEffect extends SpellAbilityEffect {
for (final String type : CardType.getBasicTypes()) {
final CardCollectionView cl = CardLists.getType(land, type);
if (!cl.isEmpty()) {
final String prompt = "Choose " + Lang.nounWithAmount(1, type);
final String prompt = Localizer.getInstance().getMessage("lblChoose") + " " + Lang.nounWithAmount(1, type);
Card c = p.getController().chooseSingleEntityForEffect(cl, sa, prompt, false);
if (c != null) {
chosen.add(c);
@@ -98,10 +99,10 @@ public class ChooseCardEffect extends SpellAbilityEffect {
int chosenP = 0;
while (!creature.isEmpty()) {
Card c = p.getController().chooseSingleEntityForEffect(creature, sa,
"Select creature(s) with total power less than or equal to " + (totP - chosenP - negativeNum)
+ "\r\n(Selected:" + chosenPool + ")\r\n" + "(Total Power: " + chosenP + ")", chosenP <= totP);
Localizer.getInstance().getMessage("lblSelectCreatureWithTotalPowerLessOrEqualTo", (totP - chosenP - negativeNum))
+ "\r\n(" + Localizer.getInstance().getMessage("lblSelected") + ":" + chosenPool + ")\r\n(" + Localizer.getInstance().getMessage("lblTotalPowerNum", chosenP) + ")", chosenP <= totP);
if (c == null) {
if (p.getController().confirmAction(sa, PlayerActionConfirmMode.OptionalChoose, "Cancel Choose?")) {
if (p.getController().confirmAction(sa, PlayerActionConfirmMode.OptionalChoose, Localizer.getInstance().getMessage("lblCancelChooseConfirm"))) {
break;
}
} else {
@@ -118,7 +119,7 @@ public class ChooseCardEffect extends SpellAbilityEffect {
if (sa.hasParam("AtRandom") && !choices.isEmpty()) {
Aggregates.random(choices, validAmount, chosen);
} else {
String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : "Choose a card ";
String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : Localizer.getInstance().getMessage("lblChooseaCard") + " ";
chosen.addAll(p.getController().chooseCardsForEffect(choices, sa, title, minAmount, validAmount, !sa.hasParam("Mandatory")));
}
}

View File

@@ -22,6 +22,7 @@ import forge.game.spellability.TargetRestrictions;
import forge.item.PaperCard;
import forge.util.Aggregates;
import forge.util.ComparableOp;
import forge.util.Localizer;
import org.apache.commons.lang3.StringUtils;
@@ -57,6 +58,15 @@ public class ChooseCardNameEffect extends SpellAbilityEffect {
validDesc = sa.getParam("ValidDesc");
}
String message;
if (sa.hasParam("SelectPrompt")) {
message = sa.getParam("SelectPrompt");
} else if (validDesc.equals("card")) {
message = Localizer.getInstance().getMessage("lblChooseACardName");
} else {
message = Localizer.getInstance().getMessage("lblChooseASpecificCard", validDesc);
}
boolean randomChoice = sa.hasParam("AtRandom");
boolean chooseFromDefined = sa.hasParam("ChooseFromDefinedCards");
for (final Player p : tgtPlayers) {
@@ -99,11 +109,9 @@ public class ChooseCardNameEffect extends SpellAbilityEffect {
}
}
Collections.sort(faces);
chosen = p.getController().chooseCardName(sa, faces, "Choose a card name");
chosen = p.getController().chooseCardName(sa, faces, message);
} else {
// use CardFace because you might name a alternate name
final String message = validDesc.equals("card") ? "Name a card" : "Name a " + validDesc + " card.";
// use CardFace because you might name a alternate names
Predicate<ICardFace> cpp = Predicates.alwaysTrue();
if (sa.hasParam("ValidCards")) {
cpp = CardFacePredicates.valid(valid);
@@ -114,9 +122,12 @@ public class ChooseCardNameEffect extends SpellAbilityEffect {
host.setNamedCard(chosen);
if(!randomChoice) {
p.getGame().getAction().nofityOfValue(sa, host, p.getName() + " picked " + chosen, p);
p.getGame().getAction().nofityOfValue(sa, host, Localizer.getInstance().getMessage("lblPlayerPickedChosen", p.getName(), chosen), p);
p.setNamedCard(chosen);
}
if (sa.hasParam("NoteFor")) {
p.addNoteForName(sa.getParam("NoteFor"), "Name:" + chosen);
}
}
}
}

View File

@@ -7,6 +7,7 @@ import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.util.Lang;
import forge.util.Localizer;
import java.util.ArrayList;
import java.util.Arrays;
@@ -49,27 +50,25 @@ public class ChooseColorEffect extends SpellAbilityEffect {
List<String> chosenColors;
int cntMin = sa.hasParam("TwoColors") ? 2 : 1;
int cntMax = sa.hasParam("TwoColors") ? 2 : sa.hasParam("OrColors") ? colorChoices.size() : 1;
String prompt;
String prompt = null;
if (cntMax == 1) {
prompt = "Choose a color";
prompt = Localizer.getInstance().getMessage("lblChooseAColor");
}
else {
prompt = "Choose " + Lang.getNumeral(cntMin);
if (cntMax > cntMin) {
if (cntMax >= MagicColor.NUMBER_OR_COLORS) {
prompt += " or more";
prompt = Localizer.getInstance().getMessage("lblAtLastChooseNumColors", Lang.getNumeral(cntMin));
} else {
prompt += " to " + Lang.getNumeral(cntMax);
prompt = Localizer.getInstance().getMessage("lblChooseSpecifiedRangeColors", Lang.getNumeral(cntMin), Lang.getNumeral(cntMax));
}
}
prompt += " colors";
}
chosenColors = p.getController().chooseColors(prompt, sa, cntMin, cntMax, colorChoices);
if (chosenColors.isEmpty()) {
return;
}
card.setChosenColors(chosenColors);
p.getGame().getAction().nofityOfValue(sa, card, p.getName() + " picked " + Lang.joinHomogenous(chosenColors), p);
p.getGame().getAction().nofityOfValue(sa, card, Localizer.getInstance().getMessage("lblPlayerPickedChosen", p.getName(), Lang.joinHomogenous(chosenColors)), p);
}
}
}

View File

@@ -10,6 +10,7 @@ import forge.game.player.Player;
import forge.game.player.PlayerController.BinaryChoiceType;
import forge.game.spellability.SpellAbility;
import forge.util.collect.FCollection;
import forge.util.Localizer;
public class ChooseDirectionEffect extends SpellAbilityEffect {
@Override
@@ -18,11 +19,11 @@ public class ChooseDirectionEffect extends SpellAbilityEffect {
final Game game = source.getGame();
final FCollection<Player> left = new FCollection<>(game.getPlayers());
// TODO: We'd better set up turn order UI here
final String info = "Left (clockwise): " + left + "\r\nRight (anticlockwise):" + Lists.reverse(left);
final String info = Localizer.getInstance().getMessage("lblLeftClockwise") + ": " + left + "\r\n" + Localizer.getInstance().getMessage("lblRightAntiClockwise") + ":" + Lists.reverse(left);
sa.getActivatingPlayer().getController().notifyOfValue(sa, source, info);
boolean chosen = sa.getActivatingPlayer().getController().chooseBinary(sa,
"Choose a direction", BinaryChoiceType.LeftOrRight);
Localizer.getInstance().getMessage("lblChooseDirection"), BinaryChoiceType.LeftOrRight);
source.setChosenDirection(chosen ? Direction.Left : Direction.Right);
}
}

View File

@@ -9,6 +9,7 @@ import forge.game.event.GameEventCardModeChosen;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.util.MyRandom;
import forge.util.Localizer;
import java.util.List;
@@ -69,7 +70,7 @@ public class ChooseGenericEffect extends SpellAbilityEffect {
int idxChosen = MyRandom.getRandom().nextInt(abilities.size());
chosenSA = abilities.get(idxChosen);
} else {
chosenSA = p.getController().chooseSingleSpellForEffect(abilities, sa, "Choose one",
chosenSA = p.getController().chooseSingleSpellForEffect(abilities, sa, Localizer.getInstance().getMessage("lblChooseOne"),
ImmutableMap.of());
}

View File

@@ -10,6 +10,7 @@ import forge.game.spellability.AbilitySub;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.util.MyRandom;
import forge.util.Localizer;
import java.util.List;
import java.util.Map;
@@ -57,7 +58,7 @@ public class ChooseNumberEffect extends SpellAbilityEffect {
chosen = MyRandom.getRandom().nextInt(max - min) + min;
p.getGame().getAction().nofityOfValue(sa, p, Integer.toString(chosen), null);
} else {
String title = sa.hasParam("ListTitle") ? sa.getParam("ListTitle") : "Choose a number";
String title = sa.hasParam("ListTitle") ? sa.getParam("ListTitle") : Localizer.getInstance().getMessage("lblChooseNumber");
if (anyNumber) {
Integer value = p.getController().announceRequirements(sa, title, true);
chosen = (value == null ? 0 : value);
@@ -72,7 +73,7 @@ public class ChooseNumberEffect extends SpellAbilityEffect {
card.setChosenNumber(chosen);
}
if (sa.hasParam("Notify")) {
p.getGame().getAction().nofityOfValue(sa, card, p.getName() + " picked " + chosen, p);
p.getGame().getAction().nofityOfValue(sa, card, Localizer.getInstance().getMessage("lblPlayerPickedChosen", p.getName(), chosen), p);
}
}
}
@@ -85,7 +86,7 @@ public class ChooseNumberEffect extends SpellAbilityEffect {
for (Entry<Player, Integer> ev : chooseMap.entrySet()) {
int num = ev.getValue();
Player player = ev.getKey();
sb.append(player).append(" chose ").append(num);
sb.append(Localizer.getInstance().getMessage("lblPlayerChoseNum", player.getName(), String.valueOf(num)));
sb.append("\r\n");
if (num > highest) {
highestNum.clear();

View File

@@ -9,6 +9,7 @@ import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.util.Aggregates;
import forge.util.collect.FCollectionView;
import forge.util.Localizer;
import java.util.List;
@@ -37,7 +38,7 @@ public class ChoosePlayerEffect extends SpellAbilityEffect {
final FCollectionView<Player> choices = sa.hasParam("Choices") ? AbilityUtils.getDefinedPlayers(
sa.getHostCard(), sa.getParam("Choices"), sa) : sa.getActivatingPlayer().getGame().getPlayersInTurnOrder();
final String choiceDesc = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : "Choose a player";
final String choiceDesc = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : Localizer.getInstance().getMessage("lblChoosePlayer");
final boolean random = sa.hasParam("Random");
for (final Player p : tgtPlayers) {

View File

@@ -12,6 +12,7 @@ import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityStackInstance;
import forge.game.spellability.TargetRestrictions;
import forge.game.zone.ZoneType;
import forge.util.Localizer;
import org.apache.commons.lang3.StringUtils;
@@ -134,7 +135,7 @@ public class ChooseSourceEffect extends SpellAbilityEffect {
final CardCollection chosen = new CardCollection();
if (tgt == null || p.canBeTargetedBy(sa)) {
for (int i = 0; i < validAmount; i++) {
final String choiceTitle = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : "Choose a source ";
final String choiceTitle = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : Localizer.getInstance().getMessage("lblChooseSource") + " ";
Card o = null;
do {
o = p.getController().chooseSingleEntityForEffect(sourcesToChooseFrom, sa, choiceTitle);

View File

@@ -12,6 +12,7 @@ import forge.game.spellability.SpellAbility;
import forge.game.trigger.TriggerType;
import forge.game.zone.PlayerZone;
import forge.game.zone.ZoneType;
import forge.util.Localizer;
import java.util.Map;
@@ -74,7 +75,7 @@ public class ClashEffect extends SpellAbilityEffect {
*/
final Card source = sa.getHostCard();
final Player player = source.getController();
final Player opponent = sa.getActivatingPlayer().getController().chooseSingleEntityForEffect(player.getOpponents(), sa, "Choose a opponent") ;
final Player opponent = sa.getActivatingPlayer().getController().chooseSingleEntityForEffect(player.getOpponents(), sa, Localizer.getInstance().getMessage("lblChooseOpponent")) ;
final ZoneType lib = ZoneType.Library;
if (sa.hasParam("RememberClasher")) {
@@ -110,11 +111,11 @@ public class ClashEffect extends SpellAbilityEffect {
// TODO: Split cards will return two CMC values, so both players may become winners of clash
reveal.append(player).append(" reveals: ").append(pCard.getName()).append(". CMC = ").append(pCMC);
reveal.append(player).append(" " + Localizer.getInstance().getMessage("lblReveals") + ": ").append(pCard.getName()).append(". " + Localizer.getInstance().getMessage("lblCMC") + "= ").append(pCMC);
reveal.append("\r\n");
reveal.append(opponent).append(" reveals: ").append(oCard.getName()).append(". CMC = ").append(oCMC);
reveal.append(opponent).append(" " + Localizer.getInstance().getMessage("lblReveals") + ": ").append(oCard.getName()).append(". " + Localizer.getInstance().getMessage("lblCMC") + "= ").append(oCMC);
reveal.append("\r\n\r\n");
reveal.append(player).append(pCMC > oCMC ? " wins clash." : " loses clash.");
reveal.append(player).append(pCMC > oCMC ? " " + Localizer.getInstance().getMessage("lblWinsClash") + "." : " " + Localizer.getInstance().getMessage("lblLosesClash") + ".");
player.getGame().getAction().nofityOfValue(sa, source, reveal.toString(), null);
clashMoveToTopOrBottom(player, pCard, sa);

View File

@@ -9,6 +9,8 @@ import forge.game.event.GameEventCardStatsChanged;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.Localizer;
import forge.util.CardTranslation;
import java.util.Arrays;
import java.util.List;
@@ -78,7 +80,7 @@ public class CloneEffect extends SpellAbilityEffect {
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host);
String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : "Choose a card ";
String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : Localizer.getInstance().getMessage("lblChooseaCard") + " ";
cardToCopy = activator.getController().chooseSingleEntityForEffect(choices, sa, title, false);
} else if (sa.hasParam("Defined")) {
List<Card> cloneSources = AbilityUtils.getDefinedCards(host, sa.getParam("Defined"), sa);
@@ -93,7 +95,7 @@ public class CloneEffect extends SpellAbilityEffect {
}
final boolean optional = sa.hasParam("Optional");
if (optional && !host.getController().getController().confirmAction(sa, null, "Do you want to copy " + cardToCopy + "?")) {
if (optional && !host.getController().getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantCopy", CardTranslation.getTranslatedName(cardToCopy.getName())))) {
return;
}

View File

@@ -7,6 +7,7 @@ import forge.game.card.CardCollectionView;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.Localizer;
import java.util.List;
@@ -35,9 +36,9 @@ public class ControlExchangeVariantEffect extends SpellAbilityEffect {
CardCollectionView list2 = AbilityUtils.filterListByType(player2.getCardsIn(zone), type, sa);
int max = Math.min(list1.size(), list2.size());
// choose the same number of cards
CardCollectionView chosen1 = activator.getController().chooseCardsForEffect(list1, sa, "Choose cards: " + player1, 0, max, true);
CardCollectionView chosen1 = activator.getController().chooseCardsForEffect(list1, sa, Localizer.getInstance().getMessage("lblChooseCards") + ":" + player1, 0, max, true);
int num = chosen1.size();
CardCollectionView chosen2 = activator.getController().chooseCardsForEffect(list2, sa, "Choose cards: " + player2, num, num, true);
CardCollectionView chosen2 = activator.getController().chooseCardsForEffect(list2, sa, Localizer.getInstance().getMessage("lblChooseCards") + ":" + player2, num, num, true);
// check all cards can be controlled by the other player
for (final Card c : chosen1) {
if (!c.canBeControlledBy(player2)) {

View File

@@ -22,6 +22,8 @@ import forge.game.spellability.Ability;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.collect.FCollectionView;
import forge.util.Localizer;
import forge.util.CardTranslation;
public class ControlGainEffect extends SpellAbilityEffect {
/* (non-Javadoc)
@@ -227,7 +229,7 @@ public class ControlGainEffect extends SpellAbilityEffect {
final FCollectionView<GameEntity> e = combat.getDefenders();
final GameEntity defender = sa.getActivatingPlayer().getController().chooseSingleEntityForEffect(e, sa,
"Declare a defender for " + tgtC);
Localizer.getInstance().getMessage("lblChooseDefenderToAttackWithCard", CardTranslation.getTranslatedName(tgtC.getName())));
if (defender != null) {
combat.addAttacker(tgtC, defender);

View File

@@ -27,6 +27,8 @@ import forge.util.Aggregates;
import forge.util.TextUtil;
import forge.util.collect.FCollectionView;
import forge.util.PredicateString.StringOp;
import forge.util.Localizer;
import forge.util.CardTranslation;
import org.apache.commons.lang3.StringUtils;
@@ -64,7 +66,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
final long timestamp = game.getNextTimestamp();
if (sa.hasParam("Optional")) {
if (!activator.getController().confirmAction(sa, null, "Copy this permanent?")) {
if (!activator.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblCopyPermanentConfirm"))) {
return;
}
}
@@ -145,7 +147,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
CardCollectionView choices = game.getCardsIn(ZoneType.Battlefield);
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host);
if (!choices.isEmpty()) {
String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : "Choose a card ";
String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : Localizer.getInstance().getMessage("lblChooseaCard") +" ";
Card choosen = chooser.getController().chooseSingleEntityForEffect(choices, sa, title, false);
@@ -206,12 +208,12 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
GameEntity defender;
if ("True".equals(attacked)) {
FCollectionView<GameEntity> defs = game.getCombat().getDefenders();
defender = c.getController().getController().chooseSingleEntityForEffect(defs, sa, "Choose which defender to attack with " + c, false);
defender = c.getController().getController().chooseSingleEntityForEffect(defs, sa, Localizer.getInstance().getMessage("lblChooseDefenderToAttackWithCard", CardTranslation.getTranslatedName(c.getName())), false);
} else {
defender = AbilityUtils.getDefinedPlayers(host, sa.getParam("CopyAttacking"), sa).get(0);
if (sa.hasParam("ChoosePlayerOrPlaneswalker") && defender != null) {
FCollectionView<GameEntity> defs = game.getCombat().getDefendersControlledBy((Player) defender);
defender = c.getController().getController().chooseSingleEntityForEffect(defs, sa, "Choose which defender to attack with " + c + " {defender: "+ defender + "}", false);
defender = c.getController().getController().chooseSingleEntityForEffect(defs, sa, Localizer.getInstance().getMessage("lblChooseDefenderToAttackWithCard", CardTranslation.getTranslatedName(c.getName())) + " {" + Localizer.getInstance().getMessage("lblDefender") + ": " + defender + "}", false);
}
}
game.getCombat().addAttacker(copyInPlay, defender);
@@ -243,7 +245,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
list = CardLists.getValidCards(list, sa.getParam("AttachedTo"), copyInPlay.getController(), copyInPlay);
}
if (!list.isEmpty()) {
Card attachedTo = activator.getController().chooseSingleEntityForEffect(list, sa, copyInPlay + " - Select a card to attach to.");
Card attachedTo = activator.getController().chooseSingleEntityForEffect(list, sa, Localizer.getInstance().getMessage("lblSelectACardAttachSourceTo", copyInPlay.toString()));
copyInPlay.attachToEntity(attachedTo);
} else {

View File

@@ -15,6 +15,8 @@ import forge.game.player.Player;
import forge.game.spellability.AbilitySub;
import forge.game.spellability.SpellAbility;
import forge.util.Lang;
import forge.util.Localizer;
import forge.util.CardTranslation;
import java.util.ArrayList;
import java.util.Iterator;
@@ -66,7 +68,7 @@ public class CopySpellAbilityEffect extends SpellAbilityEffect {
}
boolean isOptional = sa.hasParam("Optional");
if (isOptional && !controller.getController().confirmAction(sa, null, "Do you want to copy the spell " + card + "?")) {
if (isOptional && !controller.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoyouWantCopyTheSpell", CardTranslation.getTranslatedName(card.getName())))) {
return;
}
@@ -84,7 +86,7 @@ public class CopySpellAbilityEffect extends SpellAbilityEffect {
final int spellCount = Integer.parseInt(sa.getParam("CopyMultipleSpells"));
for (int multi = 0; multi < spellCount && !tgtSpells.isEmpty(); multi++) {
String prompt = "Select " + Lang.getOrdinal(multi + 1) + " spell to copy to stack";
String prompt = Localizer.getInstance().getMessage("lblSelectMultiSpellCopyToStack", Lang.getOrdinal(multi + 1));
SpellAbility chosen = controller.getController().chooseSingleSpellForEffect(tgtSpells, sa, prompt,
ImmutableMap.of());
SpellAbility copiedSpell = CardFactory.copySpellAbilityAndPossiblyHost(card, chosen.getHostCard(), chosen, true);
@@ -96,7 +98,7 @@ public class CopySpellAbilityEffect extends SpellAbilityEffect {
}
else if (sa.hasParam("CopyForEachCanTarget")) {
SpellAbility chosenSA = controller.getController().chooseSingleSpellForEffect(tgtSpells, sa,
"Select a spell to copy", ImmutableMap.of());
Localizer.getInstance().getMessage("lblSelectASpellCopy"), ImmutableMap.of());
chosenSA.setActivatingPlayer(controller);
// Find subability or rootability that has targets
SpellAbility targetedSA = chosenSA;
@@ -144,7 +146,7 @@ public class CopySpellAbilityEffect extends SpellAbilityEffect {
valid.remove(originalTarget);
mayChooseNewTargets = false;
if (sa.hasParam("ChooseOnlyOne")) {
Card choice = controller.getController().chooseSingleEntityForEffect(valid, sa, "Choose one");
Card choice = controller.getController().chooseSingleEntityForEffect(valid, sa, Localizer.getInstance().getMessage("lblChooseOne"));
SpellAbility copy = CardFactory.copySpellAbilityAndPossiblyHost(card, chosenSA.getHostCard(), chosenSA, true);
resetFirstTargetOnCopy(copy, choice, targetedSA);
copies.add(copy);
@@ -164,7 +166,7 @@ public class CopySpellAbilityEffect extends SpellAbilityEffect {
}
else {
SpellAbility chosenSA = controller.getController().chooseSingleSpellForEffect(tgtSpells, sa,
"Select a spell to copy", ImmutableMap.of());
Localizer.getInstance().getMessage("lblSelectASpellCopy"), ImmutableMap.of());
chosenSA.setActivatingPlayer(controller);
for (int i = 0; i < amount; i++) {
SpellAbility copy = CardFactory.copySpellAbilityAndPossiblyHost(

View File

@@ -12,6 +12,7 @@ import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityStackInstance;
import forge.game.spellability.SpellPermanent;
import forge.game.trigger.TriggerType;
import forge.util.Localizer;
import java.util.Arrays;
import java.util.List;
@@ -174,7 +175,7 @@ public class CounterEffect extends SpellAbilityEffect {
String destination = srcSA.hasParam("Destination") ? srcSA.getParam("Destination") : tgtSA.isAftermath() ? "Exile" : "Graveyard";
if (srcSA.hasParam("DestinationChoice")) {//Hinder
List<String> pos = Arrays.asList(srcSA.getParam("DestinationChoice").split(","));
destination = srcSA.getActivatingPlayer().getController().chooseSomeType("a destination to remove", tgtSA, pos, null);
destination = srcSA.getActivatingPlayer().getController().chooseSomeType(Localizer.getInstance().getMessage("lblRemoveDestination"), tgtSA, pos, null);
}
if (tgtSA.isAbility()) {
// For Ability-targeted counterspells - do not move it anywhere,

View File

@@ -12,6 +12,8 @@ import forge.game.player.Player;
import forge.game.player.PlayerController;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.Localizer;
import forge.util.CardTranslation;
import java.util.List;
import java.util.Map;
@@ -109,10 +111,7 @@ public class CountersMoveEffect extends SpellAbilityEffect {
// only select cards if the counterNum is any
if (counterNum.equals("Any")) {
StringBuilder sb = new StringBuilder();
sb.append("Choose cards to take ").append(cType.getName()).append(" counters from");
srcCards = player.getController().chooseCardsForEffect(srcCards, sa, sb.toString(), 0, srcCards.size(), true);
srcCards = player.getController().chooseCardsForEffect(srcCards, sa, Localizer.getInstance().getMessage("lblChooseTakeCountersCard", cType.getName()), 0, srcCards.size(), true);
}
for (Card src : srcCards) {
@@ -134,10 +133,7 @@ public class CountersMoveEffect extends SpellAbilityEffect {
params.put("CounterType", cType);
params.put("Source", src);
params.put("Target", dest);
StringBuilder sb = new StringBuilder();
sb.append("Take how many ").append(cType.getName());
sb.append(" counters from ").append(src).append("?");
cnum = player.getController().chooseNumber(sa, sb.toString(), 0, cmax, params);
cnum = player.getController().chooseNumber(sa, Localizer.getInstance().getMessage("lblTakeHowManyTargetCounterFromCard", cType.getName(), CardTranslation.getTranslatedName(src.getName())), 0, cmax, params);
} else {
cnum = AbilityUtils.calculateAmount(host, counterNum, sa);
}
@@ -171,12 +167,8 @@ public class CountersMoveEffect extends SpellAbilityEffect {
tgtCards = CardLists.getValidCards(tgtCards, sa.getParam("ValidDefined"), player, host, sa);
if (counterNum.equals("Any")) {
StringBuilder sb = new StringBuilder();
sb.append("Choose cards to get ").append(cType.getName());
sb.append(" counters from ").append(source).append(".");
tgtCards = player.getController().chooseCardsForEffect(
tgtCards, sa, sb.toString(), 0, tgtCards.size(), true);
tgtCards = player.getController().chooseCardsForEffect(tgtCards, sa,
Localizer.getInstance().getMessage("lblChooseCardToGetCountersFrom", cType.getName(), CardTranslation.getTranslatedName(source.getName())), 0, tgtCards.size(), true);
}
boolean updateSource = false;
@@ -200,9 +192,7 @@ public class CountersMoveEffect extends SpellAbilityEffect {
params.put("CounterType", cType);
params.put("Source", source);
params.put("Target", cur);
StringBuilder sb = new StringBuilder();
sb.append("Put how many ").append(cType.getName()).append(" counters on ").append(cur).append("?");
int cnum = player.getController().chooseNumber(sa, sb.toString(), 0, source.getCounters(cType), params);
int cnum = player.getController().chooseNumber(sa, Localizer.getInstance().getMessage("lblPutHowManyTargetCounterOnCard", cType.getName(), CardTranslation.getTranslatedName(cur.getName())), 0, source.getCounters(cType), params);
if (cnum > 0) {
source.subtractCounter(cType, cnum);
@@ -260,10 +250,7 @@ public class CountersMoveEffect extends SpellAbilityEffect {
params.put("CounterType", cType);
params.put("Source", source);
params.put("Target", cur);
StringBuilder sb = new StringBuilder();
sb.append("Take how many ").append(cType.getName());
sb.append(" counters from ").append(source).append("?");
cntToMove = pc.chooseNumber(sa, sb.toString(), 0, cntToMove, params);
cntToMove = pc.chooseNumber(sa, Localizer.getInstance().getMessage("lblTakeHowManyTargetCounterFromCard", cType.getName(), CardTranslation.getTranslatedName(source.getName())), 0, cntToMove, params);
}
if (source.getCounters(cType) >= cntToMove) {
@@ -289,17 +276,15 @@ public class CountersMoveEffect extends SpellAbilityEffect {
Map<String, Object> params = Maps.newHashMap();
params.put("Source", source);
params.put("Target", dest);
String title = "Select type counters to remove";
String title = Localizer.getInstance().getMessage("lblSelectRemoveCounterType");
CounterType chosenType = pc.chooseCounterType(typeChoices, sa, title, params);
params = Maps.newHashMap();
params.put("CounterType", chosenType);
params.put("Source", source);
params.put("Target", dest);
StringBuilder sb = new StringBuilder();
sb.append("Take how many ").append(chosenType.getName()).append(" counters?");
int chosenAmount = pc.chooseNumber(
sa, sb.toString(), 0, Math.min(tgtCounters.get(chosenType), cntToMove), params);
int chosenAmount = pc.chooseNumber(sa, Localizer.getInstance().getMessage("lblTakeHowManyTargetCounters", chosenType.getName()),
0, Math.min(tgtCounters.get(chosenType), cntToMove), params);
if (chosenAmount > 0) {
dest.addCounter(chosenType, chosenAmount, player, true, table);

View File

@@ -14,6 +14,7 @@ import forge.game.player.PlayerPredicates;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.collect.FCollection;
import forge.util.Localizer;
import java.util.List;
@@ -42,7 +43,7 @@ public class CountersProliferateEffect extends SpellAbilityEffect {
list.addAll(CardLists.filter(game.getCardsIn(ZoneType.Battlefield), CardPredicates.hasCounters()));
List<GameEntity> result = pc.chooseEntitiesForEffect(list, 0, list.size(), null, sa,
"Choose any number of permanents and/or players for proliferate", p);
Localizer.getInstance().getMessage("lblChooseProliferateTarget"), p);
GameEntityCounterTable table = new GameEntityCounterTable();
for (final GameEntity ge : result) {

View File

@@ -26,6 +26,8 @@ import forge.game.trigger.TriggerType;
import forge.game.zone.Zone;
import forge.game.zone.ZoneType;
import forge.util.Aggregates;
import forge.util.Localizer;
import forge.util.CardTranslation;
import java.util.Map;
import java.util.Iterator;
@@ -129,7 +131,7 @@ public class CountersPutEffect extends SpellAbilityEffect {
if (sa.hasParam("Bolster")) {
CardCollection creatsYouCtrl = CardLists.filter(activator.getCardsIn(ZoneType.Battlefield), Presets.CREATURES);
CardCollection leastToughness = new CardCollection(Aggregates.listWithMin(creatsYouCtrl, CardPredicates.Accessors.fnGetDefense));
tgtCards.addAll(pc.chooseCardsForEffect(leastToughness, sa, "Choose a creature with the least toughness", 1, 1, false));
tgtCards.addAll(pc.chooseCardsForEffect(leastToughness, sa, Localizer.getInstance().getMessage("lblChooseACreatureWithLeastToughness"), 1, 1, false));
tgtObjects.addAll(tgtCards);
} else {
tgtObjects.addAll(getDefinedOrTargeted(sa, "Defined"));
@@ -183,7 +185,7 @@ public class CountersPutEffect extends SpellAbilityEffect {
Map<String, Object> params = Maps.newHashMap();
params.put("Target", obj);
StringBuilder sb = new StringBuilder();
sb.append("Select counter type to add to ");
sb.append(Localizer.getInstance().getMessage("lblSelectCounterTypeAddTo") + " ");
sb.append(obj);
counterType = pc.chooseCounterType(choices, sa, sb.toString(), params);
}
@@ -199,7 +201,7 @@ public class CountersPutEffect extends SpellAbilityEffect {
Map<String, Object> params = Maps.newHashMap();
params.put("Target", obj);
params.put("CounterType", counterType);
counterAmount = pc.chooseNumber(sa, "How many counters?", 0, counterAmount, params);
counterAmount = pc.chooseNumber(sa, Localizer.getInstance().getMessage("lblHowManyCounters"), 0, counterAmount, params);
}
// Adapt need extra logic
@@ -235,8 +237,8 @@ public class CountersPutEffect extends SpellAbilityEffect {
continue;
}
String message = "Do you want to put " + counterAmount + " +1/+1 counters on " + gameCard + " ?";
Player chooser = pc.chooseSingleEntityForEffect(activator.getOpponents(), sa, "Choose an opponent");
String message = Localizer.getInstance().getMessage("lblDoYouWantPutTargetP1P1CountersOnCard", String.valueOf(counterAmount), CardTranslation.getTranslatedName(gameCard.getName()));
Player chooser = pc.chooseSingleEntityForEffect(activator.getOpponents(), sa, Localizer.getInstance().getMessage("lblChooseAnOpponent"));
if (chooser.getController().confirmAction(sa, PlayerActionConfirmMode.Tribute, message)) {
gameCard.setTributed(true);

View File

@@ -13,6 +13,7 @@ import forge.game.spellability.SpellAbility;
import forge.game.zone.Zone;
import forge.game.zone.ZoneType;
import forge.util.Lang;
import forge.util.Localizer;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
@@ -97,11 +98,11 @@ public class CountersPutOrRemoveEffect extends SpellAbilityEffect {
list = Lists.newArrayList(ctype);
}
String prompt = "Select type of counters to add or remove";
String prompt = Localizer.getInstance().getMessage("lblSelectCounterTypeToAddOrRemove");
CounterType chosenType = pc.chooseCounterType(list, sa, prompt, params);
params.put("CounterType", chosenType);
prompt = "What to do with that '" + chosenType.getName() + "' counter ";
prompt = Localizer.getInstance().getMessage("lblWhatToDoWithTargetCounter", chosenType.getName()) + " ";
Boolean putCounter = pc.chooseBinary(sa, prompt, BinaryChoiceType.AddOrRemove, params);
if (putCounter) {

View File

@@ -13,6 +13,7 @@ import forge.game.player.PlayerController;
import forge.game.spellability.SpellAbility;
import forge.game.zone.Zone;
import forge.game.zone.ZoneType;
import forge.util.Localizer;
import java.util.Map;
@@ -84,8 +85,8 @@ public class CountersRemoveEffect extends SpellAbilityEffect {
}
if (sa.hasParam("Optional")) {
String ctrs = cntToRemove > 1 ? "counters" : num.equals("All") ? "all counters" : "a counter";
if (!sa.getActivatingPlayer().getController().confirmAction(sa, null, "Remove " + ctrs + "?")) {
String ctrs = cntToRemove > 1 ? Localizer.getInstance().getMessage("lblCounters") : num.equals("All") ? Localizer.getInstance().getMessage("lblAllCounters") : Localizer.getInstance().getMessage("lblACounters");
if (!sa.getActivatingPlayer().getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblRemove") + " " + ctrs + "?")) {
return;
}
}
@@ -129,10 +130,7 @@ public class CountersRemoveEffect extends SpellAbilityEffect {
srcCards = game.getCardsIn(ZoneType.Battlefield);
srcCards = CardLists.getValidCards(srcCards, sa.getParam("ValidSource"), player, card, sa);
if (num.equals("Any")) {
StringBuilder sb = new StringBuilder();
sb.append("Choose cards to take ").append(counterType.getName()).append(" counters from");
srcCards = player.getController().chooseCardsForEffect(srcCards, sa, sb.toString(), 0, srcCards.size(), true);
srcCards = player.getController().chooseCardsForEffect(srcCards, sa, Localizer.getInstance().getMessage("lblChooseCardsToTakeTargetCounters", counterType.getName()), 0, srcCards.size(), true);
}
} else {
srcCards = getTargetCards(sa);
@@ -172,7 +170,7 @@ public class CountersRemoveEffect extends SpellAbilityEffect {
Map<String, Object> params = Maps.newHashMap();
params.put("Target", gameCard);
params.put("CounterType", type);
String title = "Select the number of " + type + " counters to remove";
String title = Localizer.getInstance().getMessage("lblSelectRemoveCountersNumberOfTarget", type);
cntToRemove = pc.chooseNumber(sa, title, 0, cntToRemove, params);
}
@@ -213,10 +211,10 @@ public class CountersRemoveEffect extends SpellAbilityEffect {
Map<String, Object> params = Maps.newHashMap();
params.put("Target", entity);
String prompt = "Select type of counters to remove";
String prompt = Localizer.getInstance().getMessage("lblSelectCountersTypeToRemove");
CounterType chosenType = pc.chooseCounterType(
ImmutableList.copyOf(tgtCounters.keySet()), sa, prompt, params);
prompt = "Select the number of " + chosenType.getName() + " counters to remove";
prompt = Localizer.getInstance().getMessage("lblSelectRemoveCountersNumberOfTarget", chosenType.getName());
int max = Math.min(cntToRemove, tgtCounters.get(chosenType));
params = Maps.newHashMap();
params.put("Target", entity);

View File

@@ -13,6 +13,7 @@ import forge.game.card.CardUtil;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.util.Lang;
import forge.util.Localizer;
import java.util.List;
import java.util.Map;
@@ -83,7 +84,7 @@ public class DamageDealEffect extends DamageBaseEffect {
List<GameObject> tgts = getTargets(sa);
if (sa.hasParam("OptionalDecider")) {
Player decider = Iterables.getFirst(AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("OptionalDecider"), sa), null);
if (decider != null && !decider.getController().confirmAction(sa, null, "Do you want to deal " + dmg + " damage to " + tgts + " ?")) {
if (decider != null && !decider.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoyouWantDealTargetDamageToTarget", String.valueOf(dmg), tgts.toString()))) {
return;
}
}

View File

@@ -22,6 +22,9 @@ import forge.game.zone.PlayerZone;
import forge.game.zone.ZoneType;
import forge.util.Lang;
import forge.util.TextUtil;
import forge.util.collect.FCollectionView;
import forge.util.Localizer;
import forge.util.CardTranslation;
import java.util.*;
@@ -99,13 +102,6 @@ public class DigEffect extends SpellAbilityEffect {
final TargetRestrictions tgt = sa.getTargetRestrictions();
final List<Player> tgtPlayers = getTargetPlayers(sa);
if (sa.hasParam("Choser")) {
final List<Player> choosers = AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("Choser"), sa);
if (!choosers.isEmpty()) {
chooser = choosers.get(0);
}
}
CardZoneTable table = new CardZoneTable();
GameEntityCounterTable counterTable = new GameEntityCounterTable();
for (final Player p : tgtPlayers) {
@@ -128,7 +124,7 @@ public class DigEffect extends SpellAbilityEffect {
game.getAction().reveal(top, p, false);
}
else if (sa.hasParam("RevealOptional")) {
String question = TextUtil.concatWithSpace("Reveal:", TextUtil.addSuffix(Lang.joinHomogenous(top),"?"));
String question = TextUtil.concatWithSpace(Localizer.getInstance().getMessage("lblReveal") + ":", TextUtil.addSuffix(Lang.joinHomogenous(top),"?"));
hasRevealed = p.getController().confirmAction(sa, null, question);
if (hasRevealed) {
@@ -151,7 +147,7 @@ public class DigEffect extends SpellAbilityEffect {
}
else if (!sa.hasParam("NoLooking")) {
// show the user the revealed cards
delayedReveal = new DelayedReveal(top, srcZone, PlayerView.get(p), host.getName() + " - Looking at cards in ");
delayedReveal = new DelayedReveal(top, srcZone, PlayerView.get(p), CardTranslation.getTranslatedName(host.getName()) + " - " + Localizer.getInstance().getMessage("lblLookingCardIn") + " ");
if (noMove) {
// Let the activating player see the cards even if they're not moved
@@ -164,7 +160,15 @@ public class DigEffect extends SpellAbilityEffect {
host.addRemembered(one);
}
}
if (sa.hasParam("Choser")) {
final FCollectionView<Player> choosers = AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("Choser"), sa);
if (!choosers.isEmpty()) {
chooser = player.getController().chooseSingleEntityForEffect(choosers, sa, "Choser:");
}
if (sa.hasParam("SetChosenPlayer")) {
host.setChosenPlayer(chooser);
}
}
if (!noMove) {
CardCollection movedCards;
rest.addAll(top);
@@ -194,8 +198,8 @@ public class DigEffect extends SpellAbilityEffect {
// Optional abilities that use a dialog box to prompt the user to skip the ability (e.g. Explorer's Scope, Quest for Ula's Temple)
if (optional && mayBeSkipped && !valid.isEmpty()) {
String prompt = !optionalAbilityPrompt.isEmpty() ? optionalAbilityPrompt : "Would you like to proceed with the optional ability for " + sa.getHostCard() + "?\n\n(" + sa.getDescription() + ")";
if (!p.getController().confirmAction(sa, null, TextUtil.fastReplace(prompt, "CARDNAME", sa.getHostCard().getName()))) {
String prompt = !optionalAbilityPrompt.isEmpty() ? optionalAbilityPrompt : Localizer.getInstance().getMessage("lblWouldYouLikeProceedWithOptionalAbility") + " " + sa.getHostCard() + "?\n\n(" + sa.getDescription() + ")";
if (!p.getController().confirmAction(sa, null, TextUtil.fastReplace(prompt, "CARDNAME", CardTranslation.getTranslatedName(sa.getHostCard().getName())))) {
return;
}
}
@@ -214,24 +218,24 @@ public class DigEffect extends SpellAbilityEffect {
}
for (final byte pair : MagicColor.COLORPAIR) {
Card chosen = chooser.getController().chooseSingleEntityForEffect(CardLists.filter(valid, CardPredicates.isExactlyColor(pair)),
delayedReveal, sa, "Choose one", false, p);
delayedReveal, sa, Localizer.getInstance().getMessage("lblChooseOne"), false, p);
if (chosen != null) {
movedCards.add(chosen);
}
}
chooser.getController().endTempShowCards();
if (!movedCards.isEmpty()) {
game.getAction().reveal(movedCards, chooser, true, chooser + " picked ");
game.getAction().reveal(movedCards, chooser, true, Localizer.getInstance().getMessage("lblPlayerPickedChosen", chooser.getName(), ""));
}
}
else if (allButOne) {
movedCards = new CardCollection(valid);
String prompt;
if (destZone2.equals(ZoneType.Library) && libraryPosition2 == 0) {
prompt = "Choose a card to leave on top of {player's} library";
prompt = Localizer.getInstance().getMessage("lblChooseACardToLeaveTargetLibraryTop", "{player's}");
}
else {
prompt = "Choose a card to leave in {player's} " + destZone2.name();
prompt = Localizer.getInstance().getMessage("lblChooseACardLeaveTarget", "{player's}", destZone2.getTranslatedName());
}
Card chosen = chooser.getController().chooseSingleEntityForEffect(valid, delayedReveal, sa, prompt, false, p);
@@ -245,19 +249,19 @@ public class DigEffect extends SpellAbilityEffect {
if (sa.hasParam("PrimaryPrompt")) {
prompt = sa.getParam("PrimaryPrompt");
} else {
prompt = "Choose card(s) to put into " + destZone1.name();
prompt = Localizer.getInstance().getMessage("lblChooseCardsPutIntoZone", destZone1.getTranslatedName());
if (destZone1.equals(ZoneType.Library)) {
if (libraryPosition == -1) {
prompt = "Choose card(s) to put on the bottom of {player's} library";
prompt = Localizer.getInstance().getMessage("lblChooseCardPutOnTargetLibarayBottom", "{player's}");
} else if (libraryPosition == 0) {
prompt = "Choose card(s) to put on top of {player's} library";
prompt = Localizer.getInstance().getMessage("lblChooseCardPutOnTargetLibarayTop", "{player's}");
}
}
}
movedCards = new CardCollection();
if (valid.isEmpty()) {
chooser.getController().notifyOfValue(sa, null, "No valid cards");
chooser.getController().notifyOfValue(sa, null, Localizer.getInstance().getMessage("lblNoValidCards"));
} else {
if ( p == chooser ) { // the digger can still see all the dug cards when choosing
chooser.getController().tempShowCards(top);
@@ -275,8 +279,7 @@ public class DigEffect extends SpellAbilityEffect {
}
if (!changeValid.isEmpty() && !sa.hasParam("ExileFaceDown") && !sa.hasParam("NoReveal")) {
game.getAction().reveal(movedCards, chooser, true,
chooser + " picked " + (movedCards.size() == 1 ? "this card" : "these cards") + " from ");
game.getAction().reveal(movedCards, chooser, true, Localizer.getInstance().getMessage("lblPlayerPickedCardFrom", chooser.getName()));
}
}
if (sa.hasParam("ForgetOtherRemembered")) {

View File

@@ -16,6 +16,7 @@ import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.zone.PlayerZone;
import forge.game.zone.ZoneType;
import forge.util.Localizer;
public class DigMultipleEffect extends SpellAbilityEffect {
@@ -74,15 +75,14 @@ public class DigMultipleEffect extends SpellAbilityEffect {
}
if (validMap.isEmpty()) {
chooser.getController().notifyOfValue(sa, null, "No valid cards");
chooser.getController().notifyOfValue(sa, null, Localizer.getInstance().getMessage("lblNoValidCards"));
continue;
}
CardCollection chosen = chooser.getController().chooseCardsForEffectMultiple(validMap, sa, "Choose cards");
CardCollection chosen = chooser.getController().chooseCardsForEffectMultiple(validMap, sa, Localizer.getInstance().getMessage("lblChooseCards"));
if (!chosen.isEmpty()) {
game.getAction().reveal(chosen, chooser, true,
chooser + " picked " + (chosen.size() == 1 ? "this card" : "these cards") + " from ");
game.getAction().reveal(chosen, chooser, true, Localizer.getInstance().getMessage("lblPlayerPickedCardFrom", chooser.getName()));
}
for (Card c : chosen) {

View File

@@ -11,6 +11,7 @@ import forge.game.spellability.SpellAbility;
import forge.game.zone.PlayerZone;
import forge.game.zone.ZoneType;
import forge.util.MyRandom;
import forge.util.Localizer;
import java.util.*;
@@ -86,6 +87,7 @@ public class DigUntilEffect extends SpellAbilityEffect {
int untilAmount = 1;
if (sa.hasParam("Amount")) {
untilAmount = AbilityUtils.calculateAmount(host, sa.getParam("Amount"), sa);
if (untilAmount == 0) return;
}
Integer maxRevealed = null;
@@ -113,7 +115,7 @@ public class DigUntilEffect extends SpellAbilityEffect {
continue;
}
if (!sa.usesTargeting() || p.canBeTargetedBy(sa)) {
if (optional && !p.getController().confirmAction(sa, null, "Do you want to dig your library?")) {
if (optional && !p.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantDigYourLibrary"))) {
continue;
}
CardCollection found = new CardCollection();
@@ -159,7 +161,7 @@ public class DigUntilEffect extends SpellAbilityEffect {
final Card c = itr.next();
final ZoneType origin = c.getZone().getZoneType();
if (optionalFound && !p.getController().confirmAction(sa, null,
"Do you want to put that card to " + foundDest.name() + "?")) {
Localizer.getInstance().getMessage("lblDoYouWantPutCardToZone", foundDest.getTranslatedName()))) {
continue;
} else {
Card m = null;

View File

@@ -15,6 +15,7 @@ import forge.game.zone.ZoneType;
import forge.util.Lang;
import forge.util.Aggregates;
import forge.util.TextUtil;
import forge.util.Localizer;
import org.apache.commons.lang3.StringUtils;
@@ -205,7 +206,7 @@ public class DiscardEffect extends SpellAbilityEffect {
if (!p.canDiscardBy(sa)) {
continue;
}
String message = "Would you like to discard " + numCards + " random card(s)?";
String message = Localizer.getInstance().getMessage("lblWouldYouLikeRandomDiscardTargetCard", String.valueOf(numCards));
boolean runDiscard = !sa.hasParam("Optional") || p.getController().confirmAction(sa, PlayerActionConfirmMode.Random, message);
if (runDiscard) {
@@ -257,7 +258,7 @@ public class DiscardEffect extends SpellAbilityEffect {
final CardCollectionView dPHand = p.getCardsIn(ZoneType.Hand);
for (final Player opp : p.getAllOtherPlayers()) {
opp.getController().reveal(dPHand, ZoneType.Hand, p, "Reveal ");
opp.getController().reveal(dPHand, ZoneType.Hand, p, Localizer.getInstance().getMessage("lblReveal") + " ");
}
if (!p.canDiscardBy(sa)) {
@@ -325,8 +326,7 @@ public class DiscardEffect extends SpellAbilityEffect {
}
if (mode.startsWith("Reveal") ) {
p.getController().reveal(toBeDiscarded, ZoneType.Hand, p,
chooser + " has chosen " + (toBeDiscarded.size() == 1 ? "this card" : "these cards") + " from ");
p.getController().reveal(toBeDiscarded, ZoneType.Hand, p, Localizer.getInstance().getMessage("lblPlayerHasChosenCardsFrom", chooser.getName()));
}
for (Card card : toBeDiscarded) {
if (card == null) { continue; }

View File

@@ -8,6 +8,7 @@ import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.util.Lang;
import forge.util.Localizer;
import java.util.List;
@@ -49,12 +50,12 @@ public class DrawEffect extends SpellAbilityEffect {
for (final Player p : getDefinedPlayersOrTargeted(sa)) {
if ((tgt == null) || p.canBeTargetedBy(sa))
if (optional && !p.getController().confirmAction(sa, null, "Do you want to draw " + Lang.nounWithAmount(numCards, " card") + "?"))
if (optional && !p.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantDrawCards", Lang.nounWithAmount(numCards, " card"))))
continue;
int actualNum = numCards;
if (upto) {
actualNum = p.getController().chooseNumber(sa, "How may cards do you want to draw?", 0, numCards);
actualNum = p.getController().chooseNumber(sa, "lblHowMayCardDoYouWantDraw", 0, numCards);
}
final CardCollectionView drawn = p.drawCards(actualNum);

View File

@@ -8,6 +8,8 @@ import forge.game.card.CardCollectionView;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.Localizer;
import forge.util.CardTranslation;
public class EncodeEffect extends SpellAbilityEffect {
@Override
@@ -44,9 +46,7 @@ public class EncodeEffect extends SpellAbilityEffect {
// Handle choice of whether or not to encoded
final StringBuilder sb = new StringBuilder();
sb.append("Do you want to exile ").append(host).append(" and encode it onto a creature you control?");
if (!player.getController().confirmAction(sa, null, sb.toString())) {
if (!player.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantExileCardAndEncodeOntoYouCreature", CardTranslation.getTranslatedName(host.getName())))) {
return;
}
@@ -54,7 +54,7 @@ public class EncodeEffect extends SpellAbilityEffect {
Card movedCard = game.getAction().moveTo(ZoneType.Exile, host, sa);
// choose a creature
Card choice = player.getController().chooseSingleEntityForEffect(choices, sa, "Choose a creature you control to encode ", true);
Card choice = player.getController().chooseSingleEntityForEffect(choices, sa, Localizer.getInstance().getMessage("lblChooseACreatureYouControlToEncode") + " ", true);
if (choice == null) {
return;

View File

@@ -14,6 +14,7 @@ import forge.game.spellability.SpellAbility;
import forge.game.trigger.TriggerType;
import forge.game.zone.ZoneType;
import forge.util.Lang;
import forge.util.Localizer;
import java.util.List;
@@ -54,7 +55,7 @@ public class ExploreEffect extends SpellAbilityEffect {
boolean revealedLand = false;
CardCollection top = pl.getTopXCardsFromLibrary(1);
if (!top.isEmpty()) {
game.getAction().reveal(top, pl, false, "Revealed for Explore - ");
game.getAction().reveal(top, pl, false, Localizer.getInstance().getMessage("lblRevealedForExplore") + " - ");
final Card r = top.getFirst();
if (r.isLand()) {
game.getAction().moveTo(ZoneType.Hand, r, sa);
@@ -63,7 +64,7 @@ public class ExploreEffect extends SpellAbilityEffect {
// TODO find better way to choose optional send away
final Card choosen = pc.chooseSingleCardForZoneChange(
ZoneType.Graveyard, Lists.newArrayList(ZoneType.Library), sa, top, null,
"Put this card in your graveyard?", true, pl);
Localizer.getInstance().getMessage("lblPutThisCardToYourGraveyard"), true, pl);
if (choosen != null) {
game.getAction().moveTo(ZoneType.Graveyard, choosen, sa);
}

View File

@@ -12,6 +12,7 @@ import forge.game.spellability.AbilitySub;
import forge.game.spellability.SpellAbility;
import forge.game.trigger.TriggerType;
import forge.util.MyRandom;
import forge.util.Localizer;
import java.util.HashSet;
import java.util.List;
@@ -163,7 +164,7 @@ public class FlipCoinEffect extends SpellAbilityEffect {
if (result) {
numSuccesses++;
}
flipper.getGame().getAction().nofityOfValue(sa, flipper, result ? "heads" : "tails", null);
flipper.getGame().getAction().nofityOfValue(sa, flipper, result ? Localizer.getInstance().getMessage("lblHeads") : Localizer.getInstance().getMessage("lblTails"), null);
} while (sa.hasParam("FlipUntilYouLose") && result != false);
if (sa.hasParam("FlipUntilYouLose") && sa.hasAdditionalAbility("LoseSubAbility")) {
@@ -193,7 +194,7 @@ public class FlipCoinEffect extends SpellAbilityEffect {
do {
Set<Boolean> flipResults = new HashSet<>();
final boolean choice = caller.getController().chooseBinary(sa, sa.getHostCard().getName() + " - Call coin flip", PlayerController.BinaryChoiceType.HeadsOrTails);
final boolean choice = caller.getController().chooseBinary(sa, sa.getHostCard().getName() + " - " + Localizer.getInstance().getMessage("lblCallCoinFlip"), PlayerController.BinaryChoiceType.HeadsOrTails);
for (int i = 0; i < multiplier; i++) {
flipResults.add(MyRandom.getRandom().nextBoolean());
}
@@ -206,7 +207,7 @@ public class FlipCoinEffect extends SpellAbilityEffect {
numSuccesses++;
}
caller.getGame().getAction().nofityOfValue(sa, caller, wonFlip ? "win" : "lose", null);
caller.getGame().getAction().nofityOfValue(sa, caller, wonFlip ? Localizer.getInstance().getMessage("lblWin") : Localizer.getInstance().getMessage("lblLose"), null);
// Run triggers
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();

View File

@@ -5,6 +5,7 @@ import forge.game.ability.SpellAbilityEffect;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.util.Localizer;
import java.util.ArrayList;
import java.util.List;
@@ -34,7 +35,7 @@ public class LifeSetEffect extends SpellAbilityEffect {
if (!redistribute) {
p.setLife(lifeAmount, sa.getHostCard());
} else {
int life = sa.getActivatingPlayer().getController().chooseNumber(sa, "Life Total: " + p, lifetotals, p);
int life = sa.getActivatingPlayer().getController().chooseNumber(sa, Localizer.getInstance().getMessage("lblLifeTotal") + ": " + p, lifetotals, p);
p.setLife(life, sa.getHostCard());
lifetotals.remove((Integer) life);
}

View File

@@ -17,6 +17,7 @@ import forge.game.spellability.AbilityManaPart;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.game.zone.ZoneType;
import forge.util.Localizer;
import org.apache.commons.lang3.StringUtils;
@@ -39,7 +40,7 @@ public class ManaEffect extends SpellAbilityEffect {
final boolean optional = sa.hasParam("Optional");
final Game game = sa.getActivatingPlayer().getGame();
if (optional && !sa.getActivatingPlayer().getController().confirmAction(sa, null, "Do you want to add mana?")) {
if (optional && !sa.getActivatingPlayer().getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantAddMana"))) {
return;
}
@@ -91,7 +92,7 @@ public class ManaEffect extends SpellAbilityEffect {
// just use the first possible color.
choice = colorsProduced[differentChoice ? nMana : 0];
} else {
byte chosenColor = activator.getController().chooseColor("Select Mana to Produce", sa,
byte chosenColor = activator.getController().chooseColor(Localizer.getInstance().getMessage("lblSelectManaProduce"), sa,
differentChoice ? fullOptions : colorOptions);
if (chosenColor == 0)
throw new RuntimeException("ManaEffect::resolve() /*combo mana*/ - " + activator + " color mana choice is empty for " + card.getName());
@@ -111,7 +112,7 @@ public class ManaEffect extends SpellAbilityEffect {
return;
}
game.action.nofityOfValue(sa, card, activator + " picked " + choiceString, activator);
game.action.nofityOfValue(sa, card, Localizer.getInstance().getMessage("lblPlayerPickedChosen", activator.getName(), choiceString), activator);
abMana.setExpressChoice(choiceString.toString());
}
}
@@ -135,13 +136,13 @@ public class ManaEffect extends SpellAbilityEffect {
mask |= MagicColor.fromName(colorsNeeded.charAt(nChar));
}
colorMenu = mask == 0 ? ColorSet.ALL_COLORS : ColorSet.fromMask(mask);
byte val = p.getController().chooseColor("Select Mana to Produce", sa, colorMenu);
byte val = p.getController().chooseColor(Localizer.getInstance().getMessage("lblSelectManaProduce"), sa, colorMenu);
if (0 == val) {
throw new RuntimeException("ManaEffect::resolve() /*any mana*/ - " + act + " color mana choice is empty for " + card.getName());
}
choice = MagicColor.toShortString(val);
game.action.nofityOfValue(sa, card, act + " picked " + choice, act);
game.action.nofityOfValue(sa, card, Localizer.getInstance().getMessage("lblPlayerPickedChosen", act.getName(), choice), act);
abMana.setExpressChoice(choice);
}
}
@@ -172,7 +173,7 @@ public class ManaEffect extends SpellAbilityEffect {
if (cs.isMonoColor())
sb.append(MagicColor.toShortString(s.getColorMask()));
else /* (cs.isMulticolor()) */ {
byte chosenColor = sa.getActivatingPlayer().getController().chooseColor("Choose a single color from " + s.toString(), sa, cs);
byte chosenColor = sa.getActivatingPlayer().getController().chooseColor(Localizer.getInstance().getMessage("lblChooseSingleColorFromTarget", s.toString()), sa, cs);
sb.append(MagicColor.toShortString(chosenColor));
}
}

View File

@@ -8,6 +8,7 @@ import forge.game.card.CardUtil;
import forge.game.player.Player;
import forge.game.spellability.AbilityManaPart;
import forge.game.spellability.SpellAbility;
import forge.util.Localizer;
import java.util.Collection;
import java.util.List;
@@ -68,7 +69,7 @@ public class ManaReflectedEffect extends SpellAbilityEffect {
}
if (mask == 0 && !expressChoiceColors.isEmpty() && colors.contains("colorless")) {
baseMana = MagicColor.toShortString(player.getController().chooseColorAllowColorless("Select Mana to Produce", sa.getHostCard(), ColorSet.fromMask(mask)));
baseMana = MagicColor.toShortString(player.getController().chooseColorAllowColorless(Localizer.getInstance().getMessage("lblSelectManaProduce"), sa.getHostCard(), ColorSet.fromMask(mask)));
} else {
// Nothing set previously so ask player if needed
if (mask == 0) {
@@ -78,14 +79,14 @@ public class ManaReflectedEffect extends SpellAbilityEffect {
baseMana = MagicColor.toShortString(colors.iterator().next());
} else {
if (colors.contains("colorless")) {
baseMana = MagicColor.toShortString(player.getController().chooseColorAllowColorless("Select Mana to Produce", sa.getHostCard(), ColorSet.fromNames(colors)));
baseMana = MagicColor.toShortString(player.getController().chooseColorAllowColorless(Localizer.getInstance().getMessage("lblSelectManaProduce"), sa.getHostCard(), ColorSet.fromNames(colors)));
} else {
baseMana = MagicColor.toShortString(player.getController().chooseColor("Select Mana to Produce", sa, ColorSet.fromNames(colors)));
baseMana = MagicColor.toShortString(player.getController().chooseColor(Localizer.getInstance().getMessage("lblSelectManaProduce"), sa, ColorSet.fromNames(colors)));
}
}
} else {
colorMenu = ColorSet.fromMask(mask);
byte color = sa.getActivatingPlayer().getController().chooseColor("Select Mana to Produce", sa, colorMenu);
byte color = sa.getActivatingPlayer().getController().chooseColor(Localizer.getInstance().getMessage("lblSelectManaProduce"), sa, colorMenu);
if (color == 0) {
System.err.println("Unexpected behavior in ManaReflectedEffect: " + sa.getActivatingPlayer() + " - color mana choice is empty for " + sa.getHostCard().getName());
}

View File

@@ -13,6 +13,7 @@ import forge.game.card.CardUtil;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.Localizer;
public class ManifestEffect extends SpellAbilityEffect {
@Override
@@ -42,7 +43,7 @@ public class ManifestEffect extends SpellAbilityEffect {
continue;
}
String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : "Choose cards to manifest ";
String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : Localizer.getInstance().getMessage("lblChooseCardToManifest") + " ";
tgtCards = new CardCollection(activator.getController().chooseEntitiesForEffect(choices, amount, amount, null, sa, title, p));
} else if ("TopOfLibrary".equals(defined)) {
tgtCards = p.getTopXCardsFromLibrary(amount);

View File

@@ -13,6 +13,7 @@ import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.zone.PlayerZoneBattlefield;
import forge.game.zone.ZoneType;
import forge.util.Localizer;
public class MeldEffect extends SpellAbilityEffect {
@Override
@@ -35,7 +36,7 @@ public class MeldEffect extends SpellAbilityEffect {
return;
}
Card secondary = controller.getController().chooseSingleEntityForEffect(field, sa, "Choose card to meld with");
Card secondary = controller.getController().chooseSingleEntityForEffect(field, sa, Localizer.getInstance().getMessage("lblChooseCardToMeld"));
secondary = game.getAction().exile(secondary, sa);

View File

@@ -13,6 +13,7 @@ import forge.game.zone.ZoneType;
import forge.util.Lang;
import forge.util.TextUtil;
import forge.util.Localizer;
public class MillEffect extends SpellAbilityEffect {
@Override
@@ -39,7 +40,7 @@ public class MillEffect extends SpellAbilityEffect {
for (final Player p : getTargetPlayers(sa)) {
if (!sa.usesTargeting() || p.canBeTargetedBy(sa)) {
if (sa.hasParam("Optional")) {
final String prompt = TextUtil.concatWithSpace("Do you want to put card(s) from library to", TextUtil.addSuffix(destination.toString(),"?"));
final String prompt = TextUtil.concatWithSpace(Localizer.getInstance().getMessage("lblDoYouWantPutLibraryCardsTo", destination.getTranslatedName()));
if (!p.getController().confirmAction(sa, null, prompt)) {
continue;
}

View File

@@ -15,6 +15,7 @@ import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.game.zone.ZoneType;
import forge.util.Aggregates;
import forge.util.Localizer;
import java.util.List;
import java.util.Map;
@@ -85,7 +86,7 @@ public class MultiplePilesEffect extends SpellAbilityEffect {
for (int i = 1; i < piles; i++) {
int size = pool.size();
CardCollectionView pile = p.getController().chooseCardsForEffect(pool, sa, "Choose cards in Pile " + i, 0, size, false);
CardCollectionView pile = p.getController().chooseCardsForEffect(pool, sa, Localizer.getInstance().getMessage("lblChooseCardsInTargetPile", String.valueOf(i)), 0, size, false);
pileList.add(pile);
pool.removeAll(pile);
}

View File

@@ -11,6 +11,7 @@ import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.zone.PlayerZone;
import forge.game.zone.ZoneType;
import forge.util.Localizer;
import java.util.List;
@@ -52,11 +53,11 @@ public class PeekAndRevealEffect extends SpellAbilityEffect {
CardCollectionView revealableCards = CardLists.getValidCards(peekCards, revealValid, sa.getActivatingPlayer(), sa.getHostCard());
boolean doReveal = !sa.hasParam("NoReveal") && !revealableCards.isEmpty();
if (!sa.hasParam("NoPeek")) {
peekingPlayer.getController().reveal(peekCards, ZoneType.Library, peekingPlayer, source + " - Revealing cards from ");
peekingPlayer.getController().reveal(peekCards, ZoneType.Library, peekingPlayer, source + " - " + Localizer.getInstance().getMessage("lblRevealingCardFrom") + " ");
}
if( doReveal && sa.hasParam("RevealOptional") )
doReveal = peekingPlayer.getController().confirmAction(sa, null, "Reveal cards to other players?");
doReveal = peekingPlayer.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblRevealCardToOtherPlayers"));
if (doReveal) {
peekingPlayer.getGame().getAction().reveal(revealableCards, peekingPlayer);

View File

@@ -2,6 +2,7 @@ package forge.game.ability.effects;
import forge.game.card.Card;
import forge.game.spellability.SpellAbility;
import forge.util.CardTranslation;
import forge.util.Localizer;
/**
@@ -14,7 +15,7 @@ public class PermanentCreatureEffect extends PermanentEffect {
public String getStackDescription(final SpellAbility sa) {
final Card sourceCard = sa.getHostCard();
final StringBuilder sb = new StringBuilder();
sb.append(sourceCard.getName()).append(" - ").append(Localizer.getInstance().getMessage("lblCreature")).append(" ").append(sourceCard.getNetPower());
sb.append(CardTranslation.getTranslatedName(sourceCard.getName())).append(" - ").append(Localizer.getInstance().getMessage("lblCreature")).append(" ").append(sourceCard.getNetPower());
sb.append(" / ").append(sourceCard.getNetToughness());
return sb.toString();
}

View File

@@ -3,7 +3,6 @@ package forge.game.ability.effects;
import java.util.ArrayList;
import java.util.List;
import forge.util.TextUtil;
import org.apache.commons.lang3.StringUtils;
import com.google.common.base.Predicate;
@@ -32,6 +31,8 @@ import forge.game.zone.ZoneType;
import forge.item.PaperCard;
import forge.util.Aggregates;
import forge.util.Lang;
import forge.util.Localizer;
import forge.util.CardTranslation;
public class PlayEffect extends SpellAbilityEffect {
@Override
@@ -117,7 +118,7 @@ public class PlayEffect extends SpellAbilityEffect {
final int choicenum = AbilityUtils.calculateAmount(source, sa.getParam("ChoiceNum"), sa);
tgtCards = new CardCollection(
activator.getController().chooseCardsForEffect(choice, sa,
source + " - Choose up to " + Lang.nounWithNumeral(choicenum, "card"), 0, choicenum, true
source + " - " + Localizer.getInstance().getMessage("lblChooseUpTo") + " " + Lang.nounWithNumeral(choicenum, "card"), 0, choicenum, true
)
);
}
@@ -144,7 +145,7 @@ public class PlayEffect extends SpellAbilityEffect {
final CardCollection saidNoTo = new CardCollection();
while (tgtCards.size() > saidNoTo.size() && saidNoTo.size() < amount && amount > 0) {
activator.getController().tempShowCards(showCards);
Card tgtCard = controller.getController().chooseSingleEntityForEffect(tgtCards, sa, "Select a card to play");
Card tgtCard = controller.getController().chooseSingleEntityForEffect(tgtCards, sa, Localizer.getInstance().getMessage("lblSelectCardToPlay"));
activator.getController().endTempShowCards();
if (tgtCard == null) {
return;
@@ -162,7 +163,7 @@ public class PlayEffect extends SpellAbilityEffect {
game.getAction().revealTo(tgtCard, activator);
}
if (optional && !controller.getController().confirmAction(sa, null, TextUtil.concatWithSpace("Do you want to play", TextUtil.addSuffix(tgtCard.toString(),"?")))) {
if (optional && !controller.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantPlayCard", CardTranslation.getTranslatedName(tgtCard.getName())))) {
if (wasFaceDown) {
tgtCard.turnFaceDownNoUpdate();
}

View File

@@ -17,6 +17,7 @@ import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.Lang;
import forge.util.TextUtil;
import forge.util.Localizer;
import java.util.ArrayList;
import java.util.List;
@@ -51,7 +52,7 @@ public class ProtectAllEffect extends SpellAbilityEffect {
final List<String> gains = new ArrayList<>();
if (isChoice) {
Player choser = sa.getActivatingPlayer();
final String choice = choser.getController().chooseProtectionType("Choose a protection", sa, choices);
final String choice = choser.getController().chooseProtectionType(Localizer.getInstance().getMessage("lblChooseAProtection"), sa, choices);
if( null == choice)
return;
gains.add(choice);

View File

@@ -12,6 +12,7 @@ import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.util.Lang;
import forge.util.TextUtil;
import forge.util.Localizer;
import java.util.ArrayList;
import java.util.Arrays;
@@ -108,7 +109,7 @@ public class ProtectEffect extends SpellAbilityEffect {
if (sa.hasParam("Choser") && sa.getParam("Choser").equals("Controller") && !tgtCards.isEmpty()) {
choser = tgtCards.get(0).getController();
}
final String choice = choser.getController().chooseProtectionType("Choose a protection", sa, choices);
final String choice = choser.getController().chooseProtectionType(Localizer.getInstance().getMessage("lblChooseAProtection"), sa, choices);
if( null == choice)
return;
gains.add(choice);

View File

@@ -15,6 +15,7 @@ import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.Aggregates;
import forge.util.Lang;
import forge.util.Localizer;
import java.util.Arrays;
import java.util.List;
@@ -327,7 +328,7 @@ public class PumpEffect extends SpellAbilityEffect {
final String targets = Lang.joinHomogenous(tgtCards);
final String message = sa.hasParam("OptionQuestion")
? TextUtil.fastReplace(sa.getParam("OptionQuestion"), "TARGETS", targets)
: TextUtil.concatNoSpace("Apply pump to ", targets, "?");
: Localizer.getInstance().getMessage("lblApplyPumpToTarget", targets);
if (!sa.getActivatingPlayer().getController().confirmAction(sa, null, message)) {
return;
@@ -344,6 +345,14 @@ public class PumpEffect extends SpellAbilityEffect {
pumpForget = sa.getParam("ForgetObjects");
}
if (sa.hasParam("NoteCardsFor")) {
for (final Card c : AbilityUtils.getDefinedCards(host, sa.getParam("NoteCards"), sa)) {
for (Player p : tgtPlayers) {
p.addNoteForName(sa.getParam("NoteCardsFor"), "Id:" + c.getId());
}
}
}
if (pumpForget != null) {
for (final Object o : AbilityUtils.getDefinedObjects(host, pumpForget, sa)) {
host.removeRemembered(o);

View File

@@ -10,6 +10,7 @@ import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.game.zone.ZoneType;
import forge.util.Lang;
import forge.util.Localizer;
import java.util.List;
@@ -116,7 +117,7 @@ public class RearrangeTopOfLibraryEffect extends SpellAbilityEffect {
Card next = orderedCards.get(i);
player.getGame().getAction().moveToLibrary(next, 0, sa);
}
if (mayshuffle && activator.getController().confirmAction(sa, null, "Do you want to shuffle the library?")) {
if (mayshuffle && activator.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoyouWantShuffleTheLibrary"))) {
player.shuffle(sa);
}
}

View File

@@ -11,9 +11,11 @@ import forge.game.card.*;
import forge.game.player.Player;
import forge.game.spellability.AbilitySub;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityStackInstance;
import forge.game.zone.ZoneType;
import forge.util.Aggregates;
import forge.util.collect.FCollection;
import forge.util.Localizer;
import java.util.List;
import java.util.Map;
@@ -46,6 +48,7 @@ public class RepeatEachEffect extends SpellAbilityEffect {
boolean loopOverCards = false;
boolean recordChoice = sa.hasParam("RecordChoice");
CardCollectionView repeatCards = null;
List<SpellAbility> repeatSas = null;
if (sa.hasParam("RepeatCards")) {
List<ZoneType> zone = Lists.newArrayList();
@@ -58,6 +61,16 @@ public class RepeatEachEffect extends SpellAbilityEffect {
sa.getParam("RepeatCards"), source.getController(), source);
loopOverCards = !recordChoice;
}
else if (sa.hasParam(("RepeatSpellAbilities"))) {
repeatSas = Lists.newArrayList();
String[] restrictions = sa.getParam("RepeatSpellAbilities").split((","));
for (SpellAbilityStackInstance stackInstance : game.getStack()) {
if (stackInstance.getSpellAbility(false).isValid(restrictions, source.getController(), source, sa)) {
repeatSas.add(stackInstance.getSpellAbility(false));
}
}
}
else if (sa.hasParam("DefinedCards")) {
repeatCards = AbilityUtils.getDefinedCards(source, sa.getParam("DefinedCards"), sa);
if (sa.hasParam("AdditionalRestriction")) { // lki cards might not be in game
@@ -109,6 +122,13 @@ public class RepeatEachEffect extends SpellAbilityEffect {
}
}
}
if (repeatSas != null) {
for (SpellAbility card : repeatSas) {
source.addRemembered(card);
AbilityUtils.resolve(repeat);
source.removeRemembered(card);
}
}
if (sa.hasParam("RepeatPlayers")) {
final FCollection<Player> repeatPlayers = AbilityUtils.getDefinedPlayers(source, sa.getParam("RepeatPlayers"), sa);
@@ -167,7 +187,7 @@ public class RepeatEachEffect extends SpellAbilityEffect {
if (random) {
p = Aggregates.random(game.getPlayers());
} else {
p = sa.getActivatingPlayer().getController().chooseSingleEntityForEffect(game.getPlayers(), sa, "Choose a player");
p = sa.getActivatingPlayer().getController().chooseSingleEntityForEffect(game.getPlayers(), sa, Localizer.getInstance().getMessage("lblChoosePlayer"));
}
if (recordMap.containsKey(p)) {
recordMap.get(p).add(0, card);
@@ -188,7 +208,7 @@ public class RepeatEachEffect extends SpellAbilityEffect {
valid = CardLists.filterControlledBy(valid,
game.getNextPlayerAfter(p, source.getChosenDirection()));
}
Card card = p.getController().chooseSingleEntityForEffect(valid, sa, "Choose a card");
Card card = p.getController().chooseSingleEntityForEffect(valid, sa, Localizer.getInstance().getMessage("lblChooseaCard"));
if (recordMap.containsKey(p)) {
recordMap.get(p).add(0, card);
} else {

View File

@@ -12,6 +12,7 @@ import forge.game.spellability.AbilitySub;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.Expressions;
import forge.util.Localizer;
public class RepeatEffect extends SpellAbilityEffect {
@@ -129,7 +130,7 @@ public class RepeatEffect extends SpellAbilityEffect {
Player decider = sa.hasParam("RepeatOptionalDecider")
? AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("RepeatOptionalDecider"), sa).get(0)
: sa.getActivatingPlayer();
return decider.getController().confirmAction(sa, null, "Do you want to repeat this process again?");
return decider.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantRepeatProcessAgain"));
}
return true;

View File

@@ -7,6 +7,7 @@ import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.game.zone.ZoneType;
import forge.util.Localizer;
import java.util.List;
@@ -41,7 +42,7 @@ public class RevealHandEffect extends SpellAbilityEffect {
for (final Player p : getTargetPlayers(sa)) {
if ((tgt == null) || p.canBeTargetedBy(sa)) {
if (optional && !p.getController().confirmAction(sa, null, "Do you want to reveal your hand?")) {
if (optional && !p.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantRevealYourHand"))) {
continue;
}
final CardCollectionView hand = p.getCardsIn(ZoneType.Hand);

View File

@@ -5,6 +5,7 @@ import forge.game.PlanarDice;
import forge.game.ability.SpellAbilityEffect;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.util.Localizer;
/**
* TODO: Write javadoc for this type.
@@ -25,7 +26,7 @@ public class RollPlanarDiceEffect extends SpellAbilityEffect {
game.getPhaseHandler().incPlanarDiceRolledthisTurn();
}
PlanarDice result = PlanarDice.roll(activator, null);
String message = activator.getName() + " rolled " + result.toString();
String message = Localizer.getInstance().getMessage("lblPlayerRolledResult", activator.getName(), result.toString());
game.getAction().nofityOfValue(sa, activator, message, null);
}

View File

@@ -15,6 +15,7 @@ import forge.game.spellability.SpellAbility;
import forge.game.trigger.TriggerType;
import forge.game.zone.ZoneType;
import forge.util.Aggregates;
import forge.util.Localizer;
import org.apache.commons.lang3.StringUtils;
import java.util.List;
@@ -30,11 +31,11 @@ public class SacrificeEffect extends SpellAbilityEffect {
if (sa.hasParam("Echo")) {
boolean isPaid;
if (activator.hasKeyword("You may pay 0 rather than pay the echo cost for permanents you control.")
&& activator.getController().confirmAction(sa, null, "Do you want to pay Echo {0}?")) {
&& activator.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantPayEcho") + " {0}?")) {
isPaid = true;
} else {
isPaid = activator.getController().payManaOptional(card, new Cost(sa.getParam("Echo"), true),
sa, "Pay Echo", ManaPaymentPurpose.Echo);
sa, Localizer.getInstance().getMessage("lblPayEcho"), ManaPaymentPurpose.Echo);
}
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromCard(card);
runParams.put(AbilityKey.EchoPaid, isPaid);
@@ -117,7 +118,7 @@ public class SacrificeEffect extends SpellAbilityEffect {
if (sa.hasParam("Random")) {
choosenToSacrifice = Aggregates.random(validTargets, Math.min(amount, validTargets.size()), new CardCollection());
} else if (sa.hasParam("OptionalSacrifice") && !p.getController().confirmAction(sa, null, "Do you want to sacrifice?")) {
} else if (sa.hasParam("OptionalSacrifice") && !p.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantSacrifice"))) {
choosenToSacrifice = CardCollection.EMPTY;
} else {
boolean isOptional = sa.hasParam("Optional");
@@ -193,10 +194,10 @@ public class SacrificeEffect extends SpellAbilityEffect {
final int amount = AbilityUtils.calculateAmount(sa.getHostCard(), num, sa);
if (valid.equals("Self")) {
sb.append("Sacrifice ").append(sa.getHostCard().toString());
sb.append("Sacrifices ").append(sa.getHostCard().toString());
} else if (valid.equals("Card.AttachedBy")) {
final Card toSac = sa.getHostCard().getEnchantingCard();
sb.append(toSac.getController()).append(" sacrifices ").append(toSac).append(".");
sb.append(toSac.getController()).append(" Sacrifices ").append(toSac).append(".");
} else {
for (final Player p : tgts) {
sb.append(p.getName()).append(" ");

View File

@@ -1,12 +1,13 @@
package forge.game.ability.effects;
import com.google.common.collect.Lists;
import forge.game.ability.AbilityUtils;
import forge.game.ability.SpellAbilityEffect;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import java.util.List;
import forge.util.Localizer;
import com.google.common.collect.Lists;
import java.util.List;
public class ScryEffect extends SpellAbilityEffect {
@@ -41,11 +42,10 @@ public class ScryEffect extends SpellAbilityEffect {
// Optional here for spells that have optional multi-player scrying
for (final Player p : getTargetPlayers(sa)) {
if ( (!sa.usesTargeting() || p.canBeTargetedBy(sa)) &&
(!isOptional || p.getController().confirmAction(sa, null, "Do you want to scry?")) ) {
(!isOptional || p.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWanttoScry"))) ) {
players.add(p);
}
}
sa.getActivatingPlayer().getGame().getAction().scry(players, num, sa);
}
}

View File

@@ -15,6 +15,7 @@ import forge.game.player.PlayerActionConfirmMode;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.TextUtil;
import forge.util.Localizer;
import java.util.Iterator;
import java.util.List;
@@ -76,7 +77,7 @@ public class SetStateEffect extends SpellAbilityEffect {
&& !tgt.getState(CardStateName.Original).getType().isPermanent()) {
Card lki = CardUtil.getLKICopy(tgt);
lki.turnFaceUp(true, false);
game.getAction().reveal(new CardCollection(lki), lki.getOwner(), true, "Face-down card can't turn face up");
game.getAction().reveal(new CardCollection(lki), lki.getOwner(), true, Localizer.getInstance().getMessage("lblFaceDownCardCantTurnFaceUp"));
continue;
}

View File

@@ -4,6 +4,7 @@ import forge.game.ability.SpellAbilityEffect;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.util.Localizer;
import java.util.Iterator;
import java.util.List;
@@ -20,7 +21,7 @@ public class ShuffleEffect extends SpellAbilityEffect {
for (final Player p : tgtPlayers) {
if ((tgt == null) || p.canBeTargetedBy(sa)) {
boolean mustShuffle = !optional || sa.getActivatingPlayer().getController().confirmAction(sa, null, "Have " + p + " shuffle?");
boolean mustShuffle = !optional || sa.getActivatingPlayer().getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblHaveTargetShuffle", p.getName()));
if (mustShuffle)
p.shuffle(sa);
}

View File

@@ -5,6 +5,7 @@ import forge.game.ability.SpellAbilityEffect;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.util.Lang;
import forge.util.Localizer;
public class SurveilEffect extends SpellAbilityEffect {
@Override
@@ -33,7 +34,7 @@ public class SurveilEffect extends SpellAbilityEffect {
for (final Player p : getTargetPlayers(sa)) {
if (!sa.usesTargeting() || p.canBeTargetedBy(sa)) {
if (isOptional && !p.getController().confirmAction(sa, null, "Do you want to surveil?")) {
if (isOptional && !p.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantSurveil"))) {
continue;
}

Some files were not shown because too many files have changed in this diff Show More