This commit is contained in:
Alessandro Coli
2019-06-22 17:22:36 +02:00
97 changed files with 1712 additions and 476 deletions

View File

@@ -1213,6 +1213,7 @@ public class ComputerUtilCard {
final Game game = ai.getGame(); final Game game = ai.getGame();
final PhaseHandler phase = game.getPhaseHandler(); final PhaseHandler phase = game.getPhaseHandler();
final Combat combat = phase.getCombat(); final Combat combat = phase.getCombat();
final boolean main1Preferred = "Main1IfAble".equals(sa.getParam("AILogic")) && phase.is(PhaseType.MAIN1, ai);
final boolean isBerserk = "Berserk".equals(sa.getParam("AILogic")); final boolean isBerserk = "Berserk".equals(sa.getParam("AILogic"));
final boolean loseCardAtEOT = "Sacrifice".equals(sa.getParam("AtEOT")) || "Exile".equals(sa.getParam("AtEOT")) final boolean loseCardAtEOT = "Sacrifice".equals(sa.getParam("AtEOT")) || "Exile".equals(sa.getParam("AtEOT"))
|| "Destroy".equals(sa.getParam("AtEOT")) || "ExileCombat".equals(sa.getParam("AtEOT")); || "Destroy".equals(sa.getParam("AtEOT")) || "ExileCombat".equals(sa.getParam("AtEOT"));
@@ -1250,7 +1251,7 @@ public class ComputerUtilCard {
// will the creature attack (only relevant for sorcery speed)? // will the creature attack (only relevant for sorcery speed)?
if (phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) if (phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)
&& phase.isPlayerTurn(ai) && phase.isPlayerTurn(ai)
&& SpellAbilityAi.isSorcerySpeed(sa) && SpellAbilityAi.isSorcerySpeed(sa) || main1Preferred
&& power > 0 && power > 0
&& ComputerUtilCard.doesCreatureAttackAI(ai, c)) { && ComputerUtilCard.doesCreatureAttackAI(ai, c)) {
return true; return true;
@@ -1456,6 +1457,10 @@ public class ComputerUtilCard {
} }
if (totalPowerUnblocked >= opp.getLife()) { if (totalPowerUnblocked >= opp.getLife()) {
return true; return true;
} else if (totalPowerUnblocked > dmg && sa.getHostCard() != null && sa.getHostCard().isInPlay()) {
if (sa.getPayCosts() != null && sa.getPayCosts().hasNoManaCost()) {
return true; // always activate abilities which cost no mana and which can increase unblocked damage
}
} }
} }
float value = 1.0f * (pumpedDmg - dmg); float value = 1.0f * (pumpedDmg - dmg);

View File

@@ -97,6 +97,9 @@ public abstract class GameState {
private String precastHuman = null; private String precastHuman = null;
private String precastAI = null; private String precastAI = null;
private String putOnStackHuman = null;
private String putOnStackAI = null;
private int turn = 1; private int turn = 1;
private boolean removeSummoningSickness = false; private boolean removeSummoningSickness = false;
@@ -535,6 +538,13 @@ public abstract class GameState {
precastAI = categoryValue; precastAI = categoryValue;
} }
else if (categoryName.endsWith("putonstack")) {
if (isHuman)
putOnStackHuman = categoryValue;
else
putOnStackAI = categoryValue;
}
else if (categoryName.endsWith("manapool")) { else if (categoryName.endsWith("manapool")) {
if (isHuman) if (isHuman)
humanManaPool = categoryValue; humanManaPool = categoryValue;
@@ -614,6 +624,9 @@ public abstract class GameState {
game.getTriggerHandler().setSuppressAllTriggers(false); game.getTriggerHandler().setSuppressAllTriggers(false);
// SAs added to stack cause triggers to fire, as if the relevant SAs were cast
handleAddSAsToStack(game);
// Combat only works for 1v1 matches for now (which are the only matches dev mode supports anyway) // Combat only works for 1v1 matches for now (which are the only matches dev mode supports anyway)
// Note: triggers may fire during combat declarations ("whenever X attacks, ...", etc.) // Note: triggers may fire during combat declarations ("whenever X attacks, ...", etc.)
if (newPhase == PhaseType.COMBAT_DECLARE_ATTACKERS || newPhase == PhaseType.COMBAT_DECLARE_BLOCKERS) { if (newPhase == PhaseType.COMBAT_DECLARE_ATTACKERS || newPhase == PhaseType.COMBAT_DECLARE_BLOCKERS) {
@@ -803,6 +816,9 @@ public abstract class GameState {
} }
private void executeScript(Game game, Card c, String sPtr) { private void executeScript(Game game, Card c, String sPtr) {
executeScript(game, c, sPtr, false);
}
private void executeScript(Game game, Card c, String sPtr, boolean putOnStack) {
int tgtID = TARGET_NONE; int tgtID = TARGET_NONE;
if (sPtr.contains("->")) { if (sPtr.contains("->")) {
String tgtDef = sPtr.substring(sPtr.lastIndexOf("->") + 2); String tgtDef = sPtr.substring(sPtr.lastIndexOf("->") + 2);
@@ -878,6 +894,9 @@ public abstract class GameState {
sa.setActivatingPlayer(c.getController()); sa.setActivatingPlayer(c.getController());
handleScriptedTargetingForSA(game, sa, tgtID); handleScriptedTargetingForSA(game, sa, tgtID);
if (putOnStack) {
game.getStack().addAndUnfreeze(sa);
} else {
sa.resolve(); sa.resolve();
// resolve subabilities // resolve subabilities
@@ -887,6 +906,7 @@ public abstract class GameState {
subSa = subSa.getSubAbility(); subSa = subSa.getSubAbility();
} }
} }
}
private void handlePrecastSpells(final Game game) { private void handlePrecastSpells(final Game game) {
Player human = game.getPlayers().get(0); Player human = game.getPlayers().get(0);
@@ -906,7 +926,28 @@ public abstract class GameState {
} }
} }
private void handleAddSAsToStack(final Game game) {
Player human = game.getPlayers().get(0);
Player ai = game.getPlayers().get(1);
if (putOnStackHuman != null) {
String[] spellList = TextUtil.split(putOnStackHuman, ';');
for (String spell : spellList) {
precastSpellFromCard(spell, human, game, true);
}
}
if (putOnStackAI != null) {
String[] spellList = TextUtil.split(putOnStackAI, ';');
for (String spell : spellList) {
precastSpellFromCard(spell, ai, game, true);
}
}
}
private void precastSpellFromCard(String spellDef, final Player activator, final Game game) { private void precastSpellFromCard(String spellDef, final Player activator, final Game game) {
precastSpellFromCard(spellDef, activator, game, false);
}
private void precastSpellFromCard(String spellDef, final Player activator, final Game game, final boolean putOnStack) {
int tgtID = TARGET_NONE; int tgtID = TARGET_NONE;
String scriptID = ""; String scriptID = "";
@@ -931,7 +972,7 @@ public abstract class GameState {
SpellAbility sa = null; SpellAbility sa = null;
if (!scriptID.isEmpty()) { if (!scriptID.isEmpty()) {
executeScript(game, c, scriptID); executeScript(game, c, scriptID, putOnStack);
return; return;
} }
@@ -940,8 +981,12 @@ public abstract class GameState {
handleScriptedTargetingForSA(game, sa, tgtID); handleScriptedTargetingForSA(game, sa, tgtID);
if (putOnStack) {
game.getStack().addAndUnfreeze(sa);
} else {
sa.resolve(); sa.resolve();
} }
}
private void handleMarkedDamage() { private void handleMarkedDamage() {
for (Entry<Card, Integer> entry : markedDamage.entrySet()) { for (Entry<Card, Integer> entry : markedDamage.entrySet()) {
@@ -1167,6 +1212,14 @@ public abstract class GameState {
// TODO: improve this for game states with more than two players // TODO: improve this for game states with more than two players
String tgt = info.substring(info.indexOf(':') + 1); String tgt = info.substring(info.indexOf(':') + 1);
cardToEnchantPlayerId.put(c, tgt.equalsIgnoreCase("AI") ? TARGET_AI : TARGET_HUMAN); cardToEnchantPlayerId.put(c, tgt.equalsIgnoreCase("AI") ? TARGET_AI : TARGET_HUMAN);
} else if (info.startsWith("Owner:")) {
// TODO: improve this for game states with more than two players
Player human = player.getGame().getPlayers().get(0);
Player ai = player.getGame().getPlayers().get(1);
String owner = info.substring(info.indexOf(':') + 1);
Player controller = c.getController();
c.setOwner(owner.equalsIgnoreCase("AI") ? ai : human);
c.setController(controller, c.getGame().getNextTimestamp());
} else if (info.startsWith("Ability:")) { } else if (info.startsWith("Ability:")) {
String abString = info.substring(info.indexOf(':') + 1).toLowerCase(); String abString = info.substring(info.indexOf(':') + 1).toLowerCase();
c.addSpellAbility(AbilityFactory.getAbility(abilityString.get(abString), c)); c.addSpellAbility(AbilityFactory.getAbility(abilityString.get(abString), c));

View File

@@ -38,8 +38,13 @@ public class CountersPutAllAi extends SpellAbilityAi {
final boolean curse = sa.isCurse(); final boolean curse = sa.isCurse();
final TargetRestrictions tgt = sa.getTargetRestrictions(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if ("OwnCreatsAndOtherPWs".equals(sa.getParam("AILogic"))) {
hList = CardLists.getValidCards(ai.getWeakestOpponent().getCardsIn(ZoneType.Battlefield), "Creature.YouCtrl,Planeswalker.YouCtrl+Other", source.getController(), source);
cList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), "Creature.YouCtrl,Planeswalker.YouCtrl+Other", source.getController(), source);
} else {
hList = CardLists.getValidCards(ai.getWeakestOpponent().getCardsIn(ZoneType.Battlefield), valid, source.getController(), source); hList = CardLists.getValidCards(ai.getWeakestOpponent().getCardsIn(ZoneType.Battlefield), valid, source.getController(), source);
cList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid, source.getController(), source); cList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid, source.getController(), source);
}
if (abCost != null) { if (abCost != null) {
// AI currently disabled for these costs // AI currently disabled for these costs

View File

@@ -1,5 +1,6 @@
package forge.ai.ability; package forge.ai.ability;
import forge.game.card.*;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
@@ -12,10 +13,6 @@ import forge.card.CardType.Supertype;
import forge.card.mana.ManaCost; import forge.card.mana.ManaCost;
import forge.game.Game; import forge.game.Game;
import forge.game.GlobalRuleChange; import forge.game.GlobalRuleChange;
import forge.game.card.Card;
import forge.game.card.CardCollection;
import forge.game.card.CardLists;
import forge.game.card.CardPredicates;
import forge.game.cost.Cost; import forge.game.cost.Cost;
import forge.game.keyword.KeywordInterface; import forge.game.keyword.KeywordInterface;
import forge.game.mana.ManaCostBeingPaid; import forge.game.mana.ManaCostBeingPaid;
@@ -198,11 +195,13 @@ public class PermanentAi extends SpellAbilityAi {
} }
} else if (param.startsWith("MaxControlled")) { } else if (param.startsWith("MaxControlled")) {
// Only cast unless there are X or more cards like this on the battlefield under AI control already, // Only cast unless there are X or more cards like this on the battlefield under AI control already,
CardCollection ctrld = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals(card.getName())); CardCollectionView valid = param.contains("Globally") ? ai.getGame().getCardsIn(ZoneType.Battlefield)
: ai.getCardsIn(ZoneType.Battlefield);
CardCollection ctrld = CardLists.filter(valid, CardPredicates.nameEquals(card.getName()));
int numControlled = 0; int numControlled = 0;
if (param.endsWith("WithoutOppAuras")) { if (param.endsWith("WithoutOppAuras")) {
// Check that the permanet does not have any auras attached to it by the opponent (this assumes that if // Check that the permanent does not have any auras attached to it by the opponent (this assumes that if
// the opponent cast an aura on the opposing permanent, it's not with good intentions, and thus it might // the opponent cast an aura on the opposing permanent, it's not with good intentions, and thus it might
// be better to have a pristine copy of the card - might not always be a correct assumption, but sounds // be better to have a pristine copy of the card - might not always be a correct assumption, but sounds
// like a reasonable default for some cards). // like a reasonable default for some cards).

View File

@@ -104,6 +104,7 @@ public class PumpAi extends PumpAiBase {
@Override @Override
protected boolean checkPhaseRestrictions(final Player ai, final SpellAbility sa, final PhaseHandler ph) { protected boolean checkPhaseRestrictions(final Player ai, final SpellAbility sa, final PhaseHandler ph) {
final Game game = ai.getGame(); final Game game = ai.getGame();
boolean main1Preferred = "Main1IfAble".equals(sa.getParam("AILogic")) && ph.is(PhaseType.MAIN1, ai);
if (game.getStack().isEmpty() && hasTapCost(sa.getPayCosts(), sa.getHostCard())) { if (game.getStack().isEmpty() && hasTapCost(sa.getPayCosts(), sa.getHostCard())) {
if (ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) && ph.isPlayerTurn(ai)) { if (ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) && ph.isPlayerTurn(ai)) {
return false; return false;
@@ -112,10 +113,11 @@ public class PumpAi extends PumpAiBase {
return false; return false;
} }
} }
if (game.getStack().isEmpty() && ph.getPhase().isBefore(PhaseType.COMBAT_BEGIN)) { if (game.getStack().isEmpty() && (ph.getPhase().isBefore(PhaseType.COMBAT_BEGIN)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS))) {
// Instant-speed pumps should not be cast outside of combat when the // Instant-speed pumps should not be cast outside of combat when the
// stack is empty // stack is empty
if (!sa.isCurse() && !SpellAbilityAi.isSorcerySpeed(sa)) { if (!sa.isCurse() && !SpellAbilityAi.isSorcerySpeed(sa) && !main1Preferred) {
return false; return false;
} }
} }

View File

@@ -460,6 +460,10 @@ public abstract class PumpAiBase extends SpellAbilityAi {
if (combat == null || !(combat.isBlocking(card) || combat.isBlocked(card))) { if (combat == null || !(combat.isBlocking(card) || combat.isBlocked(card))) {
return false; return false;
} }
} else if (keyword.equals("Menace")) {
if (combat == null || !combat.isAttacking(card)) {
return false;
}
} }
return true; return true;
} }

View File

@@ -24,8 +24,7 @@ import java.util.List;
public class TapAllAi extends SpellAbilityAi { public class TapAllAi extends SpellAbilityAi {
@Override @Override
protected boolean canPlayAI(final Player ai, SpellAbility sa) { protected boolean canPlayAI(final Player ai, SpellAbility sa) {
// If tapping all creatures do it either during declare attackers of AIs // If tapping all creatures do it either during declare attackers of AIs turn
// turn
// or during upkeep/begin combat? // or during upkeep/begin combat?
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
@@ -86,7 +85,7 @@ public class TapAllAi extends SpellAbilityAi {
return false; return false;
} }
// in AI's turn, check if there are possible attackers, before tapping blockers // in AI's turn, check if there are possible attackers, before tapping blockers
if (game.getPhaseHandler().isPlayerTurn(ai) && !SpellAbilityAi.isSorcerySpeed(sa)) { if (game.getPhaseHandler().isPlayerTurn(ai)) {
validTappables = ai.getCardsIn(ZoneType.Battlefield); validTappables = ai.getCardsIn(ZoneType.Battlefield);
final boolean any = Iterables.any(validTappables, new Predicate<Card>() { final boolean any = Iterables.any(validTappables, new Predicate<Card>() {
@Override @Override

View File

@@ -28,6 +28,7 @@ import forge.StaticData;
import forge.card.CardDb; import forge.card.CardDb;
import forge.card.CardRarity; import forge.card.CardRarity;
import forge.card.CardRules; import forge.card.CardRules;
import forge.util.Localizer;
import forge.util.TextUtil; import forge.util.TextUtil;
/** /**
@@ -95,7 +96,8 @@ public final class PaperCard implements Comparable<IPaperCard>, InventoryItemFro
@Override @Override
public String getItemType() { public String getItemType() {
return "Card"; final Localizer localizer = Localizer.getInstance();
return localizer.getMessage("lblCard");
} }
public boolean hasImage() { public boolean hasImage() {

View File

@@ -184,6 +184,10 @@ public class ForgeScript {
if (!sa.isKicked()) { if (!sa.isKicked()) {
return false; return false;
} }
} else if (property.equals("Loyalty")) {
if (!sa.isPwAbility()) {
return false;
}
} else if (property.equals("Aftermath")) { } else if (property.equals("Aftermath")) {
if (!sa.isAftermath()) { if (!sa.isAftermath()) {
return false; return false;

View File

@@ -391,8 +391,11 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
if (sa.hasParam("DestinationAlternative")) { if (sa.hasParam("DestinationAlternative")) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append(sa.getParam("AlternativeDestinationMessage")); sb.append(sa.getParam("AlternativeDestinationMessage"));
Player alterDecider = player;
if (!player.getController().confirmAction(sa, PlayerActionConfirmMode.ChangeZoneToAltDestination, sb.toString())) { if (sa.hasParam("AlternativeDecider")) {
alterDecider = AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("AlternativeDecider"), sa).get(0);
}
if (!alterDecider.getController().confirmAction(sa, PlayerActionConfirmMode.ChangeZoneToAltDestination, sb.toString())) {
destination = ZoneType.smartValueOf(sa.getParam("DestinationAlternative")); destination = ZoneType.smartValueOf(sa.getParam("DestinationAlternative"));
altDest = true; altDest = true;
} }
@@ -543,15 +546,29 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
movedCard.turnFaceDown(true); movedCard.turnFaceDown(true);
} }
if (sa.hasParam("Attacking")) { if (sa.hasParam("Attacking")) {
// What should they attack? final Combat combat = game.getCombat();
FCollectionView<GameEntity> defenders = game.getCombat().getDefenders(); if ( null != combat ) {
if (!defenders.isEmpty()) { final FCollectionView<GameEntity> e = combat.getDefenders();
// Blockeres are already declared, set this to unblocked
game.getCombat().addAttacker(tgtC, defenders.getFirst()); GameEntity defender = null;
game.getCombat().getBandOfAttacker(tgtC).setBlocked(false); if (sa.hasParam("DefinedDefender")) {
FCollection<GameObject> objs = AbilityUtils.getDefinedObjects(sa.getHostCard(), sa.getParam("DefinedDefender"), sa);
for(GameObject obj : objs) {
if (obj instanceof GameEntity) {
defender = (GameEntity)obj;
break;
}
}
} else {
defender = player.getController().chooseSingleEntityForEffect(e, sa, "Declare a defender for " + movedCard );
}
if (defender != null) {
combat.addAttacker(movedCard, defender);
game.getCombat().getBandOfAttacker(movedCard).setBlocked(false);
game.fireEvent(new GameEventCombatChanged()); game.fireEvent(new GameEventCombatChanged());
} }
} }
}
if (sa.hasParam("Ninjutsu")) { if (sa.hasParam("Ninjutsu")) {
// Ninjutsu need to get the Defender of the Returned Creature // Ninjutsu need to get the Defender of the Returned Creature
final Card returned = sa.getPaidList("Returned").getFirst(); final Card returned = sa.getPaidList("Returned").getFirst();
@@ -1028,6 +1045,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
} }
if (defender != null) { if (defender != null) {
combat.addAttacker(c, defender); combat.addAttacker(c, defender);
game.getCombat().getBandOfAttacker(c).setBlocked(false);
game.fireEvent(new GameEventCombatChanged()); game.fireEvent(new GameEventCombatChanged());
} }
} }

View File

@@ -2815,7 +2815,7 @@ public class Player extends GameEntity implements Comparable<Player> {
public void createMonarchEffect() { public void createMonarchEffect() {
final PlayerZone com = getZone(ZoneType.Command); final PlayerZone com = getZone(ZoneType.Command);
if (monarchEffect == null) { if (monarchEffect == null) {
monarchEffect = new Card(-1, game); monarchEffect = new Card(game.nextCardId(), null, false, game);
monarchEffect.setOwner(this); monarchEffect.setOwner(this);
monarchEffect.setImageKey("t:monarch"); monarchEffect.setImageKey("t:monarch");
monarchEffect.setName("The Monarch"); monarchEffect.setName("The Monarch");
@@ -2869,7 +2869,7 @@ public class Player extends GameEntity implements Comparable<Player> {
final PlayerZone com = getZone(ZoneType.Command); final PlayerZone com = getZone(ZoneType.Command);
if(bless) { if(bless) {
blessingEffect = new Card(-1, game); blessingEffect = new Card(game.nextCardId(), null, false, game);
blessingEffect.setOwner(this); blessingEffect.setOwner(this);
blessingEffect.setImageKey("t:blessing"); blessingEffect.setImageKey("t:blessing");
blessingEffect.setName("City's Blessing"); blessingEffect.setName("City's Blessing");

View File

@@ -357,6 +357,8 @@ public class SpellAbilityStackInstance implements IIdentifiable, IHasCardView {
runParams.put("Target", tgt); runParams.put("Target", tgt);
getSourceCard().getGame().getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false); getSourceCard().getGame().getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false);
} }
runParams.put("Targets", target.getTargets());
getSourceCard().getGame().getTriggerHandler().runTrigger(TriggerType.BecomesTargetOnce, runParams, false);
} }
} }

View File

@@ -0,0 +1,95 @@
/*
* Forge: Play Magic: the Gathering.
* Copyright (C) 2011 Forge Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package forge.game.trigger;
import forge.game.GameObject;
import forge.game.card.Card;
import forge.game.spellability.SpellAbility;
import java.util.List;
import java.util.Map;
/**
* <p>
* Trigger_BecomesTargetOnce class.
* </p>
*
* @author Forge
* @version $Id$
* @since 1.0.15
*/
public class TriggerBecomesTargetOnce extends Trigger {
/**
* <p>
* Constructor for Trigger_BecomesTargetOnce.
* </p>
*
* @param params
* a {@link java.util.HashMap} object.
* @param host
* a {@link forge.game.card.Card} object.
* @param intrinsic
* the intrinsic
*/
public TriggerBecomesTargetOnce(final java.util.Map<String, String> params, final Card host, final boolean intrinsic) {
super(params, host, intrinsic);
}
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override
public final boolean performTest(final Map<String, Object> runParams2) {
if (this.mapParams.containsKey("ValidSource")) {
if (!matchesValid(((SpellAbility) runParams2.get("SourceSA")).getHostCard(), this.mapParams
.get("ValidSource").split(","), this.getHostCard())) {
return false;
}
}
if (this.mapParams.containsKey("ValidTarget")) {
List<GameObject> targets = (List<GameObject>) runParams2.get("Targets");
boolean valid = false;
for (GameObject b : targets) {
if (matchesValid(b, this.mapParams.get("ValidTarget").split(","), this.getHostCard())) {
valid = true;
break;
}
}
if (!valid) {
return false;
}
}
return true;
}
/** {@inheritDoc} */
@Override
public final void setTriggeringObjects(final SpellAbility sa) {
sa.setTriggeringObject("SourceSA", this.getRunParams().get("SourceSA"));
sa.setTriggeringObject("Source", ((SpellAbility) this.getRunParams().get("SourceSA")).getHostCard());
sa.setTriggeringObject("Targets", this.getRunParams().get("Targets"));
}
@Override
public String getImportantStackObjects(SpellAbility sa) {
StringBuilder sb = new StringBuilder();
sb.append("Source: ").append(((SpellAbility) sa.getTriggeringObject("SourceSA")).getHostCard()).append(", ");
sb.append("Targets: ").append(sa.getTriggeringObject("Targets"));
return sb.toString();
}
}

View File

@@ -27,6 +27,7 @@ public enum TriggerType {
BecomeMonstrous(TriggerBecomeMonstrous.class), BecomeMonstrous(TriggerBecomeMonstrous.class),
BecomeRenowned(TriggerBecomeRenowned.class), BecomeRenowned(TriggerBecomeRenowned.class),
BecomesTarget(TriggerBecomesTarget.class), BecomesTarget(TriggerBecomesTarget.class),
BecomesTargetOnce(TriggerBecomesTargetOnce.class),
BlockersDeclared(TriggerBlockersDeclared.class), BlockersDeclared(TriggerBlockersDeclared.class),
Blocks(TriggerBlocks.class), Blocks(TriggerBlocks.class),
Championed(TriggerChampioned.class), Championed(TriggerChampioned.class),

View File

@@ -438,6 +438,8 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
runParams.put("Target", tgt); runParams.put("Target", tgt);
game.getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false); game.getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false);
} }
runParams.put("Targets", tc.getTargets());
game.getTriggerHandler().runTrigger(TriggerType.BecomesTargetOnce, runParams, false);
} }
} }
} }
@@ -447,6 +449,9 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
runParams.put("Target", sp.getTargetCard()); runParams.put("Target", sp.getTargetCard());
game.getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false); game.getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false);
runParams.put("Targets", Lists.newArrayList(sp.getTargetCard()));
game.getTriggerHandler().runTrigger(TriggerType.BecomesTargetOnce, runParams, false);
} }
game.fireEvent(new GameEventZone(ZoneType.Stack, sp.getActivatingPlayer(), EventValueChangeType.Added, source)); game.fireEvent(new GameEventZone(ZoneType.Stack, sp.getActivatingPlayer(), EventValueChangeType.Added, source));

View File

@@ -124,19 +124,16 @@ public enum FControl implements KeyEventDispatcher {
* instantiated separately by each screen's top level view class. * instantiated separately by each screen's top level view class.
*/ */
FControl() { FControl() {
final Localizer localizer = Localizer.getInstance();
Singletons.getView().getFrame().addWindowListener(new WindowAdapter() { Singletons.getView().getFrame().addWindowListener(new WindowAdapter() {
@Override @Override
public void windowClosing(final WindowEvent e) { public void windowClosing(final WindowEvent e) {
switch (closeAction) { switch (closeAction) {
case NONE: //prompt user for close action if not previously specified case NONE: //prompt user for close action if not previously specified
final List<String> options = ImmutableList.of("Close Screen", "Exit Forge", "Cancel"); final List<String> options = ImmutableList.of(localizer.getMessage("lblCloseScreen"), localizer.getMessage("lblExitForge"), localizer.getMessage("lblCancel"));
final int reply = FOptionPane.showOptionDialog( final int reply = FOptionPane.showOptionDialog(
"Forge now supports navigation tabs which allow closing and switching between different screens with ease. " localizer.getMessage("txCloseAction1") + "\n\n" + localizer.getMessage("txCloseAction2"),
+ "As a result, you no longer need to use the X button in the upper right to close the current screen and go back." localizer.getMessage("titCloseAction"),
+ "\n\n"
+ "Please select what you want to happen when clicking the X button in the upper right. This choice will be used "
+ "going forward and you will not see this message again. You can change this behavior at any time in Preferences.",
"Select Your Close Action",
FOptionPane.INFORMATION_ICON, FOptionPane.INFORMATION_ICON,
options, options,
2); 2);
@@ -179,13 +176,14 @@ public enum FControl implements KeyEventDispatcher {
} }
public boolean canExitForge(final boolean forRestart) { public boolean canExitForge(final boolean forRestart) {
final String action = (forRestart ? "Restart" : "Exit"); final Localizer localizer = Localizer.getInstance();
String userPrompt = "Are you sure you wish to " + (forRestart ? "restart" : "exit") + " Forge?"; final String action = (forRestart ? localizer.getMessage("lblRestart") : localizer.getMessage("lblExit"));
String userPrompt =(forRestart ? localizer.getMessage("lblAreYouSureYouWishRestartForge") : localizer.getMessage("lblAreYouSureYouWishExitForge"));
final boolean hasCurrentMatches = hasCurrentMatches(); final boolean hasCurrentMatches = hasCurrentMatches();
if (hasCurrentMatches) { if (hasCurrentMatches) {
userPrompt = "One or more games are currently active. " + userPrompt; userPrompt = localizer.getMessage("lblOneOrMoreGamesActive") + ". " + userPrompt;
} }
if (!FOptionPane.showConfirmDialog(userPrompt, action + " Forge", action, "Cancel", !hasCurrentMatches)) { //default Yes if no game active if (!FOptionPane.showConfirmDialog(userPrompt, action + " Forge", action, localizer.getMessage("lblCancel"), !hasCurrentMatches)) { //default Yes if no game active
return false; return false;
} }
return CDeckEditorUI.SINGLETON_INSTANCE.canSwitchAway(true); return CDeckEditorUI.SINGLETON_INSTANCE.canSwitchAway(true);
@@ -223,7 +221,8 @@ public enum FControl implements KeyEventDispatcher {
closeAction = CloseAction.valueOf(prefs.getPref(FPref.UI_CLOSE_ACTION)); closeAction = CloseAction.valueOf(prefs.getPref(FPref.UI_CLOSE_ACTION));
FView.SINGLETON_INSTANCE.setSplashProgessBarMessage("Loading quest..."); final Localizer localizer = Localizer.getInstance();
FView.SINGLETON_INSTANCE.setSplashProgessBarMessage(localizer.getMessage("lblLoadingQuest"));
// Preload quest data if present // Preload quest data if present
final File dirQuests = new File(ForgeConstants.QUEST_SAVE_DIR); final File dirQuests = new File(ForgeConstants.QUEST_SAVE_DIR);
final String questname = FModel.getQuestPreferences().getPref(QPref.CURRENT_QUEST); final String questname = FModel.getQuestPreferences().getPref(QPref.CURRENT_QUEST);
@@ -258,7 +257,6 @@ public enum FControl implements KeyEventDispatcher {
FView.SINGLETON_INSTANCE.getLpnDocument().addComponentListener(SResizingUtil.getWindowResizeListener()); FView.SINGLETON_INSTANCE.getLpnDocument().addComponentListener(SResizingUtil.getWindowResizeListener());
setGlobalKeyboardHandler(); setGlobalKeyboardHandler();
final Localizer localizer = Localizer.getInstance();
FView.SINGLETON_INSTANCE.setSplashProgessBarMessage(localizer.getMessage("lblOpeningMainWindow")); FView.SINGLETON_INSTANCE.setSplashProgessBarMessage(localizer.getMessage("lblOpeningMainWindow"));
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override @Override
@@ -318,7 +316,8 @@ public enum FControl implements KeyEventDispatcher {
try { try {
SLayoutIO.loadLayout(null); SLayoutIO.loadLayout(null);
} catch (final InvalidLayoutFileException ex) { } catch (final InvalidLayoutFileException ex) {
SOptionPane.showMessageDialog(String.format("Your %s layout file could not be read. It will be deleted after you press OK.\nThe game will proceed with default layout.", screen.getTabCaption()), "Warning!"); final Localizer localizer = Localizer.getInstance();
SOptionPane.showMessageDialog(String.format(localizer.getMessage("lblerrLoadingLayoutFile"), screen.getTabCaption()), "Warning!");
if (screen.deleteLayoutFile()) { if (screen.deleteLayoutFile()) {
SLayoutIO.loadLayout(null); //try again SLayoutIO.loadLayout(null); //try again
} }

View File

@@ -134,11 +134,9 @@ public class ListChooser<T> {
} }
}); });
this.lstChoices.addMouseListener(new FMouseAdapter() { this.lstChoices.addMouseListener(new FMouseAdapter() {
@Override public void onLeftClick(final MouseEvent e) { @Override public void onLeftDoubleClick(final MouseEvent e) {
if (e.getClickCount() == 2) {
ListChooser.this.commit(); ListChooser.this.commit();
} }
}
}); });
} }

View File

@@ -10,6 +10,7 @@ import forge.quest.data.QuestPreferences;
import forge.screens.home.quest.DialogChooseFormats; import forge.screens.home.quest.DialogChooseFormats;
import forge.screens.home.quest.DialogChooseSets; import forge.screens.home.quest.DialogChooseSets;
import forge.screens.match.controllers.CDetailPicture; import forge.screens.match.controllers.CDetailPicture;
import forge.util.Localizer;
import javax.swing.*; import javax.swing.*;
import java.util.HashMap; import java.util.HashMap;
@@ -81,8 +82,8 @@ public class CardManager extends ItemManager<PaperCard> {
public void buildAddFilterMenu(JMenu menu, final ItemManager<? super PaperCard> itemManager) { public void buildAddFilterMenu(JMenu menu, final ItemManager<? super PaperCard> itemManager) {
GuiUtils.addSeparator(menu); //separate from current search item GuiUtils.addSeparator(menu); //separate from current search item
final Localizer localizer = Localizer.getInstance();
JMenu fmt = GuiUtils.createMenu("Format"); JMenu fmt = GuiUtils.createMenu(localizer.getMessage("lblFormat"));
for (final GameFormat f : FModel.getFormats().getFilterList()) { for (final GameFormat f : FModel.getFormats().getFilterList()) {
GuiUtils.addMenuItem(fmt, f.getName(), null, new Runnable() { GuiUtils.addMenuItem(fmt, f.getName(), null, new Runnable() {
@Override @Override
@@ -93,7 +94,7 @@ public class CardManager extends ItemManager<PaperCard> {
} }
menu.add(fmt); menu.add(fmt);
GuiUtils.addMenuItem(menu, "Formats...", null, new Runnable() { GuiUtils.addMenuItem(menu, localizer.getMessage("lblFormats") + "...", null, new Runnable() {
@Override public void run() { @Override public void run() {
final CardFormatFilter existingFilter = itemManager.getFilter(CardFormatFilter.class); final CardFormatFilter existingFilter = itemManager.getFilter(CardFormatFilter.class);
if (existingFilter != null) { if (existingFilter != null) {
@@ -113,7 +114,7 @@ public class CardManager extends ItemManager<PaperCard> {
} }
}); });
GuiUtils.addMenuItem(menu, "Sets...", null, new Runnable() { GuiUtils.addMenuItem(menu, localizer.getMessage("lblSets") + "...", null, new Runnable() {
@Override @Override
public void run() { public void run() {
CardSetFilter existingFilter = itemManager.getFilter(CardSetFilter.class); CardSetFilter existingFilter = itemManager.getFilter(CardSetFilter.class);
@@ -135,7 +136,7 @@ public class CardManager extends ItemManager<PaperCard> {
} }
}); });
JMenu world = GuiUtils.createMenu("Quest world"); JMenu world = GuiUtils.createMenu(localizer.getMessage("lblQuestWorld"));
for (final QuestWorld w : FModel.getWorlds()) { for (final QuestWorld w : FModel.getWorlds()) {
GuiUtils.addMenuItem(world, w.getName(), null, new Runnable() { GuiUtils.addMenuItem(world, w.getName(), null, new Runnable() {
@Override @Override
@@ -148,19 +149,19 @@ public class CardManager extends ItemManager<PaperCard> {
GuiUtils.addSeparator(menu); GuiUtils.addSeparator(menu);
GuiUtils.addMenuItem(menu, "Colors", null, new Runnable() { GuiUtils.addMenuItem(menu, localizer.getMessage("lblColors"), null, new Runnable() {
@Override @Override
public void run() { public void run() {
itemManager.addFilter(new CardColorFilter(itemManager)); itemManager.addFilter(new CardColorFilter(itemManager));
} }
}, itemManager.getFilter(CardColorFilter.class) == null); }, itemManager.getFilter(CardColorFilter.class) == null);
GuiUtils.addMenuItem(menu, "Types", null, new Runnable() { GuiUtils.addMenuItem(menu, localizer.getMessage("lblTypes"), null, new Runnable() {
@Override @Override
public void run() { public void run() {
itemManager.addFilter(new CardTypeFilter(itemManager)); itemManager.addFilter(new CardTypeFilter(itemManager));
} }
}, itemManager.getFilter(CardTypeFilter.class) == null); }, itemManager.getFilter(CardTypeFilter.class) == null);
GuiUtils.addMenuItem(menu, "Converted mana costs", null, new Runnable() { GuiUtils.addMenuItem(menu, localizer.getMessage("lblConvertedManaCosts"), null, new Runnable() {
@Override @Override
public void run() { public void run() {
itemManager.addFilter(new CardCMCFilter(itemManager)); itemManager.addFilter(new CardCMCFilter(itemManager));
@@ -169,19 +170,19 @@ public class CardManager extends ItemManager<PaperCard> {
GuiUtils.addSeparator(menu); GuiUtils.addSeparator(menu);
GuiUtils.addMenuItem(menu, "CMC range", null, new Runnable() { GuiUtils.addMenuItem(menu, localizer.getMessage("lblCMCRange"), null, new Runnable() {
@Override @Override
public void run() { public void run() {
itemManager.addFilter(new CardCMCRangeFilter(itemManager)); itemManager.addFilter(new CardCMCRangeFilter(itemManager));
} }
}, itemManager.getFilter(CardCMCRangeFilter.class) == null); }, itemManager.getFilter(CardCMCRangeFilter.class) == null);
GuiUtils.addMenuItem(menu, "Power range", null, new Runnable() { GuiUtils.addMenuItem(menu, localizer.getMessage("lblPowerRange"), null, new Runnable() {
@Override @Override
public void run() { public void run() {
itemManager.addFilter(new CardPowerFilter(itemManager)); itemManager.addFilter(new CardPowerFilter(itemManager));
} }
}, itemManager.getFilter(CardPowerFilter.class) == null); }, itemManager.getFilter(CardPowerFilter.class) == null);
GuiUtils.addMenuItem(menu, "Toughness range", null, new Runnable() { GuiUtils.addMenuItem(menu, localizer.getMessage("lblToughnessRange"), null, new Runnable() {
@Override @Override
public void run() { public void run() {
itemManager.addFilter(new CardToughnessFilter(itemManager)); itemManager.addFilter(new CardToughnessFilter(itemManager));
@@ -190,7 +191,7 @@ public class CardManager extends ItemManager<PaperCard> {
GuiUtils.addSeparator(menu); GuiUtils.addSeparator(menu);
GuiUtils.addMenuItem(menu, "Foil", null, new Runnable() { GuiUtils.addMenuItem(menu, localizer.getMessage("lblFoil"), null, new Runnable() {
@Override @Override
public void run() { public void run() {
itemManager.addFilter(new CardFoilFilter(itemManager)); itemManager.addFilter(new CardFoilFilter(itemManager));
@@ -198,7 +199,7 @@ public class CardManager extends ItemManager<PaperCard> {
}, itemManager.getFilter(CardFoilFilter.class) == null); }, itemManager.getFilter(CardFoilFilter.class) == null);
if (QuestMode) { if (QuestMode) {
GuiUtils.addMenuItem(menu, "Personal Rating", null, new Runnable() { GuiUtils.addMenuItem(menu, localizer.getMessage("lblPersonalRating"), null, new Runnable() {
@Override @Override
public void run() { public void run() {
itemManager.addFilter(new CardRatingFilter(itemManager)); itemManager.addFilter(new CardRatingFilter(itemManager));
@@ -208,7 +209,7 @@ public class CardManager extends ItemManager<PaperCard> {
GuiUtils.addSeparator(menu); GuiUtils.addSeparator(menu);
GuiUtils.addMenuItem(menu, "Advanced...", null, new Runnable() { GuiUtils.addMenuItem(menu, localizer.getMessage("lblAdvanced")+ "...", null, new Runnable() {
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void run() { public void run() {

View File

@@ -12,6 +12,7 @@ import forge.itemmanager.SItemManagerUtil.StatTypes;
import forge.toolbox.FLabel; import forge.toolbox.FLabel;
import forge.toolbox.FSkin; import forge.toolbox.FSkin;
import forge.util.ItemPool; import forge.util.ItemPool;
import forge.util.Localizer;
import javax.swing.*; import javax.swing.*;
@@ -28,9 +29,10 @@ public abstract class StatTypeFilter<T extends InventoryItem> extends ToggleButt
@SuppressWarnings("serial") @SuppressWarnings("serial")
protected void addToggleButton(JPanel widget, final StatTypes st) { protected void addToggleButton(JPanel widget, final StatTypes st) {
final Localizer localizer = Localizer.getInstance();
StringBuilder tooltip = new StringBuilder(); StringBuilder tooltip = new StringBuilder();
tooltip.append(st.label); tooltip.append(st.label);
tooltip.append(" (click to toggle the filter, right-click to show only "); tooltip.append(" (" + localizer.getMessage("lblclicktotoogle") + " ");
if (st.label.length() > 1 && !Character.isUpperCase(st.label.charAt(1))) { if (st.label.length() > 1 && !Character.isUpperCase(st.label.charAt(1))) {
tooltip.append(st.label.substring(0, 1).toLowerCase()); tooltip.append(st.label.substring(0, 1).toLowerCase());
tooltip.append(st.label.substring(1)); tooltip.append(st.label.substring(1));

View File

@@ -56,6 +56,7 @@ import forge.toolbox.FSkin.SkinFont;
import forge.toolbox.FSkin.SkinImage; import forge.toolbox.FSkin.SkinImage;
import forge.toolbox.FTextField; import forge.toolbox.FTextField;
import forge.toolbox.special.CardZoomer; import forge.toolbox.special.CardZoomer;
import forge.util.Localizer;
import forge.view.arcane.CardPanel; import forge.view.arcane.CardPanel;
public class ImageView<T extends InventoryItem> extends ItemView<T> { public class ImageView<T extends InventoryItem> extends ItemView<T> {
@@ -83,6 +84,7 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
private ItemInfo focalItem; private ItemInfo focalItem;
private final List<ItemInfo> orderedItems = new ArrayList<ItemInfo>(); private final List<ItemInfo> orderedItems = new ArrayList<ItemInfo>();
private final List<Group> groups = new ArrayList<Group>(); private final List<Group> groups = new ArrayList<Group>();
final Localizer localizer = Localizer.getInstance();
private static boolean isPreferenceEnabled(final ForgePreferences.FPref preferenceName) { private static boolean isPreferenceEnabled(final ForgePreferences.FPref preferenceName) {
return FModel.getPreferences().getPrefBoolean(preferenceName); return FModel.getPreferences().getPrefBoolean(preferenceName);
@@ -127,9 +129,8 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
repaintSelf(); repaintSelf();
} }
} }
private void updateToolTip() { private void updateToolTip() {
setToolTipText(isAllCollapsed ? "Expand all groups" : "Collapse all groups"); setToolTipText(isAllCollapsed ? localizer.getMessage("lblExpandallgroups") : localizer.getMessage("lblCollapseallgroups"));
} }
@Override @Override
@@ -211,11 +212,11 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
}); });
getPnlOptions().add(btnExpandCollapseAll, "w " + FTextField.HEIGHT + "px, h " + FTextField.HEIGHT + "px"); getPnlOptions().add(btnExpandCollapseAll, "w " + FTextField.HEIGHT + "px, h " + FTextField.HEIGHT + "px");
getPnlOptions().add(new FLabel.Builder().text("Group by:").fontSize(12).build()); getPnlOptions().add(new FLabel.Builder().text(localizer.getMessage("lblGroupby") +":").fontSize(12).build());
cbGroupByOptions.addTo(getPnlOptions(), "pushx, growx"); cbGroupByOptions.addTo(getPnlOptions(), "pushx, growx");
getPnlOptions().add(new FLabel.Builder().text("Pile by:").fontSize(12).build()); getPnlOptions().add(new FLabel.Builder().text(localizer.getMessage("lblPileby") +":").fontSize(12).build());
cbPileByOptions.addTo(getPnlOptions(), "pushx, growx"); cbPileByOptions.addTo(getPnlOptions(), "pushx, growx");
getPnlOptions().add(new FLabel.Builder().text("Columns:").fontSize(12).build()); getPnlOptions().add(new FLabel.Builder().text(localizer.getMessage("lblColumns") +":").fontSize(12).build());
cbColumnCount.addTo(getPnlOptions(), "w 38px!"); cbColumnCount.addTo(getPnlOptions(), "w 38px!");
//setup display //setup display

View File

@@ -44,6 +44,7 @@ import forge.toolbox.FLabel;
import forge.toolbox.FSkin; import forge.toolbox.FSkin;
import forge.util.Aggregates; import forge.util.Aggregates;
import forge.util.ItemPool; import forge.util.ItemPool;
import forge.util.Localizer;
import forge.view.FView; import forge.view.FView;
import javax.swing.*; import javax.swing.*;
@@ -77,37 +78,39 @@ public abstract class ACEditorBase<TItem extends InventoryItem, TModel extends D
private final CDetailPicture cDetailPicture; private final CDetailPicture cDetailPicture;
// card transfer buttons // card transfer buttons
final Localizer localizer = Localizer.getInstance();
private final FLabel btnAdd = new FLabel.Builder() private final FLabel btnAdd = new FLabel.Builder()
.fontSize(14) .fontSize(14)
.text("Add card") .text(localizer.getMessage("lblAddcard"))
.tooltip("Add selected card to current deck (or double click the row or hit the spacebar)") .tooltip(localizer.getMessage("ttAddcard"))
.icon(FSkin.getIcon(FSkinProp.ICO_PLUS)) .icon(FSkin.getIcon(FSkinProp.ICO_PLUS))
.iconScaleAuto(false).hoverable().build(); .iconScaleAuto(false).hoverable().build();
private final FLabel btnAdd4 = new FLabel.Builder() private final FLabel btnAdd4 = new FLabel.Builder()
.fontSize(14) .fontSize(14)
.text("Add 4 of card") .text(localizer.getMessage("lblAdd4ofcard"))
.tooltip("Add up to 4 of selected card to current deck") .tooltip(localizer.getMessage("ttAdd4ofcard"))
.icon(FSkin.getIcon(FSkinProp.ICO_PLUS)) .icon(FSkin.getIcon(FSkinProp.ICO_PLUS))
.iconScaleAuto(false).hoverable().build(); .iconScaleAuto(false).hoverable().build();
private final FLabel btnRemove = new FLabel.Builder() private final FLabel btnRemove = new FLabel.Builder()
.fontSize(14) .fontSize(14)
.text("Remove card") .text(localizer.getMessage("lblRemovecard"))
.tooltip("Remove selected card from current deck (or double click the row or hit the spacebar)") .tooltip(localizer.getMessage("ttRemovecard"))
.icon(FSkin.getIcon(FSkinProp.ICO_MINUS)) .icon(FSkin.getIcon(FSkinProp.ICO_MINUS))
.iconScaleAuto(false).hoverable().build(); .iconScaleAuto(false).hoverable().build();
private final FLabel btnRemove4 = new FLabel.Builder() private final FLabel btnRemove4 = new FLabel.Builder()
.fontSize(14) .fontSize(14)
.text("Remove 4 of card") .text(localizer.getMessage("lblRemove4ofcard"))
.tooltip("Remove up to 4 of selected card to current deck") .tooltip(localizer.getMessage("ttRemove4ofcard"))
.icon(FSkin.getIcon(FSkinProp.ICO_MINUS)) .icon(FSkin.getIcon(FSkinProp.ICO_MINUS))
.iconScaleAuto(false).hoverable().build(); .iconScaleAuto(false).hoverable().build();
private final FLabel btnAddBasicLands = new FLabel.Builder() private final FLabel btnAddBasicLands = new FLabel.Builder()
.fontSize(14) .fontSize(14)
.text("Add Basic Lands") .text(localizer.getMessage("lblAddBasicLands"))
.tooltip("Add basic lands to the deck") .tooltip(localizer.getMessage("ttAddBasicLands"))
.icon(FSkin.getImage(FSkinProp.IMG_LAND, 18, 18)) .icon(FSkin.getImage(FSkinProp.IMG_LAND, 18, 18))
.iconScaleAuto(false).hoverable().build(); .iconScaleAuto(false).hoverable().build();
@@ -390,13 +393,13 @@ public abstract class ACEditorBase<TItem extends InventoryItem, TModel extends D
VCurrentDeck.SINGLETON_INSTANCE.getPnlHeader().setVisible(true); VCurrentDeck.SINGLETON_INSTANCE.getPnlHeader().setVisible(true);
VCardCatalog.SINGLETON_INSTANCE.getTabLabel().setText("Card Catalog"); VCardCatalog.SINGLETON_INSTANCE.getTabLabel().setText(localizer.getMessage("lblCardCatalog"));
VCurrentDeck.SINGLETON_INSTANCE.getBtnPrintProxies().setVisible(true); VCurrentDeck.SINGLETON_INSTANCE.getBtnPrintProxies().setVisible(true);
getCbxSection().setVisible(false); getCbxSection().setVisible(false);
VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().setVisible(true); VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().setVisible(true);
VCurrentDeck.SINGLETON_INSTANCE.getLblTitle().setText("Title:"); VCurrentDeck.SINGLETON_INSTANCE.getLblTitle().setText(localizer.getMessage("lblTitle") + ":");
} }
public FLabel getBtnAdd() { return btnAdd; } public FLabel getBtnAdd() { return btnAdd; }
@@ -445,7 +448,7 @@ public abstract class ACEditorBase<TItem extends InventoryItem, TModel extends D
menu.addSeparator(); menu.addSeparator();
} }
GuiUtils.addMenuItem(menu, "Jump to previous table", GuiUtils.addMenuItem(menu, localizer.getMessage("lblJumptoprevioustable"),
KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0),
new Runnable() { new Runnable() {
@Override @Override
@@ -453,7 +456,7 @@ public abstract class ACEditorBase<TItem extends InventoryItem, TModel extends D
getNextItemManager().focus(); getNextItemManager().focus();
} }
}); });
GuiUtils.addMenuItem(menu, "Jump to next table", GuiUtils.addMenuItem(menu, localizer.getMessage("lblJumptopnexttable"),
KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0),
new Runnable() { new Runnable() {
@Override @Override
@@ -461,7 +464,7 @@ public abstract class ACEditorBase<TItem extends InventoryItem, TModel extends D
getNextItemManager().focus(); getNextItemManager().focus();
} }
}); });
GuiUtils.addMenuItem(menu, "Jump to text filter", GuiUtils.addMenuItem(menu, localizer.getMessage("lblJumptotextfilter"),
KeyStroke.getKeyStroke(KeyEvent.VK_F, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), KeyStroke.getKeyStroke(KeyEvent.VK_F, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),
new Runnable() { new Runnable() {
@Override @Override
@@ -498,13 +501,13 @@ public abstract class ACEditorBase<TItem extends InventoryItem, TModel extends D
* @param qty a negative quantity will prompt the user for a number * @param qty a negative quantity will prompt the user for a number
*/ */
private void addMakeFoil(final int qty) { private void addMakeFoil(final int qty) {
String label = "Foil " + SItemManagerUtil.getItemDisplayString(getItemManager().getSelectedItems(), qty, false); String label = localizer.getMessage("lblConvertToFoil") + " " + SItemManagerUtil.getItemDisplayString(getItemManager().getSelectedItems(), qty, false);
GuiUtils.addMenuItem(menu, label, null, new Runnable() { GuiUtils.addMenuItem(menu, label, null, new Runnable() {
@Override public void run() { @Override public void run() {
Integer quantity = qty; Integer quantity = qty;
if (quantity < 0) { if (quantity < 0) {
quantity = GuiChoose.getInteger("Choose a value for X", 1, -quantity, 20); quantity = GuiChoose.getInteger(localizer.getMessage("lblChooseavalueforX"), 1, -quantity, 20);
if (quantity == null) { return; } if (quantity == null) { return; }
} }
// get the currently selected card from the editor // get the currently selected card from the editor
@@ -525,7 +528,7 @@ public abstract class ACEditorBase<TItem extends InventoryItem, TModel extends D
} }
}, true, true); }, true, true);
} }
//TODO: need to translate getItemDisplayString
private void addItem(final String verb, final String dest, final boolean toAlternate, final int qty, final int shortcutModifiers) { private void addItem(final String verb, final String dest, final boolean toAlternate, final int qty, final int shortcutModifiers) {
String label = verb + " " + SItemManagerUtil.getItemDisplayString(getItemManager().getSelectedItems(), qty, false); String label = verb + " " + SItemManagerUtil.getItemDisplayString(getItemManager().getSelectedItems(), qty, false);
if (dest != null && !dest.isEmpty()) { if (dest != null && !dest.isEmpty()) {
@@ -536,7 +539,7 @@ public abstract class ACEditorBase<TItem extends InventoryItem, TModel extends D
@Override public void run() { @Override public void run() {
Integer quantity = qty; Integer quantity = qty;
if (quantity < 0) { if (quantity < 0) {
quantity = GuiChoose.getInteger("Choose a value for X", 1, -quantity, 20); quantity = GuiChoose.getInteger(localizer.getMessage("lblChooseavalueforX"), 1, -quantity, 20);
if (quantity == null) { return; } if (quantity == null) { return; }
} }
if (isAddContextMenu) { if (isAddContextMenu) {

View File

@@ -38,6 +38,7 @@ import forge.screens.deckeditor.SEditorIO;
import forge.screens.match.controllers.CDetailPicture; import forge.screens.match.controllers.CDetailPicture;
import forge.toolbox.FComboBox; import forge.toolbox.FComboBox;
import forge.util.ItemPool; import forge.util.ItemPool;
import forge.util.Localizer;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
@@ -126,7 +127,9 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
catalogManager = new CardManager(getCDetailPicture(), wantUnique, false); catalogManager = new CardManager(getCDetailPicture(), wantUnique, false);
deckManager = new CardManager(getCDetailPicture(), wantUnique, false); deckManager = new CardManager(getCDetailPicture(), wantUnique, false);
catalogManager.setCaption("Catalog"); final Localizer localizer = Localizer.getInstance();
catalogManager.setCaption(localizer.getMessage("lblCatalog"));
this.setCatalogManager(catalogManager); this.setCatalogManager(catalogManager);
this.setDeckManager(deckManager); this.setDeckManager(deckManager);
@@ -258,13 +261,14 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
} }
public static void buildAddContextMenu(EditorContextMenuBuilder cmb, DeckSection sectionMode) { public static void buildAddContextMenu(EditorContextMenuBuilder cmb, DeckSection sectionMode) {
final Localizer localizer = Localizer.getInstance();
switch (sectionMode) { switch (sectionMode) {
case Main: case Main:
cmb.addMoveItems("Add", "to deck"); cmb.addMoveItems(localizer.getMessage("lblAdd"), localizer.getMessage("lbltodeck"));
cmb.addMoveAlternateItems("Add", "to sideboard"); cmb.addMoveAlternateItems(localizer.getMessage("lblAdd"), localizer.getMessage("lbltosideboard"));
break; break;
case Sideboard: case Sideboard:
cmb.addMoveItems("Add", "to sideboard"); cmb.addMoveItems(localizer.getMessage("lblAdd"), "to sideboard");
break; break;
case Commander: case Commander:
cmb.addMoveItems("Set", "as commander"); cmb.addMoveItems("Set", "as commander");
@@ -273,41 +277,42 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
cmb.addMoveItems("Set", "as avatar"); cmb.addMoveItems("Set", "as avatar");
break; break;
case Schemes: case Schemes:
cmb.addMoveItems("Add", "to scheme deck"); cmb.addMoveItems(localizer.getMessage("lblAdd"), "to scheme deck");
break; break;
case Planes: case Planes:
cmb.addMoveItems("Add", "to planar deck"); cmb.addMoveItems(localizer.getMessage("lblAdd"), "to planar deck");
break; break;
case Conspiracy: case Conspiracy:
cmb.addMoveItems("Add", "to conspiracy deck"); cmb.addMoveItems(localizer.getMessage("lblAdd"), "to conspiracy deck");
break; break;
} }
} }
public static void buildRemoveContextMenu(EditorContextMenuBuilder cmb, DeckSection sectionMode, boolean foilAvailable) { public static void buildRemoveContextMenu(EditorContextMenuBuilder cmb, DeckSection sectionMode, boolean foilAvailable) {
final Localizer localizer = Localizer.getInstance();
switch (sectionMode) { switch (sectionMode) {
case Main: case Main:
cmb.addMoveItems("Remove", "from deck"); cmb.addMoveItems(localizer.getMessage("lblRemove"), localizer.getMessage("lblfromdeck"));
cmb.addMoveAlternateItems("Move", "to sideboard"); cmb.addMoveAlternateItems("Move", "to sideboard");
break; break;
case Sideboard: case Sideboard:
cmb.addMoveItems("Remove", "from sideboard"); cmb.addMoveItems(localizer.getMessage("lblRemove"), localizer.getMessage("lblfromsideboard"));
cmb.addMoveAlternateItems("Move", "to deck"); cmb.addMoveAlternateItems("Move", "to deck");
break; break;
case Commander: case Commander:
cmb.addMoveItems("Remove", "as commander"); cmb.addMoveItems(localizer.getMessage("lblRemove"), localizer.getMessage("lblascommander"));
break; break;
case Avatar: case Avatar:
cmb.addMoveItems("Remove", "as avatar"); cmb.addMoveItems(localizer.getMessage("lblRemove"), localizer.getMessage("lblasavatar"));
break; break;
case Schemes: case Schemes:
cmb.addMoveItems("Remove", "from scheme deck"); cmb.addMoveItems(localizer.getMessage("lblRemove"), localizer.getMessage("lblfromschemedeck"));
break; break;
case Planes: case Planes:
cmb.addMoveItems("Remove", "from planar deck"); cmb.addMoveItems(localizer.getMessage("lblRemove"), localizer.getMessage("lblfromplanardeck"));
break; break;
case Conspiracy: case Conspiracy:
cmb.addMoveItems("Remove", "from conspiracy deck"); cmb.addMoveItems(localizer.getMessage("lblRemove"), localizer.getMessage("lblfromconspiracydeck"));
break; break;
} }
if (foilAvailable) { if (foilAvailable) {

View File

@@ -35,6 +35,7 @@ import forge.screens.deckeditor.views.VAllDecks;
import forge.screens.deckeditor.views.VDeckgen; import forge.screens.deckeditor.views.VDeckgen;
import forge.screens.match.controllers.CDetailPicture; import forge.screens.match.controllers.CDetailPicture;
import forge.util.ItemPool; import forge.util.ItemPool;
import forge.util.Localizer;
import forge.util.storage.IStorage; import forge.util.storage.IStorage;
import java.util.Map.Entry; import java.util.Map.Entry;
@@ -70,8 +71,9 @@ public final class CEditorVariant extends CDeckEditor<Deck> {
final CardManager catalogManager = new CardManager(cDetailPicture, true, false); final CardManager catalogManager = new CardManager(cDetailPicture, true, false);
final CardManager deckManager = new CardManager(cDetailPicture, true, false); final CardManager deckManager = new CardManager(cDetailPicture, true, false);
final Localizer localizer = Localizer.getInstance();
catalogManager.setCaption("Catalog"); catalogManager.setCaption(localizer.getMessage("lblCatalog"));
this.setCatalogManager(catalogManager); this.setCatalogManager(catalogManager);
this.setDeckManager(deckManager); this.setDeckManager(deckManager);
@@ -131,12 +133,12 @@ public final class CEditorVariant extends CDeckEditor<Deck> {
@Override @Override
protected void buildAddContextMenu(EditorContextMenuBuilder cmb) { protected void buildAddContextMenu(EditorContextMenuBuilder cmb) {
cmb.addMoveItems("Add", "to deck"); cmb.addMoveItems(localizer.getMessage("lblAdd"), localizer.getMessage("lbltodeck"));
} }
@Override @Override
protected void buildRemoveContextMenu(EditorContextMenuBuilder cmb) { protected void buildRemoveContextMenu(EditorContextMenuBuilder cmb) {
cmb.addMoveItems("Remove", "from deck"); cmb.addMoveItems(localizer.getMessage("lblRemove"), localizer.getMessage("lblfromdeck"));
} }
/* /*

View File

@@ -21,6 +21,7 @@ import forge.StaticData;
import forge.deck.*; import forge.deck.*;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.util.ItemPool; import forge.util.ItemPool;
import forge.util.Localizer;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
@@ -402,9 +403,10 @@ public class DeckController<T extends DeckBase> {
} }
public void updateCaptions() { public void updateCaptions() {
String tabCaption = "Current Deck"; final Localizer localizer = Localizer.getInstance();
String tabCaption = localizer.getMessage("lblCurrentDeck2");
final String title = getModelName(); final String title = getModelName();
String itemManagerCaption = title.isEmpty() ? "[Untitled]" : title; String itemManagerCaption = title.isEmpty() ? "[" + localizer.getMessage("lblUntitled") +"]" : title;
if (!saved) { if (!saved) {
tabCaption = "*" + tabCaption; tabCaption = "*" + tabCaption;

View File

@@ -5,6 +5,7 @@ import forge.menus.MenuUtil;
import forge.screens.deckeditor.CDeckEditorUI; import forge.screens.deckeditor.CDeckEditorUI;
import forge.screens.deckeditor.views.VCurrentDeck; import forge.screens.deckeditor.views.VCurrentDeck;
import forge.toolbox.FSkin.SkinnedMenuItem; import forge.toolbox.FSkin.SkinnedMenuItem;
import forge.util.Localizer;
import javax.swing.*; import javax.swing.*;
@@ -24,8 +25,8 @@ public final class DeckFileMenu {
public static JMenu getMenu(boolean showMenuIcons) { public static JMenu getMenu(boolean showMenuIcons) {
showIcons = showMenuIcons; showIcons = showMenuIcons;
final Localizer localizer = Localizer.getInstance();
JMenu menu = new JMenu("File"); JMenu menu = new JMenu(localizer.getMessage("lblFile"));
menu.setMnemonic(KeyEvent.VK_F); menu.setMnemonic(KeyEvent.VK_F);
menu.add(getMenuItem_New()); menu.add(getMenuItem_New());
menu.add(getMenuItem_Open()); menu.add(getMenuItem_Open());
@@ -51,7 +52,8 @@ public final class DeckFileMenu {
} }
private static SkinnedMenuItem getMenuItem_New() { private static SkinnedMenuItem getMenuItem_New() {
SkinnedMenuItem menuItem = new SkinnedMenuItem("New Deck"); final Localizer localizer = Localizer.getInstance();
SkinnedMenuItem menuItem = new SkinnedMenuItem(localizer.getMessage("lblNewDeck"));
menuItem.setIcon(showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_NEW) : null); menuItem.setIcon(showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_NEW) : null);
menuItem.setAccelerator(MenuUtil.getAcceleratorKey(KeyEvent.VK_N)); menuItem.setAccelerator(MenuUtil.getAcceleratorKey(KeyEvent.VK_N));
menuItem.addActionListener(getNewAction()); menuItem.addActionListener(getNewAction());
@@ -68,7 +70,8 @@ public final class DeckFileMenu {
} }
private static SkinnedMenuItem getMenuItem_Open() { private static SkinnedMenuItem getMenuItem_Open() {
SkinnedMenuItem menuItem = new SkinnedMenuItem("Open Deck"); final Localizer localizer = Localizer.getInstance();
SkinnedMenuItem menuItem = new SkinnedMenuItem(localizer.getMessage("lblOpenDeck"));
menuItem.setIcon(showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_OPEN) : null); menuItem.setIcon(showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_OPEN) : null);
menuItem.setAccelerator(MenuUtil.getAcceleratorKey(KeyEvent.VK_O)); menuItem.setAccelerator(MenuUtil.getAcceleratorKey(KeyEvent.VK_O));
menuItem.addActionListener(getOpenAction()); menuItem.addActionListener(getOpenAction());
@@ -85,7 +88,8 @@ public final class DeckFileMenu {
} }
private static SkinnedMenuItem getMenuItem_Import() { private static SkinnedMenuItem getMenuItem_Import() {
SkinnedMenuItem menuItem = new SkinnedMenuItem("Import Deck"); final Localizer localizer = Localizer.getInstance();
SkinnedMenuItem menuItem = new SkinnedMenuItem(localizer.getMessage("lblImportDeck"));
menuItem.setAccelerator(MenuUtil.getAcceleratorKey(KeyEvent.VK_I)); menuItem.setAccelerator(MenuUtil.getAcceleratorKey(KeyEvent.VK_I));
menuItem.addActionListener(getImportAction()); menuItem.addActionListener(getImportAction());
return menuItem; return menuItem;
@@ -101,7 +105,8 @@ public final class DeckFileMenu {
} }
private static SkinnedMenuItem getMenuItem_Save() { private static SkinnedMenuItem getMenuItem_Save() {
SkinnedMenuItem menuItem = new SkinnedMenuItem("Save Deck"); final Localizer localizer = Localizer.getInstance();
SkinnedMenuItem menuItem = new SkinnedMenuItem(localizer.getMessage("lblSaveDeck"));
menuItem.setIcon(showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_SAVE) : null); menuItem.setIcon(showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_SAVE) : null);
menuItem.setAccelerator(MenuUtil.getAcceleratorKey(KeyEvent.VK_S)); menuItem.setAccelerator(MenuUtil.getAcceleratorKey(KeyEvent.VK_S));
menuItem.addActionListener(getSaveAction()); menuItem.addActionListener(getSaveAction());
@@ -119,7 +124,8 @@ public final class DeckFileMenu {
} }
private static SkinnedMenuItem getMenuItem_SaveAs() { private static SkinnedMenuItem getMenuItem_SaveAs() {
SkinnedMenuItem menuItem = new SkinnedMenuItem("Save Deck As"); final Localizer localizer = Localizer.getInstance();
SkinnedMenuItem menuItem = new SkinnedMenuItem(localizer.getMessage("lblSaveDeckAs"));
menuItem.setIcon(showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_SAVEAS) : null); menuItem.setIcon(showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_SAVEAS) : null);
menuItem.setAccelerator(MenuUtil.getAcceleratorKey(KeyEvent.VK_E)); menuItem.setAccelerator(MenuUtil.getAcceleratorKey(KeyEvent.VK_E));
menuItem.addActionListener(getSaveAsAction()); menuItem.addActionListener(getSaveAsAction());
@@ -137,7 +143,8 @@ public final class DeckFileMenu {
} }
private static SkinnedMenuItem getMenuItem_Print() { private static SkinnedMenuItem getMenuItem_Print() {
SkinnedMenuItem menuItem = new SkinnedMenuItem("Print to HTML file"); final Localizer localizer = Localizer.getInstance();
SkinnedMenuItem menuItem = new SkinnedMenuItem(localizer.getMessage("lblPrinttoHTMLfile"));
menuItem.setIcon(showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_PRINT) : null); menuItem.setIcon(showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_PRINT) : null);
menuItem.setAccelerator(MenuUtil.getAcceleratorKey(KeyEvent.VK_P)); menuItem.setAccelerator(MenuUtil.getAcceleratorKey(KeyEvent.VK_P));
menuItem.addActionListener(getPrintAction()); menuItem.addActionListener(getPrintAction());

View File

@@ -10,6 +10,7 @@ import forge.itemmanager.DeckManager;
import forge.itemmanager.ItemManagerContainer; import forge.itemmanager.ItemManagerContainer;
import forge.screens.deckeditor.controllers.CAllDecks; import forge.screens.deckeditor.controllers.CAllDecks;
import forge.screens.match.controllers.CDetailPicture; import forge.screens.match.controllers.CDetailPicture;
import forge.util.Localizer;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import javax.swing.*; import javax.swing.*;
@@ -25,7 +26,8 @@ public enum VAllDecks implements IVDoc<CAllDecks> {
// Fields used with interface IVDoc // Fields used with interface IVDoc
private DragCell parentCell; private DragCell parentCell;
private final DragTab tab = new DragTab("Constructed"); final Localizer localizer = Localizer.getInstance();
private final DragTab tab = new DragTab(localizer.getMessage("lblConstructed"));
private DeckManager lstDecks; private DeckManager lstDecks;
@@ -93,6 +95,6 @@ public enum VAllDecks implements IVDoc<CAllDecks> {
public void setCDetailPicture(final CDetailPicture cDetailPicture) { public void setCDetailPicture(final CDetailPicture cDetailPicture) {
this.lstDecks = new DeckManager(GameType.Constructed, cDetailPicture); this.lstDecks = new DeckManager(GameType.Constructed, cDetailPicture);
this.lstDecks.setCaption("Constructed Decks"); this.lstDecks.setCaption(localizer.getMessage("lblConstructedDecks"));
} }
} }

View File

@@ -10,6 +10,7 @@ import forge.itemmanager.DeckManager;
import forge.itemmanager.ItemManagerContainer; import forge.itemmanager.ItemManagerContainer;
import forge.screens.deckeditor.controllers.CBrawlDecks; import forge.screens.deckeditor.controllers.CBrawlDecks;
import forge.screens.match.controllers.CDetailPicture; import forge.screens.match.controllers.CDetailPicture;
import forge.util.Localizer;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import javax.swing.*; import javax.swing.*;
@@ -25,7 +26,8 @@ public enum VBrawlDecks implements IVDoc<CBrawlDecks> {
// Fields used with interface IVDoc // Fields used with interface IVDoc
private DragCell parentCell; private DragCell parentCell;
private final DragTab tab = new DragTab("Brawl"); final Localizer localizer = Localizer.getInstance();
private final DragTab tab = new DragTab(localizer.getMessage("lblBrawl"));
private DeckManager lstDecks; private DeckManager lstDecks;
@@ -93,6 +95,6 @@ public enum VBrawlDecks implements IVDoc<CBrawlDecks> {
public void setCDetailPicture(final CDetailPicture cDetailPicture) { public void setCDetailPicture(final CDetailPicture cDetailPicture) {
this.lstDecks = new DeckManager(GameType.Brawl, cDetailPicture); this.lstDecks = new DeckManager(GameType.Brawl, cDetailPicture);
this.lstDecks.setCaption("Brawl Decks"); this.lstDecks.setCaption(localizer.getMessage("lblBrawlDecks"));
} }
} }

View File

@@ -8,6 +8,7 @@ import forge.item.InventoryItem;
import forge.itemmanager.ItemManager; import forge.itemmanager.ItemManager;
import forge.itemmanager.ItemManagerContainer; import forge.itemmanager.ItemManagerContainer;
import forge.screens.deckeditor.controllers.CCardCatalog; import forge.screens.deckeditor.controllers.CCardCatalog;
import forge.util.Localizer;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import javax.swing.*; import javax.swing.*;
@@ -23,7 +24,8 @@ public enum VCardCatalog implements IVDoc<CCardCatalog> {
// Fields used with interface IVDoc // Fields used with interface IVDoc
private DragCell parentCell; private DragCell parentCell;
private final DragTab tab = new DragTab("Card Catalog"); final Localizer localizer = Localizer.getInstance();
private final DragTab tab = new DragTab(localizer.getMessage("lblCardCatalog"));
private final ItemManagerContainer itemManagerContainer = new ItemManagerContainer(); private final ItemManagerContainer itemManagerContainer = new ItemManagerContainer();
private ItemManager<? extends InventoryItem> itemManager; private ItemManager<? extends InventoryItem> itemManager;

View File

@@ -10,6 +10,7 @@ import forge.itemmanager.DeckManager;
import forge.itemmanager.ItemManagerContainer; import forge.itemmanager.ItemManagerContainer;
import forge.screens.deckeditor.controllers.CCommanderDecks; import forge.screens.deckeditor.controllers.CCommanderDecks;
import forge.screens.match.controllers.CDetailPicture; import forge.screens.match.controllers.CDetailPicture;
import forge.util.Localizer;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import javax.swing.*; import javax.swing.*;
@@ -25,7 +26,8 @@ public enum VCommanderDecks implements IVDoc<CCommanderDecks> {
// Fields used with interface IVDoc // Fields used with interface IVDoc
private DragCell parentCell; private DragCell parentCell;
private final DragTab tab = new DragTab("Commander"); final Localizer localizer = Localizer.getInstance();
private final DragTab tab = new DragTab(localizer.getMessage("lblCommander"));
private DeckManager lstDecks; private DeckManager lstDecks;
@@ -93,6 +95,6 @@ public enum VCommanderDecks implements IVDoc<CCommanderDecks> {
public void setCDetailPicture(final CDetailPicture cDetailPicture) { public void setCDetailPicture(final CDetailPicture cDetailPicture) {
this.lstDecks = new DeckManager(GameType.Commander, cDetailPicture); this.lstDecks = new DeckManager(GameType.Commander, cDetailPicture);
this.lstDecks.setCaption("Commander Decks"); this.lstDecks.setCaption(localizer.getMessage("lblCommanderDecks"));
} }
} }

View File

@@ -3,6 +3,7 @@ package forge.screens.deckeditor.views;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import forge.util.Localizer;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import forge.assets.FSkinProp; import forge.assets.FSkinProp;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
@@ -24,16 +25,17 @@ import forge.toolbox.FTextField;
*/ */
public enum VCurrentDeck implements IVDoc<CCurrentDeck> { public enum VCurrentDeck implements IVDoc<CCurrentDeck> {
SINGLETON_INSTANCE; SINGLETON_INSTANCE;
final Localizer localizer = Localizer.getInstance();
// Fields used with interface IVDoc // Fields used with interface IVDoc
private DragCell parentCell; private DragCell parentCell;
private final DragTab tab = new DragTab("Current Deck"); private final DragTab tab = new DragTab(localizer.getMessage("lblVCurrentDeck"));
// Other fields // Other fields
private final FLabel btnSave = new FLabel.Builder() private final FLabel btnSave = new FLabel.Builder()
.fontSize(14) .fontSize(14)
.tooltip("Save Deck (Ctrl+S)") .tooltip(localizer.getMessage("ttbtnSave"))
.iconInBackground(true) .iconInBackground(true)
.iconAlignX(SwingConstants.CENTER) .iconAlignX(SwingConstants.CENTER)
.icon(FSkin.getIcon(FSkinProp.ICO_SAVE)) .icon(FSkin.getIcon(FSkinProp.ICO_SAVE))
@@ -41,7 +43,7 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck> {
private final FLabel btnSaveAs = new FLabel.Builder() private final FLabel btnSaveAs = new FLabel.Builder()
.fontSize(14) .fontSize(14)
.tooltip("Save Deck As (Ctrl+E)") .tooltip(localizer.getMessage("ttbtnSaveAs"))
.iconInBackground(true) .iconInBackground(true)
.iconAlignX(SwingConstants.CENTER) .iconAlignX(SwingConstants.CENTER)
.icon(FSkin.getIcon(FSkinProp.ICO_SAVEAS)) .icon(FSkin.getIcon(FSkinProp.ICO_SAVEAS))
@@ -49,7 +51,7 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck> {
private final FLabel btnLoad = new FLabel.Builder() private final FLabel btnLoad = new FLabel.Builder()
.fontSize(14) .fontSize(14)
.tooltip("Open Deck (Ctrl+O)") .tooltip(localizer.getMessage("ttbtnLoadDeck"))
.iconInBackground(true) .iconInBackground(true)
.iconAlignX(SwingConstants.CENTER) .iconAlignX(SwingConstants.CENTER)
.icon(FSkin.getIcon(FSkinProp.ICO_OPEN)) .icon(FSkin.getIcon(FSkinProp.ICO_OPEN))
@@ -57,7 +59,7 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck> {
private final FLabel btnNew = new FLabel.Builder() private final FLabel btnNew = new FLabel.Builder()
.fontSize(14) .fontSize(14)
.tooltip("New Deck (Ctrl+N)") .tooltip(localizer.getMessage("ttbtnNewDeck"))
.iconInBackground(true) .iconInBackground(true)
.iconAlignX(SwingConstants.CENTER) .iconAlignX(SwingConstants.CENTER)
.icon(FSkin.getIcon(FSkinProp.ICO_NEW)) .icon(FSkin.getIcon(FSkinProp.ICO_NEW))
@@ -65,7 +67,7 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck> {
private final FLabel btnPrintProxies = new FLabel.Builder() private final FLabel btnPrintProxies = new FLabel.Builder()
.fontSize(14) .fontSize(14)
.tooltip("Print to HTML file (Ctrl+P)") .tooltip(localizer.getMessage("ttbtnPrintProxies"))
.iconInBackground(true) .iconInBackground(true)
.iconAlignX(SwingConstants.CENTER) .iconAlignX(SwingConstants.CENTER)
.icon(FSkin.getIcon(FSkinProp.ICO_PRINT)) .icon(FSkin.getIcon(FSkinProp.ICO_PRINT))
@@ -73,15 +75,15 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck> {
private final FLabel btnImport = new FLabel.Builder() private final FLabel btnImport = new FLabel.Builder()
.fontSize(14) .fontSize(14)
.text("Import") .text(localizer.getMessage("lblImport"))
.tooltip("Attempt to import a deck from a non-Forge format (Ctrl+I)") .tooltip(localizer.getMessage("ttImportDeck"))
.opaque(true).hoverable(true).build(); .opaque(true).hoverable(true).build();
private final FTextField txfTitle = new FTextField.Builder().ghostText("[New Deck]").build(); private final FTextField txfTitle = new FTextField.Builder().ghostText("[New Deck]").build();
private final JPanel pnlHeader = new JPanel(); private final JPanel pnlHeader = new JPanel();
private final FLabel lblTitle = new FLabel.Builder().text("Title").fontSize(14).build(); private final FLabel lblTitle = new FLabel.Builder().text(localizer.getMessage("lblTitle")).fontSize(14).build();
private final ItemManagerContainer itemManagerContainer = new ItemManagerContainer(); private final ItemManagerContainer itemManagerContainer = new ItemManagerContainer();
private ItemManager<? extends InventoryItem> itemManager; private ItemManager<? extends InventoryItem> itemManager;

View File

@@ -6,6 +6,7 @@ import forge.gui.framework.EDocID;
import forge.gui.framework.IVDoc; import forge.gui.framework.IVDoc;
import forge.screens.deckeditor.controllers.CDeckgen; import forge.screens.deckeditor.controllers.CDeckgen;
import forge.toolbox.FLabel; import forge.toolbox.FLabel;
import forge.util.Localizer;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
/** /**
@@ -16,30 +17,29 @@ import net.miginfocom.swing.MigLayout;
public enum VDeckgen implements IVDoc<CDeckgen> { public enum VDeckgen implements IVDoc<CDeckgen> {
/** */ /** */
SINGLETON_INSTANCE; SINGLETON_INSTANCE;
// Fields used with interface IVDoc // Fields used with interface IVDoc
private DragCell parentCell; private DragCell parentCell;
private final DragTab tab = new DragTab("Deck Generation"); final Localizer localizer = Localizer.getInstance();
private final DragTab tab = new DragTab(localizer.getMessage("lblDeckGeneration"));
// Deckgen buttons // Deckgen buttons
private final FLabel btnRandCardpool = new FLabel.Builder() private final FLabel btnRandCardpool = new FLabel.Builder()
.tooltip("Generate random constructed cardpool in current deck area") .tooltip(localizer.getMessage("ttbtnRandCardpool"))
.text("Random Cardpool").fontSize(14) .text(localizer.getMessage("btnRandCardpool")).fontSize(14)
.opaque(true).hoverable(true).build(); .opaque(true).hoverable(true).build();
private final FLabel btnRandDeck2 = new FLabel.Builder() private final FLabel btnRandDeck2 = new FLabel.Builder()
.tooltip("Generate 2 color constructed deck in current deck area") .tooltip(localizer.getMessage("ttbtnRandDeck2"))
.text("Constructed (2 color)").fontSize(14) .text(localizer.getMessage("btnRandDeck2")).fontSize(14)
.opaque(true).hoverable(true).build(); .opaque(true).hoverable(true).build();
private final FLabel btnRandDeck3 = new FLabel.Builder() private final FLabel btnRandDeck3 = new FLabel.Builder()
.tooltip("Generate 3 color constructed deck in current deck area") .tooltip(localizer.getMessage("ttbtnRandDeck3"))
.text("Constructed (3 color)").fontSize(14) .text(localizer.getMessage("btnRandDeck3")).fontSize(14)
.opaque(true).hoverable(true).build(); .opaque(true).hoverable(true).build();
private final FLabel btnRandDeck5 = new FLabel.Builder() private final FLabel btnRandDeck5 = new FLabel.Builder()
.tooltip("Generate 5 color constructed deck in current deck area") .tooltip(localizer.getMessage("ttbtnRandDeck5"))
.text("Constructed (5 color)").fontSize(14) .text(localizer.getMessage("btnRandDeck5")).fontSize(14)
.opaque(true).hoverable(true).build(); .opaque(true).hoverable(true).build();
//========== Constructor //========== Constructor

View File

@@ -10,6 +10,7 @@ import forge.itemmanager.DeckManager;
import forge.itemmanager.ItemManagerContainer; import forge.itemmanager.ItemManagerContainer;
import forge.screens.deckeditor.controllers.CTinyLeadersDecks; import forge.screens.deckeditor.controllers.CTinyLeadersDecks;
import forge.screens.match.controllers.CDetailPicture; import forge.screens.match.controllers.CDetailPicture;
import forge.util.Localizer;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import javax.swing.*; import javax.swing.*;
@@ -25,7 +26,8 @@ public enum VTinyLeadersDecks implements IVDoc<CTinyLeadersDecks> {
// Fields used with interface IVDoc // Fields used with interface IVDoc
private DragCell parentCell; private DragCell parentCell;
private final DragTab tab = new DragTab("Tiny Leaders"); final Localizer localizer = Localizer.getInstance();
private final DragTab tab = new DragTab(localizer.getMessage("lblTinyLeaders"));
private DeckManager lstDecks; private DeckManager lstDecks;
@@ -93,6 +95,6 @@ public enum VTinyLeadersDecks implements IVDoc<CTinyLeadersDecks> {
public void setCDetailPicture(final CDetailPicture cDetailPicture) { public void setCDetailPicture(final CDetailPicture cDetailPicture) {
this.lstDecks = new DeckManager(GameType.TinyLeaders, cDetailPicture); this.lstDecks = new DeckManager(GameType.TinyLeaders, cDetailPicture);
this.lstDecks.setCaption("Tiny Leaders Decks"); this.lstDecks.setCaption(localizer.getMessage("lblTinyLeadersDecks"));
} }
} }

View File

@@ -862,7 +862,7 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
private JPanel getPlayerNamePanel() { private JPanel getPlayerNamePanel() {
JPanel p = new JPanel(new MigLayout("insets 0, gap 0!")); JPanel p = new JPanel(new MigLayout("insets 0, gap 0!"));
p.setOpaque(false); p.setOpaque(false);
FLabel lbl = new FLabel.Builder().text("Player Name: ").fontSize(12).fontStyle(Font.BOLD).build(); FLabel lbl = new FLabel.Builder().text(localizer.getMessage("lblPlayerName") +": ").fontSize(12).fontStyle(Font.BOLD).build();
p.add(lbl, "aligny top, h 100%, gap 4px 0 0 0"); p.add(lbl, "aligny top, h 100%, gap 4px 0 0 0");
p.add(btnPlayerName, "aligny top, h 100%, w 200px!"); p.add(btnPlayerName, "aligny top, h 100%, w 200px!");
return p; return p;

View File

@@ -13,6 +13,7 @@ import forge.screens.match.controllers.CDetailPicture;
import forge.screens.workshop.controllers.CCardScript; import forge.screens.workshop.controllers.CCardScript;
import forge.screens.workshop.controllers.CWorkshopCatalog; import forge.screens.workshop.controllers.CWorkshopCatalog;
import forge.util.ItemPool; import forge.util.ItemPool;
import forge.util.Localizer;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import javax.swing.*; import javax.swing.*;
@@ -27,10 +28,10 @@ import javax.swing.event.ListSelectionListener;
*/ */
public enum VWorkshopCatalog implements IVDoc<CWorkshopCatalog> { public enum VWorkshopCatalog implements IVDoc<CWorkshopCatalog> {
SINGLETON_INSTANCE; SINGLETON_INSTANCE;
final Localizer localizer = Localizer.getInstance();
// Fields used with interface IVDoc // Fields used with interface IVDoc
private DragCell parentCell; private DragCell parentCell;
private final DragTab tab = new DragTab("Card Catalog"); private final DragTab tab = new DragTab(localizer.getMessage("lblCardCatalog"));
private final ItemManagerContainer cardManagerContainer = new ItemManagerContainer(); private final ItemManagerContainer cardManagerContainer = new ItemManagerContainer();
private final CardManager cardManager; private final CardManager cardManager;
private final CDetailPicture cDetailPicture = new CDetailPicture(); private final CDetailPicture cDetailPicture = new CDetailPicture();
@@ -38,7 +39,7 @@ public enum VWorkshopCatalog implements IVDoc<CWorkshopCatalog> {
//========== Constructor //========== Constructor
VWorkshopCatalog() { VWorkshopCatalog() {
this.cardManager = new CardManager(cDetailPicture, true, false); this.cardManager = new CardManager(cDetailPicture, true, false);
this.cardManager.setCaption("Catalog"); this.cardManager.setCaption(localizer.getMessage("lblCatalog"));
final Iterable<PaperCard> allCards = Iterables.concat(FModel.getMagicDb().getCommonCards(), FModel.getMagicDb().getVariantCards()); final Iterable<PaperCard> allCards = Iterables.concat(FModel.getMagicDb().getCommonCards(), FModel.getMagicDb().getVariantCards());
this.cardManager.setPool(ItemPool.createFrom(allCards, PaperCard.class), true); this.cardManager.setPool(ItemPool.createFrom(allCards, PaperCard.class), true);
this.cardManagerContainer.setItemManager(this.cardManager); this.cardManagerContainer.setItemManager(this.cardManager);

View File

@@ -501,7 +501,7 @@ public class GameSimulatorTest extends SimulationTestCase {
assertTrue(depths.hasCounters()); assertTrue(depths.hasCounters());
SpellAbility sa = findSAWithPrefix(thespian, SpellAbility sa = findSAWithPrefix(thespian,
"{2}, {T}: CARDNAME becomes a copy of target land and gains this ability."); "{2}, {T}: CARDNAME becomes a copy of target land, except it has this ability.");
assertNotNull(sa); assertNotNull(sa);
sa.getTargets().add(depths); sa.getTargets().add(depths);
@@ -526,7 +526,7 @@ public class GameSimulatorTest extends SimulationTestCase {
game.getAction().checkStateEffects(true); game.getAction().checkStateEffects(true);
SpellAbility sa = findSAWithPrefix(thespian, SpellAbility sa = findSAWithPrefix(thespian,
"{2}, {T}: CARDNAME becomes a copy of target land and gains this ability."); "{2}, {T}: CARDNAME becomes a copy of target land, except it has this ability.");
assertNotNull(sa); assertNotNull(sa);
sa.getTargets().add(thespian); sa.getTargets().add(thespian);

View File

@@ -235,7 +235,7 @@ public class SpellAbilityPickerTest extends SimulationTestCase {
assertEquals("Urborg, Tomb of Yawgmoth", choices.get(1)); assertEquals("Urborg, Tomb of Yawgmoth", choices.get(1));
// Next, expected to use Thespian's Stage to copy Dark Depths. // Next, expected to use Thespian's Stage to copy Dark Depths.
Plan.Decision d2 = picker.getPlan().getDecisions().get(1); Plan.Decision d2 = picker.getPlan().getDecisions().get(1);
String expected = "{2}, {T}: Thespian's Stage becomes a copy of target land and gains this ability."; String expected = "{2}, {T}: Thespian's Stage becomes a copy of target land, except it has this ability.";
assertEquals(expected, d2.saRef.toString()); assertEquals(expected, d2.saRef.toString());
assertTrue(d2.targets.toString().contains("Dark Depths")); assertTrue(d2.targets.toString().contains("Dark Depths"));
} }

View File

@@ -1458,3 +1458,6 @@ Snow-Covered Island
Snow-Covered Swamp Snow-Covered Swamp
Snow-Covered Mountain Snow-Covered Mountain
Snow-Covered Forest Snow-Covered Forest
[M20 Secret Cards]
Rienne, Angel of Rebirth

View File

@@ -5,8 +5,8 @@ Loyalty:5
S:Mode$ Continuous | Affected$ Creature.YouCtrl | AddKeyword$ Vigilance | Description$ Creatures you control have vigilance. S:Mode$ Continuous | Affected$ Creature.YouCtrl | AddKeyword$ Vigilance | Description$ Creatures you control have vigilance.
SVar:NonStackingEffect:True SVar:NonStackingEffect:True
SVar:PlayMain1:TRUE SVar:PlayMain1:TRUE
A:AB$ GainLife | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ true | LifeAmount$ 3 | SpellDescription$ You gain 3 life. A:AB$ GainLife | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | LifeAmount$ 3 | SpellDescription$ You gain 3 life.
A:AB$ PutCounterAll | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ true | ValidCards$ Creature.YouCtrl | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBPutCounterAll | SpellDescription$ Put a +1/+1 counter on each creature you control and a loyalty counter on each other planeswalker you control. A:AB$ PutCounterAll | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | ValidCards$ Creature.YouCtrl | CounterType$ P1P1 | CounterNum$ 1 | AILogic$ OwnCreatsAndOtherPWs | SubAbility$ DBPutCounterAll | SpellDescription$ Put a +1/+1 counter on each creature you control and a loyalty counter on each other planeswalker you control.
SVar:DBPutCounterAll:DB$ PutCounterAll | ValidCards$ Planeswalker.YouCtrl+Other | CounterType$ LOYALTY | CounterNum$ 1 SVar:DBPutCounterAll:DB$ PutCounterAll | ValidCards$ Planeswalker.YouCtrl+Other | CounterType$ LOYALTY | CounterNum$ 1 | AILogic$ OwnCreatsAndOtherPWs
DeckHas:Ability$Counters & Ability$LifeGain DeckHas:Ability$Counters & Ability$LifeGain
Oracle:Creatures you control have vigilance.\n[+1]: You gain 3 life.\n[-2]: Put a +1/+1 counter on each creature you control and a loyalty counter on each other planeswalker you control. Oracle:Creatures you control have vigilance.\n[+1]: You gain 3 life.\n[-2]: Put a +1/+1 counter on each creature you control and a loyalty counter on each other planeswalker you control.

View File

@@ -3,6 +3,6 @@ ManaCost:B R
Types:Sorcery Types:Sorcery
A:SP$ Charm | Cost$ B R | Choices$ SacArtifact,SacCreature,SacPW A:SP$ Charm | Cost$ B R | Choices$ SacArtifact,SacCreature,SacPW
SVar:SacArtifact:DB$ Sacrifice | ValidTgts$ Player | SacValid$ Artifact | Amount$ 1 | SpellDescription$ Target player sacrifices an artifact. SVar:SacArtifact:DB$ Sacrifice | ValidTgts$ Player | SacValid$ Artifact | Amount$ 1 | SpellDescription$ Target player sacrifices an artifact.
SVar:SacCreature:DB$ Sacrifice | ValidTgts$ Player | SacValid$ Creature | Amount$ 1 | SpellDescription$ Target player sacrifices an creature. SVar:SacCreature:DB$ Sacrifice | ValidTgts$ Player | SacValid$ Creature | Amount$ 1 | SpellDescription$ Target player sacrifices a creature.
SVar:SacPW:DB$ Sacrifice | ValidTgts$ Player | SacValid$ Planeswalker | Amount$ 1 | SpellDescription$ Target player sacrifices an planeswalker. SVar:SacPW:DB$ Sacrifice | ValidTgts$ Player | SacValid$ Planeswalker | Amount$ 1 | SpellDescription$ Target player sacrifices a planeswalker.
Oracle:Choose one —\n• Target player sacrifices an artifact.\n• Target player sacrifices a creature.\n• Target player sacrifices a planeswalker. Oracle:Choose one —\n• Target player sacrifices an artifact.\n• Target player sacrifices a creature.\n• Target player sacrifices a planeswalker.

View File

@@ -2,7 +2,7 @@ Name:Aquatic Incursion
ManaCost:3 U ManaCost:3 U
Types:Enchantment Types:Enchantment
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create two 1/1 blue Merfolk creature tokens with hexproof. T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create two 1/1 blue Merfolk creature tokens with hexproof.
SVar:TrigToken:DB$Token | LegacyImage$ u 1 1 merfolk hexproof rix | TokenScript$ u_1_1_merfolk_hexproof | TokenOwner$ You SVar:TrigToken:DB$Token | TokenAmount$ 2 | LegacyImage$ u 1 1 merfolk hexproof rix | TokenScript$ u_1_1_merfolk_hexproof | TokenOwner$ You
A:AB$ Pump | Cost$ 3 U | ValidTgts$ Merfolk | TgtPrompt$ Select target Merfolk | KW$ HIDDEN Unblockable | SpellDescription$ Target Merfolk can't be blocked this turn. A:AB$ Pump | Cost$ 3 U | ValidTgts$ Merfolk | TgtPrompt$ Select target Merfolk | KW$ HIDDEN Unblockable | SpellDescription$ Target Merfolk can't be blocked this turn.
DeckHints:Type$Merfolk DeckHints:Type$Merfolk
SVar:Picture:http://www.wizards.com/global/images/magic/general/aquatic_incursion.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/aquatic_incursion.jpg

View File

@@ -1,6 +1,6 @@
Name:Arrester's Zeal Name:Arrester's Zeal
ManaCost:W ManaCost:W
Types:Instant Types:Instant
A:SP$ Pump | Cost$ W | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +2 | NumDef$ +2 | SubAbility$ DBAddendum | SpellDescription$ Target creature gets +2/+2 until end of turn. A:SP$ Pump | Cost$ W | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +2 | NumDef$ +2 | SubAbility$ DBAddendum | AILogic$ Main1IfAble | SpellDescription$ Target creature gets +2/+2 until end of turn.
SVar:DBAddendum:DB$ Pump | Defined$ Targeted | ConditionPlayerTurn$ True | ConditionPhases$ Main1,Main2 | ConditionDefined$ Self | ConditionPresent$ Card.wasCast | KW$ Flying | SpellDescription$ Addendum - If you cast this spell during your main phase, that creature gains flying until end of turn. SVar:DBAddendum:DB$ Pump | Defined$ Targeted | ConditionPlayerTurn$ True | ConditionPhases$ Main1,Main2 | ConditionDefined$ Self | ConditionPresent$ Card.wasCast | KW$ Flying | SpellDescription$ Addendum - If you cast this spell during your main phase, that creature gains flying until end of turn.
Oracle:Target creature gets +2/+2 until end of turn.\nAddendum — If you cast this spell during your main phase, that creature gains flying until end of turn. Oracle:Target creature gets +2/+2 until end of turn.\nAddendum — If you cast this spell during your main phase, that creature gains flying until end of turn.

View File

@@ -1,6 +1,6 @@
Name:Bond of Discipline Name:Bond of Discipline
ManaCost:4 W ManaCost:4 W
Types:Sorcery Types:Sorcery
A:SP$ TapAll | Cost$ 4 W | ValidCards$ Creature.OppCtrl | SubAbility$ DBPumpAll | SpellDescription$ Tap all creatures your opponents control. Creatures you control gain lifelink until end of turn. A:SP$ TapAll | Cost$ 4 W | ValidCards$ Creature.OppCtrl | AILogic$ AtLeast3 | SubAbility$ DBPumpAll | SpellDescription$ Tap all creatures your opponents control. Creatures you control gain lifelink until end of turn.
SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Creature.YouCtrl | KW$ Lifelink SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Creature.YouCtrl | KW$ Lifelink
Oracle:Tap all creatures your opponents control. Creatures you control gain lifelink until end of turn. Oracle:Tap all creatures your opponents control. Creatures you control gain lifelink until end of turn.

View File

@@ -5,6 +5,7 @@ S:Mode$ Continuous | Affected$ Creature | AddKeyword$ Haste | Description$ All c
SVar:BuffedBy:Creature SVar:BuffedBy:Creature
SVar:AntiBuffedBy:Creature SVar:AntiBuffedBy:Creature
SVar:NonStackingEffect:True SVar:NonStackingEffect:True
SVar:AICastPreference:MaxControlledGlobally$ 1
AI:RemoveDeck:Random AI:RemoveDeck:Random
SVar:Picture:http://www.wizards.com/global/images/magic/general/concordant_crossroads.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/concordant_crossroads.jpg
Oracle:All creatures have haste. Oracle:All creatures have haste.

View File

@@ -3,7 +3,7 @@ ManaCost:2 B B
Types:Legendary Creature Spirit Types:Legendary Creature Spirit
PT:4/4 PT:4/4
K:Flying K:Flying
T:Mode$ BecomesTarget | ValidTarget$ Creature | TriggerZones$ Battlefield | Execute$ TrigDestroy | TriggerDescription$ Whenever a creature becomes the target of a spell or ability, destroy that creature. T:Mode$ BecomesTarget | ValidTarget$ Creature+inZoneBattlefield | TriggerZones$ Battlefield | Execute$ TrigDestroy | TriggerDescription$ Whenever a creature becomes the target of a spell or ability, destroy that creature.
SVar:TrigDestroy:DB$Destroy | Defined$ TriggeredTarget SVar:TrigDestroy:DB$Destroy | Defined$ TriggeredTarget
SVar:Picture:http://www.wizards.com/global/images/magic/general/horobi_deaths_wail.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/horobi_deaths_wail.jpg
Oracle:Flying\nWhenever a creature becomes the target of a spell or ability, destroy that creature. Oracle:Flying\nWhenever a creature becomes the target of a spell or ability, destroy that creature.

View File

@@ -6,5 +6,6 @@ SVar:NonStackingEffect:True
AI:RemoveDeck:Random AI:RemoveDeck:Random
SVar:BuffedBy:Creature SVar:BuffedBy:Creature
SVar:AntiBuffedBy:Creature SVar:AntiBuffedBy:Creature
SVar:AICastPreference:MaxControlledGlobally$ 1
SVar:Picture:http://www.wizards.com/global/images/magic/general/mass_hysteria.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/mass_hysteria.jpg
Oracle:All creatures have haste. Oracle:All creatures have haste.

View File

@@ -1,7 +1,7 @@
Name:Might of Old Krosa Name:Might of Old Krosa
ManaCost:G ManaCost:G
Types:Instant Types:Instant
A:SP$ Pump | Cost$ G | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ X | NumDef$ X | References$ X | SpellDescription$ Target creature gets +2/+2 until end of turn. If you cast this spell during your main phase, that creature gets +4/+4 until end of turn instead. A:SP$ Pump | Cost$ G | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ X | NumDef$ X | References$ X | AILogic$ Main1IfAble | SpellDescription$ Target creature gets +2/+2 until end of turn. If you cast this spell during your main phase, that creature gets +4/+4 until end of turn instead.
SVar:X:Count$IfCastInOwnMainPhase.4.2 SVar:X:Count$IfCastInOwnMainPhase.4.2
SVar:Picture:http://www.wizards.com/global/images/magic/general/might_of_old_krosa.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/might_of_old_krosa.jpg
Oracle:Target creature gets +2/+2 until end of turn. If you cast this spell during your main phase, that creature gets +4/+4 until end of turn instead. Oracle:Target creature gets +2/+2 until end of turn. If you cast this spell during your main phase, that creature gets +4/+4 until end of turn instead.

View File

@@ -3,7 +3,7 @@ ManaCost:4 B
Types:Legendary Creature Spirit Types:Legendary Creature Spirit
PT:2/2 PT:2/2
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | TriggerZones$ Battlefield | ValidCard$ Creature.powerLE1+YouOwn | OptionalDecider$ You | Execute$ DelTrig | TriggerDescription$ Whenever a creature with power 1 or less is put into your graveyard from the battlefield, you may return that card to the battlefield at the beginning of the next end step if CARDNAME is still on the battlefield. T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | TriggerZones$ Battlefield | ValidCard$ Creature.powerLE1+YouOwn | OptionalDecider$ You | Execute$ DelTrig | TriggerDescription$ Whenever a creature with power 1 or less is put into your graveyard from the battlefield, you may return that card to the battlefield at the beginning of the next end step if CARDNAME is still on the battlefield.
SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | ValidPlayer$ Player | Execute$ TrigReturn | IsPresent$ Card.Self | PresentZone$ Battlefield | RememberObjects$ TriggeredCard | TriggerDescription$ Return creature to the battlefield. SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | ValidPlayer$ Player | Execute$ TrigReturn | IsPresent$ Card.Self+StrictlySelf | PresentZone$ Battlefield | RememberObjects$ TriggeredCard | TriggerDescription$ Return creature to the battlefield.
SVar:TrigReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | Defined$ DelayTriggerRemembered | IsPresent$ Card.Self+StrictlySelf | PresentZone$ Battlefield SVar:TrigReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | Defined$ DelayTriggerRemembered | IsPresent$ Card.Self+StrictlySelf | PresentZone$ Battlefield
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Static$ True | Execute$ DBCleanup T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Static$ True | Execute$ DBCleanup
SVar:DBCleanup:DB$Cleanup | ClearTriggered$ True SVar:DBCleanup:DB$Cleanup | ClearTriggered$ True

View File

@@ -0,0 +1,5 @@
Name:Aether Gust
ManaCost:1 U
Types:Instant
A:SP$ ChangeZone | Cost$ 1 U | ValidTgts$ Card.inZoneStack+Red,Card.inZoneStack+Green,Permanent.Red,Permanent.Green | TgtZone$ Battlefield,Stack | TgtPrompt$ Select target spell or permanent that's red or green | AlternativeDecider$ TargetedController | Origin$ Battlefield,Stack | Fizzle$ True | Destination$ Library | LibraryPosition$ 0 | DestinationAlternative$ Library | LibraryPositionAlternative$ -1 | AlternativeDestinationMessage$ Would you like to put the card on the top of your library (and not on the bottom)? | SpellDescription$ Choose target spell or permanent that's red or green. Its owner puts it on the top or bottom of their library.
Oracle:Choose target spell or permanent that's red or green. Its owner puts it on the top or bottom of their library.

View File

@@ -0,0 +1,13 @@
Name:Ajani, Strength of the Pride
ManaCost:2 W W
Types:Legendary Planeswalker Ajani
Loyalty:5
A:AB$ GainLife | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | LifeAmount$ NumCreatures | References$ NumCreatures,NumPlaneswalkers | SpellDescription$ You gain life equal to the number of creatures you control plus the number of planeswalkers you control.
SVar:NumCreatures:Count$Valid Creature.YouCtrl/Plus.NumPlaneswalkers
SVar:NumPlaneswalkers:Count$Valid Planeswalker.YouCtrl
A:AB$ Token | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | TokenScript$ ajanis_pridemate | LegacyImage$ ajanis pridemate m20 | SpellDescription$ Create a 2/2 white Cat Soldier creature token named Ajani's Pridemate with "Whenever you gain life, put a +1/+1 counter on Ajani's Pridemate."
DeckHas:Ability$Token
A:AB$ ChangeZoneAll | Cost$ SubCounter<0/LOYALTY> | ConditionCheckSVar$ CurLife | ConditionSVarCompare$ GEInitLife | References$ CurLife,InitLife | Planeswalker$ True | Ultimate$ True | ChangeType$ Card.Self,Creature.OppCtrl,Artifact.OppCtrl | Origin$ Battlefield | Destination$ Exile | SpellDescription$ If you have at least 15 life more than your starting life total, exile CARDNAME and each artifact and creature your opponents control.
SVar:CurLife:Count$YourLifeTotal
SVar:InitLife:Count$YourStartingLife/Plus.15
Oracle:[+1]: You gain life equal to the number of creatures you control plus the number of planeswalkers you control.\n[-2]: Create a 2/2 white Cat Soldier creature token named Ajani's Pridemate with "Whenever you gain life, put a +1/+1 counter on Ajani's Pridemate."\n[0]: If you have at least 15 life or more than your starting life total, exile Ajani, Strength of the Pride and each artifact and creature your opponents control.

View File

@@ -0,0 +1,13 @@
Name:Angel of Vitality
ManaCost:2 W
Types:Creature Angel
PT:2/2
K:Flying
R:Event$ GainLife | ActiveZones$ Battlefield | ValidPlayer$ You | ReplaceWith$ GainLife | AiLogic$ DoubleLife | Description$ If you would gain life, you gain that much life plus 1 instead.
SVar:GainLife:DB$ ReplaceEffect | VarName$ LifeGained | VarValue$ X | References$ X
SVar:X:ReplaceCount$LifeGained/Plus.1
SVar:PlayMain1:True
DeckHints:Ability$LifeGain
S:Mode$ Continuous | Affected$ Card.Self | AddPower$ 2 | AddToughness$ 2 | CheckSVar$ Y | SVarCompare$ GE25 | Description$ CARDNAME gets +2/+2 as long as you have 25 or more life.
SVar:Y:Count$YourLifeTotal
Oracle:Flying\nIf you would gain life, you gain that much life plus 1 instead.\nAngel of Vitality gets +2/+2 as long as you have 25 or more life.

View File

@@ -0,0 +1,13 @@
Name:Atemsis, All-Seeing
ManaCost:3 U U U
Types:Legendary Creature Sphinx
PT:4/5
K:Flying
A:AB$ Draw | Cost$ 2 U T | NumCards$ 2 | SpellDescription$ Draw two cards, then discard a card. | SubAbility$ DBDiscard
SVar:DBDiscard:DB$Discard | Defined$ You | NumCards$ 1 | Mode$ TgtChoose
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Opponent | OptionalDecider$ You | Execute$ TrigReveal | TriggerDescription$ Whenever CARDNAME deals damage to an opponent, you may reveal your hand. If cards with at least six different converted mana costs are revealed this way, that player loses the game.
SVar:TrigReveal:DB$ RevealHand | Defined$ You | RememberRevealed$ True | SubAbility$ DBLoseGame
SVar:DBLoseGame:DB$ LosesGame | Defined$ TriggeredTarget | ConditionCheckSVar$ X | ConditionSVarCompare$ GE6 | References$ X | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:X:Remembered$DifferentCMC
Oracle:Flying\n{2}{U}, {T}: Draw two cards, then discard a card.\nWhenever Atemsis, All-Seeing deals damage to an opponent, you may reveal your hand. If cards with at least six different converted mana costs are revealed this way, that player loses the game.

View File

@@ -0,0 +1,8 @@
Name:Blightbeetle
ManaCost:1 B
Types:Creature Insect
PT:1/1
K:Protection from green
S:Mode$ CantPutCounter | Affected$ Creature.OppCtrl | CounterType$ P1P1 | Description$ Creatures your opponents control can't have +1/+1 counters put on them.
SVar:PlayMain1:TRUE
Oracle:Protection from green (This creature can't be blocked, targeted, dealt damage, enchanted, or equipped by anything green.)\nCreatures your opponents control can't have +1/+1 counters put on them.

View File

@@ -0,0 +1,14 @@
Name:Cavalier of Flame
ManaCost:2 R R R
Types:Creature Elemental Knight
PT:6/5
A:AB$ PumpAll | Cost$ 1 R | ValidCards$ Creature.YouCtrl | NumAtt$ +1 | KW$ Haste | SpellDescription$ Creatures you control get +1/+0 and gain haste until end of turn.
T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigDiscard | TriggerDescription$ When CARDNAME enters the battlefield, discard any number of cards, then draw that many cards.
SVar:TrigDiscard:DB$ Discard | Cost$ 3 R | AnyNumber$ True | Optional$ True | Mode$ TgtChoose | RememberDiscarded$ True | SubAbility$ DBDraw | SpellDescription$ Discard any number of cards, then draw that many cards.
SVar:DBDraw:DB$Draw | Defined$ You | NumCards$ Y | References$ Y | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:Y:Remembered$Amount
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigDamageAll | OptionalDecider$ You | TriggerController$ TriggeredCardController | TriggerDescription$ When CARDNAME dies, it deals X damage to each opponent and each planeswalker they control, where X is the number of land cards in your graveyard.
SVar:TrigDamageAll:DB$ DamageAll | ValidPlayers$ Player.Opponent | ValidCards$ Planeswalker.OppCtrl | NumDmg$ X | References$ X | SpellDescription$ CARDNAME deals X damage to each opponent and each planeswalker they control, where X is the number of land cards in your graveyard.
SVar:X:Count$TypeInYourYard.Land
Oracle:{1}{R}: Creatures you control get +1/+0 and gain haste until end of turn.\nWhen Cavalier of Flame enters the battlefield, discard any number of cards, then draw that many cards.\nWhen Cavalier of Flame dies, it deals X damage to each opponent and each planeswalker they control, where X is the number of land cards in your graveyard.

View File

@@ -0,0 +1,14 @@
Name:Chandra, Acolyte of Flame
Types:Legendary Planeswalker Chandra
ManaCost:1 R R
Loyalty:4
A:AB$ PutCounterAll | Cost$ AddCounter<0/LOYALTY> | Planeswalker$ True | ValidCards$ Planeswalker.YouCtrl+Red | CounterType$ LOYALTY | CounterNum$ 1 | SpellDescription$ Put a loyalty counter on each red planeswalker you control.
A:AB$ Token | Cost$ AddCounter<0/LOYALTY> | Planeswalker$ True | TokenAmount$ 2 | TokenScript$ r_1_1_elemental | TokenOwner$ You | LegacyImage$ r 1 1 elemental m20 | AtEOT$ Sacrifice | RememberTokens$ True | SubAbility$ DBPump | SpellDescription$ Create two 1/1 red Elemental creature tokens. They gain haste. Sacrifice them at the beginning of the next end step.
SVar:DBPump:DB$ Pump | Defined$ Remembered | KW$ Haste | Permanent$ True | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
A:AB$ Effect | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | AILogic$ CastFromGraveThisTurn | ValidTgts$ Instant.YouCtrl+cmcLE3,Sorcery.YouCtrl+cmcLE3 | TgtZone$ Graveyard | TgtPrompt$ Select target instant or sorcery card with mana cost 3 or less | RememberObjects$ Targeted | StaticAbilities$ Play | ExileOnMoved$ Graveyard | SubAbility$ DBEffect | SpellDescription$ You may cast target instant or sorcery card with mana cost 3 or less from your graveyard this turn. If that card would be put into your graveyard this turn, exile it instead.
SVar:Play:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Graveyard | Description$ You may play remembered card.
SVar:DBEffect:DB$ Effect | RememberObjects$ Targeted | ExileOnMoved$ Stack | ReplacementEffects$ ReplaceGraveyard | SVars$ MoveExile
SVar:ReplaceGraveyard:Event$ Moved | ValidCard$ Card.IsRemembered | Origin$ Stack | Destination$ Graveyard | ReplaceWith$ MoveExile | Description$ If that card would be put into your graveyard this turn, exile it instead.
SVar:MoveExile:DB$ ChangeZone | Defined$ ReplacedCard | Origin$ Stack | Destination$ Exile
Oracle:[0]: Put a loyalty counter on each red planeswalker you control.\n[0]: Create two 1/1 red Elemental creature tokens. They gain haste. Sacrifice them at the beginning of the next end step.\n:[-2]: You may cast target instant or sorcery with mana cost 3 or less card from your graveyard this turn. If that card would be put into your graveyard this turn, exile it instead.

View File

@@ -0,0 +1,12 @@
Name:Chandra, Awakened Inferno
Types:Legendary Planeswalker Chandra
ManaCost:4 R R
Loyalty:6
K:CARDNAME can't be countered.
A:AB$ Effect | Cost$ AddCounter<2/LOYALTY> | Planeswalker$ True | EffectOwner$ Player.Opponent | Name$ Emblem - Chandra, Awakened Inferno | Triggers$ BOTTrig | SVars$ ChandraDmg | Duration$ Permanent | AILogic$ Always | SpellDescription$ Each opponent gets an emblem with "At the beginning of your upkeep, this emblem deals 1 damage to you."
SVar:BOTTrig:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Command | Execute$ ChandraDmg | TriggerDescription$ At the beginning of your upkeep, this emblem deals 1 damage to you.
SVar:ChandraDmg:DB$ DealDamage | Defined$ TriggeredPlayer | NumDmg$ 1
A:AB$ DamageAll | Cost$ SubCounter<3/LOYALTY> | Planeswalker$ True | ValidCards$ Creature.nonElemental | NumDmg$ 3 | SpellDescription$ CARDNAME deals 3 damage to each non-Elemental creature.
A:AB$ DealDamage | Cost$ SubCounter<X/LOYALTY> | Planeswalker$ True | Ultimate$ True | ValidTgts$ Creature,Planeswalker | NumDmg$ ChosenX | References$ X | ReplaceDyingDefined$ Targeted | SpellDescription$ CARDNAME deals X damage to target creature or planeswalker. If a permanent dealt damage this way would die this turn, exile it instead.
SVar:X:XChoice
Oracle:This spell can't be countered.\n[+2]: Each opponent gets an emblem with "At the beginning of your upkeep, this emblem deals 1 damage to you."\n[-3]: Chandra, Awakened Inferno deals 3 damage to each non-Elemental creature.\n[-X]: Chandra, Awakened Inferno deals X damage to target creature or planeswalker. If a permanent dealt damage this way would die this turn, exile it instead.

View File

@@ -0,0 +1,8 @@
Name:Chandra, Novice Pyromancer
Types:Legendary Planeswalker Chandra
ManaCost:3 R
Loyalty:5
A:AB$ PumpAll | Cost$ AddCounter<1/LOYALTY> | ValidCards$ Elemental.YouCtrl | NumAtt$ +2 | NumDef$ +0 | Planeswalker$ True | AILogic$ Always | SpellDescription$ Elementals you control get +2/+0 until end of turn.
A:AB$ Mana | Cost$ SubCounter<1/LOYALTY> | Planeswalker$ True | Produced$ R | Amount$ 2 | SubAbility$ DBEffect | SpellDescription$ Add {R}{R}.
A:AB$ DealDamage | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 2 | SpellDescription$ CARDNAME deals 2 damage to any target.
Oracle:[+1]: Elementals you control get +2/+0 until end of turn.\n[-1]: Add {R}{R}.\n[-2]: Chandra, Novice Pyromancer deals 2 damage to any target.

View File

@@ -0,0 +1,7 @@
Name:Chandra's Embercat
ManaCost:1 R
Types:Creature Elemental Cat
PT:2/2
A:AB$ Mana | Cost$ T | Produced$ R | RestrictValid$ Spell.Elemental,Spell.Planeswalker+Chandra | SpellDescription$ Add {R}. Spend this mana only to cast an Elemental spell or a Chandra planeswalker spell.
SVar:BuffedBy:Planeswalker.Chandra
Oracle:{T}: Add {R}. Spend this mana only to cast an Elemental spell or a Chandra planeswalker spell.

View File

@@ -0,0 +1,9 @@
Name:Chandra's Regulator
ManaCost:1 R
Types:Legendary Artifact
T:Mode$ AbilityCast | ValidCard$ Planeswalker.Chandra | ValidActivatingPlayer$ You | ValidSA$ Activated.Loyalty | TriggerZones$ Battlefield | Execute$ TrigCopyAbility | TriggerDescription$ Whenever you activate a loyalty ability of a Chandra planeswalker, you may pay {1}. If you do, copy that ability. You may choose new targets for the copy.
SVar:TrigCopyAbility:AB$ CopySpellAbility | Cost$ 1 | Defined$ TriggeredSpellAbility
A:AB$ Draw | Cost$ 1 T Discard<1/Mountain;Card.Red> | NumCards$ 1 | SpellDescription$ Draw a card.
SVar:AIPreference:SacCost$Card.Mountain,Card.Red
DeckNeeds:Type$Chandra
Oracle:Whenever you activate a loyalty ability of a Chandra planeswalker, you may pay {1}. If you do, copy that ability. You may choose new targets for the copy.\n{1}, {T}, Discard a Mountain card or a red card: Draw a card.

View File

@@ -0,0 +1,7 @@
Name:Corpse Knight
ManaCost:W B
Types:Creature Zombie Knight
PT:2/2
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.Other+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigDrain | TriggerDescription$ Whenever another creature enters the battlefield under your control, each opponent loses 1 life.
SVar:TrigDrain:DB$ LoseLife | Defined$ Player.Opponent | LifeAmount$ 1
Oracle:Whenever another creature enters the battlefield under your control, each opponent loses 1 life.

View File

@@ -0,0 +1,10 @@
Name:Creeping Trailblazer
ManaCost:R G
Types:Creature Elemental
PT:2/2
S:Mode$ Continuous | Affected$ Elemental.YouCtrl+Other | AddPower$ 1 | Description$ Other Elementals you control get +1/+0.
SVar:PlayMain1:TRUE
A:AB$ Pump | Cost$ 2 R G | NumAtt$ +X | NumDef$ +X | References$ X | SpellDescription$ CARDNAME gets +1/+1 until end of turn for each Elemental you control.
SVar:X:Count$Valid Elemental.YouCtrl
SVar:BuffedBy:Card.Elemental
Oracle:Other Elementals you control get +1/+0.\n{2}{R}{G}: Creeping Trailblazer gets +1/+1 until end of turn for each Elemental you control.

View File

@@ -0,0 +1,6 @@
Name:Cryptic Caves
ManaCost:no cost
Types:Land
A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}.
A:AB$ Draw | Cost$ 1 T Sac<1/CARDNAME> | NumCards$ 1 | IsPresent$ Land.YouCtrl | PresentCompare$ GE5 | SpellDescription$ Draw a card. Activate this ability only if you control five or more lands.
Oracle:{T}: Add {C}.\n{1}, {T}, Sacrifice Cryptic Caves: Draw a card. Activate this ability only if you control five or more lands.

View File

@@ -0,0 +1,10 @@
Name:Field of the Dead
ManaCost:no cost
Types:Land
K:CARDNAME enters the battlefield tapped.
A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}.
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | CheckSVar$ X | SVarCompare$ GE7 | Execute$ TrigToken | TriggerDescription$ Whenever CARDNAME or another land enters the battlefield under your control, if you control seven or more lands with different names, create a 2/2 black Zombie creature token.
T:Mode$ ChangesZone | TriggerZones$ Battlefield | CheckSVar$ X | SVarCompare$ GE7 | Origin$ Any | Destination$ Battlefield | ValidCard$ Land.YouCtrl | Execute$ TrigToken | Secondary$ True | TriggerDescription$ Whenever CARDNAME or another land enters the battlefield under your control, if you control seven or more lands with different names, create a 2/2 black Zombie creature token.
SVar:TrigToken:DB$ Token | TokenScript$ b_2_2_zombie | TokenOwner$ You | TokenAmount$ 1 | LegacyImage$ b 2 2 zombie m20
SVar:X:Count$DifferentCardNames_Land.YouCtrl+inZoneBattlefield
Oracle:Field of the Dead enters the battlefield tapped.\n{T}: Add {C}.\nWhenever Field of the Dead or another land enters the battlefield under your control, if you control seven or more lands with different names, create a 2/2 black Zombie creature token.

View File

@@ -0,0 +1,11 @@
Name:Golos, Tireless Pilgrim
ManaCost:5
Types:Legendary Artifact Creature Scout
PT:3/5
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.Self | OptionalDecider$ You | Execute$ TrigChange | TriggerDescription$ When CARDNAME enters the battlefield, you may search your library for a land card, put that card onto the battlefield tapped, then shuffle your library.
SVar:TrigChange:DB$ChangeZone | Origin$ Library | Destination$ Battlefield | Tapped$ True | ChangeType$ Land | ChangeNum$ 1 | ShuffleNonMandatory$ True
A:AB$ Mill | Cost$ 2 W U B R G | Defined$ You | NumCards$ 3 | Destination$ Exile | RememberMilled$ True | SubAbility$ DBEffect | SpellDescription$ Exile the top three cards of your library. You may play them this turn without paying their mana costs.
SVar:DBEffect:DB$ Effect | StaticAbilities$ EffPlay | EffectOwner$ You | RememberObjects$ Remembered | ForgetOnMoved$ Exile | SubAbility$ DBCleanup
SVar:EffPlay:Mode$ Continuous | MayPlay$ True | MayPlayWithoutManaCost$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play them this turn without paying their mana costs.
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
Oracle:When Golos, Tireless Pilgrim enters the battlefield, you may search your library for a land card, put that card onto the battlefield tapped, then shuffle your library.\n{2}{W}{U}{B}{R}{G}: Exile the top three cards of your library. You may play them this turn without paying their mana costs.

View File

@@ -0,0 +1,7 @@
Name:Growth Cycle
ManaCost:1 G
Types:Instant
A:SP$ Pump | Cost$ 1 G | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ 3 | NumDef$ 3 | SubAbility$ DBPump | SpellDescription$ Target creature gets +3/+3 until end of turn. It gets an additional +2/+2 until end of turn for each card named Growth Cycle in your graveyard.
SVar:DBPump:DB$ Pump | Defined$ ParentTarget | NumAtt$ +X | NumDef$ +X | References$ X
SVar:X:Count$ValidGraveyard Card.namedGrowth Cycle/Times.2
Oracle:Target creature gets +3/+3 until end of turn. It gets an additional +2/+2 until end of turn for each card named Growth Cycle in your graveyard.

View File

@@ -0,0 +1,8 @@
Name:Ironroot Warlord
ManaCost:1 G W
Types:Creature Treefolk Soldier
PT:*/5
S:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$ X | Description$ CARDNAME's power is equal to the number of creatures you control.
SVar:X:Count$Valid Creature.YouCtrl
A:AB$ Token | Cost$ 3 G W | TokenAmount$ 1 | TokenScript$ w_1_1_soldier | TokenOwner$ You | LegacyImage$ w 1 1 soldier m20 | SpellDescription$ Create a 1/1 white Soldier creature token.
Oracle:Ironroot Warlord's power is equal to the number of creatures you control.\n{3}{G}{W}: Create a 1/1 white Soldier creature token.

View File

@@ -0,0 +1,10 @@
Name:Kykar, Wind's Fury
ManaCost:1 U R W
Types:Legendary Creature Bird Wizard
PT:3/3
K:Flying
T:Mode$ SpellCast | ValidCard$ Card.nonCreature | ValidActivatingPlayer$ You | Execute$ TrigToken | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a noncreature spell, create a 1/1 white Spirit creature token with flying.
SVar:TrigToken:DB$ Token | LegacyImage$ w 1 1 spirit flying m20 | TokenAmount$ 1 | TokenScript$ w_1_1_spirit_flying | TokenOwner$ You
SVar:BuffedBy:Card.nonCreature+nonLand
A:AB$ Mana | Cost$ Sac<1/Spirit> | Produced$ R | SpellDescription$ Add {R}.
Oracle:Flying\nWhenever you cast a noncreature spell, create a 1/1 white Spirit creature token with flying.\nSacrifice a Spirit: Add {R}.

View File

@@ -0,0 +1,8 @@
Name:Leyline of Combustion
ManaCost:2 R R
Types:Enchantment
K:MayEffectFromOpeningHand:FromHand
SVar:FromHand:DB$ ChangeZone | Defined$ Self | Origin$ Hand | Destination$ Battlefield | SpellDescription$ If CARDNAME is in your opening hand, you may begin the game with it on the battlefield.
T:Mode$ BecomesTargetOnce | ValidTarget$ You,Permanent.YouCtrl+inZoneBattlefield | ValidSource$ Card.OppCtrl | TriggerZones$ Battlefield | Execute$ TrigDmg | TriggerDescription$ Whenever you and/or at least one permanent you control becomes the target of a spell or ability an opponent controls, CARDNAME deals 2 damage to that player.
SVar:TrigDmg:DB$ DealDamage | Defined$ TriggeredSourceSAController | NumDmg$ 2
Oracle:If Leyline of Combustion is in your opening hand, you may begin the game with it on the battlefield.\nWhenever you and/or at least one permanent you control becomes the target of a spell or ability an opponent controls, Leyline of Combustion deals 2 damage to that player.

View File

@@ -0,0 +1,7 @@
Name:Octoprophet
ManaCost:3 U
Types:Creature Octopus
PT:3/3
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigScry | TriggerDescription$ When CARDNAME enters the battlefield, scry 2. (To scry 2, look at the top two cards of your library, then put any number of them on the bottom of your library and the rest on top in any order.)
SVar:TrigScry:DB$ Scry | ScryNum$ 2
Oracle:When Octoprophet enters the battlefield, scry 2. (Look at the top two cards of your library, then put any number of them on the bottom of your library and the rest on top in any order.)

View File

@@ -0,0 +1,14 @@
Name:Overgrowth Elemental
ManaCost:2 G
Types:Creature Elemental
PT:3/2
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigPut | TriggerDescription$ When CARDNAME enters the battlefield, put a +1/+1 counter on another target Elemental you control.
SVar:TrigPut:DB$ PutCounter | ValidTgts$ Elemental.Other+YouCtrl | TgtPrompt$ Select another target Elemental you control | CounterType$ P1P1 | CounterNum$ 1
AI:RemoveDeck:Random
SVar:PlayMain1:TRUE
DeckHints:Type$Elemental
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.Other+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigGainLife | TriggerDescription$ Whenever another creature you control dies, you gain 1 life. If that creature was an Elemental, put a +1/+1 counter on CARDNAME.
SVar:TrigGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 1 | SubAbility$ DBPutCounter
SVar:DBPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 | ConditionDefined$ TriggeredCardLKICopy | ConditionPresent$ Creature.Elemental
DeckHas:Ability$Counters
Oracle:When Overgrowth Elemental enters the battlefield, put a +1/+1 counter on another target Elemental you control.\nWhenever another creature you control dies, you gain 1 life. If that creature was an Elemental, put a +1/+1 counter on Overgrowth Elemental.

View File

@@ -0,0 +1,11 @@
Name:Rienne, Angel of Rebirth
ManaCost:2 R G W
Types:Legendary Creature Angel
PT:5/4
K:Flying
S:Mode$ Continuous | Affected$ Creature.MultiColor+Other+YouCtrl | AddPower$ 1 | Description$ Other multicolored creatures you control get +1/+0.
SVar:PlayMain1:TRUE
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.MultiColor+Other+YouCtrl | TriggerZones$ Battlefield | Execute$ DelayedTrig | TriggerDescription$ Whenever another multicolored creature you control dies, return it to its owner's hand at the beginning of the next end step.
SVar:TrigDelay:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ TrigReturn | RememberObjects$ TriggeredCard | TriggerDescription$ Return it to its owner's hand at the beginning of the next end step.
SVar:TrigReturn:DB$ ChangeZone | Defined$ DelayTriggerRemembered | Origin$ Graveyard | Destination$ Hand
Oracle:Flying\nOther multicolored creatures you control get +1/+0.\nWhenever another multicolored creature you control dies, return it to its owner's hand at the beginning of the next end step.

View File

@@ -0,0 +1,9 @@
Name:Silverback Shaman
ManaCost:3 G G
Types:Creature Ape Shaman
PT:5/4
K:Trample
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerController$ TriggeredCardController | TriggerDescription$ When CARDNAME dies, draw a card.
SVar:TrigDraw:DB$ Draw | NumCards$ 1 | Defined$ You
SVar:SacMe:1
Oracle:Trample (This creature can deal excess combat damage to the player or planeswalker it's attacking.)\nWhen Silverback Shaman dies, draw a card.

View File

@@ -0,0 +1,8 @@
Name:Starfield Mystic
ManaCost:1 W
Types:Creature Human Cleric
PT:2/2
S:Mode$ ReduceCost | ValidCard$ Enchantment | Type$ Spell | Activator$ You | Amount$ 1 | Description$ Enchantment spells you cast cost {1} less to cast.
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever an enchantment you control is put into a graveyard from the battlefield, put a +1/+1 counter on CARDNAME.
SVar:TrigPutCounter:DB$PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1
Oracle:Enchantment spells you cast cost {1} less to cast.\nWhenever an enchantment you control is put into a graveyard from the battlefield, put a +1/+1 counter on Starfield Mystic.

View File

@@ -0,0 +1,7 @@
Name:Wakeroot Elemental
ManaCost:4 G G
Types:Creature Elemental
PT:5/5
A:AB$ Uptap | Cost$ G G G G G | ValidTgts$ Land.YouCtrl | TgtPrompt$ Select target land you control | SubAbility$ DBAnimate | SpellDescription$ Untap target land you control. It becomes a 5/5 Elemental creature with haste. It's still a land.
SVar:DBAnimate:DB$ Animate | Power$ 5 | Toughness$ 5 | Types$ Creature,Elemental | Keywords$ Haste | Permanent$ True
Oracle:{G}{G}{G}{G}{G}: Untap target land you control. It becomes a 5/5 Elemental creature with haste. It's still a land.

View File

@@ -0,0 +1,8 @@
Name:Yarok's Fenlurker
ManaCost:B B
Types:Creature Horror
PT:1/1
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME enters the battlefield, each opponent exiles a card from their hand.
SVar:TrigExile:DB$ ChangeZone | Origin$ Hand | Destination$ Exile | ChangeType$ Card | DefinedPlayer$ Player.Opponent | Mandatory$ True | ChangeType$ Card | ChangeNum$ 1 | Hidden$ True | IsCurse$ True
A:AB$ Pump | Cost$ 2 B | NumAtt$ +1 | NumDef$ +1 | SpellDescription$ CARDNAME gets +1/+1 until end of turn.
Oracle:When Yarok's Fenlurker enters the battlefield, each opponent exiles a card from their hand.\n{2}{B}: Yarok's Fenlurker gets +1/+1 until end of turn.

View File

@@ -1,7 +1,7 @@
Name:Wild Defiance Name:Wild Defiance
ManaCost:2 G ManaCost:2 G
Types:Enchantment Types:Enchantment
T:Mode$ BecomesTarget | ValidTarget$ Creature.YouCtrl | ValidSource$ Instant,Sorcery | SourceType$ spell | TriggerZones$ Battlefield | Execute$ WildPump | TriggerDescription$ Whenever a creature you control becomes the target of an instant or sorcery spell, it gets +3/+3 until end of turn. T:Mode$ BecomesTarget | ValidTarget$ Creature.YouCtrl+inZoneBattlefield | ValidSource$ Instant,Sorcery | SourceType$ spell | TriggerZones$ Battlefield | Execute$ WildPump | TriggerDescription$ Whenever a creature you control becomes the target of an instant or sorcery spell, it gets +3/+3 until end of turn.
SVar:WildPump:DB$ Pump | Defined$ TriggeredTarget | NumAtt$ +3 | NumDef$ +3 SVar:WildPump:DB$ Pump | Defined$ TriggeredTarget | NumAtt$ +3 | NumDef$ +3
SVar:Picture:http://www.wizards.com/global/images/magic/general/wild_defiance.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/wild_defiance.jpg
Oracle:Whenever a creature you control becomes the target of an instant or sorcery spell, that creature gets +3/+3 until end of turn. Oracle:Whenever a creature you control becomes the target of an instant or sorcery spell, that creature gets +3/+3 until end of turn.

View File

@@ -6,4 +6,5 @@ T:Mode$ Explores | Execute$ DBPutCounter | ValidCard$ Creature.YouCtrl | Trigger
SVar:DBPutCounter:DB$ PutCounter | Defined$ Self | CounterNum$ 1 | CounterType$ P1P1 | SubAbility$ DBGainLife SVar:DBPutCounter:DB$ PutCounter | Defined$ Self | CounterNum$ 1 | CounterType$ P1P1 | SubAbility$ DBGainLife
SVar:DBGainLife:DB$ GainLife | LifeAmount$ 3 SVar:DBGainLife:DB$ GainLife | LifeAmount$ 3
SVar:Picture:http://www.wizards.com/global/images/magic/general/wildgrowth_walker.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/wildgrowth_walker.jpg
SVar:AIPriorityModifier:1
Oracle:Whenever a creature you control explores, put a +1/+1 counter on Wildgrowth Walker and you gain 3 life. Oracle:Whenever a creature you control explores, put a +1/+1 counter on Wildgrowth Walker and you gain 3 life.

View File

@@ -2,5 +2,5 @@ Name:Hypercube (383 cards)
DeckFile:Hypercube (383 cards) DeckFile:Hypercube (383 cards)
Singleton:True Singleton:True
Booster: 15 Any Booster: 12 Any
NumPacks: 3 NumPacks: 4

View File

@@ -0,0 +1,150 @@
[metadata]
Code=M20
Date=2019-07-12
Name=Core Set 2020
MciCode=m20
Type=Core
BoosterCovers=3
Booster=10 Common:!fromSheet("M20 Secret Cards"), 3 Uncommon:!fromSheet("M20 Secret Cards"), 1 RareMythic:!fromSheet("M20 Secret Cards"), 1 BasicLand
[cards]
2 M Ajani, Strength of the Pride
4 U Angel of Vitality
8 R Angelic Cleric
13 U Devout Decree
14 C Disenchant
22 R Hanged Executioner
24 R Leyline of Sanctity
27 R Loxodon Lifesinger
28 U Loyal Pegasus
C Pacifism
33 R Planar Cleansing
35 U Rule of Law
39 R Starfield Mystic
42 U Aether Gust
46 R Atemsis, All-Seeing
51 U Captivating Gyre
55 C Convolute
57 R Dungeon Geists
59 R Flood of Tears
64 R Leyline of Anticipation
69 C Negate
70 C Octoprophet
78 C Unsummon
87 U Blightbeetle
92 C Bone Splinters
95 U Disfigure
96 R Dread Presence
106 R Legion's End
107 R Leyline of the Void
113 R Scheming Symmetry
117 U Thought Distortion
123 U Yarok's Fenlurker
125 M Cavalier of Flame
126 R Chandra, Acolyte of Flame
127 M Chandra, Awakened Inferno
128 U Chandra, Novice Pyromancer
129 C Chandra's Embercat
131 R Chandra's Regulator
132 U Chandra's Spitfire
134 C Chinese Goblin Miner
135 U Dragon Mage
137 U Ember Hauler
139 U Flame Sweep
142 C Goblin Hitchhiker
143 U Goblin Ringleader
145 C Infuriate
148 R Leyline of Combustion
154 C Reckless Airstrike
156 R Repeated Reverberation
163 U Uncaged Fury
164 U Unchained Berserker
165 U Barkhide Troll
175 C Growth Cycle
180 U Loaming Shaman
187 U Overgrowth Elemental
189 U Pulse of Murasa
191 U Season of Growth
195 C Silverback Shaman
197 R Thrashing Brontodon
198 U Veil of Summer
200 R Voracious Hydra
202 R Wakeroot Elemental
204 U Wolfrider's Saddle
206 U Corpse Knight
207 U Creeping Trailblazer
208 U Empyrean Eagle
209 U Ironroot Warlord
210 M Kaalia, Zenith Seeker
212 M Kykar, Wind's Fury
217 U Risen Reef
226 R Golos, Tireless Pilgrim
236 U Bacchetta Punitiva
244 U Cryptic Caves
247 R Field of the Dead
280 L Forest
281 M Rienne, Angel of Rebirth
[tokens]
ajanis_pridemate
r_1_1_elemental
w_1_1_soldier
w_1_1_spirit_flying
g_2_2_wolf
b_2_2_zombie

View File

@@ -5,7 +5,7 @@ Name=War of the Spark
Code2=WAR Code2=WAR
MciCode=war MciCode=war
Type=Expansion Type=Expansion
BoosterCovers=5 BoosterCovers=3
Booster=10 Common:!fromSheet("WAR Secret Cards"), 3 Uncommon:!fromSheet("WAR Secret Cards"), 1 RareMythic:!fromSheet("WAR Secret Cards"), 1 BasicLand Booster=10 Common:!fromSheet("WAR Secret Cards"), 3 Uncommon:!fromSheet("WAR Secret Cards"), 1 RareMythic:!fromSheet("WAR Secret Cards"), 1 BasicLand
BoosterMustContain=Planeswalker BoosterMustContain=Planeswalker

View File

@@ -7,6 +7,36 @@ splash.loading.decks=Lade Decks...
splash.loading.processingimagesprites=Verarbeite Bilddaten splash.loading.processingimagesprites=Verarbeite Bilddaten
#FControl.java #FControl.java
lblOpeningMainWindow=Öffne Hauptfenster... lblOpeningMainWindow=Öffne Hauptfenster...
lblCloseScreen=Close Screen
txCloseAction1=Forge now supports navigation tabs which allow closing and switching between different screens with ease. As a result, you no longer need to use the X button in the upper right to close the current screen and go back.
txCloseAction2=Please select what you want to happen when clicking the X button in the upper right. This choice will be used going forward and you will not see this message again. You can change this behavior at any time in Preferences.
titCloseAction=Select Your Close Action
lblAreYouSureYouWishRestartForge=Are you sure you wish restart Forge?
lblAreYouSureYouWishExitForge=Are you sure you wish exit Forge?
lblOneOrMoreGamesActive=One or more games are currently active
lblerrLoadingLayoutFile=Your %s layout file could not be read. It will be deleted after you press OK.\nThe game will proceed with default layout.
lblLoadingQuest=Loading quest...
#FScreen.java
lblHome=Home
lblWorkshop=Workshop
lblBacktoHome=Back to Home
lblDeckEditor=Deck Editor
lblCloseEditor=Close Editor
lblCommanderDeckEditor=Commander Deck Editor
lblTinyLeadersDeckEditor=Tiny Leaders DeckEditor
lblBrawlDeckEditor=Brawl Deck Editor
lblDraftDeckEditor=Draft Deck Editor
lblSealedDeckEditor=Sealed Deck Editor
lblTokenViewer=Token Viewer
lblCloseViewer=Close Viewer
lblQuestDeckEditor=Quest Deck Editor
lblQuestTournamentDeckEditor=Quest Tournament Deck Editor
lblSpellShop=Spell Shop
lblLeaveShop=Leave Shop
lblLeaveDraft=Leave Draft
lblBazaar=Bazaar
lblConcedeGame=Concede Game
txerrFailedtodeletelayoutfile=Failed to delete layout file.
#VSubmenuPreferences.java #VSubmenuPreferences.java
Preferences=Einstellungen Preferences=Einstellungen
btnReset=Alles zurücksetzen btnReset=Alles zurücksetzen
@@ -70,7 +100,6 @@ cbUseSentry=Sende automatisch Fehlerberichte
cbpGameLogEntryType=Spielberichtsumfang cbpGameLogEntryType=Spielberichtsumfang
cbpCloseAction=Beenden cbpCloseAction=Beenden
cbpDefaultFontSize=Standard Schriftgröße cbpDefaultFontSize=Standard Schriftgröße
cbpMulliganRule = Mulligan Rule
cbpAiProfiles=KI Persönlichkeit cbpAiProfiles=KI Persönlichkeit
cbpDisplayCurrentCardColors=Zeige detailierte Kartenfarben cbpDisplayCurrentCardColors=Zeige detailierte Kartenfarben
cbpAutoYieldMode=Automatische Bestätigung cbpAutoYieldMode=Automatische Bestätigung
@@ -79,6 +108,7 @@ cbpCounterDisplayLocation=Markeranzeige Ort
cbpGraveyardOrdering=Genaue Reihenfolge im Friedhof einhalten cbpGraveyardOrdering=Genaue Reihenfolge im Friedhof einhalten
Troubleshooting=Fehlerbehebung Troubleshooting=Fehlerbehebung
GeneralConfiguration=Allgemeine Einstellungen GeneralConfiguration=Allgemeine Einstellungen
lblPlayerName=Player Name
nlPlayerName=Name unter welchem du beim Spielen geführt wirst. nlPlayerName=Name unter welchem du beim Spielen geführt wirst.
nlCompactMainMenu=Aktiviere, um im Seitenmenü platzsparend immer nur eine Menügruppe anzeigen zu lassen. (Erfordert Neustart) nlCompactMainMenu=Aktiviere, um im Seitenmenü platzsparend immer nur eine Menügruppe anzeigen zu lassen. (Erfordert Neustart)
nlUseSentry=Aktiviere, um automatische Fehlerberichte an die Entwickler zu senden. nlUseSentry=Aktiviere, um automatische Fehlerberichte an die Entwickler zu senden.
@@ -120,6 +150,7 @@ nlLoadCardsLazily=Wenn aktiviert, lädt Forge Kartenscripte erst wenn sie benöt
nlLoadHistoricFormats=Wenn aktiviert, lädt Forge auch ältere Spielformate. Verlängert den Programmstart. nlLoadHistoricFormats=Wenn aktiviert, lädt Forge auch ältere Spielformate. Verlängert den Programmstart.
GraphicOptions=Grafik Optionen GraphicOptions=Grafik Optionen
nlDefaultFontSize=Die Standardschriftgröße. Alle Schriftelemente werden werden relative zu dieser angepaßt. (Erfordert Neustart) nlDefaultFontSize=Die Standardschriftgröße. Alle Schriftelemente werden werden relative zu dieser angepaßt. (Erfordert Neustart)
cbpMulliganRule=Mulligan Rule
nlImageFetcher=Ermöglicht bei bestehender Onlineverbindung das automatisches Nachladen fehlender Kartenbilder. nlImageFetcher=Ermöglicht bei bestehender Onlineverbindung das automatisches Nachladen fehlender Kartenbilder.
nlDisplayFoil=Zeige FOIL-Karten mit einem optischen FOIL-Effekt. nlDisplayFoil=Zeige FOIL-Karten mit einem optischen FOIL-Effekt.
nlRandomFoil=Zeige den FOIL-Effekt bei zufälligen Karten. nlRandomFoil=Zeige den FOIL-Effekt bei zufälligen Karten.
@@ -660,3 +691,135 @@ lblWinsperDraftRotation=Siege pro Draft notwendig
ttWinsperDraftRotation=Wenn ein Draft nicht soweit fertig gespielt wird, wird er entfernt oder ersetzt. ttWinsperDraftRotation=Wenn ein Draft nicht soweit fertig gespielt wird, wird er entfernt oder ersetzt.
lblRotationType=Austauschtyp lblRotationType=Austauschtyp
ttRotationType=Bei 0 verschwinden alte Drafts, bei 1 wird er duch einen neuen ersetzt. ttRotationType=Bei 0 verschwinden alte Drafts, bei 1 wird er duch einen neuen ersetzt.
#StatTypeFilter.java
lblclicktotoogle=click to toggle the filter, right-click to show only
#SItemManagerUtil.java
lblWhitecards=White cards
lblBluecards=Blue cards
lblBlackcards=Black cards
lblRedcards=Red cards
lblGreencards=Green cards
lblColorlesscards=Colorless cards
lblMulticolorcards=Multicolor cards
lblPackordeck=Card packs and prebuilt decks
lblLands=Lands
lblArtifacts=Artifacts
lblCreatures=Creatures
lblEnchantments=Enchantments
lblPlaneswalkers=Planeswalkers
lblInstants=Instants
lblSorceries=Sorceries
lblCCMC0=Cards with CMC 0
lblCCMC1=Cards with CMC 1
lblCCMC2=Cards with CMC 2
lblCCMC3=Cards with CMC 3
lblCCMC4=Cards with CMC 4
lblCCMC5=Cards with CMC 5
lblCCMC6orMore=Cards with CMC 6
lblWhitedecks=White decks
lblBluedecks=Blue decks
lblBlackdecks=Black decks
lblReddecks=Red decks
lblGreendecks=Green decks
lblColorlessdecks=Colorless decks
lblMulticolordecks=Multicolor decks
lblOldstyleFoilcards=Old style Foil cards
lblNewstyleFoilcards=New style Foil cards
lblNon-Foilcards=Non-Foil cards
lblUnratedcards=Unrated cards
lbl1starcards=1 star cards
lbl2starcards=2 star cards
lbl3starcards=3 star cards
lbl4starcards=4 star cards
lbl5starcards=5 star cards
lblXcopiesof=X copies of
lblcopiesof=copies of
#ACEditorBase.java
lblAddcard=Add card
ttAddcard=Add selected card to current deck (or double click the row or hit the spacebar)
lblAdd4ofcard=Add 4 of card
ttAdd4ofcard=Add up to 4 of selected card to current deck
lblRemovecard=Remove card
ttRemovecard=Remove selected card from current deck (or double click the row or hit the spacebar)
lblRemove4ofcard=Remove 4 of card
ttRemove4ofcard=Remove up to 4 of selected card to current deck
lblAddBasicLands=Add Basic Lands
ttAddBasicLands=Add basic lands to the deck
lblCardCatalog=Card Catalog
lblJumptoprevioustable=Jump to previous table
lblJumptopnexttable=Jump to next table
lblJumptotextfilter=Jump to text filter
lblChooseavalueforX=Choose a value for X
#VCurrentDeck.java
lblVCurrentDeck=Current Deck
ttbtnSave=Save Deck (Ctrl+S)
ttbtnSaveAs=Save Deck As (Ctrl+E)
ttbtnLoadDeck=Open Deck (Ctrl+O)
ttbtnNewDeck=New Deck (Ctrl+N)
ttbtnPrintProxies=Print to HTML file (Ctrl+P)
lblImport=Import
ttImportDeck=Attempt to import a deck from a non-Forge format (Ctrl+I)
lblTitle=Title
#ImageView.java
lblExpandallgroups=Expand all groups
lblCollapseallgroups=Collapse all groups
lblGroupby=group by
lblPileby=pile by
lblColumns=Columns
#CEditorVariant.java
lblCatalog=Catalog
lblAdd=Add
lbltodeck=to deck
lblfromdeck=from deck
lbltosideboard=to sideboard
lblfromsideboard=from sideboard
lblascommander=as commander
lblasavatar=as avatar
lblfromschemedeck=from scheme deck
lblfromplanardeck=from planar deck
lblfromconspiracydeck=from conspiracy deck
#GroupDef.java
lblColor=Color
lblColorIdentity=Color Identity
lblSet=Set
lblDefault=Default
lblType=Type
lblPlaneswalkerDeckSort=Planeswalker Deck Sort
lblRarity=Rarity
lblConvertToFoil=Foil
lblMulticolor=Multicolor
#DeckFileMenu.java
lblNewDeck=New Deck
lblOpenDeck=Open Deck
lblImportDeck=Import Deck
lblSaveDeck=Save Deck
lblSaveDeckAs=Save Deck As...
lblPrinttoHTMLfile=Print to HTML file
#PaperCard.java
lblCard=Carta
#CardManager.java
lblFormat=Format
lblFormats=Formats
lblQuestWorld=Quest World
lblSets=Sets
lblTypes=Types
lblConvertedManaCosts=Converted mana
lblCMCRange=CMC Range
lblPowerRange=Power Range
lblToughnessRange=Toughness Range
lblFoil=Foil
lblPersonalRating=Personal Rating
lblAdvanced=Advanced
#VDeckgen.java
lblDeckGeneration=Deck Generation
btnRandCardpool=Random Cardpool
ttbtnRandCardpool=Generate random constructed cardpool in current deck area
btnRandDeck2=Constructed (2 color)
ttbtnRandDeck2=Generate 2 color constructed deck in current deck area
btnRandDeck3=Constructed (3 color)
ttbtnRandDeck3=Generate 3 color constructed deck in current deck area
btnRandDeck5=Constructed (5 color)
ttbtnRandDeck5=Generate 5 color constructed deck in current deck area
#DeckCotroller.java
lblCurrentDeck2=Current Deck
lblUntitled=Untitled

View File

@@ -7,6 +7,36 @@ splash.loading.decks = Loading decks...
splash.loading.processingimagesprites=Processing image sprites splash.loading.processingimagesprites=Processing image sprites
#FControl.java #FControl.java
lblOpeningMainWindow=Opening main window... lblOpeningMainWindow=Opening main window...
lblCloseScreen=Close Screen
txCloseAction1=Forge now supports navigation tabs which allow closing and switching between different screens with ease. As a result, you no longer need to use the X button in the upper right to close the current screen and go back.
txCloseAction2=Please select what you want to happen when clicking the X button in the upper right. This choice will be used going forward and you will not see this message again. You can change this behavior at any time in Preferences.
titCloseAction=Select Your Close Action
lblAreYouSureYouWishRestartForge=Are you sure you wish restart Forge?
lblAreYouSureYouWishExitForge=Are you sure you wish exit Forge?
lblOneOrMoreGamesActive=One or more games are currently active
lblerrLoadingLayoutFile=Your %s layout file could not be read. It will be deleted after you press OK.\nThe game will proceed with default layout.
lblLoadingQuest=Loading quest...
#FScreen.java
lblHome=Home
lblWorkshop=Workshop
lblBacktoHome=Back to Home
lblDeckEditor=Deck Editor
lblCloseEditor=Close Editor
lblCommanderDeckEditor=Commander Deck Editor
lblTinyLeadersDeckEditor=Tiny Leaders DeckEditor
lblBrawlDeckEditor=Brawl Deck Editor
lblDraftDeckEditor=Draft Deck Editor
lblSealedDeckEditor=Sealed Deck Editor
lblTokenViewer=Token Viewer
lblCloseViewer=Close Viewer
lblQuestDeckEditor=Quest Deck Editor
lblQuestTournamentDeckEditor=Quest Tournament Deck Editor
lblSpellShop=Spell Shop
lblLeaveShop=Leave Shop
lblLeaveDraft=Leave Draft
lblBazaar=Bazaar
lblConcedeGame=Concede Game
txerrFailedtodeletelayoutfile=Failed to delete layout file.
#VSubmenuPreferences.java #VSubmenuPreferences.java
Preferences=Preferences Preferences=Preferences
btnReset=Reset to Default Settings btnReset=Reset to Default Settings
@@ -70,7 +100,6 @@ cbUseSentry = Automatically submit bug reports.
cbpGameLogEntryType=Game Log Verbosity cbpGameLogEntryType=Game Log Verbosity
cbpCloseAction=Close Action cbpCloseAction=Close Action
cbpDefaultFontSize=Default Font Size cbpDefaultFontSize=Default Font Size
cbpMulliganRule = Mulligan Rule
cbpAiProfiles=AI Personality cbpAiProfiles=AI Personality
cbpDisplayCurrentCardColors=Show Detailed Card Color cbpDisplayCurrentCardColors=Show Detailed Card Color
cbpAutoYieldMode=Auto-Yield cbpAutoYieldMode=Auto-Yield
@@ -79,6 +108,7 @@ cbpCounterDisplayLocation = Counter Display Location
cbpGraveyardOrdering=Allow Ordering Cards Put in Graveyard cbpGraveyardOrdering=Allow Ordering Cards Put in Graveyard
Troubleshooting=Troubleshooting Troubleshooting=Troubleshooting
GeneralConfiguration=General Configuration GeneralConfiguration=General Configuration
lblPlayerName=Player Name
nlPlayerName=Sets the name that you will be referred to by Forge during gameplay. nlPlayerName=Sets the name that you will be referred to by Forge during gameplay.
nlCompactMainMenu=Enable for a space efficient sidebar that displays only one menu group at a time (RESTART REQUIRED). nlCompactMainMenu=Enable for a space efficient sidebar that displays only one menu group at a time (RESTART REQUIRED).
nlUseSentry=When enabled, automatically submits bug reports to developers. nlUseSentry=When enabled, automatically submits bug reports to developers.
@@ -120,6 +150,7 @@ nlLoadCardsLazily = If turned on, Forge will load card scripts as they're needed
nlLoadHistoricFormats=If turned on, Forge will load all historic format definitions, this may take slightly longer to load at startup. nlLoadHistoricFormats=If turned on, Forge will load all historic format definitions, this may take slightly longer to load at startup.
GraphicOptions=Graphic Options GraphicOptions=Graphic Options
nlDefaultFontSize=The default font size within the UI. All font elements are scaled relative to this. (Needs restart) nlDefaultFontSize=The default font size within the UI. All font elements are scaled relative to this. (Needs restart)
cbpMulliganRule = Mulligan Rule
nlImageFetcher=Enables live fetching of missing card images from an online resource. nlImageFetcher=Enables live fetching of missing card images from an online resource.
nlDisplayFoil=Displays foil cards with the visual foil overlay effect. nlDisplayFoil=Displays foil cards with the visual foil overlay effect.
nlRandomFoil=Adds foil effect to random cards. nlRandomFoil=Adds foil effect to random cards.
@@ -285,7 +316,7 @@ lblIsGoingFirst=is going first
lblYouAreGoing=you are going lblYouAreGoing=you are going
lblMulligan=Mulligan lblMulligan=Mulligan
lblDoYouWantToKeepYourHand=Do you want to keep your hand? lblDoYouWantToKeepYourHand=Do you want to keep your hand?
lblReturnForLondon=Return %s of %s card(s) to bottom of library lblReturnForLondon=Return %n card(s) to bottom of library
lblOk=Ok lblOk=Ok
lblReset=Reset lblReset=Reset
lblAuto=Auto lblAuto=Auto
@@ -660,3 +691,135 @@ lblWinsperDraftRotation=Wins per Draft Rotation
ttWinsperDraftRotation=If a Draft is not played for this many match wins, it will be removed or replaced. ttWinsperDraftRotation=If a Draft is not played for this many match wins, it will be removed or replaced.
lblRotationType=Rotation Type lblRotationType=Rotation Type
ttRotationType=If set to 0, old drafts disappear, if set to 1, they are replaced with another one using different sets. ttRotationType=If set to 0, old drafts disappear, if set to 1, they are replaced with another one using different sets.
#StatTypeFilter.java
lblclicktotoogle=click to toggle the filter, right-click to show only
#SItemManagerUtil.java
lblWhitecards=White cards
lblBluecards=Blue cards
lblBlackcards=Black cards
lblRedcards=Red cards
lblGreencards=Green cards
lblColorlesscards=Colorless cards
lblMulticolorcards=Multicolor cards
lblPackordeck=Card packs and prebuilt decks
lblLands=Lands
lblArtifacts=Artifacts
lblCreatures=Creatures
lblEnchantments=Enchantments
lblPlaneswalkers=Planeswalkers
lblInstants=Instants
lblSorceries=Sorceries
lblCCMC0=Cards with CMC 0
lblCCMC1=Cards with CMC 1
lblCCMC2=Cards with CMC 2
lblCCMC3=Cards with CMC 3
lblCCMC4=Cards with CMC 4
lblCCMC5=Cards with CMC 5
lblCCMC6orMore=Cards with CMC 6+
lblWhitedecks=White decks
lblBluedecks=Blue decks
lblBlackdecks=Black decks
lblReddecks=Red decks
lblGreendecks=Green decks
lblColorlessdecks=Colorless decks
lblMulticolordecks=Multicolor decks
lblOldstyleFoilcards=Old style Foil cards
lblNewstyleFoilcards=New style Foil cards
lblNon-Foilcards=Non-Foil cards
lblUnratedcards=Unrated cards
lbl1starcards=1 star cards
lbl2starcards=2 star cards
lbl3starcards=3 star cards
lbl4starcards=4 star cards
lbl5starcards=5 star cards
lblXcopiesof=X copies of
lblcopiesof=copies of
#ACEditorBase.java
lblAddcard=Add card
ttAddcard=Add selected card to current deck (or double click the row or hit the spacebar)
lblAdd4ofcard=Add 4 of card
ttAdd4ofcard=Add up to 4 of selected card to current deck
lblRemovecard=Remove card
ttRemovecard=Remove selected card from current deck (or double click the row or hit the spacebar)
lblRemove4ofcard=Remove 4 of card
ttRemove4ofcard=Remove up to 4 of selected card to current deck
lblAddBasicLands=Add Basic Lands
ttAddBasicLands=Add basic lands to the deck
lblCardCatalog=Card Catalog
lblJumptoprevioustable=Jump to previous table
lblJumptopnexttable=Jump to next table
lblJumptotextfilter=Jump to text filter
lblChooseavalueforX=Choose a value for X
#VCurrentDeck.java
lblVCurrentDeck=Current Deck
ttbtnSave=Save Deck (Ctrl+S)
ttbtnSaveAs=Save Deck As (Ctrl+E)
ttbtnLoadDeck=Open Deck (Ctrl+O)
ttbtnNewDeck=New Deck (Ctrl+N)
ttbtnPrintProxies=Print to HTML file (Ctrl+P)
lblImport=Import
ttImportDeck=Attempt to import a deck from a non-Forge format (Ctrl+I)
lblTitle=Title
#ImageView.java
lblExpandallgroups=Expand all groups
lblCollapseallgroups=Collapse all groups
lblGroupby=group by
lblPileby=pile by
lblColumns=Columns
#CEditorVariant.java
lblCatalog=Catalog
lblAdd=Add
lbltodeck=to deck
lblfromdeck=from deck
lbltosideboard=to sideboard
lblfromsideboard=from sideboard
lblascommander=as commander
lblasavatar=as avatar
lblfromschemedeck=from scheme deck
lblfromplanardeck=from planar deck
lblfromconspiracydeck=from conspiracy deck
#GroupDef.java
lblColor=Color
lblColorIdentity=Color Identity
lblSet=Set
lblDefault=Default
lblType=Type
lblPlaneswalkerDeckSort=Planeswalker Deck Sort
lblRarity=Rarity
lblConvertToFoil=Foil
lblMulticolor=Multicolor
#DeckFileMenu.java
lblNewDeck=New Deck
lblOpenDeck=Open Deck
lblImportDeck=Import Deck
lblSaveDeck=Save Deck
lblSaveDeckAs=Save Deck As
lblPrinttoHTMLfile=Print to HTML file
#PaperCard.java
lblCard=Card
#CardManager.java
lblFormat=Format
lblFormats=Formats
lblQuestWorld=Quest World
lblSets=Sets
lblTypes=Types
lblConvertedManaCosts=Converted mana
lblCMCRange=CMC Range
lblPowerRange=Power Range
lblToughnessRange=Toughness Range
lblFoil=Foil
lblPersonalRating=Personal Rating
lblAdvanced=Advanced
#VDeckgen.java
lblDeckGeneration=Deck Generation
btnRandCardpool=Random Cardpool
ttbtnRandCardpool=Generate random constructed cardpool in current deck area
btnRandDeck2=Constructed (2 color)
ttbtnRandDeck2=Generate 2 color constructed deck in current deck area
btnRandDeck3=Constructed (3 color)
ttbtnRandDeck3=Generate 3 color constructed deck in current deck area
btnRandDeck5=Constructed (5 color)
ttbtnRandDeck5=Generate 5 color constructed deck in current deck area
#DeckCotroller.java
lblCurrentDeck2=Current Deck
lblUntitled=Untitled

View File

@@ -7,6 +7,36 @@ splash.loading.decks=Cargando Mazos...
splash.loading.processingimagesprites=Procesando imágenes de cartas splash.loading.processingimagesprites=Procesando imágenes de cartas
#FControl.java #FControl.java
lblOpeningMainWindow=Abriendo ventana principal... lblOpeningMainWindow=Abriendo ventana principal...
lblCloseScreen=Cerrar Pantalla
txCloseAction1=Forge ahora admite pestañas de navegación que permiten cerrar y cambiar entre diferentes pantallas con facilidad. Como resultado, ya no necesita usar el botón X en la esquina superior derecha para cerrar la pantalla actual y regresar.
txCloseAction2=Seleccione lo que desea que suceda al hacer clic en el botón X en la parte superior derecha. Esta opción se utilizará en el futuro y no volverá a ver este mensaje. Puedes cambiar este comportamiento en cualquier momento en Preferencias.
titCloseAction=Seleccione su Acción al Cerrar
lblAreYouSureYouWishRestartForge=¿Estás seguro de que deseas reiniciar Forge?
lblAreYouSureYouWishExitForge=¿Estás seguro de que deseas salir de Forge?
lblOneOrMoreGamesActive=Una o más partidas están actualmente activos
lblerrLoadingLayoutFile=No se pudo leer el archivo de diseño %s. Se eliminará después de presionar OK.\nEl juego continuará con el diseño predeterminado.
lblLoadingQuest=Cargando datos de Aventura....
#FScreen.java
lblHome=Inicio
lblWorkshop=Taller
lblBacktoHome=Volver a Inicio
lblDeckEditor=Editor de Mazos
lblCloseEditor=Cerrar Editor
lblCommanderDeckEditor=Editor Mazos Commander
lblTinyLeadersDeckEditor=Editor Mazos Tiny Leaders
lblBrawlDeckEditor=Editor Mazos Brawl
lblDraftDeckEditor=Editor Mazo Draft
lblSealedDeckEditor=Editor Mazo Sellao
lblTokenViewer=Visor de Tokens
lblCloseViewer=Cerrar Visor
lblQuestDeckEditor=Editor Mazos Aventura
lblQuestTournamentDeckEditor=Editor Mazos Torneos Aventura
lblSpellShop=Tienda de Hechizos
lblLeaveShop=Salir de la Tienda
lblLeaveDraft=Abandonar Draft
lblBazaar=Bazar
lblConcedeGame=Conceder Partida
txerrFailedtodeletelayoutfile=Fallo al borrar el archivo de disposición
#VSubmenuPreferences.java #VSubmenuPreferences.java
Preferences=Preferencias Preferences=Preferencias
btnReset=Restablecer la configuración predeterminada btnReset=Restablecer la configuración predeterminada
@@ -70,7 +100,6 @@ cbUseSentry=Enviar automáticamente informes de errores.
cbpGameLogEntryType=Verbosidad del registro del juego cbpGameLogEntryType=Verbosidad del registro del juego
cbpCloseAction=Acción al cerrar cbpCloseAction=Acción al cerrar
cbpDefaultFontSize=Tamaño de fuente predeterminado cbpDefaultFontSize=Tamaño de fuente predeterminado
cbpMulliganRule = Mulligan Rule
cbpAiProfiles=Personalidad de la IA cbpAiProfiles=Personalidad de la IA
cbpDisplayCurrentCardColors=Mostrar color detallado de la carta cbpDisplayCurrentCardColors=Mostrar color detallado de la carta
cbpAutoYieldMode=Auto-Ceder cbpAutoYieldMode=Auto-Ceder
@@ -79,11 +108,12 @@ cbpCounterDisplayLocation=Ubicación del contador
cbpGraveyardOrdering=Permitir ordenar cartas puestas en el cementerio cbpGraveyardOrdering=Permitir ordenar cartas puestas en el cementerio
Troubleshooting=Solución de problemas Troubleshooting=Solución de problemas
GeneralConfiguration=Configuración general GeneralConfiguration=Configuración general
lblPlayerName=Nombre Jugador
nlPlayerName=Establece el nombre al que te referirá Forge durante el juego. nlPlayerName=Establece el nombre al que te referirá Forge durante el juego.
nlCompactMainMenu=Habilitar para una barra lateral eficiente en espacio que muestre solo un grupo de menús a la vez (REQUIERE REINICIAR). nlCompactMainMenu=Habilitar para una barra lateral eficiente en espacio que muestre solo un grupo de menús a la vez (REQUIERE REINICIAR).
nlUseSentry=Cuando está habilitado, envía automáticamente informes de errores a los desarrolladores. nlUseSentry=Cuando está habilitado, envía automáticamente informes de errores a los desarrolladores.
GamePlay=Juego GamePlay=Juego
nlpMulliganRule=Choose the version of the Mulligan rule nlpMulliganRule=Elige versión de reglas de Mulligan
nlpAiProfiles=Elige tu oponente de la IA nlpAiProfiles=Elige tu oponente de la IA
nlAnte=Determina si el juego se juega con apuesta o no. nlAnte=Determina si el juego se juega con apuesta o no.
nlAnteMatchRarity=Intenta crear apuesta de la misma rareza para todos los jugadores. nlAnteMatchRarity=Intenta crear apuesta de la misma rareza para todos los jugadores.
@@ -120,6 +150,7 @@ nlLoadCardsLazily=Si está activado, Forge cargará los scripts de las cartas se
nlLoadHistoricFormats=Si está activado, Forge cargará todas los formatos históricos, esto puede demorar un poco más en cargarse en el inicio. nlLoadHistoricFormats=Si está activado, Forge cargará todas los formatos históricos, esto puede demorar un poco más en cargarse en el inicio.
GraphicOptions=Opciones gráficas GraphicOptions=Opciones gráficas
nlDefaultFontSize=El tamaño de fuente predeterminado dentro de la interfaz de usuario. Todos los elementos de fuente se escalan en relación a esto. (Necesita reinicio) nlDefaultFontSize=El tamaño de fuente predeterminado dentro de la interfaz de usuario. Todos los elementos de fuente se escalan en relación a esto. (Necesita reinicio)
cbpMulliganRule=Regla de Mulligan
nlImageFetcher=Permite la descarga instantánea de imágenes de cartas faltantes. nlImageFetcher=Permite la descarga instantánea de imágenes de cartas faltantes.
nlDisplayFoil=Mostrar cartas foil con un capa que da efecto foil sobre la carta nlDisplayFoil=Mostrar cartas foil con un capa que da efecto foil sobre la carta
nlRandomFoil=Agrega efecto de foil a cartas aleatorias. nlRandomFoil=Agrega efecto de foil a cartas aleatorias.
@@ -207,7 +238,7 @@ lblConstructedMode=Modo Construido
lblConstructed=Construido lblConstructed=Construido
#PlayerPanel.java #PlayerPanel.java
lblSelectaDeck=Selecciona un Mazo lblSelectaDeck=Selecciona un Mazo
lblSelectaSchemeDeck=Selecciona un Mazo de Fenómenos (Scheme) lblSelectaSchemeDeck=Selecciona un Mazo de Escenario (Scheme)
lblSchemeDeckEditor=Editor de Mazo de Escenario (Scheme) lblSchemeDeckEditor=Editor de Mazo de Escenario (Scheme)
lblSelectaCommanderDeck=Selecciona un Mazo Commander lblSelectaCommanderDeck=Selecciona un Mazo Commander
lblSelectaPlanarDeck=Selecciona un Mazo Planar lblSelectaPlanarDeck=Selecciona un Mazo Planar
@@ -381,7 +412,7 @@ cbSummonPlant=Invocar Planta
cbLaunchZeppelin=Lanzar Zeppelin cbLaunchZeppelin=Lanzar Zeppelin
#VSubmenuQuest.java #VSubmenuQuest.java
lblQuestData=Datos de Aventura lblQuestData=Datos de Aventura
lblLoadQuestData=Load Quest Data lblLoadQuestData=Cargar Datos de Aventura
lblStartanewQuest=Comenzar una nueva Aventura lblStartanewQuest=Comenzar una nueva Aventura
lblOldQuestData=Viejos datos de Aventura? Poner en %n y reiniciar Forge. lblOldQuestData=Viejos datos de Aventura? Poner en %n y reiniciar Forge.
rbEasy=Fácil rbEasy=Fácil
@@ -477,7 +508,7 @@ btnSpendToken=Gastar Token
btnStartMatchSmall=Comenzar Siguiente Partida btnStartMatchSmall=Comenzar Siguiente Partida
lblUndetermined=Sin determinar lblUndetermined=Sin determinar
btnSpendTokenTT=Crea un nuevo torneo que se puede jugar de inmediato. btnSpendTokenTT=Crea un nuevo torneo que se puede jugar de inmediato.
lblPastResults=Past Results lblPastResults=Resultados Anteriores
#VSubmenuQuestDecks.java #VSubmenuQuestDecks.java
lblQuestDecks=Mazos de la Aventura lblQuestDecks=Mazos de la Aventura
lblQuestDesc1=En el modo Aventura, construyes un mazo a partir de un inventario limitado. lblQuestDesc1=En el modo Aventura, construyes un mazo a partir de un inventario limitado.
@@ -566,7 +597,7 @@ lblnextChallengeInWins1=Un nuevo desafío estará disponible después de 1 victo
lblnextChallengeInWins2=Un nuevo desafío estará disponible después de %n victorias más. lblnextChallengeInWins2=Un nuevo desafío estará disponible después de %n victorias más.
lblWinStreak=Racha lblWinStreak=Racha
lblBest=Mejor lblBest=Mejor
lblBuildAndSelectaDeck=Construye, luego selecciona un mazo en el submenú "Mazo de misiones". lblBuildAndSelectaDeck=Construye, luego selecciona un mazo en el submenú "Mazos de la Aventura".
lblCurrentDeck=Tu mazo actual es %n lblCurrentDeck=Tu mazo actual es %n
PleaseCreateAQuestBefore=Por favor crea una aventura antes de intentar %n. PleaseCreateAQuestBefore=Por favor crea una aventura antes de intentar %n.
lblNoQuest=No Aventura lblNoQuest=No Aventura
@@ -591,7 +622,7 @@ lblBoosterPackRatios=Proporción de pack de sobres
lblDifficultyAdjustments=Ajustes de dificultad lblDifficultyAdjustments=Ajustes de dificultad
lblShopPreferences=Preferencias de la tienda lblShopPreferences=Preferencias de la tienda
lblDraftTournaments=Torneos de Draft lblDraftTournaments=Torneos de Draft
lblBaseWinnings= lblBaseWinnings=Base Winnings
lblNoLosses=Sin pérdidas lblNoLosses=Sin pérdidas
lblPoisonWin=Victoria por Veneno lblPoisonWin=Victoria por Veneno
lblMillingWin=Victoria por Deckeo lblMillingWin=Victoria por Deckeo
@@ -660,3 +691,135 @@ lblWinsperDraftRotation=Victorias Rotación de Draft
ttWinsperDraftRotation=Si no se juega un Draft para esta cantidad de victorias, se eliminará o reemplazará. ttWinsperDraftRotation=Si no se juega un Draft para esta cantidad de victorias, se eliminará o reemplazará.
lblRotationType=Tipo de Rotación lblRotationType=Tipo de Rotación
ttRotationType=Si se establece en 0, los anteriores Draft desaparecen, si se establece en 1, se reemplazan por otros que utilizan sets diferentes. ttRotationType=Si se establece en 0, los anteriores Draft desaparecen, si se establece en 1, se reemplazan por otros que utilizan sets diferentes.
#StatTypeFilter.java
lblclicktotoogle=haga clic para alternar el filtro, haga clic con el botón derecho para mostrar solo
#SItemManagerUtil.java
lblWhitecards=Cartas Blancas
lblBluecards=Cartas Azules
lblBlackcards=Cartas Negras
lblRedcards=Cartas Rojas
lblGreencards=Cartas Verdes
lblColorlesscards=Cartas Incoloras
lblMulticolorcards=Cartas Multicolor
lblPackordeck=Pack de Cartas y Mazos Preconstruidos
lblLands=Tierras
lblArtifacts=Artefactos
lblCreatures=Criaturas
lblEnchantments=Encantamientos
lblPlaneswalkers=Planeswalkers
lblInstants=Instantáneos
lblSorceries=Conjuros
lblCCMC0=Cartas con CMC 0
lblCCMC1=Cartas con CMC 1
lblCCMC2=Cartas con CMC 2
lblCCMC3=Cartas con CMC 3
lblCCMC4=Cartas con CMC 4
lblCCMC5=Cartas con CMC 5
lblCCMC6orMore=Cartas con CMC 6 o mas
lblWhitedecks=Mazos Blancos
lblBluedecks=Mazos Azules
lblBlackdecks=Mazos Negros
lblReddecks=Mazos Rojos
lblGreendecks=Mazos Verdes
lblColorlessdecks=Mazos Incoloros
lblMulticolordecks=Mazos Multicolor
lblOldstyleFoilcards=Cartas Foil Viejo Estilo
lblNewstyleFoilcards=Cartas Foil Nuevo Estilo
lblNon-Foilcards=Cartas no Foil
lblUnratedcards=Cartas sin valorar
lbl1starcards=Cartas 1 estrella
lbl2starcards=Cartas 2 estrellas
lbl3starcards=Cartas 3 estrellas
lbl4starcards=Cartas 4 estrellas
lbl5starcards=Cartas 5 estrellas
lblXcopiesof=X copias de
lblcopiesof=copias de
#ACEditorBase.java
lblAddcard=Añadir carta
ttAddcard=Añade la carta seleccionada al mazo actual (o haz doble clic en la fila o presiona la barra espaciadora)
lblAdd4ofcard=Añadir 4 cartas
ttAdd4ofcard=Añadir hasta 4 de la carta seleccionada al mazo actual
lblRemovecard=Quitar carta
ttRemovecard=Quitar la carta seleccionada del mazo actual (o haz doble clic en la fila o presiona la barra espaciadora)
lblRemove4ofcard=Quitar 4 cartas
ttRemove4ofcard=Quitar hasta 4 de la carta seleccionada al mazo actual
lblAddBasicLands=Añadir Tierras Básicas
ttAddBasicLands=Añadir tierras básicas al mazo
lblCardCatalog=Catálogo de Cartas
lblJumptoprevioustable=Saltar a la tabla anterior
lblJumptopnexttable=Saltar a la siguiente tabla
lblJumptotextfilter=Saltar al filtro de texto
lblChooseavalueforX=Elige un valor para X
#VCurrentDeck.java
lblVCurrentDeck=Mazo Actual
ttbtnSave=Guardar Mazo (Ctrl+S)
ttbtnSaveAs=Guardar Mazo como... (Ctrl+E)
ttbtnLoadDeck=Abrir Mazo (Ctrl+O)
ttbtnNewDeck=Nuevo Mazo ((Ctrl+N)
ttbtnPrintProxies=Imprimir a archivo HTML (Ctrl+P)
lblImport=Importar
ttImportDeck=Intenta importar un deck desde un formato que no sea Forge (Ctrl + I)
lblTitle=Título
#ImageView.java
lblExpandallgroups=Expandir todos los grupos
lblCollapseallgroups=Contraer todos los grupos
lblGroupby=agrupar por
lblPileby=apilar por
lblColumns=Columnas
#CEditorVariant.java
lblCatalog=Catálogo
lblAdd=Añadir
lbltodeck=al mazo
lblfromdeck=del mazo
lbltosideboard=al banquillo
lblfromsideboard=del banquillo
lblascommander=como comandante
lblasavatar=como avatar
lblfromschemedeck=del mazo de escenario
lblfromplanardeck=del mazo planar
lblfromconspiracydeck=del mazo conspiracy
#GroupDef.java
lblColor=Color
lblColorIdentity=Identidad de Color
lblSet=Edición
lblDefault=por defecto
lblType=Tipo
lblPlaneswalkerDeckSort=por Planewalkers
lblRarity=Rareza
lblConvertToFoil=Foil
lblMulticolor=Multicolor
#DeckFileMenu.java
lblNewDeck=Nuevo Mazo
lblOpenDeck=Abrir Mazo
lblImportDeck=Importar Mazo
lblSaveDeck=Guardar Mazo
lblSaveDeckAs=Guardar Mazo como...
lblPrinttoHTMLfile=Imprimir en fichero HTML
#PaperCard.java
lblCard=Carta
#CardManager.java
lblFormat=Formato
lblFormats=Formatos
lblQuestWorld=Mundos del Modo Aventura
lblSets=Ediciones
lblTypes=Tipos
lblConvertedManaCosts=Maná Convertido
lblCMCRange=Rango de CMC
lblPowerRange=Rango de Fuerza
lblToughnessRange=Rango de Resistencia
lblFoil=Foil
lblPersonalRating=Puntuación Personal
lblAdvanced=Avanzado
#VDeckgen.java
lblDeckGeneration=Deck Generation
btnRandCardpool=Random Cardpool
ttbtnRandCardpool=Generate random constructed cardpool in current deck area
btnRandDeck2=Constructed (2 color)
ttbtnRandDeck2=Generate 2 color constructed deck in current deck area
btnRandDeck3=Constructed (3 color)
ttbtnRandDeck3=Generate 3 color constructed deck in current deck area
btnRandDeck5=Constructed (5 color)
ttbtnRandDeck5=Generate 5 color constructed deck in current deck area
#DeckCotroller.java
lblCurrentDeck2=Current Deck
lblUntitled=Untitled

View File

@@ -0,0 +1,24 @@
# This is an example puzzle, currently disabled. It demonstrates how to set up a puzzle where a spell is put on stack
# at the beginning of the puzzle. Unfortunately, this particular puzzle doesn't work well in Forge due to the fact that
# the AI does not use its resources optimally, thus naturally failing to defeat the player in one turn and losing.
# Also, this puzzle demonstrates how it's possible to add a card which is owned by a player other than its controller.
[metadata]
Name:Possibility Storm - Guilds of Ravnica Special (Survive the Turn)
URL:http://www.possibilitystorm.com/wp-content/uploads/2019/01/094.-GRN004-3.jpg
Goal:Survive
Turns:1
Difficulty:Special
Description:Start in your opponent's first main phase with their Mnemonic Betrayal just cast and on the stack. Find a way to survive the turn! The trigger from Deeproot Champion is also on the stack and it will get one +1/+1 counter! Assume that any cards that could be drawn by either player are lands that enter the battlefield tapped. Goblin Banneret and Runaway Steam-Kin controlled by your opponent are owned by you.
[state]
humanlife=9
ailife=20
turn=1
activeplayer=ai
activephase=MAIN1
humanhand=Mission Briefing
humanlibrary=Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard
humangraveyard=Fervent Strike;Warlord's Fury;Dinosaur Stampede;Sure Strike;Crash the Ramparts;Buccaneer's Bravado;Rescue;Forebear's Blade
humanbattlefield=Raptor Hatchling;Diamond Mare|ChosenColor:Blue;Beamsplitter Mage;Island;Island;Island;Mountain;Forest
ailibrary=Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard;Foul Orchard
aibattlefield=Relic Runner;Goblin Banneret|Owner:Human;Deeproot Champion;Runaway Steam-Kin|Owner:Human;Overgrown Tomb;Overgrown Tomb;Overgrown Tomb;Overgrown Tomb|Tapped;Island;Island;Island;Island|Tapped
aiputonstack=Mnemonic Betrayal

View File

@@ -0,0 +1,17 @@
[metadata]
Name:Possibility Storm - War of the Spark #07
URL:http://www.possibilitystorm.com/wp-content/uploads/2019/06/117.-WAR7-v2.jpg
Goal:Win
Turns:1
Difficulty:Rare
Description:Win this turn. Assume any cards you could draw are irrelevant to the puzzle.
[state]
humanlife=8
ailife=20
turn=1
activeplayer=human
activephase=MAIN1
humanhand=Narset's Reversal;Siren's Ruse;Fraying Omnipotence;Expansion // Explosion
humanlibrary=Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus;Gigantosaurus
humanbattlefield=Saheeli, Sublime Artificer|Counters:LOYALTY=3;Desperate Castaways;Sleek Schooner;Naru Meha, Master Wizard;Firemind Vessel;Steam Vents|NoETBTrigs;Steam Vents|NoETBTrigs;Steam Vents|NoETBTrigs;Blood Crypt|NoETBTrigs;Blood Crypt|NoETBTrigs;Blood Crypt|NoETBTrigs;Blood Crypt|NoETBTrigs
aibattlefield=God-Eternal Oketra;t:Zombie Warrior,P:4,T:4,Cost:no cost,Color:B,Types:Creature-Zombie-Warrior,Keywords:Vigilance,Image:b_4_4_zombie_warrior_vigilance_war;Impassioned Orator;t:Zombie Warrior,P:4,T:4,Cost:no cost,Color:B,Types:Creature-Zombie-Warrior,Keywords:Vigilance,Image:b_4_4_zombie_warrior_vigilance_war;Impassioned Orator;t:Zombie Warrior,P:4,T:4,Cost:no cost,Color:B,Types:Creature-Zombie-Warrior,Keywords:Vigilance,Image:b_4_4_zombie_warrior_vigilance_war;Impassioned Orator

View File

@@ -15,7 +15,7 @@ Treetop Village
Dryad Arbor Dryad Arbor
[/Group] [/Group]
[Group MaxCnt=2 Percentage=5] [Group MaxCnt=4 Percentage=5]
Kabira Crossroads Kabira Crossroads
Karakas Karakas
The Tabernacle at Pendrell Vale The Tabernacle at Pendrell Vale

View File

@@ -1,5 +1,6 @@
Name:Main world Name:Main world
Name:Random Standard Name:Random Standard
Name:Random Modern
Name:Random Commander Name:Random Commander
Name:Amonkhet|Dir:Amonkhet|Sets:AKH, HOU Name:Amonkhet|Dir:Amonkhet|Sets:AKH, HOU
Name:Jamuraa|Dir:jamuraa|Sets:5ED, ARN, MIR, VIS, WTH|Banned:Chaos Orb; Falling Star Name:Jamuraa|Dir:jamuraa|Sets:5ED, ARN, MIR, VIS, WTH|Banned:Chaos Orb; Falling Star

View File

@@ -0,0 +1,10 @@
Name:Ajani's Pridemate
ManaCost:no cost
Types:Creature Cat Soldier
PT:2/2
T:Mode$ LifeGained | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever you gain life, put a +1/+1 counter on CARDNAME.
SVar:TrigPutCounter:DB$PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1
SVar:Picture:http://www.wizards.com/global/images/magic/general/ajanis_pridemate.jpg
DeckHints:Ability$LifeGain
DeckHas:Ability$Counters
Oracle:Whenever you gain life, put a +1/+1 counter on Ajani's Pridemate.

View File

@@ -131,17 +131,16 @@ public class DeckGeneratorTheme extends DeckGeneratorBase {
ss = s.split("\\|"); ss = s.split("\\|");
int lc = 0; int lc = 0;
while ((cardCounts.get(ss[0]) >= g.maxCnt) || (lc > 999)) { while ((cardCounts.get(ss[0]) >= g.maxCnt)) {
// looping // looping
// forever // forever
s = g.cardnames.get(MyRandom.getRandom().nextInt(cnSize)); s = g.cardnames.get(MyRandom.getRandom().nextInt(cnSize));
ss = s.split("\\|"); ss = s.split("\\|");
lc++;
}
if (lc > 999) { if (lc > 999) {
throw new RuntimeException("ThemeDeckGenerator : getThemeDeck -- looped too much -- filename is " throw new RuntimeException("ThemeDeckGenerator : getThemeDeck -- looped too much -- filename is "
+ tFileName); + tFileName);
} }
}
final int n = cardCounts.get(ss[0]); final int n = cardCounts.get(ss[0]);
if (ss.length == 1) { if (ss.length == 1) {

View File

@@ -624,13 +624,13 @@ public class DeckgenUtil {
}else { }else {
List<Map.Entry<PaperCard,Integer>> potentialCards = new ArrayList<>(); List<Map.Entry<PaperCard,Integer>> potentialCards = new ArrayList<>();
potentialCards.addAll(CardRelationMatrixGenerator.cardPools.get(DeckFormat.Commander.toString()).get(commander.getName())); potentialCards.addAll(CardRelationMatrixGenerator.cardPools.get(DeckFormat.Commander.toString()).get(commander.getName()));
Collections.shuffle(potentialCards, MyRandom.getRandom());
for(Map.Entry<PaperCard,Integer> pair:potentialCards){ for(Map.Entry<PaperCard,Integer> pair:potentialCards){
if(format.isLegalCard(pair.getKey())) { if(format.isLegalCard(pair.getKey())) {
preSelectedCards.add(pair.getKey()); preSelectedCards.add(pair.getKey());
} }
} }
} }
//Collections.shuffle(potentialCards, r);
//check for partner commanders //check for partner commanders

View File

@@ -15,9 +15,10 @@ import forge.deck.DeckProxy;
import forge.item.InventoryItem; import forge.item.InventoryItem;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.model.FModel; import forge.model.FModel;
import forge.util.Localizer;
public enum GroupDef { public enum GroupDef {
COLOR("Color", getColorGroups(), COLOR("lblColor", getColorGroups(),
new Function<Integer, ColumnDef>() { new Function<Integer, ColumnDef>() {
@Override @Override
public ColumnDef apply(final Integer groupIndex) { public ColumnDef apply(final Integer groupIndex) {
@@ -36,7 +37,7 @@ public enum GroupDef {
return -1; return -1;
} }
}), }),
COLOR_IDENTITY("Color Identity", getColorGroups(), COLOR_IDENTITY("lblColorIdentity", getColorGroups(),
new Function<Integer, ColumnDef>() { new Function<Integer, ColumnDef>() {
@Override @Override
public ColumnDef apply(final Integer groupIndex) { public ColumnDef apply(final Integer groupIndex) {
@@ -55,7 +56,7 @@ public enum GroupDef {
return -1; return -1;
} }
}), }),
SET("Set", getSetGroups(), SET("lblSet", getSetGroups(),
new Function<Integer, ColumnDef>() { new Function<Integer, ColumnDef>() {
@Override @Override
public ColumnDef apply(final Integer groupIndex) { public ColumnDef apply(final Integer groupIndex) {
@@ -74,7 +75,7 @@ public enum GroupDef {
return -1; return -1;
} }
}), }),
DEFAULT("Default", DEFAULT("lblDefault",
new String[] { "Creatures", "Spells", "Lands" }, new String[] { "Creatures", "Spells", "Lands" },
new Function<Integer, ColumnDef>() { new Function<Integer, ColumnDef>() {
@Override @Override
@@ -104,7 +105,7 @@ public enum GroupDef {
} }
}), }),
CARD_TYPE("Type", CARD_TYPE("lblType",
new String[] { "Planeswalker", "Creature", "Sorcery", "Instant", "Artifact", "Enchantment", "Land", "Tribal instant" }, new String[] { "Planeswalker", "Creature", "Sorcery", "Instant", "Artifact", "Enchantment", "Land", "Tribal instant" },
new Function<Integer, ColumnDef>() { new Function<Integer, ColumnDef>() {
@Override @Override
@@ -148,7 +149,7 @@ public enum GroupDef {
return -1; return -1;
} }
}), }),
PW_DECK_SORT("Planeswalker Deck Sort", PW_DECK_SORT("lblPlaneswalkerDeckSort",
new String[] { "Planeswalker", "Rares", "Creature", "Land", "Other Spells" }, new String[] { "Planeswalker", "Rares", "Creature", "Land", "Other Spells" },
new Function<Integer, ColumnDef>() { new Function<Integer, ColumnDef>() {
@Override @Override
@@ -178,7 +179,7 @@ public enum GroupDef {
return -1; return -1;
} }
}), }),
CARD_RARITY("Rarity", CARD_RARITY("lblRarity",
new String[] {"Mythic Rares", "Rares", "Uncommons", "Commons", "Basic Lands"}, new String[] {"Mythic Rares", "Rares", "Uncommons", "Commons", "Basic Lands"},
new Function<Integer, ColumnDef>() { new Function<Integer, ColumnDef>() {
@Override @Override
@@ -210,7 +211,8 @@ public enum GroupDef {
}); });
GroupDef(String name0, String[] groups0, Function<Integer, ColumnDef> fnGetPileByOverride0, Function<InventoryItem, Integer> fnGroupItem0) { GroupDef(String name0, String[] groups0, Function<Integer, ColumnDef> fnGetPileByOverride0, Function<InventoryItem, Integer> fnGroupItem0) {
this.name = name0; final Localizer localizer = Localizer.getInstance();
this.name = localizer.getMessage(name0);
this.groups = groups0; this.groups = groups0;
this.fnGetPileByOverride = fnGetPileByOverride0; this.fnGetPileByOverride = fnGetPileByOverride0;
this.fnGroupItem = fnGroupItem0; this.fnGroupItem = fnGroupItem0;
@@ -247,8 +249,15 @@ public enum GroupDef {
} }
private static String[] getColorGroups() { private static String[] getColorGroups() {
final Localizer localizer = Localizer.getInstance();
String white = new String(localizer.getMessage("lblWhite"));
String blue = new String(localizer.getMessage("lblBlue"));
String black = new String(localizer.getMessage("lblBlack"));
String green = new String(localizer.getMessage("lblGreen"));
String multicolor = new String(localizer.getMessage("lblMulticolor"));
String colorless = new String(localizer.getMessage("lblColorless"));
//TODO: Support breaking up Multicolor into separate groups for each color combination //TODO: Support breaking up Multicolor into separate groups for each color combination
return new String[] { "White", "Blue", "Black", "Red", "Green", "Multicolor", "Colorless" }; return new String[] {white,blue,black,green,multicolor,colorless };
} }
private static Integer getColorGroup(ColorSet color) { private static Integer getColorGroup(ColorSet color) {

View File

@@ -9,6 +9,7 @@ import forge.deck.DeckProxy;
import forge.interfaces.IComboBox; import forge.interfaces.IComboBox;
import forge.item.InventoryItem; import forge.item.InventoryItem;
import forge.util.ComparableOp; import forge.util.ComparableOp;
import forge.util.Localizer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@@ -28,49 +29,49 @@ import java.util.Map.Entry;
public final class SItemManagerUtil { public final class SItemManagerUtil {
/** An enum to encapsulate metadata for the stats/filter objects. */ /** An enum to encapsulate metadata for the stats/filter objects. */
public static enum StatTypes implements IHasSkinProp { public static enum StatTypes implements IHasSkinProp {
WHITE (FSkinProp.IMG_MANA_W, CardRulesPredicates.Presets.IS_WHITE, "White cards"), WHITE (FSkinProp.IMG_MANA_W, CardRulesPredicates.Presets.IS_WHITE, "lblWhitecards"),
BLUE (FSkinProp.IMG_MANA_U, CardRulesPredicates.Presets.IS_BLUE, "Blue cards"), BLUE (FSkinProp.IMG_MANA_U, CardRulesPredicates.Presets.IS_BLUE, "lblBluecards"),
BLACK (FSkinProp.IMG_MANA_B, CardRulesPredicates.Presets.IS_BLACK, "Black cards"), BLACK (FSkinProp.IMG_MANA_B, CardRulesPredicates.Presets.IS_BLACK, "lblBlackcards"),
RED (FSkinProp.IMG_MANA_R, CardRulesPredicates.Presets.IS_RED, "Red cards"), RED (FSkinProp.IMG_MANA_R, CardRulesPredicates.Presets.IS_RED, "lblRedcards"),
GREEN (FSkinProp.IMG_MANA_G, CardRulesPredicates.Presets.IS_GREEN, "Green cards"), GREEN (FSkinProp.IMG_MANA_G, CardRulesPredicates.Presets.IS_GREEN, "lblGreencards"),
COLORLESS (FSkinProp.IMG_MANA_COLORLESS, CardRulesPredicates.Presets.IS_COLORLESS, "Colorless cards"), COLORLESS (FSkinProp.IMG_MANA_COLORLESS, CardRulesPredicates.Presets.IS_COLORLESS, "lblColorlesscards"),
MULTICOLOR (FSkinProp.IMG_MULTI, CardRulesPredicates.Presets.IS_MULTICOLOR, "Multicolor cards"), MULTICOLOR (FSkinProp.IMG_MULTI, CardRulesPredicates.Presets.IS_MULTICOLOR, "lblMulticolorcards"),
PACK_OR_DECK (FSkinProp.IMG_PACK, null, "Card packs and prebuilt decks"), PACK_OR_DECK (FSkinProp.IMG_PACK, null, "lblPackordeck"),
LAND (FSkinProp.IMG_LAND, CardRulesPredicates.Presets.IS_LAND, "Lands"), LAND (FSkinProp.IMG_LAND, CardRulesPredicates.Presets.IS_LAND, "lblLands"),
ARTIFACT (FSkinProp.IMG_ARTIFACT, CardRulesPredicates.Presets.IS_ARTIFACT, "Artifacts"), ARTIFACT (FSkinProp.IMG_ARTIFACT, CardRulesPredicates.Presets.IS_ARTIFACT, "lblArtifacts"),
CREATURE (FSkinProp.IMG_CREATURE, CardRulesPredicates.Presets.IS_CREATURE, "Creatures"), CREATURE (FSkinProp.IMG_CREATURE, CardRulesPredicates.Presets.IS_CREATURE, "lblCreatures"),
ENCHANTMENT (FSkinProp.IMG_ENCHANTMENT, CardRulesPredicates.Presets.IS_ENCHANTMENT, "Enchantments"), ENCHANTMENT (FSkinProp.IMG_ENCHANTMENT, CardRulesPredicates.Presets.IS_ENCHANTMENT, "lblEnchantments"),
PLANESWALKER (FSkinProp.IMG_PLANESWALKER, CardRulesPredicates.Presets.IS_PLANESWALKER, "Planeswalkers"), PLANESWALKER (FSkinProp.IMG_PLANESWALKER, CardRulesPredicates.Presets.IS_PLANESWALKER, "lblPlaneswalkers"),
INSTANT (FSkinProp.IMG_INSTANT, CardRulesPredicates.Presets.IS_INSTANT, "Instants"), INSTANT (FSkinProp.IMG_INSTANT, CardRulesPredicates.Presets.IS_INSTANT, "lblInstants"),
SORCERY (FSkinProp.IMG_SORCERY, CardRulesPredicates.Presets.IS_SORCERY, "Sorceries"), SORCERY (FSkinProp.IMG_SORCERY, CardRulesPredicates.Presets.IS_SORCERY, "lblSorceries"),
CMC_0 (FSkinProp.IMG_MANA_0, new CardRulesPredicates.LeafNumber(CardRulesPredicates.LeafNumber.CardField.CMC, ComparableOp.EQUALS, 0), "Cards with CMC 0"), CMC_0 (FSkinProp.IMG_MANA_0, new CardRulesPredicates.LeafNumber(CardRulesPredicates.LeafNumber.CardField.CMC, ComparableOp.EQUALS, 0), "lblCCMC0"),
CMC_1 (FSkinProp.IMG_MANA_1, new CardRulesPredicates.LeafNumber(CardRulesPredicates.LeafNumber.CardField.CMC, ComparableOp.EQUALS, 1), "Cards with CMC 1"), CMC_1 (FSkinProp.IMG_MANA_1, new CardRulesPredicates.LeafNumber(CardRulesPredicates.LeafNumber.CardField.CMC, ComparableOp.EQUALS, 1), "lblCCMC1"),
CMC_2 (FSkinProp.IMG_MANA_2, new CardRulesPredicates.LeafNumber(CardRulesPredicates.LeafNumber.CardField.CMC, ComparableOp.EQUALS, 2), "Cards with CMC 2"), CMC_2 (FSkinProp.IMG_MANA_2, new CardRulesPredicates.LeafNumber(CardRulesPredicates.LeafNumber.CardField.CMC, ComparableOp.EQUALS, 2), "lblCCMC2"),
CMC_3 (FSkinProp.IMG_MANA_3, new CardRulesPredicates.LeafNumber(CardRulesPredicates.LeafNumber.CardField.CMC, ComparableOp.EQUALS, 3), "Cards with CMC 3"), CMC_3 (FSkinProp.IMG_MANA_3, new CardRulesPredicates.LeafNumber(CardRulesPredicates.LeafNumber.CardField.CMC, ComparableOp.EQUALS, 3), "lblCCMC3"),
CMC_4 (FSkinProp.IMG_MANA_4, new CardRulesPredicates.LeafNumber(CardRulesPredicates.LeafNumber.CardField.CMC, ComparableOp.EQUALS, 4), "Cards with CMC 4"), CMC_4 (FSkinProp.IMG_MANA_4, new CardRulesPredicates.LeafNumber(CardRulesPredicates.LeafNumber.CardField.CMC, ComparableOp.EQUALS, 4), "lblCCMC4"),
CMC_5 (FSkinProp.IMG_MANA_5, new CardRulesPredicates.LeafNumber(CardRulesPredicates.LeafNumber.CardField.CMC, ComparableOp.EQUALS, 5), "Cards with CMC 5"), CMC_5 (FSkinProp.IMG_MANA_5, new CardRulesPredicates.LeafNumber(CardRulesPredicates.LeafNumber.CardField.CMC, ComparableOp.EQUALS, 5), "lblCCMC5"),
CMC_6 (FSkinProp.IMG_MANA_6, new CardRulesPredicates.LeafNumber(CardRulesPredicates.LeafNumber.CardField.CMC, ComparableOp.GT_OR_EQUAL, 6), "Cards with CMC 6+"), CMC_6 (FSkinProp.IMG_MANA_6, new CardRulesPredicates.LeafNumber(CardRulesPredicates.LeafNumber.CardField.CMC, ComparableOp.GT_OR_EQUAL, 6), "lblCCMC6orMore"),
DECK_WHITE (FSkinProp.IMG_MANA_W, null, "White decks"), DECK_WHITE (FSkinProp.IMG_MANA_W, null, "lblWhitedecks"),
DECK_BLUE (FSkinProp.IMG_MANA_U, null, "Blue decks"), DECK_BLUE (FSkinProp.IMG_MANA_U, null, "lblBluedecks"),
DECK_BLACK (FSkinProp.IMG_MANA_B, null, "Black decks"), DECK_BLACK (FSkinProp.IMG_MANA_B, null, "lblBlackdecks"),
DECK_RED (FSkinProp.IMG_MANA_R, null, "Red decks"), DECK_RED (FSkinProp.IMG_MANA_R, null, "lblReddecks"),
DECK_GREEN (FSkinProp.IMG_MANA_G, null, "Green decks"), DECK_GREEN (FSkinProp.IMG_MANA_G, null, "lblGreendecks"),
DECK_COLORLESS (FSkinProp.IMG_MANA_COLORLESS, null, "Colorless decks"), DECK_COLORLESS (FSkinProp.IMG_MANA_COLORLESS, null, "lblColorlessdecks"),
DECK_MULTICOLOR (FSkinProp.IMG_MULTI, null, "Multicolor decks"), DECK_MULTICOLOR (FSkinProp.IMG_MULTI, null, "lblMulticolordecks"),
FOIL_OLD (FSkinProp.FOIL_11, null, "Old style Foil cards"), FOIL_OLD (FSkinProp.FOIL_11, null, "lblOldstyleFoilcards"),
FOIL_NEW (FSkinProp.FOIL_01, null, "New style Foil cards"), FOIL_NEW (FSkinProp.FOIL_01, null, "lblNewstyleFoilcards"),
FOIL_NONE (FSkinProp.ICO_CLOSE, null, "Non-Foil cards"), FOIL_NONE (FSkinProp.ICO_CLOSE, null, "lblNon-Foilcards"),
RATE_NONE (FSkinProp.IMG_FAVNONE, null, "Unrated cards"), RATE_NONE (FSkinProp.IMG_FAVNONE, null, "lblUnratedcards"),
RATE_1 (FSkinProp.IMG_FAV1, null, "1 star cards"), RATE_1 (FSkinProp.IMG_FAV1, null, "lbl1starcards"),
RATE_2 (FSkinProp.IMG_FAV2, null, "2 star cards"), RATE_2 (FSkinProp.IMG_FAV2, null, "lbl2starcards"),
RATE_3 (FSkinProp.IMG_FAV3, null, "3 star cards"), RATE_3 (FSkinProp.IMG_FAV3, null, "lbl3starcards"),
RATE_4 (FSkinProp.IMG_FAV4, null, "4 star cards"), RATE_4 (FSkinProp.IMG_FAV4, null, "lbl4starcards"),
RATE_5 (FSkinProp.IMG_FAV5, null, "5 star cards"); RATE_5 (FSkinProp.IMG_FAV5, null, "lbl5starcards");
public final FSkinProp skinProp; public final FSkinProp skinProp;
@@ -80,7 +81,8 @@ public final class SItemManagerUtil {
private StatTypes(final FSkinProp skinProp0, final Predicate<CardRules> predicate0, final String label0) { private StatTypes(final FSkinProp skinProp0, final Predicate<CardRules> predicate0, final String label0) {
skinProp = skinProp0; skinProp = skinProp0;
predicate = predicate0; predicate = predicate0;
label = label0; final Localizer localizer = Localizer.getInstance();
label = localizer.getMessage(label0);
} }
@Override @Override
@@ -95,6 +97,7 @@ public final class SItemManagerUtil {
return getItemDisplayString(items, qty, forTitle); return getItemDisplayString(items, qty, forTitle);
} }
public static String getItemDisplayString(final Iterable<? extends InventoryItem> items, final int qty, final boolean forTitle) { public static String getItemDisplayString(final Iterable<? extends InventoryItem> items, final int qty, final boolean forTitle) {
final Localizer localizer = Localizer.getInstance();
//determine shared type among items //determine shared type among items
int itemCount = 0; int itemCount = 0;
String sharedType = null; String sharedType = null;
@@ -130,10 +133,10 @@ public final class SItemManagerUtil {
result = itemCount + " " + result + "s"; result = itemCount + " " + result + "s";
} }
if (qty < 0) { //treat negative numbers as unknown quantity if (qty < 0) { //treat negative numbers as unknown quantity
result = "X copies of " + result; result = localizer.getMessage("lblXcopiesof") + " " + result;
} }
else if (qty != 1) { else if (qty != 1) {
result = qty + " copies of " + result; result = qty + " " + localizer.getMessage("lblcopiesof")+ " " + result;
} }
} }
return result; return result;
@@ -166,8 +169,9 @@ public final class SItemManagerUtil {
final boolean isDeckManager = itemManager.getGenericType().equals(DeckProxy.class); final boolean isDeckManager = itemManager.getGenericType().equals(DeckProxy.class);
final GroupDef[] groupByOptions = isDeckManager ? DECK_GROUPBY_OPTIONS : CARD_GROUPBY_OPTIONS; final GroupDef[] groupByOptions = isDeckManager ? DECK_GROUPBY_OPTIONS : CARD_GROUPBY_OPTIONS;
final ColumnDef[] pileByOptions = isDeckManager ? DECK_PILEBY_OPTIONS : CARD_PILEBY_OPTIONS; final ColumnDef[] pileByOptions = isDeckManager ? DECK_PILEBY_OPTIONS : CARD_PILEBY_OPTIONS;
cbGroupByOptions.addItem("(none)"); final Localizer localizer = Localizer.getInstance();
cbPileByOptions.addItem("(none)"); cbGroupByOptions.addItem("(" + localizer.getMessage("lblNone") + ")");
cbPileByOptions.addItem("(" + localizer.getMessage("lblNone") + ")");
for (final GroupDef option : groupByOptions) { for (final GroupDef option : groupByOptions) {
cbGroupByOptions.addItem(option); cbGroupByOptions.addItem(option);
} }

View File

@@ -19,6 +19,7 @@ import forge.game.GameFormat;
import forge.item.IPaperCard; import forge.item.IPaperCard;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.model.FModel; import forge.model.FModel;
import forge.properties.ForgePreferences;
import forge.util.MyRandom; import forge.util.MyRandom;
import java.util.*; import java.util.*;
@@ -206,22 +207,27 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase {
// 5. If there are still on-color cards, and the average cmc is low, add // 5. If there are still on-color cards, and the average cmc is low, add
// extras. // extras.
double avCMC = getAverageCMC(deckList); double avCMC = getAverageCMC(deckList);
int maxCMC = getMaxCMC(deckList); //calculated required lands based on https://www.channelfireball.com/articles/how-many-lands-do-you-need-to-consistently-hit-your-land-drops/
if (avCMC < 4) { float baseLandParameter = 16f;
addLowCMCCard(); //reduce landcount if filtered hands enabled
if (targetSize > 60) { if(FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.FILTERED_HANDS)){
addLowCMCCard(); baseLandParameter--;
} }
} landsNeeded = new Double((baseLandParameter + 3.14f * avCMC) * targetSize/60f).intValue();
if (avCMC < 3 && maxCMC < 6) { if (logToConsole) {
addLowCMCCard(); System.out.println("Required lands from linear regression : " + avCMC + " cmc, needed: " + landsNeeded);
} }
if (avCMC < 2.5 && maxCMC < 5) { numSpellsNeeded = targetSize-landsNeeded;
addLowCMCCard(); int extraCardsToAdd = numSpellsNeeded - deckList.size();
if (targetSize > 60) { if (logToConsole) {
System.out.println("Extra cards to add : " + extraCardsToAdd);
}
if(extraCardsToAdd>0){
for(int i=0; i<extraCardsToAdd; ++i){
addLowCMCCard(); addLowCMCCard();
} }
} }
if (logToConsole) { if (logToConsole) {
System.out.println("Post lowcoc : " + deckList.size()); System.out.println("Post lowcoc : " + deckList.size());
} }
@@ -237,6 +243,9 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase {
// 7. If there are still less than 22 non-land cards add off-color // 7. If there are still less than 22 non-land cards add off-color
// cards. This should be avoided. // cards. This should be avoided.
int stillNeeds = numSpellsNeeded - deckList.size(); int stillNeeds = numSpellsNeeded - deckList.size();
if (logToConsole) {
System.out.println("Still Needs? : " + stillNeeds);
}
if (stillNeeds > 0) if (stillNeeds > 0)
addCards(onColorCreaturesAndSpells, stillNeeds); addCards(onColorCreaturesAndSpells, stillNeeds);
stillNeeds = numSpellsNeeded - deckList.size(); stillNeeds = numSpellsNeeded - deckList.size();
@@ -274,12 +283,13 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase {
} }
} }
if (logToConsole) {
System.out.println("Lands needed : " + landsNeeded);
}
if (landsNeeded > 0) { if (landsNeeded > 0) {
addLands(clrCnts); addLands(clrCnts);
} }
if (logToConsole) { if (logToConsole) {
System.out.println("Lands needed : " + landsNeeded);
System.out.println("Post Lands : " + deckList.size()); System.out.println("Post Lands : " + deckList.size());
} }
addWastesIfRequired(); addWastesIfRequired();
@@ -345,8 +355,8 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase {
protected void generateTargetCMCs(){ protected void generateTargetCMCs(){
targetCMCs = new HashMap<>(); targetCMCs = new HashMap<>();
targetCMCs.put(1,Math.round((MyRandom.getRandom().nextInt(12)+4)*targetSize/60));//10 targetCMCs.put(1,Math.round((MyRandom.getRandom().nextInt(16)+2)*targetSize/60));//10
targetCMCs.put(2,Math.round((MyRandom.getRandom().nextInt(16)+8)*targetSize/60));//16 targetCMCs.put(2,Math.round((MyRandom.getRandom().nextInt(20)+6)*targetSize/60));//16
targetCMCs.put(3,Math.round((MyRandom.getRandom().nextInt(10)+8)*targetSize/60));//13 targetCMCs.put(3,Math.round((MyRandom.getRandom().nextInt(10)+8)*targetSize/60));//13
targetCMCs.put(4,Math.round((MyRandom.getRandom().nextInt(8)+6)*targetSize/60));//8 targetCMCs.put(4,Math.round((MyRandom.getRandom().nextInt(8)+6)*targetSize/60));//8
targetCMCs.put(5,Math.round((MyRandom.getRandom().nextInt(8)+6)*targetSize/60));//7 targetCMCs.put(5,Math.round((MyRandom.getRandom().nextInt(8)+6)*targetSize/60));//7
@@ -488,7 +498,7 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase {
aiPlayables.remove(card); aiPlayables.remove(card);
rankedColorList.remove(card); rankedColorList.remove(card);
landsNeeded--; //landsNeeded--;
if (logToConsole) { if (logToConsole) {
System.out.println("Low CMC: " + card.getName()); System.out.println("Low CMC: " + card.getName());
} }
@@ -681,7 +691,7 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase {
float p = (float) clrCnts[i] / (float) totalColor; float p = (float) clrCnts[i] / (float) totalColor;
int nLand = Math.round(landsNeeded * p); // desired truncation to int int nLand = Math.round(landsNeeded * p); // desired truncation to int
if (logToConsole) { if (logToConsole) {
System.out.printf("Basics[%s]: %d/%d = %f%% = %d cards%n", MagicColor.Constant.BASIC_LANDS.get(i), clrCnts[i], totalColor, 100*p, nLand); System.out.printf("Basics[%s]: %d/%d = %f%% = %d cards%n", MagicColor.Constant.BASIC_LANDS.get(i), clrCnts[i], totalColor, 100*p, nLand + 1);
} }
PaperCard snowLand = null; PaperCard snowLand = null;

View File

@@ -12,11 +12,24 @@ import java.util.*;
public class QuestChallengeGenerator { public class QuestChallengeGenerator {
public static QuestEventChallengeList generateChallenges(){ private GameFormat formatMedium=FModel.getFormats().getModern();
private GameFormat formatHard=FModel.getFormats().get("Legacy");
private GameFormat formatExpert=FModel.getFormats().get("Vintage");
private GameFormat baseFormat;
QuestChallengeGenerator(GameFormat baseFormat){
this.baseFormat=baseFormat;
if(baseFormat.getName().equals((FModel.getFormats().getModern().getName()))){
formatMedium=FModel.getFormats().get("Legacy");
formatHard=FModel.getFormats().get("Vintage");
}
}
public QuestEventChallengeList generateChallenges(){
Map<String,QuestEventChallenge> challenges = new HashMap<>(); Map<String,QuestEventChallenge> challenges = new HashMap<>();
int id = 0; int id = 0;
for (int i=0;i<5;++i) { for (int i=0;i<5;++i) {
QuestEventChallenge qc = getFormatChallenge(FModel.getFormats().getModern()); QuestEventChallenge qc = getFormatChallenge(formatMedium);
qc.setId(Integer.valueOf(id).toString()); qc.setId(Integer.valueOf(id).toString());
qc.setCreditsReward(1000); qc.setCreditsReward(1000);
qc.setWinsReqd(MyRandom.getRandom().nextInt(5)); qc.setWinsReqd(MyRandom.getRandom().nextInt(5));
@@ -36,7 +49,7 @@ public class QuestChallengeGenerator {
id++; id++;
} }
for (int i=0;i<5;++i) { for (int i=0;i<5;++i) {
QuestEventChallenge qc = getFormatChallenge(FModel.getFormats().get("Legacy")); QuestEventChallenge qc = getFormatChallenge(formatHard);
qc.setId(Integer.valueOf(id).toString()); qc.setId(Integer.valueOf(id).toString());
qc.setCreditsReward(5000); qc.setCreditsReward(5000);
qc.setCardReward("2 multicolor rares"); qc.setCardReward("2 multicolor rares");
@@ -56,7 +69,7 @@ public class QuestChallengeGenerator {
id++; id++;
} }
for (int i=0;i<5;++i) { for (int i=0;i<5;++i) {
QuestEventChallenge qc = getFormatChallenge(FModel.getFormats().get("Vintage")); QuestEventChallenge qc = getFormatChallenge(formatExpert);
qc.setId(Integer.valueOf(id).toString()); qc.setId(Integer.valueOf(id).toString());
qc.setCreditsReward(10000); qc.setCreditsReward(10000);
qc.setCardReward("3 multicolor rares"); qc.setCardReward("3 multicolor rares");
@@ -78,7 +91,7 @@ public class QuestChallengeGenerator {
return new QuestEventChallengeList(challenges); return new QuestEventChallengeList(challenges);
} }
public static QuestEventChallenge getFormatChallenge(GameFormat format){ public QuestEventChallenge getFormatChallenge(GameFormat format){
QuestEventChallenge qc = new QuestEventChallenge(); QuestEventChallenge qc = new QuestEventChallenge();
qc.setAiLife(20); qc.setAiLife(20);
@@ -92,11 +105,11 @@ public class QuestChallengeGenerator {
return qc; return qc;
} }
public static QuestEventChallenge getAIHeadstartChallenge(int extras){ public QuestEventChallenge getAIHeadstartChallenge(int extras){
QuestEventChallenge qc = new QuestEventChallenge(); QuestEventChallenge qc = new QuestEventChallenge();
qc.setAiLife(20); qc.setAiLife(20);
qc.setEventDeck(DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getStandard(),true)); qc.setEventDeck(DeckgenUtil.buildLDACArchetypeDeck(baseFormat,true));
qc.setTitle(qc.getEventDeck().getName() + " headstart challenge"); qc.setTitle(qc.getEventDeck().getName() + " headstart challenge");
qc.setName(qc.getEventDeck().getName() + " headstart challenge"); qc.setName(qc.getEventDeck().getName() + " headstart challenge");
qc.setOpponentName(qc.getEventDeck().getName()); qc.setOpponentName(qc.getEventDeck().getName());
@@ -117,7 +130,7 @@ public class QuestChallengeGenerator {
return qc; return qc;
} }
public static class QuestEventChallengeList implements IStorage<QuestEventChallenge>{ public class QuestEventChallengeList implements IStorage<QuestEventChallenge>{
private Map<String,QuestEventChallenge> challenges; private Map<String,QuestEventChallenge> challenges;

View File

@@ -446,7 +446,10 @@ public class QuestController {
if (world != null) { if (world != null) {
if (world.getName().equals(QuestWorld.STANDARDWORLDNAME)) { if (world.getName().equals(QuestWorld.STANDARDWORLDNAME)) {
this.duelManager = new QuestEventLDADuelManager(); this.duelManager = new QuestEventLDADuelManager(FModel.getFormats().getStandard());
return;
} else if (world.getName().equals(QuestWorld.MODERNWORLDNAME)) {
this.duelManager = new QuestEventLDADuelManager(FModel.getFormats().getModern());
return; return;
}else if (world.isCustom()) { }else if (world.isCustom()) {
path = world.getDuelsDir() == null ? ForgeConstants.DEFAULT_DUELS_DIR : ForgeConstants.USER_QUEST_WORLD_DIR + world.getDuelsDir(); path = world.getDuelsDir() == null ? ForgeConstants.DEFAULT_DUELS_DIR : ForgeConstants.USER_QUEST_WORLD_DIR + world.getDuelsDir();
@@ -475,7 +478,12 @@ public class QuestController {
if (world != null) { if (world != null) {
if (world.getName().equals(QuestWorld.STANDARDWORLDNAME)) { if (world.getName().equals(QuestWorld.STANDARDWORLDNAME)) {
allChallenges = QuestChallengeGenerator.generateChallenges(); QuestChallengeGenerator gen = new QuestChallengeGenerator(FModel.getFormats().getStandard());
allChallenges = gen.generateChallenges();
return;
}else if (world.getName().equals(QuestWorld.STANDARDWORLDNAME)) {
QuestChallengeGenerator gen = new QuestChallengeGenerator(FModel.getFormats().getModern());
allChallenges = gen.generateChallenges();
return; return;
} else if (world.isCustom()) { } else if (world.isCustom()) {
path = world.getChallengesDir() == null ? ForgeConstants.DEFAULT_CHALLENGES_DIR : ForgeConstants.USER_QUEST_WORLD_DIR + world.getChallengesDir(); path = world.getChallengesDir() == null ? ForgeConstants.DEFAULT_CHALLENGES_DIR : ForgeConstants.USER_QUEST_WORLD_DIR + world.getChallengesDir();

View File

@@ -20,7 +20,7 @@ package forge.quest;
import forge.deck.DeckgenUtil; import forge.deck.DeckgenUtil;
import forge.deck.io.Archetype; import forge.deck.io.Archetype;
import forge.model.FModel; import forge.game.GameFormat;
/** /**
* <p> * <p>
@@ -32,14 +32,16 @@ import forge.model.FModel;
public class QuestEventLDADuel extends QuestEventDuel { public class QuestEventLDADuel extends QuestEventDuel {
private Archetype archetype; private Archetype archetype;
private GameFormat baseFormat;
/** /**
* Instantiates a new quest duel. * Instantiates a new quest duel.
*/ */
public QuestEventLDADuel(Archetype archetype) { public QuestEventLDADuel(Archetype archetype, GameFormat baseFormat) {
super(); super();
this.baseFormat = baseFormat;
this.archetype = archetype; this.archetype = archetype;
this.eventDeck = DeckgenUtil.buildLDACArchetypeDeck(archetype, FModel.getFormats().getStandard(),true); this.eventDeck = DeckgenUtil.buildLDACArchetypeDeck(archetype, baseFormat,true);
} }
} }

View File

@@ -19,6 +19,7 @@ package forge.quest;
import forge.deck.CardArchetypeLDAGenerator; import forge.deck.CardArchetypeLDAGenerator;
import forge.deck.io.Archetype; import forge.deck.io.Archetype;
import forge.game.GameFormat;
import forge.model.FModel; import forge.model.FModel;
import forge.quest.data.QuestPreferences; import forge.quest.data.QuestPreferences;
import forge.quest.data.QuestPreferences.DifficultyPrefs; import forge.quest.data.QuestPreferences.DifficultyPrefs;
@@ -42,9 +43,11 @@ public class QuestEventLDADuelManager implements QuestEventDuelManagerInterface
private List<Archetype> archetypes; private List<Archetype> archetypes;
private final MapOfLists<QuestEventDifficulty, QuestEventDuel> sortedDuels = new EnumMapOfLists<>(QuestEventDifficulty.class, CollectionSuppliers.<QuestEventDuel>arrayLists()); private final MapOfLists<QuestEventDifficulty, QuestEventDuel> sortedDuels = new EnumMapOfLists<>(QuestEventDifficulty.class, CollectionSuppliers.<QuestEventDuel>arrayLists());
private GameFormat baseFormat;
public QuestEventLDADuelManager(){ public QuestEventLDADuelManager(GameFormat baseFormat){
archetypes = CardArchetypeLDAGenerator.ldaArchetypes.get(FModel.getFormats().getStandard().getName()); this.baseFormat = baseFormat;
archetypes = CardArchetypeLDAGenerator.ldaArchetypes.get(baseFormat.getName());
assembleDuelDifficultyLists(); assembleDuelDifficultyLists();
} }
@@ -58,7 +61,7 @@ public class QuestEventLDADuelManager implements QuestEventDuelManagerInterface
int i=0; int i=0;
for(Archetype archetype : archetypes){ for(Archetype archetype : archetypes){
QuestEventLDADuel duel = new QuestEventLDADuel((archetype)); QuestEventLDADuel duel = new QuestEventLDADuel(archetype,baseFormat);
duel.setDescription("Randomly generated "+archetype.getName()+" archetype deck."); duel.setDescription("Randomly generated "+archetype.getName()+" archetype deck.");
duel.setName(archetype.getName()); duel.setName(archetype.getName());
duel.setTitle(archetype.getName()); duel.setTitle(archetype.getName());

View File

@@ -40,6 +40,7 @@ public class QuestWorld implements Comparable<QuestWorld>{
private final String dir; private final String dir;
private final GameFormatQuest format; private final GameFormatQuest format;
public static final String STANDARDWORLDNAME = "Random Standard"; public static final String STANDARDWORLDNAME = "Random Standard";
public static final String MODERNWORLDNAME = "Random Modern";
public static final String RANDOMCOMMANDERWORLDNAME = "Random Commander"; public static final String RANDOMCOMMANDERWORLDNAME = "Random Commander";
private boolean isCustom; private boolean isCustom;
@@ -194,6 +195,12 @@ public class QuestWorld implements Comparable<QuestWorld>{
FModel.getFormats().getStandard().getBannedCardNames(),false); FModel.getFormats().getStandard().getBannedCardNames(),false);
} }
if (useName.equalsIgnoreCase(QuestWorld.MODERNWORLDNAME)){
useFormat = new GameFormatQuest(QuestWorld.MODERNWORLDNAME,
FModel.getFormats().getModern().getAllowedSetCodes(),
FModel.getFormats().getModern().getBannedCardNames(),false);
}
if (useName.equalsIgnoreCase(QuestWorld.RANDOMCOMMANDERWORLDNAME)){ if (useName.equalsIgnoreCase(QuestWorld.RANDOMCOMMANDERWORLDNAME)){
useFormat = new GameFormatQuest(QuestWorld.RANDOMCOMMANDERWORLDNAME, useFormat = new GameFormatQuest(QuestWorld.RANDOMCOMMANDERWORLDNAME,
FModel.getFormats().getFormat("Commander").getAllowedSetCodes(), FModel.getFormats().getFormat("Commander").getAllowedSetCodes(),