Add menu item for setting Oathbreaker

Allow double-tapping to set Commander or Oathbreaker if one hasn't yet been set
This commit is contained in:
Dan Demp
2019-08-20 04:34:14 +00:00
committed by Michael Kamensky
parent ce96e64edb
commit f1e0158102
64 changed files with 1227 additions and 542 deletions

View File

@@ -36,6 +36,8 @@ public class StaticData {
private Predicate<PaperCard> standardPredicate; private Predicate<PaperCard> standardPredicate;
private Predicate<PaperCard> brawlPredicate; private Predicate<PaperCard> brawlPredicate;
private Predicate<PaperCard> modernPredicate; private Predicate<PaperCard> modernPredicate;
private Predicate<PaperCard> commanderPredicate;
private Predicate<PaperCard> oathbreakerPredicate;
private boolean filteredHandsEnabled = false; private boolean filteredHandsEnabled = false;
@@ -201,17 +203,23 @@ public class StaticData {
public void setStandardPredicate(Predicate<PaperCard> standardPredicate) { this.standardPredicate = standardPredicate; } public void setStandardPredicate(Predicate<PaperCard> standardPredicate) { this.standardPredicate = standardPredicate; }
public void setBrawlPredicate(Predicate<PaperCard> brawlPredicate) { this.brawlPredicate = brawlPredicate; }
public void setModernPredicate(Predicate<PaperCard> modernPredicate) { this.modernPredicate = standardPredicate; } public void setModernPredicate(Predicate<PaperCard> modernPredicate) { this.modernPredicate = standardPredicate; }
public void setCommanderPredicate(Predicate<PaperCard> commanderPredicate) { this.commanderPredicate = commanderPredicate; }
public void setOathbreakerPredicate(Predicate<PaperCard> oathbreakerPredicate) { this.oathbreakerPredicate = oathbreakerPredicate; }
public void setBrawlPredicate(Predicate<PaperCard> brawlPredicate) { this.brawlPredicate = brawlPredicate; }
public Predicate<PaperCard> getModernPredicate() { public Predicate<PaperCard> getModernPredicate() {
return modernPredicate; return modernPredicate;
} }
public Predicate<PaperCard> getBrawlPredicate() { public Predicate<PaperCard> getCommanderPredicate() { return commanderPredicate; }
return brawlPredicate;
} public Predicate<PaperCard> getOathbreakerPredicate() { return oathbreakerPredicate; }
public Predicate<PaperCard> getBrawlPredicate() { return brawlPredicate; }
public void setFilteredHandsEnabled(boolean filteredHandsEnabled){ public void setFilteredHandsEnabled(boolean filteredHandsEnabled){
this.filteredHandsEnabled = filteredHandsEnabled; this.filteredHandsEnabled = filteredHandsEnabled;

View File

@@ -219,7 +219,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
if (upcomingSet != null) { if (upcomingSet != null) {
addCard(new PaperCard(cr, upcomingSet.getCode(), CardRarity.Unknown, 1)); addCard(new PaperCard(cr, upcomingSet.getCode(), CardRarity.Unknown, 1));
} else { } else {
System.err.println("The card " + cr.getName() + " was not assigned to any set. Adding it to UNKNOWN set... to fix see res/cardeditions/ folder. "); System.err.println("The card " + cr.getName() + " was not assigned to any set. Adding it to UNKNOWN set... to fix see res/editions/ folder. ");
addCard(new PaperCard(cr, CardEdition.UNKNOWN.getCode(), CardRarity.Special, 1)); addCard(new PaperCard(cr, CardEdition.UNKNOWN.getCode(), CardRarity.Special, 1));
} }
} }

View File

@@ -210,6 +210,16 @@ public final class CardRules implements ICardCharacteristics {
return canBeCommander() && (hasKeyword("Partner") || !this.partnerWith.isEmpty()); return canBeCommander() && (hasKeyword("Partner") || !this.partnerWith.isEmpty());
} }
public boolean canBeOathbreaker() {
CardType type = mainPart.getType();
return type.isPlaneswalker();
}
public boolean canBeSignatureSpell() {
CardType type = mainPart.getType();
return type.isInstant() || type.isSorcery();
}
public boolean canBeBrawlCommander() { public boolean canBeBrawlCommander() {
CardType type = mainPart.getType(); CardType type = mainPart.getType();
return (type.isLegendary() && type.isCreature()) || type.isPlaneswalker(); return (type.isLegendary() && type.isCreature()) || type.isPlaneswalker();
@@ -219,7 +229,7 @@ public final class CardRules implements ICardCharacteristics {
return meldWith; return meldWith;
} }
public String getParterWith() { public String getPartnerWith() {
return partnerWith; return partnerWith;
} }

View File

@@ -570,6 +570,19 @@ public final class CardRulesPredicates {
} }
}; };
public static final Predicate<CardRules> CAN_BE_OATHBREAKER = new Predicate<CardRules>() {
@Override
public boolean apply(final CardRules subject) {
return subject.canBeOathbreaker();
}
};
public static final Predicate<CardRules> CAN_BE_SIGNATURE_SPELL = new Predicate<CardRules>() {
@Override
public boolean apply(final CardRules subject) {
return subject.canBeSignatureSpell();
}
};
public static final Predicate<CardRules> IS_PLANESWALKER = CardRulesPredicates.coreType(true, CardType.CoreType.Planeswalker); public static final Predicate<CardRules> IS_PLANESWALKER = CardRulesPredicates.coreType(true, CardType.CoreType.Planeswalker);
public static final Predicate<CardRules> IS_INSTANT = CardRulesPredicates.coreType(true, CardType.CoreType.Instant); public static final Predicate<CardRules> IS_INSTANT = CardRulesPredicates.coreType(true, CardType.CoreType.Instant);
public static final Predicate<CardRules> IS_SORCERY = CardRulesPredicates.coreType(true, CardType.CoreType.Sorcery); public static final Predicate<CardRules> IS_SORCERY = CardRulesPredicates.coreType(true, CardType.CoreType.Sorcery);

View File

@@ -122,9 +122,45 @@ public class Deck extends DeckBase implements Iterable<Entry<DeckSection, CardPo
for (final Entry<PaperCard, Integer> c : cp) { for (final Entry<PaperCard, Integer> c : cp) {
result.add(c.getKey()); result.add(c.getKey());
} }
if (result.size() > 1) { //sort by type so signature spell comes after oathbreaker
Collections.sort(result, new Comparator<PaperCard>() {
@Override
public int compare(final PaperCard c1, final PaperCard c2) {
return Boolean.compare(c1.getRules().canBeSignatureSpell(), c2.getRules().canBeSignatureSpell());
}
});
}
return result; return result;
} }
//at least for now, Oathbreaker will only support one oathbreaker and one signature spell
public PaperCard getOathbreaker() {
final CardPool cp = get(DeckSection.Commander);
if (cp == null) {
return null;
}
for (final Entry<PaperCard, Integer> c : cp) {
PaperCard card = c.getKey();
if (card.getRules().canBeOathbreaker()) {
return card;
}
}
return null;
}
public PaperCard getSignatureSpell() {
final CardPool cp = get(DeckSection.Commander);
if (cp == null) {
return null;
}
for (final Entry<PaperCard, Integer> c : cp) {
PaperCard card = c.getKey();
if (card.getRules().canBeSignatureSpell()) {
return card;
}
}
return null;
}
// may return nulls // may return nulls
public CardPool get(DeckSection deckSection) { public CardPool get(DeckSection deckSection) {
loadDeferredSections(); loadDeferredSections();

View File

@@ -48,48 +48,25 @@ public enum DeckFormat {
Constructed ( Range.between(60, Integer.MAX_VALUE), Range.between(0, 15), 4), Constructed ( Range.between(60, Integer.MAX_VALUE), Range.between(0, 15), 4),
QuestDeck ( Range.between(40, Integer.MAX_VALUE), Range.between(0, 15), 4), QuestDeck ( Range.between(40, Integer.MAX_VALUE), Range.between(0, 15), 4),
Limited ( Range.between(40, Integer.MAX_VALUE), null, Integer.MAX_VALUE), Limited ( Range.between(40, Integer.MAX_VALUE), null, Integer.MAX_VALUE),
Commander ( Range.is(99), Range.between(0, 10), 1, new Predicate<CardRules>() { Commander ( Range.is(99), Range.between(0, 10), 1, null, new Predicate<PaperCard>() {
private final Set<String> bannedCards = ImmutableSet.of(
"Adriana's Valor", "Advantageous Proclamation", "Amulet of Quoz", "Ancestral Recall", "Assemble the Rank and Vile",
"Backup Plan", "Balance", "Biorhythm", "Black Lotus", "Brago's Favor", "Braids, Cabal Minion", "Bronze Tablet",
"Channel", "Chaos Orb", "Coalition Victory", "Contract from Below", "Darkpact", "Demonic Attorney", "Double Stroke",
"Echoing Boon", "Emissary's Ploy", "Emrakul, the Aeons Torn", "Erayo, Soratami Ascendant", "Falling Star",
"Fastbond", "Gifts Ungiven", "Griselbrand", "Hired Heist", "Hold the Perimeter", "Hymn of the Wilds", "Immediate Action",
"Incendiary Dissent", "Iterative Analysis", "Jeweled Bird", "Karakas", "Leovold, Emissary of Trest", "Library of Alexandria",
"Limited Resources", "Mox Emerald", "Mox Jet", "Mox Pearl", "Mox Ruby", "Mox Sapphire", "Muzzio's Preparations",
"Natural Unity", "Painter's Servant", "Panoptic Mirror", "Power Play", "Primeval Titan", "Prophet of Kruphix",
"Rebirth", "Recurring Nightmare", "Rofellos, Llanowar Emissary", "Secret Summoning", "Secrets of Paradise",
"Sentinel Dispatch", "Shahrazad", "Sovereign's Realm", "Summoner's Bond", "Sundering Titan", "Sway of the Stars",
"Sylvan Primordial", "Tempest Efreet", "Time Vault", "Time Walk", "Timmerian Fiends", "Tinker", "Tolarian Academy",
"Trade Secrets", "Unexpected Potential", "Upheaval", "Weight Advantage", "Worldfire", "Worldknit", "Yawgmoth's Bargain");
@Override @Override
public boolean apply(CardRules rules) { public boolean apply(PaperCard card) {
if (bannedCards.contains(rules.getName())) { return StaticData.instance().getCommanderPredicate().apply(card);
return false; }
} }),
return true; Oathbreaker ( Range.is(58), Range.between(0, 10), 1, null, new Predicate<PaperCard>() {
@Override
public boolean apply(PaperCard card) {
return StaticData.instance().getOathbreakerPredicate().apply(card);
} }
}), }),
Pauper ( Range.is(60), Range.between(0, 10), 1), Pauper ( Range.is(60), Range.between(0, 10), 1),
Brawl ( Range.is(59), Range.between(0, 15), 1, null, new Predicate<PaperCard>() { Brawl ( Range.is(59), Range.between(0, 15), 1, null, new Predicate<PaperCard>() {
private final Set<String> bannedCards = ImmutableSet.of(
"Baral, Chief of Compliance","Smuggler's Copter","Sorcerous Spyglass");
@Override @Override
public boolean apply(PaperCard card) { public boolean apply(PaperCard card) {
//why do we need to hard code the bannings here - they are defined in the GameFormat predicate used below return StaticData.instance().getBrawlPredicate().apply(card);
if (bannedCards.contains(card.getName())) {
return false;
}
return StaticData.instance() == null ? false : StaticData.instance().getBrawlPredicate().apply(card);
} }
}) { }),
private final Set<String> bannedCommanders = ImmutableSet.of("Baral, Chief of Compliance");
@Override
public boolean isLegalCommander(CardRules rules) {
return super.isLegalCommander(rules) && !bannedCommanders.contains(rules.getName());
}
},
TinyLeaders ( Range.is(49), Range.between(0, 10), 1, new Predicate<CardRules>() { TinyLeaders ( Range.is(49), Range.between(0, 10), 1, new Predicate<CardRules>() {
private final Set<String> bannedCards = ImmutableSet.of( private final Set<String> bannedCards = ImmutableSet.of(
"Ancestral Recall", "Balance", "Black Lotus", "Black Vise", "Channel", "Chaos Orb", "Contract From Below", "Counterbalance", "Darkpact", "Demonic Attorney", "Demonic Tutor", "Earthcraft", "Edric, Spymaster of Trest", "Falling Star", "Ancestral Recall", "Balance", "Black Lotus", "Black Vise", "Channel", "Chaos Orb", "Contract From Below", "Counterbalance", "Darkpact", "Demonic Attorney", "Demonic Tutor", "Earthcraft", "Edric, Spymaster of Trest", "Falling Star",
@@ -167,8 +144,12 @@ public enum DeckFormat {
cardPoolFilter = null; cardPoolFilter = null;
} }
private boolean hasCommander() { public boolean hasCommander() {
return this == Commander || this == TinyLeaders || this == Brawl; return this == Commander || this == Oathbreaker || this == TinyLeaders || this == Brawl;
}
public boolean hasSignatureSpell() {
return this == Oathbreaker;
} }
/** /**
@@ -232,41 +213,56 @@ public enum DeckFormat {
noBasicLands = conspiracies.countByName(SOVREALM, false) > 0; noBasicLands = conspiracies.countByName(SOVREALM, false) > 0;
} }
if (hasCommander()) { // 1 Commander, or 2 Partner Commanders if (hasCommander()) {
final List<PaperCard> commanders = deck.getCommanders();
if (commanders.isEmpty()) {
return "is missing a commander";
}
if (commanders.size() > 2) {
return "too many commanders";
}
byte cmdCI = 0; byte cmdCI = 0;
for (PaperCard pc : commanders) { if (equals(DeckFormat.Oathbreaker)) { // 1 Oathbreaker and 1 Signature Spell
if (!isLegalCommander(pc.getRules())) { PaperCard oathbreaker = deck.getOathbreaker();
return "has an illegal commander"; if (oathbreaker == null) {
return "is missing an oathbreaker";
} }
cmdCI |= pc.getRules().getColorIdentity().getColor(); if (deck.getSignatureSpell() == null) {
return "is missing a signature spell";
}
if (deck.getCommanders().size() > 2) {
return "has too many commanders";
}
cmdCI = oathbreaker.getRules().getColorIdentity().getColor();
} }
else { // 1 Commander or 2 Partner Commanders
final List<PaperCard> commanders = deck.getCommanders();
// special check for Partner if (commanders.isEmpty()) {
if (commanders.size() == 2) { return "is missing a commander";
// two commander = 98 cards }
min--;
max--;
PaperCard a = commanders.get(0); if (commanders.size() > 2) {
PaperCard b = commanders.get(1); return "has too many commanders";
}
if (a.getRules().hasKeyword("Partner") && b.getRules().hasKeyword("Partner")) { for (PaperCard pc : commanders) {
// normal partner commander if (!isLegalCommander(pc.getRules())) {
} else if (a.getName().equals(b.getRules().getParterWith()) return "has an illegal commander";
&& b.getName().equals(a.getRules().getParterWith())) { }
// paired partner commander cmdCI |= pc.getRules().getColorIdentity().getColor();
} else { }
return "has an illegal commander partnership";
// special check for Partner
if (commanders.size() == 2) {
// two commander = 98 cards
min--;
max--;
PaperCard a = commanders.get(0);
PaperCard b = commanders.get(1);
if (a.getRules().hasKeyword("Partner") && b.getRules().hasKeyword("Partner")) {
// normal partner commander
} else if (a.getName().equals(b.getRules().getPartnerWith())
&& b.getName().equals(a.getRules().getPartnerWith())) {
// paired partner commander
} else {
return "has an illegal commander partnership";
}
} }
} }
@@ -443,7 +439,10 @@ public enum DeckFormat {
if (cardPoolFilter != null && !cardPoolFilter.apply(rules)) { if (cardPoolFilter != null && !cardPoolFilter.apply(rules)) {
return false; return false;
} }
if(this.equals(DeckFormat.Brawl)) { if (this.equals(DeckFormat.Oathbreaker)) {
return rules.canBeOathbreaker();
}
if (this.equals(DeckFormat.Brawl)) {
return rules.canBeBrawlCommander(); return rules.canBeBrawlCommander();
} }
return rules.canBeCommander(); return rules.canBeCommander();
@@ -505,19 +504,17 @@ public enum DeckFormat {
public Predicate<PaperCard> isLegalCardForCommanderPredicate(List<PaperCard> commanders) { public Predicate<PaperCard> isLegalCardForCommanderPredicate(List<PaperCard> commanders) {
byte cmdCI = 0; byte cmdCI = 0;
boolean hasPartner = false;
for (final PaperCard p : commanders) { for (final PaperCard p : commanders) {
cmdCI |= p.getRules().getColorIdentity().getColor(); cmdCI |= p.getRules().getColorIdentity().getColor();
if (p.getRules().canBePartnerCommander()) {
hasPartner = true;
}
} }
return Predicates.compose(CardRulesPredicates.hasColorIdentity(cmdCI), PaperCard.FN_GET_RULES); Predicate<CardRules> predicate = CardRulesPredicates.hasColorIdentity(cmdCI);
} if (hasPartner) { //also show available partners a commander can have a partner
predicate = Predicates.or(predicate, CardRulesPredicates.Presets.CAN_BE_PARTNER_COMMANDER);
public Predicate<PaperCard> isLegalCardForCommanderOrLegalPartnerPredicate(List<PaperCard> commanders) {
byte cmdCI = 0;
for (final PaperCard p : commanders) {
cmdCI |= p.getRules().getColorIdentity().getColor();
} }
// TODO : check commander what kind of Partner it needs return Predicates.compose(predicate, PaperCard.FN_GET_RULES);
return Predicates.compose(Predicates.or(CardRulesPredicates.hasColorIdentity(cmdCI),
CardRulesPredicates.Presets.CAN_BE_PARTNER_COMMANDER), PaperCard.FN_GET_RULES);
} }
} }

View File

@@ -296,7 +296,7 @@ public class GameFormat implements Comparable<GameFormat> {
coreFormats.add("Commander.txt"); coreFormats.add("Commander.txt");
coreFormats.add("Extended.txt"); coreFormats.add("Extended.txt");
coreFormats.add("Brawl.txt"); coreFormats.add("Brawl.txt");
coreFormats.add("Oathbreaker.txt");
} }
public Reader(File forgeFormats, File customFormats, boolean includeHistoric) { public Reader(File forgeFormats, File customFormats, boolean includeHistoric) {

View File

@@ -88,6 +88,7 @@ public class GameRules {
public boolean hasCommander() { public boolean hasCommander() {
return appliedVariants.contains(GameType.Commander) return appliedVariants.contains(GameType.Commander)
|| appliedVariants.contains(GameType.Oathbreaker)
|| appliedVariants.contains(GameType.TinyLeaders) || appliedVariants.contains(GameType.TinyLeaders)
|| appliedVariants.contains(GameType.Brawl); || appliedVariants.contains(GameType.Brawl);
} }

View File

@@ -24,6 +24,7 @@ public enum GameType {
DeckManager (DeckFormat.Constructed, false, true, true, "lblDeckManager", ""), DeckManager (DeckFormat.Constructed, false, true, true, "lblDeckManager", ""),
Vanguard (DeckFormat.Vanguard, true, true, true, "lblVanguard", "lblVanguardDesc"), Vanguard (DeckFormat.Vanguard, true, true, true, "lblVanguard", "lblVanguardDesc"),
Commander (DeckFormat.Commander, false, false, false, "lblCommander", "lblCommanderDesc"), Commander (DeckFormat.Commander, false, false, false, "lblCommander", "lblCommanderDesc"),
Oathbreaker (DeckFormat.Oathbreaker, false, false, false, "lblOathbreaker", "lblOathbreakerDesc"),
TinyLeaders (DeckFormat.TinyLeaders, false, false, false, "lblTinyLeaders", "lblTinyLeadersDesc"), TinyLeaders (DeckFormat.TinyLeaders, false, false, false, "lblTinyLeaders", "lblTinyLeadersDesc"),
Brawl (DeckFormat.Brawl, false, false, false, "lblBrawl", "lblBrawlDesc"), Brawl (DeckFormat.Brawl, false, false, false, "lblBrawl", "lblBrawlDesc"),
Planeswalker (DeckFormat.PlanarConquest, false, false, true, "lblPlaneswalker", "lblPlaneswalkerDesc"), Planeswalker (DeckFormat.PlanarConquest, false, false, true, "lblPlaneswalker", "lblPlaneswalkerDesc"),
@@ -126,6 +127,7 @@ public enum GameType {
/*switch (this) { /*switch (this) {
case Archenemy: case Archenemy:
case Commander: case Commander:
case Oathbreaker:
case TinyLeaders: case TinyLeaders:
case Planechase: case Planechase:
case Vanguard: case Vanguard:

View File

@@ -7,6 +7,7 @@ import forge.card.*;
import forge.card.mana.ManaCost; import forge.card.mana.ManaCost;
import forge.game.Direction; import forge.game.Direction;
import forge.game.GameEntityView; import forge.game.GameEntityView;
import forge.game.GameType;
import forge.game.combat.Combat; import forge.game.combat.Combat;
import forge.game.keyword.Keyword; import forge.game.keyword.Keyword;
import forge.game.player.Player; import forge.game.player.Player;
@@ -195,7 +196,29 @@ public class CardView extends GameEntityView {
return get(TrackableProperty.IsCommander); return get(TrackableProperty.IsCommander);
} }
void updateCommander(Card c) { void updateCommander(Card c) {
set(TrackableProperty.IsCommander, c.isCommander()); boolean isCommander = c.isCommander();
set(TrackableProperty.IsCommander, isCommander);
if (c.getGame().getRules().hasAppliedVariant(GameType.Oathbreaker)) {
//store alternate type for oathbreaker or signature spell for display in card text
if (isCommander) {
if (c.getPaperCard().getRules().canBeSignatureSpell()) {
set(TrackableProperty.CommanderAltType, "Signature Spell");
}
else {
set(TrackableProperty.CommanderAltType, "Oathbreaker");
}
}
else {
set(TrackableProperty.CommanderAltType, null);
}
}
}
public String getCommanderType() {
String type = get(TrackableProperty.CommanderAltType);
if (type == null) {
type = "Commander";
}
return type;
} }
public Map<CounterType, Integer> getCounters() { public Map<CounterType, Integer> getCounters() {
@@ -542,7 +565,7 @@ public class CardView extends GameEntityView {
sb.append(rulesText).append("\r\n\r\n"); sb.append(rulesText).append("\r\n\r\n");
} }
if (isCommander()) { if (isCommander()) {
sb.append(getOwner()).append("'s Commander\r\n"); sb.append(getOwner()).append("'s " + getCommanderType() + "\r\n");
sb.append(getOwner().getCommanderInfo(this)).append("\r\n"); sb.append(getOwner().getCommanderInfo(this)).append("\r\n");
} }

View File

@@ -598,9 +598,11 @@ public class Player extends GameEntity implements Comparable<Player> {
} }
} }
//Tiny Leaders and Brawl ignore commander damage rule. //Oathbreaker, Tiny Leaders, and Brawl ignore commander damage rule
if (source.isCommander() && isCombat && this.getGame().getRules().getGameType() != GameType.TinyLeaders if (source.isCommander() && isCombat
&& this.getGame().getRules().getGameType() != GameType.Brawl) { && !this.getGame().getRules().hasAppliedVariant(GameType.Oathbreaker)
&& !this.getGame().getRules().hasAppliedVariant(GameType.TinyLeaders)
&& !this.getGame().getRules().hasAppliedVariant(GameType.Brawl)) {
commanderDamage.put(source, getCommanderDamage(source) + amount); commanderDamage.put(source, getCommanderDamage(source) + amount);
view.updateCommanderDamage(this); view.updateCommanderDamage(this);
} }
@@ -2641,9 +2643,9 @@ public class Player extends GameEntity implements Comparable<Player> {
public List<Card> getCommanders() { public List<Card> getCommanders() {
return commanders; return commanders;
} }
public void setCommanders(List<Card> commander0) { public void setCommanders(List<Card> commanders0) {
if (commander0 == commanders) { return; } if (commanders0 == commanders) { return; }
commanders = commander0; commanders = commanders0;
view.updateCommander(this); view.updateCommander(this);
} }
@@ -2767,15 +2769,30 @@ public class Player extends GameEntity implements Comparable<Player> {
final String name = Lang.getPossesive(commander.getName()) + " Commander Effect"; final String name = Lang.getPossesive(commander.getName()) + " Commander Effect";
DetachedCardEffect eff = new DetachedCardEffect(commander, name); DetachedCardEffect eff = new DetachedCardEffect(commander, name);
eff.setSVar("CommanderMoveReplacement", "DB$ ChangeZone | Origin$ Battlefield,Graveyard,Exile,Library,Hand | Destination$ Command | Defined$ ReplacedCard"); if (game.getRules().hasAppliedVariant(GameType.Oathbreaker) && commander.getRules().canBeSignatureSpell()) {
//signature spells can only reside on the stack or in the command zone
eff.setSVar("SignatureSpellMoveReplacement", "DB$ ChangeZone | Origin$ Stack | Destination$ Command | Defined$ ReplacedCard");
String moved = "Event$ Moved | ValidCard$ Card.EffectSource+YouOwn | Secondary$ True | Optional$ True | OptionalDecider$ You | ReplaceWith$ CommanderMoveReplacement "; String moved = "Event$ Moved | ValidCard$ Card.EffectSource+YouOwn | Secondary$ True | ReplaceWith$ SignatureSpellMoveReplacement | Destination$ Graveyard,Exile,Hand,Library | " +
if (game.getRules().hasAppliedVariant(GameType.TinyLeaders)) { "Description$ If a signature spell would be put into another zone from the stack, put it into the command zone instead.";
moved += " | Destination$ Graveyard,Exile | Description$ If a commander would be put into its owner's graveyard or exile from anywhere, that player may put it into the command zone instead."; eff.addReplacementEffect(ReplacementHandler.parseReplacement(moved, eff, true));
} else {
moved += " | Destination$ Graveyard,Exile,Hand,Library | Description$ If a commander would be exiled or put into hand, graveyard, or library from anywhere, that player may put it into the command zone instead."; //signature spells can only be cast if your oathbreaker is in on the battlefield under your control
String castRestriction = "Mode$ CantBeCast | ValidCard$ Card.EffectSource+YouOwn | EffectZone$ Command | IsPresent$ Card.IsCommander+YouOwn+YouCtrl | PresentZone$ Battlefield | PresentCompare$ EQ0 | " +
"Description$ Signature spell can only be cast if your oathbreaker is on the battlefield under your control.";
eff.addStaticAbility(castRestriction);
}
else {
eff.setSVar("CommanderMoveReplacement", "DB$ ChangeZone | Origin$ Battlefield,Graveyard,Exile,Library,Hand | Destination$ Command | Defined$ ReplacedCard");
String moved = "Event$ Moved | ValidCard$ Card.EffectSource+YouOwn | Secondary$ True | Optional$ True | OptionalDecider$ You | ReplaceWith$ CommanderMoveReplacement ";
if (game.getRules().hasAppliedVariant(GameType.TinyLeaders)) {
moved += " | Destination$ Graveyard,Exile | Description$ If a commander would be put into its owner's graveyard or exile from anywhere, that player may put it into the command zone instead.";
} else {
moved += " | Destination$ Graveyard,Exile,Hand,Library | Description$ If a commander would be exiled or put into hand, graveyard, or library from anywhere, that player may put it into the command zone instead.";
}
eff.addReplacementEffect(ReplacementHandler.parseReplacement(moved, eff, true));
} }
eff.addReplacementEffect(ReplacementHandler.parseReplacement(moved, eff, true));
String mayBePlayedAbility = "Mode$ Continuous | EffectZone$ Command | MayPlay$ True | Affected$ Card.YouOwn+EffectSource | AffectedZone$ Command"; String mayBePlayedAbility = "Mode$ Continuous | EffectZone$ Command | MayPlay$ True | Affected$ Card.YouOwn+EffectSource | AffectedZone$ Command";
if (game.getRules().hasAppliedVariant(GameType.Planeswalker)) { //support paying for Planeswalker with any color mana if (game.getRules().hasAppliedVariant(GameType.Planeswalker)) { //support paying for Planeswalker with any color mana

View File

@@ -120,7 +120,10 @@ public class RegisteredPlayer {
start.setStartingLife(start.getStartingLife() + 20); // 903.7: ...each player sets his or her life total to 40 start.setStartingLife(start.getStartingLife() + 20); // 903.7: ...each player sets his or her life total to 40
// Modified for layering of variants to life +20 // Modified for layering of variants to life +20
} }
if (appliedVariants.contains(GameType.TinyLeaders)) { if (appliedVariants.contains(GameType.Oathbreaker)) {
start.commanders = deck.getCommanders();
}
if (appliedVariants.contains(GameType.TinyLeaders)) {
start.commanders = deck.getCommanders(); start.commanders = deck.getCommanders();
start.setStartingLife(start.getStartingLife() + 5); start.setStartingLife(start.getStartingLife() + 5);
} }

View File

@@ -20,6 +20,7 @@ package forge.game.zone;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import forge.game.Game; import forge.game.Game;
import forge.game.GameType;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.card.CardCollection; import forge.game.card.CardCollection;
import forge.game.card.CardCollectionView; import forge.game.card.CardCollectionView;
@@ -80,7 +81,7 @@ public class Zone implements java.io.Serializable, Iterable<Card> {
add(c, index, null); add(c, index, null);
} }
public void add(final Card c, final Integer index, final Card latestState) { public void add(final Card c, Integer index, final Card latestState) {
if (index != null && cardList.isEmpty() && index.intValue() > 0) { if (index != null && cardList.isEmpty() && index.intValue() > 0) {
// something went wrong, most likely the method fired when the game was in an unexpected state // something went wrong, most likely the method fired when the game was in an unexpected state
// (e.g. conceding during the mana payment prompt) // (e.g. conceding during the mana payment prompt)
@@ -88,6 +89,15 @@ public class Zone implements java.io.Serializable, Iterable<Card> {
return; return;
} }
//ensure commander returns to being first card in command zone
if (index == null && zoneType == ZoneType.Command && c.isCommander()) {
index = 0;
if (game.getRules().hasAppliedVariant(GameType.Oathbreaker) && c.getRules().canBeSignatureSpell()
&& !cardList.isEmpty() && cardList.get(0).isCommander()) {
index = 1; //signature spell should return to being second card in command zone if oathbreaker is there too
}
}
// Immutable cards are usually emblems and effects // Immutable cards are usually emblems and effects
if (!c.isImmutable()) { if (!c.isImmutable()) {
final Zone oldZone = game.getZoneOf(c); final Zone oldZone = game.getZoneOf(c);

View File

@@ -37,6 +37,7 @@ public enum TrackableProperty {
Tapped(TrackableTypes.BooleanType), Tapped(TrackableTypes.BooleanType),
Token(TrackableTypes.BooleanType), Token(TrackableTypes.BooleanType),
IsCommander(TrackableTypes.BooleanType), IsCommander(TrackableTypes.BooleanType),
CommanderAltType(TrackableTypes.StringType),
Damage(TrackableTypes.IntegerType), Damage(TrackableTypes.IntegerType),
AssignedDamage(TrackableTypes.IntegerType), AssignedDamage(TrackableTypes.IntegerType),
ShieldCount(TrackableTypes.IntegerType), ShieldCount(TrackableTypes.IntegerType),

View File

@@ -136,14 +136,22 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
private void updateCustom() { private void updateCustom() {
DeckFormat deckFormat = lstDecks.getGameType().getDeckFormat(); DeckFormat deckFormat = lstDecks.getGameType().getDeckFormat();
if(deckFormat.equals(DeckFormat.Commander)){ switch (deckFormat) {
case Commander:
updateDecks(DeckProxy.getAllCommanderDecks(), ItemManagerConfig.COMMANDER_DECKS); updateDecks(DeckProxy.getAllCommanderDecks(), ItemManagerConfig.COMMANDER_DECKS);
}else if(deckFormat.equals(DeckFormat.TinyLeaders)){ break;
updateDecks(DeckProxy.getAllTinyLeadersDecks(), ItemManagerConfig.COMMANDER_DECKS); case Oathbreaker:
}else if(deckFormat.equals(DeckFormat.Brawl)){ updateDecks(DeckProxy.getAllOathbreakerDecks(), ItemManagerConfig.COMMANDER_DECKS);
break;
case Brawl:
updateDecks(DeckProxy.getAllBrawlDecks(), ItemManagerConfig.COMMANDER_DECKS); updateDecks(DeckProxy.getAllBrawlDecks(), ItemManagerConfig.COMMANDER_DECKS);
}else { break;
case TinyLeaders:
updateDecks(DeckProxy.getAllTinyLeadersDecks(), ItemManagerConfig.COMMANDER_DECKS);
break;
default:
updateDecks(DeckProxy.getAllConstructedDecks(), ItemManagerConfig.CONSTRUCTED_DECKS); updateDecks(DeckProxy.getAllConstructedDecks(), ItemManagerConfig.CONSTRUCTED_DECKS);
break;
} }
} }
@@ -184,14 +192,13 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
} }
private void updateRandomCommander() { private void updateRandomCommander() {
if((!lstDecks.getGameType().getDeckFormat().equals(DeckFormat.Commander))&& DeckFormat deckFormat = lstDecks.getGameType().getDeckFormat();
!(lstDecks.getGameType().getDeckFormat().equals(DeckFormat.TinyLeaders))&& if (!deckFormat.hasCommander()) {
!(lstDecks.getGameType().getDeckFormat().equals(DeckFormat.Brawl))){
return; return;
} }
lstDecks.setAllowMultipleSelections(false);
lstDecks.setPool(CommanderDeckGenerator.getCommanderDecks(lstDecks.getGameType().getDeckFormat(), isAi, false)); lstDecks.setAllowMultipleSelections(false);
lstDecks.setPool(CommanderDeckGenerator.getCommanderDecks(deckFormat, isAi, false));
lstDecks.setup(ItemManagerConfig.STRING_ONLY); lstDecks.setup(ItemManagerConfig.STRING_ONLY);
btnRandom.setText("Random"); btnRandom.setText("Random");
@@ -207,13 +214,13 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
} }
private void updateRandomCardGenCommander() { private void updateRandomCardGenCommander() {
if((!lstDecks.getGameType().getDeckFormat().equals(DeckFormat.Commander))&& DeckFormat deckFormat = lstDecks.getGameType().getDeckFormat();
!(lstDecks.getGameType().getDeckFormat().equals(DeckFormat.TinyLeaders))&& if (!deckFormat.hasCommander()) {
!(lstDecks.getGameType().getDeckFormat().equals(DeckFormat.Brawl))){
return; return;
} }
lstDecks.setAllowMultipleSelections(false); lstDecks.setAllowMultipleSelections(false);
lstDecks.setPool(CommanderDeckGenerator.getCommanderDecks(lstDecks.getGameType().getDeckFormat(), isAi, true)); lstDecks.setPool(CommanderDeckGenerator.getCommanderDecks(deckFormat, isAi, true));
lstDecks.setup(ItemManagerConfig.STRING_ONLY); lstDecks.setup(ItemManagerConfig.STRING_ONLY);
btnRandom.setText("Random"); btnRandom.setText("Random");

View File

@@ -14,6 +14,7 @@ import forge.screens.deckeditor.views.VDeckgen;
import forge.screens.deckeditor.views.VProbabilities; import forge.screens.deckeditor.views.VProbabilities;
import forge.screens.deckeditor.views.VStatistics; import forge.screens.deckeditor.views.VStatistics;
import forge.screens.deckeditor.views.VTinyLeadersDecks; import forge.screens.deckeditor.views.VTinyLeadersDecks;
import forge.screens.deckeditor.views.VOathbreakerDecks;
import forge.screens.home.gauntlet.VSubmenuGauntletBuild; import forge.screens.home.gauntlet.VSubmenuGauntletBuild;
import forge.screens.home.gauntlet.VSubmenuGauntletContests; import forge.screens.home.gauntlet.VSubmenuGauntletContests;
import forge.screens.home.gauntlet.VSubmenuGauntletLoad; import forge.screens.home.gauntlet.VSubmenuGauntletLoad;
@@ -60,6 +61,7 @@ public enum EDocID {
EDITOR_COMMANDER (VCommanderDecks.SINGLETON_INSTANCE), EDITOR_COMMANDER (VCommanderDecks.SINGLETON_INSTANCE),
EDITOR_BRAWL (VBrawlDecks.SINGLETON_INSTANCE), EDITOR_BRAWL (VBrawlDecks.SINGLETON_INSTANCE),
EDITOR_TINY_LEADERS (VTinyLeadersDecks.SINGLETON_INSTANCE), EDITOR_TINY_LEADERS (VTinyLeadersDecks.SINGLETON_INSTANCE),
EDITOR_OATHBREAKER (VOathbreakerDecks.SINGLETON_INSTANCE),
WORKSHOP_CATALOG (VWorkshopCatalog.SINGLETON_INSTANCE), WORKSHOP_CATALOG (VWorkshopCatalog.SINGLETON_INSTANCE),
WORKSHOP_CARDDESIGNER (VCardDesigner.SINGLETON_INSTANCE), WORKSHOP_CARDDESIGNER (VCardDesigner.SINGLETON_INSTANCE),

View File

@@ -88,6 +88,15 @@ public class FScreen {
"Close Editor", "Close Editor",
ForgeConstants.EDITOR_LAYOUT_FILE, ForgeConstants.EDITOR_LAYOUT_FILE,
false); false);
public static final FScreen DECK_EDITOR_OATHBREAKER = new FScreen(
VDeckEditorUI.SINGLETON_INSTANCE,
CDeckEditorUI.SINGLETON_INSTANCE,
"Oathbreaker Deck Editor",
FSkin.getImage(FSkinProp.IMG_PACK),
true,
"Close Editor",
ForgeConstants.EDITOR_LAYOUT_FILE,
false);
public static final FScreen DECK_EDITOR_PLANECHASE = new FScreen( public static final FScreen DECK_EDITOR_PLANECHASE = new FScreen(
VDeckEditorUI.SINGLETON_INSTANCE, VDeckEditorUI.SINGLETON_INSTANCE,
CDeckEditorUI.SINGLETON_INSTANCE, CDeckEditorUI.SINGLETON_INSTANCE,

View File

@@ -338,6 +338,11 @@ public final class DeckManager extends ItemManager<DeckProxy> implements IHasGam
DeckPreferences.setCommanderDeck((deck != null) ? deck.toString() : ""); DeckPreferences.setCommanderDeck((deck != null) ? deck.toString() : "");
editorCtrl = new CEditorConstructed(getCDetailPicture(), this.gameType); editorCtrl = new CEditorConstructed(getCDetailPicture(), this.gameType);
break; break;
case Oathbreaker:
screen = FScreen.DECK_EDITOR_CONSTRUCTED; // re-use "Deck Editor", rather than creating a new top level tab
DeckPreferences.setCommanderDeck((deck != null) ? deck.toString() : "");
editorCtrl = new CEditorConstructed(getCDetailPicture(), this.gameType);
break;
case Brawl: case Brawl:
screen = FScreen.DECK_EDITOR_CONSTRUCTED; // re-use "Deck Editor", rather than creating a new top level tab screen = FScreen.DECK_EDITOR_CONSTRUCTED; // re-use "Deck Editor", rather than creating a new top level tab
DeckPreferences.setBrawlDeck((deck != null) ? deck.toString() : ""); DeckPreferences.setBrawlDeck((deck != null) ? deck.toString() : "");
@@ -397,6 +402,7 @@ public final class DeckManager extends ItemManager<DeckProxy> implements IHasGam
switch(this.gameType) { switch(this.gameType) {
case Brawl: case Brawl:
case Commander: case Commander:
case Oathbreaker:
case TinyLeaders: case TinyLeaders:
case Constructed: case Constructed:
case Draft: case Draft:

View File

@@ -42,6 +42,7 @@ import forge.screens.deckeditor.views.VBrawlDecks;
import forge.screens.deckeditor.views.VCardCatalog; import forge.screens.deckeditor.views.VCardCatalog;
import forge.screens.deckeditor.views.VCommanderDecks; import forge.screens.deckeditor.views.VCommanderDecks;
import forge.screens.deckeditor.views.VCurrentDeck; import forge.screens.deckeditor.views.VCurrentDeck;
import forge.screens.deckeditor.views.VOathbreakerDecks;
import forge.screens.deckeditor.views.VTinyLeadersDecks; import forge.screens.deckeditor.views.VTinyLeadersDecks;
import forge.screens.match.controllers.CDetailPicture; import forge.screens.match.controllers.CDetailPicture;
import forge.util.ItemPool; import forge.util.ItemPool;
@@ -63,6 +64,7 @@ public enum CDeckEditorUI implements ICDoc {
private final CDetailPicture cDetailPicture; private final CDetailPicture cDetailPicture;
private final VAllDecks vAllDecks; private final VAllDecks vAllDecks;
private final VCommanderDecks vCommanderDecks; private final VCommanderDecks vCommanderDecks;
private final VOathbreakerDecks vOathbreakerDecks;
private final VBrawlDecks vBrawlDecks; private final VBrawlDecks vBrawlDecks;
private final VTinyLeadersDecks vTinyLeadersDecks; private final VTinyLeadersDecks vTinyLeadersDecks;
@@ -73,6 +75,8 @@ public enum CDeckEditorUI implements ICDoc {
this.vAllDecks.setCDetailPicture(cDetailPicture); this.vAllDecks.setCDetailPicture(cDetailPicture);
this.vCommanderDecks = VCommanderDecks.SINGLETON_INSTANCE; this.vCommanderDecks = VCommanderDecks.SINGLETON_INSTANCE;
this.vCommanderDecks.setCDetailPicture(cDetailPicture); this.vCommanderDecks.setCDetailPicture(cDetailPicture);
this.vOathbreakerDecks = VOathbreakerDecks.SINGLETON_INSTANCE;
this.vOathbreakerDecks.setCDetailPicture(cDetailPicture);
this.vBrawlDecks = VBrawlDecks.SINGLETON_INSTANCE; this.vBrawlDecks = VBrawlDecks.SINGLETON_INSTANCE;
this.vBrawlDecks.setCDetailPicture(cDetailPicture); this.vBrawlDecks.setCDetailPicture(cDetailPicture);
this.vTinyLeadersDecks = VTinyLeadersDecks.SINGLETON_INSTANCE; this.vTinyLeadersDecks = VTinyLeadersDecks.SINGLETON_INSTANCE;

View File

@@ -22,6 +22,7 @@ import com.google.common.collect.Iterables;
import forge.UiCommand; import forge.UiCommand;
import forge.assets.FSkinProp; import forge.assets.FSkinProp;
import forge.deck.*; import forge.deck.*;
import forge.game.GameType;
import forge.gui.GuiChoose; import forge.gui.GuiChoose;
import forge.gui.GuiUtils; import forge.gui.GuiUtils;
import forge.gui.framework.*; import forge.gui.framework.*;
@@ -76,6 +77,7 @@ public abstract class ACEditorBase<TItem extends InventoryItem, TModel extends D
private ItemManager<TItem> deckManager; private ItemManager<TItem> deckManager;
protected DeckSection sectionMode = DeckSection.Main; protected DeckSection sectionMode = DeckSection.Main;
private final CDetailPicture cDetailPicture; private final CDetailPicture cDetailPicture;
protected final GameType gameType;
// card transfer buttons // card transfer buttons
final Localizer localizer = Localizer.getInstance(); final Localizer localizer = Localizer.getInstance();
@@ -114,9 +116,10 @@ public abstract class ACEditorBase<TItem extends InventoryItem, TModel extends D
.icon(FSkin.getImage(FSkinProp.IMG_LAND, 18, 18)) .icon(FSkin.getImage(FSkinProp.IMG_LAND, 18, 18))
.iconScaleAuto(false).hoverable().build(); .iconScaleAuto(false).hoverable().build();
protected ACEditorBase(final FScreen screen0, final CDetailPicture cDetailPicture) { protected ACEditorBase(final FScreen screen0, final CDetailPicture cDetailPicture0, final GameType gameType0) {
this.screen = screen0; this.screen = screen0;
this.cDetailPicture = cDetailPicture; this.cDetailPicture = cDetailPicture0;
this.gameType = gameType0;
} }
public FScreen getScreen() { public FScreen getScreen() {

View File

@@ -6,7 +6,7 @@ import forge.itemmanager.ItemManagerConfig;
import forge.screens.deckeditor.views.VBrawlDecks; import forge.screens.deckeditor.views.VBrawlDecks;
/** /**
* Controls the "Commander Decks" panel in the deck editor UI. * Controls the "Brawl Decks" panel in the deck editor UI.
* *
* <br><br><i>(C at beginning of class name denotes a control class.)</i> * <br><br><i>(C at beginning of class name denotes a control class.)</i>
* *

View File

@@ -1,6 +1,7 @@
package forge.screens.deckeditor.controllers; package forge.screens.deckeditor.controllers;
import forge.deck.*; import forge.deck.*;
import forge.game.GameType;
import forge.gui.framework.FScreen; import forge.gui.framework.FScreen;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.screens.match.controllers.CDetailPicture; import forge.screens.match.controllers.CDetailPicture;
@@ -8,9 +9,8 @@ import forge.screens.match.controllers.CDetailPicture;
import java.util.*; import java.util.*;
public abstract class CDeckEditor<TModel extends DeckBase> extends ACEditorBase<PaperCard, TModel> { public abstract class CDeckEditor<TModel extends DeckBase> extends ACEditorBase<PaperCard, TModel> {
protected CDeckEditor(FScreen screen0, CDetailPicture cDetailPicture0, GameType gameType0) {
protected CDeckEditor(FScreen screen0, CDetailPicture cDetailPicture) { super(screen0, cDetailPicture0, gameType0);
super(screen0, cDetailPicture);
} }
/** /**

View File

@@ -21,15 +21,19 @@ import com.google.common.base.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import forge.UiCommand; import forge.UiCommand;
import forge.card.CardDb;
import forge.card.CardRules; import forge.card.CardRules;
import forge.card.CardRulesPredicates; import forge.card.CardRulesPredicates;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckSection; import forge.deck.DeckSection;
import forge.game.GameFormat;
import forge.game.GameType;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
import forge.gui.framework.FScreen; import forge.gui.framework.FScreen;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.itemmanager.CardManager; import forge.itemmanager.CardManager;
import forge.itemmanager.ItemManagerConfig; import forge.itemmanager.ItemManagerConfig;
import forge.model.CardCollections;
import forge.model.FModel; import forge.model.FModel;
import forge.screens.deckeditor.SEditorIO; import forge.screens.deckeditor.SEditorIO;
import forge.screens.deckeditor.views.VAllDecks; import forge.screens.deckeditor.views.VAllDecks;
@@ -70,26 +74,27 @@ public final class CEditorCommander extends CDeckEditor<Deck> {
* all cards are available. * all cards are available.
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
public CEditorCommander(final CDetailPicture cDetailPicture, boolean tinyLeaders, boolean brawl) { public CEditorCommander(final CDetailPicture cDetailPicture, GameType gameType0) {
super(tinyLeaders ? FScreen.DECK_EDITOR_TINY_LEADERS : brawl ? FScreen.DECK_EDITOR_BRAWL : FScreen.DECK_EDITOR_COMMANDER, cDetailPicture); super(gameType0 == GameType.TinyLeaders ? FScreen.DECK_EDITOR_TINY_LEADERS : gameType0 == GameType.Brawl ? FScreen.DECK_EDITOR_BRAWL :
gameType0 == GameType.Oathbreaker ? FScreen.DECK_EDITOR_OATHBREAKER : FScreen.DECK_EDITOR_COMMANDER, cDetailPicture, gameType0);
allSections.add(DeckSection.Main); allSections.add(DeckSection.Main);
allSections.add(DeckSection.Sideboard); allSections.add(DeckSection.Sideboard);
allSections.add(DeckSection.Commander); allSections.add(DeckSection.Commander);
if(brawl){ CardDb commonCards = FModel.getMagicDb().getCommonCards();
if (gameType == GameType.Brawl){
GameFormat format = FModel.getFormats().get("Brawl");
Predicate<CardRules> commanderFilter = CardRulesPredicates.Presets.CAN_BE_BRAWL_COMMANDER; Predicate<CardRules> commanderFilter = CardRulesPredicates.Presets.CAN_BE_BRAWL_COMMANDER;
commanderPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCards(Predicates.and( commanderPool = ItemPool.createFrom(commonCards.getAllCards(Predicates.and(
FModel.getFormats().get("Brawl").getFilterPrinted(),Predicates.compose(commanderFilter, PaperCard.FN_GET_RULES))),PaperCard.class); format.getFilterPrinted(), Predicates.compose(commanderFilter, PaperCard.FN_GET_RULES))), PaperCard.class);
}else{ normalPool = ItemPool.createFrom(format.getAllCards(), PaperCard.class);
Predicate<CardRules> commanderFilter = CardRulesPredicates.Presets.CAN_BE_COMMANDER ;
commanderPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCards(Predicates.compose(commanderFilter, PaperCard.FN_GET_RULES)),PaperCard.class);
} }
else {
Predicate<CardRules> commanderFilter = gameType == GameType.Oathbreaker
if(brawl){ ? Predicates.or(CardRulesPredicates.Presets.CAN_BE_OATHBREAKER, CardRulesPredicates.Presets.CAN_BE_SIGNATURE_SPELL)
normalPool = ItemPool.createFrom(FModel.getFormats().get("Brawl").getAllCards(), PaperCard.class); : CardRulesPredicates.Presets.CAN_BE_COMMANDER;
}else { commanderPool = ItemPool.createFrom(commonCards.getAllCards(Predicates.compose(commanderFilter, PaperCard.FN_GET_RULES)),PaperCard.class);
normalPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCards(), PaperCard.class); normalPool = ItemPool.createFrom(commonCards.getAllCards(), PaperCard.class);
} }
CardManager catalogManager = new CardManager(getCDetailPicture(), true, false); CardManager catalogManager = new CardManager(getCDetailPicture(), true, false);
@@ -106,7 +111,21 @@ public final class CEditorCommander extends CDeckEditor<Deck> {
return new Deck(); return new Deck();
} }
}; };
this.controller = new DeckController<Deck>(tinyLeaders ? FModel.getDecks().getTinyLeaders() :brawl ? FModel.getDecks().getBrawl(): FModel.getDecks().getCommander(), this, newCreator); CardCollections decks = FModel.getDecks();
switch (gameType) {
case TinyLeaders:
this.controller = new DeckController<Deck>(decks.getTinyLeaders(), this, newCreator);
break;
case Brawl:
this.controller = new DeckController<Deck>(decks.getBrawl(), this, newCreator);
break;
case Oathbreaker:
this.controller = new DeckController<Deck>(decks.getOathbreaker(), this, newCreator);
break;
default:
this.controller = new DeckController<Deck>(decks.getCommander(), this, newCreator);
break;
}
getBtnAddBasicLands().setCommand(new UiCommand() { getBtnAddBasicLands().setCommand(new UiCommand() {
@Override @Override
@@ -144,7 +163,7 @@ public final class CEditorCommander extends CDeckEditor<Deck> {
*/ */
@Override @Override
protected void buildAddContextMenu(EditorContextMenuBuilder cmb) { protected void buildAddContextMenu(EditorContextMenuBuilder cmb) {
CEditorConstructed.buildAddContextMenu(cmb, sectionMode); CEditorConstructed.buildAddContextMenu(cmb, sectionMode, gameType);
} }
/* (non-Javadoc) /* (non-Javadoc)

View File

@@ -61,8 +61,6 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
private final List<DeckSection> allSections = new ArrayList<DeckSection>(); private final List<DeckSection> allSections = new ArrayList<DeckSection>();
private ItemPool<PaperCard> normalPool, avatarPool, planePool, schemePool, conspiracyPool, commanderPool; private ItemPool<PaperCard> normalPool, avatarPool, planePool, schemePool, conspiracyPool, commanderPool;
private final GameType gameType;
Predicate<CardRules> commanderFilter; Predicate<CardRules> commanderFilter;
CardManager catalogManager; CardManager catalogManager;
@@ -75,13 +73,12 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
* all cards are available. * all cards are available.
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
public CEditorConstructed(final CDetailPicture cDetailPicture) { public CEditorConstructed(final CDetailPicture cDetailPicture0) {
this(cDetailPicture, GameType.Constructed); this(cDetailPicture0, GameType.Constructed);
} }
public CEditorConstructed(final CDetailPicture cDetailPicture, final GameType gameType) { public CEditorConstructed(final CDetailPicture cDetailPicture0, final GameType gameType0) {
super(FScreen.DECK_EDITOR_CONSTRUCTED, cDetailPicture); super(FScreen.DECK_EDITOR_CONSTRUCTED, cDetailPicture0, gameType0);
this.gameType = gameType;
boolean wantUnique = false; boolean wantUnique = false;
@@ -110,6 +107,15 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
commanderPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCards(Predicates.compose(commanderFilter, PaperCard.FN_GET_RULES)), PaperCard.class); commanderPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCards(Predicates.compose(commanderFilter, PaperCard.FN_GET_RULES)), PaperCard.class);
normalPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCards(), PaperCard.class); normalPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCards(), PaperCard.class);
wantUnique = true;
break;
case Oathbreaker:
allSections.add(DeckSection.Commander);
commanderFilter = Predicates.or(CardRulesPredicates.Presets.CAN_BE_OATHBREAKER, CardRulesPredicates.Presets.CAN_BE_SIGNATURE_SPELL);
commanderPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCards(Predicates.compose(commanderFilter, PaperCard.FN_GET_RULES)), PaperCard.class);
normalPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCards(), PaperCard.class);
wantUnique = true; wantUnique = true;
break; break;
case Brawl: case Brawl:
@@ -148,6 +154,9 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
case Commander: case Commander:
this.controller = new DeckController<Deck>(FModel.getDecks().getCommander(), this, newCreator); this.controller = new DeckController<Deck>(FModel.getDecks().getCommander(), this, newCreator);
break; break;
case Oathbreaker:
this.controller = new DeckController<Deck>(FModel.getDecks().getOathbreaker(), this, newCreator);
break;
case Brawl: case Brawl:
this.controller = new DeckController<Deck>(FModel.getDecks().getBrawl(), this, newCreator); this.controller = new DeckController<Deck>(FModel.getDecks().getBrawl(), this, newCreator);
break; break;
@@ -176,6 +185,7 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
case Constructed: case Constructed:
return CardLimit.Default; return CardLimit.Default;
case Commander: case Commander:
case Oathbreaker:
case TinyLeaders: case TinyLeaders:
case Brawl: case Brawl:
return CardLimit.Singleton; return CardLimit.Singleton;
@@ -188,8 +198,37 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
DeckSection sectionMode = editor.sectionMode; DeckSection sectionMode = editor.sectionMode;
DeckController<Deck> controller = editor.getDeckController(); DeckController<Deck> controller = editor.getDeckController();
if (sectionMode == DeckSection.Commander || sectionMode == DeckSection.Avatar) { switch (sectionMode) {
case Commander:
int count = editor.getDeckManager().getItemCount();
if (count > 0) {
PaperCard newCard = items.iterator().next().getKey(); //can only add one card at a time when on commander section
if (editor.gameType == GameType.Oathbreaker) { //replace oathbreaker or signature spell if needed
for (Entry<PaperCard, Integer> entry : editor.getDeckManager().getPool()) {
if (entry.getKey().getRules().canBeOathbreaker() == newCard.getRules().canBeOathbreaker()) {
editor.getDeckManager().removeItem(entry.getKey(), entry.getValue());
break;
}
}
}
else { //replace existing commander unless new commander is valid partner commander
if (count == 1 && newCard.getRules().canBePartnerCommander()) { //replace existing partners regardless
PaperCard commander = editor.getDeckManager().getPool().toFlatList().get(0);
if (!commander.getRules().canBePartnerCommander()) {
editor.getDeckManager().removeAllItems();
}
}
else {
editor.getDeckManager().removeAllItems();
}
}
}
break;
case Avatar:
editor.getDeckManager().removeAllItems(); editor.getDeckManager().removeAllItems();
break;
default:
break;
} }
ItemPool<PaperCard> itemsToAdd = editor.getAllowedAdditions(items); ItemPool<PaperCard> itemsToAdd = editor.getAllowedAdditions(items);
@@ -260,7 +299,7 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
onRemoveItems(this, items, toAlternate); onRemoveItems(this, items, toAlternate);
} }
public static void buildAddContextMenu(EditorContextMenuBuilder cmb, DeckSection sectionMode) { public static void buildAddContextMenu(EditorContextMenuBuilder cmb, DeckSection sectionMode, GameType gameType) {
final Localizer localizer = Localizer.getInstance(); final Localizer localizer = Localizer.getInstance();
switch (sectionMode) { switch (sectionMode) {
case Main: case Main:
@@ -271,7 +310,18 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
cmb.addMoveItems(localizer.getMessage("lblAdd"), localizer.getMessage("lbltosideboard")); cmb.addMoveItems(localizer.getMessage("lblAdd"), localizer.getMessage("lbltosideboard"));
break; break;
case Commander: case Commander:
cmb.addMoveItems(localizer.getMessage("lblSet2"), localizer.getMessage("lblascommander")); if (gameType == GameType.Oathbreaker) {
PaperCard pc = cmb.getItemManager().getSelectedItem();
if (pc != null && pc.getRules().canBeSignatureSpell()) {
cmb.addMoveItems(localizer.getMessage("lblSet2"), localizer.getMessage("lblassignaturespell"));
}
else {
cmb.addMoveItems(localizer.getMessage("lblSet2"), localizer.getMessage("lblasoathbreaker"));
}
}
else {
cmb.addMoveItems(localizer.getMessage("lblSet2"), localizer.getMessage("lblascommander"));
}
break; break;
case Avatar: case Avatar:
cmb.addMoveItems(localizer.getMessage("lblSet2"), localizer.getMessage("lblasavatar")); cmb.addMoveItems(localizer.getMessage("lblSet2"), localizer.getMessage("lblasavatar"));
@@ -325,7 +375,7 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
*/ */
@Override @Override
protected void buildAddContextMenu(EditorContextMenuBuilder cmb) { protected void buildAddContextMenu(EditorContextMenuBuilder cmb) {
buildAddContextMenu(cmb, sectionMode); buildAddContextMenu(cmb, sectionMode, gameType);
} }
/* (non-Javadoc) /* (non-Javadoc)
@@ -377,26 +427,31 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
case Main: case Main:
this.getCatalogManager().setup(ItemManagerConfig.CARD_CATALOG); this.getCatalogManager().setup(ItemManagerConfig.CARD_CATALOG);
this.getCatalogManager().setPool(normalPool, true); this.getCatalogManager().setPool(normalPool, true);
this.getCatalogManager().setAllowMultipleSelections(true);
this.getDeckManager().setPool(this.controller.getModel().getMain()); this.getDeckManager().setPool(this.controller.getModel().getMain());
break; break;
case Sideboard: case Sideboard:
this.getCatalogManager().setup(ItemManagerConfig.CARD_CATALOG); this.getCatalogManager().setup(ItemManagerConfig.CARD_CATALOG);
this.getCatalogManager().setPool(normalPool, true); this.getCatalogManager().setPool(normalPool, true);
this.getCatalogManager().setAllowMultipleSelections(true);
this.getDeckManager().setPool(this.controller.getModel().getOrCreate(DeckSection.Sideboard)); this.getDeckManager().setPool(this.controller.getModel().getOrCreate(DeckSection.Sideboard));
break; break;
case Avatar: case Avatar:
this.getCatalogManager().setup(ItemManagerConfig.AVATAR_POOL); this.getCatalogManager().setup(ItemManagerConfig.AVATAR_POOL);
this.getCatalogManager().setPool(avatarPool, true); this.getCatalogManager().setPool(avatarPool, true);
this.getCatalogManager().setAllowMultipleSelections(false);
this.getDeckManager().setPool(this.controller.getModel().getOrCreate(DeckSection.Avatar)); this.getDeckManager().setPool(this.controller.getModel().getOrCreate(DeckSection.Avatar));
break; break;
case Planes: case Planes:
this.getCatalogManager().setup(ItemManagerConfig.PLANAR_POOL); this.getCatalogManager().setup(ItemManagerConfig.PLANAR_POOL);
this.getCatalogManager().setPool(planePool, true); this.getCatalogManager().setPool(planePool, true);
this.getCatalogManager().setAllowMultipleSelections(true);
this.getDeckManager().setPool(this.controller.getModel().getOrCreate(DeckSection.Planes)); this.getDeckManager().setPool(this.controller.getModel().getOrCreate(DeckSection.Planes));
break; break;
case Schemes: case Schemes:
this.getCatalogManager().setup(ItemManagerConfig.SCHEME_POOL); this.getCatalogManager().setup(ItemManagerConfig.SCHEME_POOL);
this.getCatalogManager().setPool(schemePool, true); this.getCatalogManager().setPool(schemePool, true);
this.getCatalogManager().setAllowMultipleSelections(true);
this.getDeckManager().setPool(this.controller.getModel().getOrCreate(DeckSection.Schemes)); this.getDeckManager().setPool(this.controller.getModel().getOrCreate(DeckSection.Schemes));
break; break;
case Commander: case Commander:
@@ -404,25 +459,30 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
case Conspiracy: case Conspiracy:
this.getCatalogManager().setup(ItemManagerConfig.CONSPIRACY_DECKS); this.getCatalogManager().setup(ItemManagerConfig.CONSPIRACY_DECKS);
this.getCatalogManager().setPool(conspiracyPool, true); this.getCatalogManager().setPool(conspiracyPool, true);
this.getCatalogManager().setAllowMultipleSelections(true);
this.getDeckManager().setPool(this.controller.getModel().getOrCreate(DeckSection.Conspiracy)); this.getDeckManager().setPool(this.controller.getModel().getOrCreate(DeckSection.Conspiracy));
} }
case Commander: case Commander:
case Oathbreaker:
case TinyLeaders: case TinyLeaders:
case Brawl: case Brawl:
switch(sectionMode) { switch(sectionMode) {
case Main: case Main:
this.getCatalogManager().setup(ItemManagerConfig.CARD_CATALOG); this.getCatalogManager().setup(ItemManagerConfig.CARD_CATALOG);
this.getCatalogManager().setPool(normalPool, true); this.getCatalogManager().setPool(normalPool, true);
this.getCatalogManager().setAllowMultipleSelections(true);
this.getDeckManager().setPool(this.controller.getModel().getMain()); this.getDeckManager().setPool(this.controller.getModel().getMain());
break; break;
case Sideboard: case Sideboard:
this.getCatalogManager().setup(ItemManagerConfig.CARD_CATALOG); this.getCatalogManager().setup(ItemManagerConfig.CARD_CATALOG);
this.getCatalogManager().setPool(normalPool, true); this.getCatalogManager().setPool(normalPool, true);
this.getCatalogManager().setAllowMultipleSelections(true);
this.getDeckManager().setPool(this.controller.getModel().getOrCreate(DeckSection.Sideboard)); this.getDeckManager().setPool(this.controller.getModel().getOrCreate(DeckSection.Sideboard));
break; break;
case Commander: case Commander:
this.getCatalogManager().setup(ItemManagerConfig.COMMANDER_POOL); this.getCatalogManager().setup(ItemManagerConfig.COMMANDER_POOL);
this.getCatalogManager().setPool(commanderPool, true); this.getCatalogManager().setPool(commanderPool, true);
this.getCatalogManager().setAllowMultipleSelections(false);
this.getDeckManager().setPool(this.controller.getModel().getOrCreate(DeckSection.Commander)); this.getDeckManager().setPool(this.controller.getModel().getOrCreate(DeckSection.Commander));
break; break;
default: default:

View File

@@ -21,6 +21,7 @@ import forge.Singletons;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckGroup; import forge.deck.DeckGroup;
import forge.deck.DeckSection; import forge.deck.DeckSection;
import forge.game.GameType;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
import forge.gui.framework.FScreen; import forge.gui.framework.FScreen;
import forge.item.PaperCard; import forge.item.PaperCard;
@@ -30,12 +31,7 @@ import forge.limited.BoosterDraft;
import forge.limited.IBoosterDraft; import forge.limited.IBoosterDraft;
import forge.model.FModel; import forge.model.FModel;
import forge.screens.deckeditor.CDeckEditorUI; import forge.screens.deckeditor.CDeckEditorUI;
import forge.screens.deckeditor.views.VAllDecks; import forge.screens.deckeditor.views.*;
import forge.screens.deckeditor.views.VBrawlDecks;
import forge.screens.deckeditor.views.VCommanderDecks;
import forge.screens.deckeditor.views.VCurrentDeck;
import forge.screens.deckeditor.views.VDeckgen;
import forge.screens.deckeditor.views.VTinyLeadersDecks;
import forge.screens.home.sanctioned.CSubmenuDraft; import forge.screens.home.sanctioned.CSubmenuDraft;
import forge.screens.match.controllers.CDetailPicture; import forge.screens.match.controllers.CDetailPicture;
import forge.toolbox.FOptionPane; import forge.toolbox.FOptionPane;
@@ -58,6 +54,7 @@ public class CEditorDraftingProcess extends ACEditorBase<PaperCard, DeckGroup> {
private String ccAddLabel = "Add card"; private String ccAddLabel = "Add card";
private DragCell constructedDecksParent = null; private DragCell constructedDecksParent = null;
private DragCell commanderDecksParent = null; private DragCell commanderDecksParent = null;
private DragCell oathbreakerDecksParent = null;
private DragCell brawlDecksParent = null; private DragCell brawlDecksParent = null;
private DragCell tinyLeadersDecksParent = null; private DragCell tinyLeadersDecksParent = null;
private DragCell deckGenParent = null; private DragCell deckGenParent = null;
@@ -68,11 +65,11 @@ public class CEditorDraftingProcess extends ACEditorBase<PaperCard, DeckGroup> {
/** /**
* Updates the deck editor UI as necessary draft selection mode. * Updates the deck editor UI as necessary draft selection mode.
*/ */
public CEditorDraftingProcess(final CDetailPicture cDetailPicture) { public CEditorDraftingProcess(final CDetailPicture cDetailPicture0) {
super(FScreen.DRAFTING_PROCESS, cDetailPicture); super(FScreen.DRAFTING_PROCESS, cDetailPicture0, GameType.Draft);
final CardManager catalogManager = new CardManager(getCDetailPicture(), false, false); final CardManager catalogManager = new CardManager(cDetailPicture0, false, false);
final CardManager deckManager = new CardManager(getCDetailPicture(), false, false); final CardManager deckManager = new CardManager(cDetailPicture0, false, false);
//hide filters and options panel so more of pack is visible by default //hide filters and options panel so more of pack is visible by default
catalogManager.setHideViewOptions(1, true); catalogManager.setHideViewOptions(1, true);
@@ -285,6 +282,7 @@ public class CEditorDraftingProcess extends ACEditorBase<PaperCard, DeckGroup> {
deckGenParent = removeTab(VDeckgen.SINGLETON_INSTANCE); deckGenParent = removeTab(VDeckgen.SINGLETON_INSTANCE);
constructedDecksParent = removeTab(VAllDecks.SINGLETON_INSTANCE); constructedDecksParent = removeTab(VAllDecks.SINGLETON_INSTANCE);
commanderDecksParent = removeTab(VCommanderDecks.SINGLETON_INSTANCE); commanderDecksParent = removeTab(VCommanderDecks.SINGLETON_INSTANCE);
oathbreakerDecksParent = removeTab(VOathbreakerDecks.SINGLETON_INSTANCE);
brawlDecksParent = removeTab(VBrawlDecks.SINGLETON_INSTANCE); brawlDecksParent = removeTab(VBrawlDecks.SINGLETON_INSTANCE);
tinyLeadersDecksParent = removeTab(VTinyLeadersDecks.SINGLETON_INSTANCE); tinyLeadersDecksParent = removeTab(VTinyLeadersDecks.SINGLETON_INSTANCE);
@@ -334,6 +332,9 @@ public class CEditorDraftingProcess extends ACEditorBase<PaperCard, DeckGroup> {
if (commanderDecksParent != null) { if (commanderDecksParent != null) {
commanderDecksParent.addDoc(VCommanderDecks.SINGLETON_INSTANCE); commanderDecksParent.addDoc(VCommanderDecks.SINGLETON_INSTANCE);
} }
if (oathbreakerDecksParent != null) {
oathbreakerDecksParent.addDoc(VOathbreakerDecks.SINGLETON_INSTANCE);
}
if (brawlDecksParent!= null) { if (brawlDecksParent!= null) {
brawlDecksParent.addDoc(VBrawlDecks.SINGLETON_INSTANCE); brawlDecksParent.addDoc(VBrawlDecks.SINGLETON_INSTANCE);
} }

View File

@@ -24,6 +24,7 @@ import forge.deck.CardPool;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckGroup; import forge.deck.DeckGroup;
import forge.deck.DeckSection; import forge.deck.DeckSection;
import forge.game.GameType;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
import forge.gui.framework.FScreen; import forge.gui.framework.FScreen;
import forge.item.PaperCard; import forge.item.PaperCard;
@@ -32,12 +33,7 @@ import forge.itemmanager.ItemManagerConfig;
import forge.model.FModel; import forge.model.FModel;
import forge.screens.deckeditor.AddBasicLandsDialog; import forge.screens.deckeditor.AddBasicLandsDialog;
import forge.screens.deckeditor.SEditorIO; import forge.screens.deckeditor.SEditorIO;
import forge.screens.deckeditor.views.VAllDecks; import forge.screens.deckeditor.views.*;
import forge.screens.deckeditor.views.VBrawlDecks;
import forge.screens.deckeditor.views.VCommanderDecks;
import forge.screens.deckeditor.views.VCurrentDeck;
import forge.screens.deckeditor.views.VDeckgen;
import forge.screens.deckeditor.views.VTinyLeadersDecks;
import forge.screens.home.sanctioned.CSubmenuDraft; import forge.screens.home.sanctioned.CSubmenuDraft;
import forge.screens.home.sanctioned.CSubmenuSealed; import forge.screens.home.sanctioned.CSubmenuSealed;
import forge.screens.match.controllers.CDetailPicture; import forge.screens.match.controllers.CDetailPicture;
@@ -62,6 +58,7 @@ public final class CEditorLimited extends CDeckEditor<DeckGroup> {
private final DeckController<DeckGroup> controller; private final DeckController<DeckGroup> controller;
private DragCell constructedDecksParent = null; private DragCell constructedDecksParent = null;
private DragCell commanderDecksParent = null; private DragCell commanderDecksParent = null;
private DragCell oathbreakerDecksParent = null;
private DragCell brawlDecksParent = null; private DragCell brawlDecksParent = null;
private DragCell tinyLeadersDecksParent = null; private DragCell tinyLeadersDecksParent = null;
private DragCell deckGenParent = null; private DragCell deckGenParent = null;
@@ -75,11 +72,11 @@ public final class CEditorLimited extends CDeckEditor<DeckGroup> {
* @param deckMap0 &emsp; {@link forge.deck.DeckGroup}<{@link forge.util.storage.IStorage}> * @param deckMap0 &emsp; {@link forge.deck.DeckGroup}<{@link forge.util.storage.IStorage}>
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
public CEditorLimited(final IStorage<DeckGroup> deckMap0, final FScreen screen0, final CDetailPicture cDetailPicture) { public CEditorLimited(final IStorage<DeckGroup> deckMap0, final FScreen screen0, final CDetailPicture cDetailPicture0) {
super(screen0, cDetailPicture); super(screen0, cDetailPicture0, GameType.Sealed);
final CardManager catalogManager = new CardManager(getCDetailPicture(), false, false); final CardManager catalogManager = new CardManager(cDetailPicture0, false, false);
final CardManager deckManager = new CardManager(getCDetailPicture(), false, false); final CardManager deckManager = new CardManager(cDetailPicture0, false, false);
catalogManager.setCaption("Sideboard"); catalogManager.setCaption("Sideboard");
@@ -208,7 +205,6 @@ public final class CEditorLimited extends CDeckEditor<DeckGroup> {
} }
} }
public void setEditorMode(DeckSection sectionMode) { public void setEditorMode(DeckSection sectionMode) {
switch(sectionMode) { switch(sectionMode) {
case Conspiracy: case Conspiracy:
@@ -244,6 +240,7 @@ public final class CEditorLimited extends CDeckEditor<DeckGroup> {
deckGenParent = removeTab(VDeckgen.SINGLETON_INSTANCE); deckGenParent = removeTab(VDeckgen.SINGLETON_INSTANCE);
constructedDecksParent = removeTab(VAllDecks.SINGLETON_INSTANCE); constructedDecksParent = removeTab(VAllDecks.SINGLETON_INSTANCE);
commanderDecksParent = removeTab(VCommanderDecks.SINGLETON_INSTANCE); commanderDecksParent = removeTab(VCommanderDecks.SINGLETON_INSTANCE);
oathbreakerDecksParent = removeTab(VOathbreakerDecks.SINGLETON_INSTANCE);
brawlDecksParent = removeTab(VBrawlDecks.SINGLETON_INSTANCE); brawlDecksParent = removeTab(VBrawlDecks.SINGLETON_INSTANCE);
tinyLeadersDecksParent = removeTab(VTinyLeadersDecks.SINGLETON_INSTANCE); tinyLeadersDecksParent = removeTab(VTinyLeadersDecks.SINGLETON_INSTANCE);
} }
@@ -274,6 +271,9 @@ public final class CEditorLimited extends CDeckEditor<DeckGroup> {
if (commanderDecksParent != null) { if (commanderDecksParent != null) {
commanderDecksParent.addDoc(VCommanderDecks.SINGLETON_INSTANCE); commanderDecksParent.addDoc(VCommanderDecks.SINGLETON_INSTANCE);
} }
if (oathbreakerDecksParent != null) {
oathbreakerDecksParent.addDoc(VOathbreakerDecks.SINGLETON_INSTANCE);
}
if (brawlDecksParent!= null) { if (brawlDecksParent!= null) {
brawlDecksParent.addDoc(VBrawlDecks.SINGLETON_INSTANCE); brawlDecksParent.addDoc(VBrawlDecks.SINGLETON_INSTANCE);
} }

View File

@@ -29,6 +29,7 @@ import forge.card.mana.ManaCost;
import forge.deck.CardPool; import forge.deck.CardPool;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckSection; import forge.deck.DeckSection;
import forge.game.GameType;
import forge.gui.GuiUtils; import forge.gui.GuiUtils;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
import forge.gui.framework.FScreen; import forge.gui.framework.FScreen;
@@ -104,8 +105,8 @@ public final class CEditorQuest extends CDeckEditor<Deck> {
* @param questData0 &emsp; {@link forge.quest.QuestController} * @param questData0 &emsp; {@link forge.quest.QuestController}
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
public CEditorQuest(final QuestController questData0, final CDetailPicture cDetailPicture) { public CEditorQuest(final QuestController questData0, final CDetailPicture cDetailPicture0) {
super(FScreen.DECK_EDITOR_QUEST, cDetailPicture); super(FScreen.DECK_EDITOR_QUEST, cDetailPicture0, GameType.Quest);
allSections.add(DeckSection.Main); allSections.add(DeckSection.Main);
allSections.add(DeckSection.Sideboard); allSections.add(DeckSection.Sideboard);
@@ -120,8 +121,8 @@ public final class CEditorQuest extends CDeckEditor<Deck> {
this.questData = questData0; this.questData = questData0;
final CardManager catalogManager = new CardManager(cDetailPicture, false, true); final CardManager catalogManager = new CardManager(cDetailPicture0, false, true);
final CardManager deckManager = new CardManager(cDetailPicture, false, true); final CardManager deckManager = new CardManager(cDetailPicture0, false, true);
catalogManager.setCaption("Quest Inventory"); catalogManager.setCaption("Quest Inventory");
@@ -203,7 +204,7 @@ public final class CEditorQuest extends CDeckEditor<Deck> {
*/ */
@Override @Override
protected void buildAddContextMenu(final EditorContextMenuBuilder cmb) { protected void buildAddContextMenu(final EditorContextMenuBuilder cmb) {
CEditorConstructed.buildAddContextMenu(cmb, sectionMode); CEditorConstructed.buildAddContextMenu(cmb, sectionMode, GameType.Quest);
AddRatingItem(cmb, 1); AddRatingItem(cmb, 1);
AddRatingItem(cmb, 2); AddRatingItem(cmb, 2);
AddRatingItem(cmb, 3); AddRatingItem(cmb, 3);

View File

@@ -20,6 +20,7 @@ package forge.screens.deckeditor.controllers;
import forge.UiCommand; import forge.UiCommand;
import forge.assets.FSkinProp; import forge.assets.FSkinProp;
import forge.deck.DeckBase; import forge.deck.DeckBase;
import forge.game.GameType;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
import forge.gui.framework.FScreen; import forge.gui.framework.FScreen;
import forge.item.*; import forge.item.*;
@@ -96,13 +97,13 @@ public final class CEditorQuestCardShop extends ACEditorBase<InventoryItem, Deck
* @param qd * @param qd
* a {@link forge.quest.data.QuestData} object. * a {@link forge.quest.data.QuestData} object.
*/ */
public CEditorQuestCardShop(final QuestController qd, final CDetailPicture cDetailPicture) { public CEditorQuestCardShop(final QuestController qd, final CDetailPicture cDetailPicture0) {
super(FScreen.QUEST_CARD_SHOP, cDetailPicture); super(FScreen.QUEST_CARD_SHOP, cDetailPicture0, GameType.Quest);
this.questData = qd; this.questData = qd;
final SpellShopManager catalogManager = new SpellShopManager(getCDetailPicture(), false); final SpellShopManager catalogManager = new SpellShopManager(cDetailPicture0, false);
final SpellShopManager deckManager = new SpellShopManager(getCDetailPicture(), false); final SpellShopManager deckManager = new SpellShopManager(cDetailPicture0, false);
catalogManager.setCaption("Spell Shop"); catalogManager.setCaption("Spell Shop");
deckManager.setCaption("Quest Inventory"); deckManager.setCaption("Quest Inventory");

View File

@@ -20,6 +20,7 @@ package forge.screens.deckeditor.controllers;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckGroup; import forge.deck.DeckGroup;
import forge.deck.DeckSection; import forge.deck.DeckSection;
import forge.game.GameType;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
import forge.gui.framework.FScreen; import forge.gui.framework.FScreen;
import forge.item.PaperCard; import forge.item.PaperCard;
@@ -28,12 +29,7 @@ import forge.itemmanager.ItemManagerConfig;
import forge.limited.BoosterDraft; import forge.limited.BoosterDraft;
import forge.limited.IBoosterDraft; import forge.limited.IBoosterDraft;
import forge.quest.QuestEventDraft; import forge.quest.QuestEventDraft;
import forge.screens.deckeditor.views.VAllDecks; import forge.screens.deckeditor.views.*;
import forge.screens.deckeditor.views.VBrawlDecks;
import forge.screens.deckeditor.views.VCommanderDecks;
import forge.screens.deckeditor.views.VCurrentDeck;
import forge.screens.deckeditor.views.VDeckgen;
import forge.screens.deckeditor.views.VTinyLeadersDecks;
import forge.screens.home.quest.CSubmenuQuestDraft; import forge.screens.home.quest.CSubmenuQuestDraft;
import forge.screens.home.quest.VSubmenuQuestDraft; import forge.screens.home.quest.VSubmenuQuestDraft;
import forge.screens.match.controllers.CDetailPicture; import forge.screens.match.controllers.CDetailPicture;
@@ -62,6 +58,7 @@ public class CEditorQuestDraftingProcess extends ACEditorBase<PaperCard, DeckGro
private String ccAddLabel = "Add card"; private String ccAddLabel = "Add card";
private DragCell constructedDecksParent = null; private DragCell constructedDecksParent = null;
private DragCell commanderDecksParent = null; private DragCell commanderDecksParent = null;
private DragCell oathbreakerDecksParent = null;
private DragCell brawlDecksParent = null; private DragCell brawlDecksParent = null;
private DragCell tinyLeadersDecksParent = null; private DragCell tinyLeadersDecksParent = null;
private DragCell deckGenParent = null; private DragCell deckGenParent = null;
@@ -72,11 +69,11 @@ public class CEditorQuestDraftingProcess extends ACEditorBase<PaperCard, DeckGro
/** /**
* Updates the deck editor UI as necessary draft selection mode. * Updates the deck editor UI as necessary draft selection mode.
*/ */
public CEditorQuestDraftingProcess(final CDetailPicture cDetailPicture) { public CEditorQuestDraftingProcess(final CDetailPicture cDetailPicture0) {
super(FScreen.DRAFTING_PROCESS, cDetailPicture); super(FScreen.DRAFTING_PROCESS, cDetailPicture0, GameType.QuestDraft);
final CardManager catalogManager = new CardManager(getCDetailPicture(), false, false); final CardManager catalogManager = new CardManager(cDetailPicture0, false, false);
final CardManager deckManager = new CardManager(getCDetailPicture(), false, false); final CardManager deckManager = new CardManager(cDetailPicture0, false, false);
//hide filters and options panel so more of pack is visible by default //hide filters and options panel so more of pack is visible by default
catalogManager.setHideViewOptions(1, true); catalogManager.setHideViewOptions(1, true);
@@ -283,6 +280,7 @@ public class CEditorQuestDraftingProcess extends ACEditorBase<PaperCard, DeckGro
deckGenParent = removeTab(VDeckgen.SINGLETON_INSTANCE); deckGenParent = removeTab(VDeckgen.SINGLETON_INSTANCE);
constructedDecksParent = removeTab(VAllDecks.SINGLETON_INSTANCE); constructedDecksParent = removeTab(VAllDecks.SINGLETON_INSTANCE);
commanderDecksParent = removeTab(VCommanderDecks.SINGLETON_INSTANCE); commanderDecksParent = removeTab(VCommanderDecks.SINGLETON_INSTANCE);
oathbreakerDecksParent = removeTab(VOathbreakerDecks.SINGLETON_INSTANCE);
brawlDecksParent = removeTab(VBrawlDecks.SINGLETON_INSTANCE); brawlDecksParent = removeTab(VBrawlDecks.SINGLETON_INSTANCE);
tinyLeadersDecksParent = removeTab(VTinyLeadersDecks.SINGLETON_INSTANCE); tinyLeadersDecksParent = removeTab(VTinyLeadersDecks.SINGLETON_INSTANCE);
@@ -334,6 +332,9 @@ public class CEditorQuestDraftingProcess extends ACEditorBase<PaperCard, DeckGro
if (commanderDecksParent != null) { if (commanderDecksParent != null) {
commanderDecksParent.addDoc(VCommanderDecks.SINGLETON_INSTANCE); commanderDecksParent.addDoc(VCommanderDecks.SINGLETON_INSTANCE);
} }
if (oathbreakerDecksParent != null) {
oathbreakerDecksParent.addDoc(VOathbreakerDecks.SINGLETON_INSTANCE);
}
if (brawlDecksParent!= null) { if (brawlDecksParent!= null) {
brawlDecksParent.addDoc(VBrawlDecks.SINGLETON_INSTANCE); brawlDecksParent.addDoc(VBrawlDecks.SINGLETON_INSTANCE);
} }

View File

@@ -23,6 +23,7 @@ import forge.UiCommand;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckGroup; import forge.deck.DeckGroup;
import forge.deck.DeckSection; import forge.deck.DeckSection;
import forge.game.GameType;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
import forge.gui.framework.FScreen; import forge.gui.framework.FScreen;
import forge.item.InventoryItem; import forge.item.InventoryItem;
@@ -91,16 +92,16 @@ public final class CEditorQuestLimited extends CDeckEditor<DeckGroup> {
* @param questData0 &emsp; {@link forge.quest.QuestController} * @param questData0 &emsp; {@link forge.quest.QuestController}
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
public CEditorQuestLimited(final QuestController questData0, final CDetailPicture cDetailPicture) { public CEditorQuestLimited(final QuestController questData0, final CDetailPicture cDetailPicture0) {
super(FScreen.DECK_EDITOR_QUEST_TOURNAMENT, cDetailPicture); super(FScreen.DECK_EDITOR_QUEST_TOURNAMENT, cDetailPicture0, GameType.QuestDraft);
allSections.add(DeckSection.Main); allSections.add(DeckSection.Main);
allSections.add(DeckSection.Sideboard); allSections.add(DeckSection.Sideboard);
this.questData = questData0; this.questData = questData0;
final CardManager catalogManager = new CardManager(cDetailPicture, false, true); final CardManager catalogManager = new CardManager(cDetailPicture0, false, true);
final CardManager deckManager = new CardManager(cDetailPicture, false, true); final CardManager deckManager = new CardManager(cDetailPicture0, false, true);
catalogManager.setCaption("Sideboard"); catalogManager.setCaption("Sideboard");

View File

@@ -2,6 +2,7 @@ package forge.screens.deckeditor.controllers;
import forge.deck.DeckBase; import forge.deck.DeckBase;
import forge.game.GameType;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
import forge.gui.framework.FScreen; import forge.gui.framework.FScreen;
import forge.item.PaperToken; import forge.item.PaperToken;
@@ -35,14 +36,14 @@ public class CEditorTokenViewer extends ACEditorBase<PaperToken, DeckBase> {
* Child controller for quest card shop UI. * Child controller for quest card shop UI.
* *
*/ */
public CEditorTokenViewer(final CDetailPicture cDetailPicture) { public CEditorTokenViewer(final CDetailPicture cDetailPicture0) {
super(FScreen.TOKEN_VIEWER, cDetailPicture); super(FScreen.TOKEN_VIEWER, cDetailPicture0, GameType.Quest);
FModel.getMagicDb().getAllTokens().preloadTokens(); FModel.getMagicDb().getAllTokens().preloadTokens();
fullCatalogCards = FModel.getMagicDb().getAllTokens().getAllTokens(); fullCatalogCards = FModel.getMagicDb().getAllTokens().getAllTokens();
final TokenManager catalogManager = new TokenManager(getCDetailPicture(), false); final TokenManager catalogManager = new TokenManager(cDetailPicture0, false);
final TokenManager deckManager = new TokenManager(cDetailPicture, false); final TokenManager deckManager = new TokenManager(cDetailPicture0, false);
catalogManager.setCaption("All Tokens"); catalogManager.setCaption("All Tokens");
catalogManager.setAlwaysNonUnique(true); catalogManager.setAlwaysNonUnique(true);
this.setCatalogManager(catalogManager); this.setCatalogManager(catalogManager);

View File

@@ -23,6 +23,7 @@ import com.google.common.collect.Iterables;
import forge.UiCommand; import forge.UiCommand;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckSection; import forge.deck.DeckSection;
import forge.game.GameType;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
import forge.gui.framework.FScreen; import forge.gui.framework.FScreen;
import forge.item.PaperCard; import forge.item.PaperCard;
@@ -63,14 +64,14 @@ public final class CEditorVariant extends CDeckEditor<Deck> {
* all cards are available. * all cards are available.
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
public CEditorVariant(final IStorage<Deck> folder, final Predicate<PaperCard> poolCondition, final DeckSection deckSection0, final FScreen screen0, final CDetailPicture cDetailPicture) { public CEditorVariant(final IStorage<Deck> folder, final Predicate<PaperCard> poolCondition, final DeckSection deckSection0, final FScreen screen0, final CDetailPicture cDetailPicture0) {
super(screen0, cDetailPicture); super(screen0, cDetailPicture0, GameType.Constructed);
this.cardPoolCondition = poolCondition; this.cardPoolCondition = poolCondition;
this.sectionMode = deckSection0; this.sectionMode = deckSection0;
final CardManager catalogManager = new CardManager(cDetailPicture, true, false); final CardManager catalogManager = new CardManager(cDetailPicture0, true, false);
final CardManager deckManager = new CardManager(cDetailPicture, true, false); final CardManager deckManager = new CardManager(cDetailPicture0, true, false);
final Localizer localizer = Localizer.getInstance(); final Localizer localizer = Localizer.getInstance();
catalogManager.setCaption(localizer.getMessage("lblCatalog")); catalogManager.setCaption(localizer.getMessage("lblCatalog"));

View File

@@ -24,6 +24,7 @@ import forge.deck.CardPool;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckGroup; import forge.deck.DeckGroup;
import forge.deck.DeckSection; import forge.deck.DeckSection;
import forge.game.GameType;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
import forge.gui.framework.FScreen; import forge.gui.framework.FScreen;
import forge.item.PaperCard; import forge.item.PaperCard;
@@ -75,11 +76,11 @@ public class CEditorWinstonProcess extends ACEditorBase<PaperCard, DeckGroup> {
* Updates the deck editor UI as necessary draft selection mode. * Updates the deck editor UI as necessary draft selection mode.
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
public CEditorWinstonProcess(final CDetailPicture cDetailPicture) { public CEditorWinstonProcess(final CDetailPicture cDetailPicture0) {
super(FScreen.DRAFTING_PROCESS, cDetailPicture); super(FScreen.DRAFTING_PROCESS, cDetailPicture0, GameType.Draft);
final CardManager catalogManager = new CardManager(cDetailPicture, false, false); final CardManager catalogManager = new CardManager(cDetailPicture0, false, false);
final CardManager deckManager = new CardManager(cDetailPicture, false, false); final CardManager deckManager = new CardManager(cDetailPicture0, false, false);
//hide filters and options panel so more of pack is visible by default //hide filters and options panel so more of pack is visible by default
catalogManager.setHideViewOptions(1, true); catalogManager.setHideViewOptions(1, true);

View File

@@ -0,0 +1,44 @@
package forge.screens.deckeditor.controllers;
import forge.deck.DeckProxy;
import forge.gui.framework.ICDoc;
import forge.itemmanager.ItemManagerConfig;
import forge.screens.deckeditor.views.VOathbreakerDecks;
/**
* Controls the "Oathbreaker Decks" panel in the deck editor UI.
*
* <br><br><i>(C at beginning of class name denotes a control class.)</i>
*
*/
public enum COathbreakerDecks implements ICDoc {
SINGLETON_INSTANCE;
private final VOathbreakerDecks view = VOathbreakerDecks.SINGLETON_INSTANCE;
//========== Overridden methods
@Override
public void register() {
}
/* (non-Javadoc)
* @see forge.gui.framework.ICDoc#initialize()
*/
@Override
public void initialize() {
refresh();
}
public void refresh() {
view.getLstDecks().setPool(DeckProxy.getAllOathbreakerDecks());
}
/* (non-Javadoc)
* @see forge.gui.framework.ICDoc#update()
*/
@Override
public void update() {
view.getLstDecks().setup(ItemManagerConfig.CONSTRUCTED_DECKS);
}
}

View File

@@ -6,7 +6,7 @@ import forge.itemmanager.ItemManagerConfig;
import forge.screens.deckeditor.views.VTinyLeadersDecks; import forge.screens.deckeditor.views.VTinyLeadersDecks;
/** /**
* Controls the "Commander Decks" panel in the deck editor UI. * Controls the "Tiny Leaders Decks" panel in the deck editor UI.
* *
* <br><br><i>(C at beginning of class name denotes a control class.)</i> * <br><br><i>(C at beginning of class name denotes a control class.)</i>
* *

View File

@@ -0,0 +1,100 @@
package forge.screens.deckeditor.views;
import forge.deck.io.DeckPreferences;
import forge.game.GameType;
import forge.gui.framework.DragCell;
import forge.gui.framework.DragTab;
import forge.gui.framework.EDocID;
import forge.gui.framework.IVDoc;
import forge.itemmanager.DeckManager;
import forge.itemmanager.ItemManagerContainer;
import forge.screens.deckeditor.controllers.COathbreakerDecks;
import forge.screens.match.controllers.CDetailPicture;
import forge.util.Localizer;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
/**
* Assembles Swing components of all deck viewer in deck editor.
*
* <br><br><i>(V at beginning of class name denotes a view class.)</i>
*/
public enum VOathbreakerDecks implements IVDoc<COathbreakerDecks> {
/** */
SINGLETON_INSTANCE;
// Fields used with interface IVDoc
private DragCell parentCell;
final Localizer localizer = Localizer.getInstance();
private final DragTab tab = new DragTab(localizer.getMessage("lblOathbreaker"));
private DeckManager lstDecks;
//========== Overridden methods
/* (non-Javadoc)
* @see forge.gui.framework.IVDoc#getDocumentID()
*/
@Override
public EDocID getDocumentID() {
return EDocID.EDITOR_OATHBREAKER;
}
/* (non-Javadoc)
* @see forge.gui.framework.IVDoc#getTabLabel()
*/
@Override
public DragTab getTabLabel() {
return tab;
}
/* (non-Javadoc)
* @see forge.gui.framework.IVDoc#getLayoutControl()
*/
@Override
public COathbreakerDecks getLayoutControl() {
return COathbreakerDecks.SINGLETON_INSTANCE;
}
/* (non-Javadoc)
* @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell)
*/
@Override
public void setParentCell(DragCell cell0) {
this.parentCell = cell0;
}
/* (non-Javadoc)
* @see forge.gui.framework.IVDoc#getParentCell()
*/
@Override
public DragCell getParentCell() {
return this.parentCell;
}
/* (non-Javadoc)
* @see forge.gui.framework.IVDoc#populate()
*/
@Override
public void populate() {
COathbreakerDecks.SINGLETON_INSTANCE.refresh(); //ensure decks refreshed in case any deleted or added since last loaded
JPanel parentBody = parentCell.getBody();
parentBody.setLayout(new MigLayout("insets 5, gap 0, wrap, hidemode 3"));
parentBody.add(new ItemManagerContainer(lstDecks), "push, grow");
String preferredDeck = DeckPreferences.getOathbreakerDeck();
lstDecks.editDeck(lstDecks.stringToItem(preferredDeck));
}
//========== Retrieval methods
/** @return {@link JPanel} */
public DeckManager getLstDecks() {
return lstDecks;
}
public void setCDetailPicture(final CDetailPicture cDetailPicture) {
this.lstDecks = new DeckManager(GameType.Oathbreaker, cDetailPicture);
this.lstDecks.setCaption(localizer.getMessage("lblOathbreakerDecks"));
}
}

View File

@@ -86,6 +86,14 @@ public class CLobby {
view.focusOnAvatar(); view.focusOnAvatar();
} }
}); });
final FDeckChooser fdobcom = view.getOathbreakerDeckChooser(iSlot);
fdobcom.initialize(FPref.OATHBREAKER_DECK_STATES[iSlot], defaultDeckTypeForOathbreakerSlot(iSlot));
fdobcom.populate();
fdobcom.getDecksComboBox().addListener(new IDecksComboBoxListener() {
@Override public final void deckTypeSelected(final DecksComboBoxEvent ev) {
view.focusOnAvatar();
}
});
final FDeckChooser fdtlcom = view.getTinyLeaderDeckChooser(iSlot); final FDeckChooser fdtlcom = view.getTinyLeaderDeckChooser(iSlot);
fdtlcom.initialize(FPref.TINY_LEADER_DECK_STATES[iSlot], defaultDeckTypeForTinyLeaderSlot(iSlot)); fdtlcom.initialize(FPref.TINY_LEADER_DECK_STATES[iSlot], defaultDeckTypeForTinyLeaderSlot(iSlot));
fdtlcom.populate(); fdtlcom.populate();
@@ -135,11 +143,15 @@ public class CLobby {
return iSlot == 0 ? DeckType.COMMANDER_DECK : DeckType.RANDOM_CARDGEN_COMMANDER_DECK; return iSlot == 0 ? DeckType.COMMANDER_DECK : DeckType.RANDOM_CARDGEN_COMMANDER_DECK;
} }
private static DeckType defaultDeckTypeForOathbreakerSlot(final int iSlot) {
return iSlot == 0 ? DeckType.OATHBREAKER_DECK : DeckType.RANDOM_CARDGEN_COMMANDER_DECK;
}
private static DeckType defaultDeckTypeForTinyLeaderSlot(final int iSlot) { private static DeckType defaultDeckTypeForTinyLeaderSlot(final int iSlot) {
return iSlot == 0 ? DeckType.TINY_LEADERS_DECKS : DeckType.RANDOM_CARDGEN_COMMANDER_DECK; return iSlot == 0 ? DeckType.TINY_LEADERS_DECK : DeckType.RANDOM_CARDGEN_COMMANDER_DECK;
} }
private static DeckType defaultDeckTypeForBrawlSlot(final int iSlot) { private static DeckType defaultDeckTypeForBrawlSlot(final int iSlot) {
return iSlot == 0 ? DeckType.BRAWL_DECKS : DeckType.CUSTOM_DECK; return iSlot == 0 ? DeckType.BRAWL_DECK : DeckType.CUSTOM_DECK;
} }
} }

View File

@@ -333,9 +333,10 @@ public class PlayerPanel extends FPanel {
}; };
private void updateVariantControlsVisibility() { private void updateVariantControlsVisibility() {
final boolean isOathbreaker = lobby.hasVariant(GameType.Oathbreaker);
final boolean isTinyLeaders = lobby.hasVariant(GameType.TinyLeaders); final boolean isTinyLeaders = lobby.hasVariant(GameType.TinyLeaders);
final boolean isBrawl = lobby.hasVariant(GameType.Brawl); final boolean isBrawl = lobby.hasVariant(GameType.Brawl);
final boolean isCommanderApplied = mayEdit && (lobby.hasVariant(GameType.Commander) || isTinyLeaders || isBrawl); final boolean isCommanderApplied = mayEdit && (lobby.hasVariant(GameType.Commander) || isOathbreaker || isTinyLeaders || isBrawl);
final boolean isPlanechaseApplied = mayEdit && lobby.hasVariant(GameType.Planechase); final boolean isPlanechaseApplied = mayEdit && lobby.hasVariant(GameType.Planechase);
final boolean isVanguardApplied = mayEdit && lobby.hasVariant(GameType.Vanguard); final boolean isVanguardApplied = mayEdit && lobby.hasVariant(GameType.Vanguard);
final boolean isArchenemyApplied = mayEdit && lobby.hasVariant(GameType.Archenemy); final boolean isArchenemyApplied = mayEdit && lobby.hasVariant(GameType.Archenemy);
@@ -507,7 +508,11 @@ public class PlayerPanel extends FPanel {
cmdDeckSelectorBtn.setCommand(new Runnable() { cmdDeckSelectorBtn.setCommand(new Runnable() {
@Override @Override
public void run() { public void run() {
lobby.setCurrentGameMode(lobby.hasVariant(GameType.TinyLeaders) ? GameType.TinyLeaders : lobby.hasVariant(GameType.Brawl) ? GameType.Brawl : GameType.Commander); lobby.setCurrentGameMode(
lobby.hasVariant(GameType.Oathbreaker) ? GameType.Oathbreaker :
lobby.hasVariant(GameType.TinyLeaders) ? GameType.TinyLeaders :
lobby.hasVariant(GameType.Brawl) ? GameType.Brawl :
GameType.Commander);
cmdDeckSelectorBtn.requestFocusInWindow(); cmdDeckSelectorBtn.requestFocusInWindow();
lobby.changePlayerFocus(index); lobby.changePlayerFocus(index);
} }

View File

@@ -68,15 +68,16 @@ public class VLobby implements ILobbyView {
private final VariantCheckBox vntMomirBasic = new VariantCheckBox(GameType.MomirBasic); private final VariantCheckBox vntMomirBasic = new VariantCheckBox(GameType.MomirBasic);
private final VariantCheckBox vntMoJhoSto = new VariantCheckBox(GameType.MoJhoSto); private final VariantCheckBox vntMoJhoSto = new VariantCheckBox(GameType.MoJhoSto);
private final VariantCheckBox vntCommander = new VariantCheckBox(GameType.Commander); private final VariantCheckBox vntCommander = new VariantCheckBox(GameType.Commander);
private final VariantCheckBox vntOathbreaker = new VariantCheckBox(GameType.Oathbreaker);
private final VariantCheckBox vntTinyLeaders = new VariantCheckBox(GameType.TinyLeaders); private final VariantCheckBox vntTinyLeaders = new VariantCheckBox(GameType.TinyLeaders);
private final VariantCheckBox vntBrawl = new VariantCheckBox(GameType.Brawl); private final VariantCheckBox vntBrawl = new VariantCheckBox(GameType.Brawl);
private final VariantCheckBox vntPlanechase = new VariantCheckBox(GameType.Planechase); private final VariantCheckBox vntPlanechase = new VariantCheckBox(GameType.Planechase);
private final VariantCheckBox vntArchenemy = new VariantCheckBox(GameType.Archenemy); private final VariantCheckBox vntArchenemy = new VariantCheckBox(GameType.Archenemy);
private final VariantCheckBox vntArchenemyRumble = new VariantCheckBox(GameType.ArchenemyRumble); private final VariantCheckBox vntArchenemyRumble = new VariantCheckBox(GameType.ArchenemyRumble);
private final ImmutableList<VariantCheckBox> vntBoxesLocal = private final ImmutableList<VariantCheckBox> vntBoxesLocal =
ImmutableList.of(vntVanguard, vntMomirBasic, vntMoJhoSto, vntCommander, vntBrawl, vntTinyLeaders, vntPlanechase, vntArchenemy, vntArchenemyRumble); ImmutableList.of(vntVanguard, vntMomirBasic, vntMoJhoSto, vntCommander, vntOathbreaker, vntBrawl, vntTinyLeaders, vntPlanechase, vntArchenemy, vntArchenemyRumble);
private final ImmutableList<VariantCheckBox> vntBoxesNetwork = private final ImmutableList<VariantCheckBox> vntBoxesNetwork =
ImmutableList.of(vntVanguard, vntMomirBasic, vntMoJhoSto, vntCommander, vntBrawl, vntTinyLeaders /*, vntPlanechase, vntArchenemy, vntArchenemyRumble */); ImmutableList.of(vntVanguard, vntMomirBasic, vntMoJhoSto, vntCommander, vntOathbreaker, vntBrawl, vntTinyLeaders /*, vntPlanechase, vntArchenemy, vntArchenemyRumble */);
// Player frame elements // Player frame elements
private final JPanel playersFrame = new JPanel(new MigLayout("insets 0, gap 0 5, wrap, hidemode 3")); private final JPanel playersFrame = new JPanel(new MigLayout("insets 0, gap 0 5, wrap, hidemode 3"));
@@ -93,16 +94,8 @@ public class VLobby implements ILobbyView {
private final Deck[] decks = new Deck[MAX_PLAYERS]; private final Deck[] decks = new Deck[MAX_PLAYERS];
// Variants // Variants
private final List<FList<Object>> commanderDeckLists = new ArrayList<FList<Object>>();
private final List<FPanel> commanderDeckPanels = new ArrayList<FPanel>(MAX_PLAYERS);
private final List<FList<Object>> tinyLeadersDeckLists = new ArrayList<FList<Object>>();
private final List<FPanel> tinyLeadersDeckPanels = new ArrayList<FPanel>(MAX_PLAYERS);
private final List<FList<Object>> brawlDeckLists = new ArrayList<FList<Object>>();
private final List<FPanel> brawlDeckPanels = new ArrayList<FPanel>(MAX_PLAYERS);
private final List<FDeckChooser> commanderDeckChoosers = Lists.newArrayListWithCapacity(MAX_PLAYERS); private final List<FDeckChooser> commanderDeckChoosers = Lists.newArrayListWithCapacity(MAX_PLAYERS);
private final List<FDeckChooser> oathbreakerDeckChoosers = Lists.newArrayListWithCapacity(MAX_PLAYERS);
private final List<FDeckChooser> tinyLeadersDeckChoosers = Lists.newArrayListWithCapacity(MAX_PLAYERS); private final List<FDeckChooser> tinyLeadersDeckChoosers = Lists.newArrayListWithCapacity(MAX_PLAYERS);
private final List<FDeckChooser> brawlDeckChoosers = Lists.newArrayListWithCapacity(MAX_PLAYERS); private final List<FDeckChooser> brawlDeckChoosers = Lists.newArrayListWithCapacity(MAX_PLAYERS);
@@ -209,6 +202,8 @@ public class VLobby implements ILobbyView {
fdc.restoreSavedState(); fdc.restoreSavedState();
final FDeckChooser fdcom = getCommanderDeckChooser(iPlayer); final FDeckChooser fdcom = getCommanderDeckChooser(iPlayer);
fdcom.restoreSavedState(); fdcom.restoreSavedState();
final FDeckChooser fdob = getOathbreakerDeckChooser(iPlayer);
fdob.restoreSavedState();
final FDeckChooser fdtl = getTinyLeaderDeckChooser(iPlayer); final FDeckChooser fdtl = getTinyLeaderDeckChooser(iPlayer);
fdtl.restoreSavedState(); fdtl.restoreSavedState();
final FDeckChooser fdbr = getBrawlDeckChooser(iPlayer); final FDeckChooser fdbr = getBrawlDeckChooser(iPlayer);
@@ -238,38 +233,22 @@ public class VLobby implements ILobbyView {
default: default:
break; break;
} }
final FDeckChooser commanderDeckChooser = getCommanderDeckChooser(slot); updateCommanderStyleDeckChooser(getCommanderDeckChooser(slot), type);
commanderDeckChooser.setIsAi(type==LobbySlotType.AI); updateCommanderStyleDeckChooser(getOathbreakerDeckChooser(slot), type);
selectedDeckType = commanderDeckChooser.getSelectedDeckType(); updateCommanderStyleDeckChooser(getTinyLeaderDeckChooser(slot), type);
updateCommanderStyleDeckChooser(getBrawlDeckChooser(slot), type);
}
private void updateCommanderStyleDeckChooser(final FDeckChooser deckChooser, final LobbySlotType type) {
deckChooser.setIsAi(type==LobbySlotType.AI);
DeckType selectedDeckType = deckChooser.getSelectedDeckType();
switch (selectedDeckType){ switch (selectedDeckType){
case RANDOM_CARDGEN_COMMANDER_DECK: case RANDOM_CARDGEN_COMMANDER_DECK:
case RANDOM_COMMANDER_DECK: case RANDOM_COMMANDER_DECK:
commanderDeckChooser.refreshDeckListForAI(); deckChooser.refreshDeckListForAI();
break; break;
default: default:
break; break;
}
final FDeckChooser tinyLeaderDeckChooser = getTinyLeaderDeckChooser(slot);
tinyLeaderDeckChooser.setIsAi(type==LobbySlotType.AI);
selectedDeckType = tinyLeaderDeckChooser.getSelectedDeckType();
switch (selectedDeckType){
case RANDOM_CARDGEN_COMMANDER_DECK:
case RANDOM_COMMANDER_DECK:
tinyLeaderDeckChooser.refreshDeckListForAI();
break;
default:
break;
}
final FDeckChooser brawlDeckChooser = getBrawlDeckChooser(slot);
brawlDeckChooser.setIsAi(type==LobbySlotType.AI);
selectedDeckType = brawlDeckChooser.getSelectedDeckType();
switch (selectedDeckType){
case RANDOM_CARDGEN_COMMANDER_DECK:
case RANDOM_COMMANDER_DECK:
brawlDeckChooser.refreshDeckListForAI();
break;
default:
break;
} }
} }
@@ -297,6 +276,7 @@ public class VLobby implements ILobbyView {
final LobbySlot slot = lobby.getSlot(i); final LobbySlot slot = lobby.getSlot(i);
final FDeckChooser deckChooser = getDeckChooser(i); final FDeckChooser deckChooser = getDeckChooser(i);
final FDeckChooser commanderDeckChooser = getCommanderDeckChooser(i); final FDeckChooser commanderDeckChooser = getCommanderDeckChooser(i);
final FDeckChooser oathbreakerDeckChooser = getOathbreakerDeckChooser(i);
final FDeckChooser tinyLeaderDeckChooser = getTinyLeaderDeckChooser(i); final FDeckChooser tinyLeaderDeckChooser = getTinyLeaderDeckChooser(i);
final FDeckChooser brawlDeckChooser = getBrawlDeckChooser(i); final FDeckChooser brawlDeckChooser = getBrawlDeckChooser(i);
final PlayerPanel panel; final PlayerPanel panel;
@@ -314,6 +294,7 @@ public class VLobby implements ILobbyView {
playersScroll.add(panel, constraints); playersScroll.add(panel, constraints);
deckChooser.restoreSavedState(); deckChooser.restoreSavedState();
commanderDeckChooser.restoreSavedState(); commanderDeckChooser.restoreSavedState();
oathbreakerDeckChooser.restoreSavedState();
tinyLeaderDeckChooser.restoreSavedState(); tinyLeaderDeckChooser.restoreSavedState();
brawlDeckChooser.restoreSavedState(); brawlDeckChooser.restoreSavedState();
if (i == 0) { if (i == 0) {
@@ -341,6 +322,7 @@ public class VLobby implements ILobbyView {
deckChooser.setIsAi(isSlotAI); deckChooser.setIsAi(isSlotAI);
commanderDeckChooser.setIsAi(isSlotAI); commanderDeckChooser.setIsAi(isSlotAI);
oathbreakerDeckChooser.setIsAi(isSlotAI);
tinyLeaderDeckChooser.setIsAi(isSlotAI); tinyLeaderDeckChooser.setIsAi(isSlotAI);
brawlDeckChooser.setIsAi(isSlotAI); brawlDeckChooser.setIsAi(isSlotAI);
if (fullUpdate && (type == LobbySlotType.LOCAL || isSlotAI)) { if (fullUpdate && (type == LobbySlotType.LOCAL || isSlotAI)) {
@@ -439,12 +421,6 @@ public class VLobby implements ILobbyView {
} }
}); });
// Commander deck list
/*buildDeckPanel("Commander Deck", playerIndex, commanderDeckLists, commanderDeckPanels, new ListSelectionListener() {
@Override public final void valueChanged(final ListSelectionEvent e) {
selectCommanderDeck(playerIndex);
}
});*/
final FDeckChooser commanderChooser = new FDeckChooser(null, isPlayerAI(playerIndex), GameType.Commander, true); final FDeckChooser commanderChooser = new FDeckChooser(null, isPlayerAI(playerIndex), GameType.Commander, true);
commanderChooser.getLstDecks().setSelectCommand(new UiCommand() { commanderChooser.getLstDecks().setSelectCommand(new UiCommand() {
@Override public final void run() { @Override public final void run() {
@@ -454,6 +430,15 @@ public class VLobby implements ILobbyView {
commanderChooser.initialize(); commanderChooser.initialize();
commanderDeckChoosers.add(commanderChooser); commanderDeckChoosers.add(commanderChooser);
final FDeckChooser oathbreakerChooser = new FDeckChooser(null, isPlayerAI(playerIndex), GameType.Oathbreaker, true);
oathbreakerChooser.getLstDecks().setSelectCommand(new UiCommand() {
@Override public final void run() {
selectOathbreakerDeck(playerIndex);
}
});
oathbreakerChooser.initialize();
oathbreakerDeckChoosers.add(oathbreakerChooser);
final FDeckChooser tinyLeaderChooser = new FDeckChooser(null, isPlayerAI(playerIndex), GameType.TinyLeaders, true); final FDeckChooser tinyLeaderChooser = new FDeckChooser(null, isPlayerAI(playerIndex), GameType.TinyLeaders, true);
tinyLeaderChooser.getLstDecks().setSelectCommand(new UiCommand() { tinyLeaderChooser.getLstDecks().setSelectCommand(new UiCommand() {
@Override public final void run() { @Override public final void run() {
@@ -472,14 +457,6 @@ public class VLobby implements ILobbyView {
brawlChooser.initialize(); brawlChooser.initialize();
brawlDeckChoosers.add(brawlChooser); brawlDeckChoosers.add(brawlChooser);
/* // Tiny Leaders deck list
buildDeckPanel("Tiny Leaders Deck", playerIndex, tinyLeadersDeckLists, tinyLeadersDeckPanels, new ListSelectionListener() {
@Override public final void valueChanged(final ListSelectionEvent e) {
selectTinyLeadersDeck(playerIndex);
}
});*/
// Planar deck list // Planar deck list
buildDeckPanel(localizer.getMessage("lblPlanarDeck"), playerIndex, planarDeckLists, planarDeckPanels, new ListSelectionListener() { buildDeckPanel(localizer.getMessage("lblPlanarDeck"), playerIndex, planarDeckLists, planarDeckPanels, new ListSelectionListener() {
@Override public final void valueChanged(final ListSelectionEvent e) { @Override public final void valueChanged(final ListSelectionEvent e) {
@@ -525,7 +502,9 @@ public class VLobby implements ILobbyView {
// Full deck selection // Full deck selection
selectMainDeck(playerIndex); selectMainDeck(playerIndex);
selectCommanderDeck(playerIndex); selectCommanderDeck(playerIndex);
selectOathbreakerDeck(playerIndex);
selectTinyLeadersDeck(playerIndex); selectTinyLeadersDeck(playerIndex);
selectBrawlDeck(playerIndex);
// Deck section selection // Deck section selection
selectSchemeDeck(playerIndex); selectSchemeDeck(playerIndex);
@@ -534,7 +513,7 @@ public class VLobby implements ILobbyView {
} }
private void selectMainDeck(final int playerIndex) { private void selectMainDeck(final int playerIndex) {
if (hasVariant(GameType.Commander) || hasVariant(GameType.TinyLeaders) || hasVariant(GameType.Brawl)) { if (hasVariant(GameType.Commander) || hasVariant(GameType.Oathbreaker) || hasVariant(GameType.TinyLeaders) || hasVariant(GameType.Brawl)) {
// These game types use specific deck panel // These game types use specific deck panel
return; return;
} }
@@ -551,7 +530,7 @@ public class VLobby implements ILobbyView {
} }
private void selectCommanderDeck(final int playerIndex) { private void selectCommanderDeck(final int playerIndex) {
if (!hasVariant(GameType.Commander)) { if (!hasVariant(GameType.Commander) && !hasVariant(GameType.Oathbreaker) && !hasVariant(GameType.TinyLeaders) && !hasVariant(GameType.Brawl)) {
// Only these game types use this specific deck panel // Only these game types use this specific deck panel
return; return;
} }
@@ -567,6 +546,23 @@ public class VLobby implements ILobbyView {
mainChooser.saveState(); mainChooser.saveState();
} }
private void selectOathbreakerDeck(final int playerIndex) {
if (!hasVariant(GameType.Oathbreaker)) {
// Only these game types use this specific deck panel
return;
}
final FDeckChooser mainChooser = getOathbreakerDeckChooser(playerIndex);
final DeckType type = mainChooser.getSelectedDeckType();
final Deck deck = mainChooser.getDeck();
final Collection<DeckProxy> selectedDecks = mainChooser.getLstDecks().getSelectedItems();
if (playerIndex < activePlayersNum && lobby.mayEdit(playerIndex)) {
final String text = type.toString() + ": " + Lang.joinHomogenous(selectedDecks, DeckProxy.FN_GET_NAME);
playerPanels.get(playerIndex).setCommanderDeckSelectorButtonText(text);
fireDeckChangeListener(playerIndex, deck);
}
mainChooser.saveState();
}
private void selectTinyLeadersDeck(final int playerIndex) { private void selectTinyLeadersDeck(final int playerIndex) {
if (!hasVariant(GameType.TinyLeaders)) { if (!hasVariant(GameType.TinyLeaders)) {
// Only these game types use this specific deck panel // Only these game types use this specific deck panel
@@ -601,8 +597,6 @@ public class VLobby implements ILobbyView {
mainChooser.saveState(); mainChooser.saveState();
} }
private void selectSchemeDeck(final int playerIndex) { private void selectSchemeDeck(final int playerIndex) {
if (playerIndex >= activePlayersNum || !(hasVariant(GameType.Archenemy) || hasVariant(GameType.ArchenemyRumble))) { if (playerIndex >= activePlayersNum || !(hasVariant(GameType.Archenemy) || hasVariant(GameType.ArchenemyRumble))) {
return; return;
@@ -737,6 +731,9 @@ public class VLobby implements ILobbyView {
case Commander: case Commander:
decksFrame.add(commanderDeckChoosers.get(playerWithFocus), "grow, push"); decksFrame.add(commanderDeckChoosers.get(playerWithFocus), "grow, push");
break; break;
case Oathbreaker:
decksFrame.add(oathbreakerDeckChoosers.get(playerWithFocus), "grow, push");
break;
case TinyLeaders: case TinyLeaders:
decksFrame.add(tinyLeadersDeckChoosers.get(playerWithFocus), "grow, push"); decksFrame.add(tinyLeadersDeckChoosers.get(playerWithFocus), "grow, push");
break; break;
@@ -790,6 +787,10 @@ public class VLobby implements ILobbyView {
return commanderDeckChoosers.get(playernum); return commanderDeckChoosers.get(playernum);
} }
public final FDeckChooser getOathbreakerDeckChooser(final int playernum) {
return oathbreakerDeckChoosers.get(playernum);
}
public final FDeckChooser getTinyLeaderDeckChooser(final int playernum) { public final FDeckChooser getTinyLeaderDeckChooser(final int playernum) {
return tinyLeadersDeckChoosers.get(playernum); return tinyLeadersDeckChoosers.get(playernum);
} }
@@ -946,21 +947,6 @@ public class VLobby implements ILobbyView {
return planarDeckLists; return planarDeckLists;
} }
/** Gets the list of commander deck lists. */
public List<FList<Object>> getCommanderDeckLists() {
return commanderDeckLists;
}
/** Gets the list of tiny leaders deck lists. */
public List<FList<Object>> getTinyLeadersDeckLists() {
return tinyLeadersDeckLists;
}
/** Gets the list of tiny leaders deck lists. */
public List<FList<Object>> getBrawlDeckLists() {
return brawlDeckLists;
}
/** Gets the list of scheme deck lists. */ /** Gets the list of scheme deck lists. */
public List<FList<Object>> getSchemeDeckLists() { public List<FList<Object>> getSchemeDeckLists() {
return schemeDeckLists; return schemeDeckLists;

View File

@@ -189,13 +189,14 @@ public class FDeckChooser extends FScreen {
case Constructed: case Constructed:
break; //delay initialize for constructed until saved decks can be reloaded break; //delay initialize for constructed until saved decks can be reloaded
case Commander: case Commander:
case Oathbreaker:
case TinyLeaders: case TinyLeaders:
case Brawl: case Brawl:
case Gauntlet: case Gauntlet:
initialize(null, DeckType.CUSTOM_DECK); initialize(null, DeckType.CUSTOM_DECK);
break; break;
case DeckManager: case DeckManager:
initialize(null, DeckType.CONSTRUCTED_DECK); initialize(null, DeckPreferences.getSelectedDeckType());
break; break;
default: default:
initialize(null, DeckType.RANDOM_DECK); initialize(null, DeckType.RANDOM_DECK);
@@ -225,6 +226,9 @@ public class FDeckChooser extends FScreen {
case Commander: case Commander:
lstDecks.setSelectedString(DeckPreferences.getCommanderDeck()); lstDecks.setSelectedString(DeckPreferences.getCommanderDeck());
break; break;
case Oathbreaker:
lstDecks.setSelectedString(DeckPreferences.getOathbreakerDeck());
break;
case TinyLeaders: case TinyLeaders:
lstDecks.setSelectedString(DeckPreferences.getTinyLeadersDeck()); lstDecks.setSelectedString(DeckPreferences.getTinyLeadersDeck());
break; break;
@@ -242,22 +246,25 @@ public class FDeckChooser extends FScreen {
case COMMANDER_DECK: case COMMANDER_DECK:
lstDecks.setSelectedString(DeckPreferences.getCommanderDeck()); lstDecks.setSelectedString(DeckPreferences.getCommanderDeck());
break; break;
case TINY_LEADERS_DECKS: case OATHBREAKER_DECK:
lstDecks.setSelectedString(DeckPreferences.getOathbreakerDeck());
break;
case TINY_LEADERS_DECK:
lstDecks.setSelectedString(DeckPreferences.getTinyLeadersDeck()); lstDecks.setSelectedString(DeckPreferences.getTinyLeadersDeck());
break; break;
case BRAWL_DECKS: case BRAWL_DECK:
lstDecks.setSelectedString(DeckPreferences.getBrawlDeck()); lstDecks.setSelectedString(DeckPreferences.getBrawlDeck());
break; break;
case SCHEME_DECKS: case SCHEME_DECK:
lstDecks.setSelectedString(DeckPreferences.getSchemeDeck()); lstDecks.setSelectedString(DeckPreferences.getSchemeDeck());
break; break;
case PLANAR_DECKS: case PLANAR_DECK:
lstDecks.setSelectedString(DeckPreferences.getPlanarDeck()); lstDecks.setSelectedString(DeckPreferences.getPlanarDeck());
break; break;
case DRAFT_DECKS: case DRAFT_DECK:
lstDecks.setSelectedString(DeckPreferences.getDraftDeck()); lstDecks.setSelectedString(DeckPreferences.getDraftDeck());
break; break;
case SEALED_DECKS: case SEALED_DECK:
lstDecks.setSelectedString(DeckPreferences.getSealedDeck()); lstDecks.setSelectedString(DeckPreferences.getSealedDeck());
break; break;
default: default:
@@ -275,10 +282,10 @@ public class FDeckChooser extends FScreen {
private void createNewDeck() { private void createNewDeck() {
FDeckEditor editor; FDeckEditor editor;
switch (selectedDeckType) { switch (selectedDeckType) {
case DRAFT_DECKS: case DRAFT_DECK:
NewGameScreen.BoosterDraft.open(); NewGameScreen.BoosterDraft.open();
return; return;
case SEALED_DECKS: case SEALED_DECK:
NewGameScreen.SealedDeck.open(); NewGameScreen.SealedDeck.open();
return; return;
case COLOR_DECK: case COLOR_DECK:
@@ -318,12 +325,13 @@ public class FDeckChooser extends FScreen {
if (lstDecks.getGameType() == GameType.DeckManager) { if (lstDecks.getGameType() == GameType.DeckManager) {
switch (selectedDeckType) { switch (selectedDeckType) {
case COMMANDER_DECK: case COMMANDER_DECK:
case TINY_LEADERS_DECKS: case OATHBREAKER_DECK:
case BRAWL_DECKS: case TINY_LEADERS_DECK:
case SCHEME_DECKS: case BRAWL_DECK:
case PLANAR_DECKS: case SCHEME_DECK:
case DRAFT_DECKS: case PLANAR_DECK:
case SEALED_DECKS: case DRAFT_DECK:
case SEALED_DECK:
break; break;
default: default:
setSelectedDeckType(DeckType.CONSTRUCTED_DECK); setSelectedDeckType(DeckType.CONSTRUCTED_DECK);
@@ -347,12 +355,13 @@ public class FDeckChooser extends FScreen {
case CUSTOM_DECK: case CUSTOM_DECK:
case CONSTRUCTED_DECK: case CONSTRUCTED_DECK:
case COMMANDER_DECK: case COMMANDER_DECK:
case TINY_LEADERS_DECKS: case OATHBREAKER_DECK:
case BRAWL_DECKS: case TINY_LEADERS_DECK:
case SCHEME_DECKS: case BRAWL_DECK:
case PLANAR_DECKS: case SCHEME_DECK:
case DRAFT_DECKS: case PLANAR_DECK:
case SEALED_DECKS: case DRAFT_DECK:
case SEALED_DECK:
editDeck(deck); editDeck(deck);
break; break;
default: default:
@@ -390,23 +399,27 @@ public class FDeckChooser extends FScreen {
switch (selectedDeckType) { switch (selectedDeckType) {
case COMMANDER_DECK: case COMMANDER_DECK:
return EditorType.Commander; return EditorType.Commander;
case TINY_LEADERS_DECKS: case OATHBREAKER_DECK:
return EditorType.Oathbreaker;
case TINY_LEADERS_DECK:
return EditorType.TinyLeaders; return EditorType.TinyLeaders;
case BRAWL_DECKS: case BRAWL_DECK:
return EditorType.Brawl; return EditorType.Brawl;
case SCHEME_DECKS: case SCHEME_DECK:
return EditorType.Archenemy; return EditorType.Archenemy;
case PLANAR_DECKS: case PLANAR_DECK:
return EditorType.Planechase; return EditorType.Planechase;
case DRAFT_DECKS: case DRAFT_DECK:
return EditorType.Draft; return EditorType.Draft;
case SEALED_DECKS: case SEALED_DECK:
return EditorType.Sealed; return EditorType.Sealed;
default: default:
return EditorType.Constructed; return EditorType.Constructed;
} }
case Commander: case Commander:
return EditorType.Commander; return EditorType.Commander;
case Oathbreaker:
return EditorType.Oathbreaker;
case TinyLeaders: case TinyLeaders:
return EditorType.TinyLeaders; return EditorType.TinyLeaders;
case Brawl: case Brawl:
@@ -426,6 +439,9 @@ public class FDeckChooser extends FScreen {
case Commander: case Commander:
DeckPreferences.setCommanderDeck(deck.getName()); DeckPreferences.setCommanderDeck(deck.getName());
break; break;
case Oathbreaker:
DeckPreferences.setOathbreakerDeck(deck.getName());
break;
case TinyLeaders: case TinyLeaders:
DeckPreferences.setTinyLeadersDeck(deck.getName()); DeckPreferences.setTinyLeadersDeck(deck.getName());
break; break;
@@ -477,6 +493,7 @@ public class FDeckChooser extends FScreen {
cmbDeckTypes.addItem(DeckType.NET_DECK); cmbDeckTypes.addItem(DeckType.NET_DECK);
break; break;
case Commander: case Commander:
case Oathbreaker:
case TinyLeaders: case TinyLeaders:
case Brawl: case Brawl:
cmbDeckTypes.addItem(DeckType.CUSTOM_DECK); cmbDeckTypes.addItem(DeckType.CUSTOM_DECK);
@@ -490,12 +507,13 @@ public class FDeckChooser extends FScreen {
case DeckManager: case DeckManager:
cmbDeckTypes.addItem(DeckType.CONSTRUCTED_DECK); cmbDeckTypes.addItem(DeckType.CONSTRUCTED_DECK);
cmbDeckTypes.addItem(DeckType.COMMANDER_DECK); cmbDeckTypes.addItem(DeckType.COMMANDER_DECK);
cmbDeckTypes.addItem(DeckType.TINY_LEADERS_DECKS); cmbDeckTypes.addItem(DeckType.OATHBREAKER_DECK);
cmbDeckTypes.addItem(DeckType.BRAWL_DECKS); cmbDeckTypes.addItem(DeckType.TINY_LEADERS_DECK);
cmbDeckTypes.addItem(DeckType.SCHEME_DECKS); cmbDeckTypes.addItem(DeckType.BRAWL_DECK);
cmbDeckTypes.addItem(DeckType.PLANAR_DECKS); cmbDeckTypes.addItem(DeckType.SCHEME_DECK);
cmbDeckTypes.addItem(DeckType.DRAFT_DECKS); cmbDeckTypes.addItem(DeckType.PLANAR_DECK);
cmbDeckTypes.addItem(DeckType.SEALED_DECKS); cmbDeckTypes.addItem(DeckType.DRAFT_DECK);
cmbDeckTypes.addItem(DeckType.SEALED_DECK);
cmbDeckTypes.addItem(DeckType.PRECONSTRUCTED_DECK); cmbDeckTypes.addItem(DeckType.PRECONSTRUCTED_DECK);
cmbDeckTypes.addItem(DeckType.QUEST_OPPONENT_DECK); cmbDeckTypes.addItem(DeckType.QUEST_OPPONENT_DECK);
cmbDeckTypes.addItem(DeckType.NET_DECK); cmbDeckTypes.addItem(DeckType.NET_DECK);
@@ -586,6 +604,10 @@ public class FDeckChooser extends FScreen {
pool = DeckProxy.getAllCommanderDecks(); pool = DeckProxy.getAllCommanderDecks();
config = ItemManagerConfig.COMMANDER_DECKS; config = ItemManagerConfig.COMMANDER_DECKS;
break; break;
case Oathbreaker:
pool = DeckProxy.getAllOathbreakerDecks();
config = ItemManagerConfig.COMMANDER_DECKS;
break;
case TinyLeaders: case TinyLeaders:
pool = DeckProxy.getAllTinyLeadersDecks(); pool = DeckProxy.getAllTinyLeadersDecks();
config = ItemManagerConfig.COMMANDER_DECKS; config = ItemManagerConfig.COMMANDER_DECKS;
@@ -616,11 +638,15 @@ public class FDeckChooser extends FScreen {
pool = DeckProxy.getAllCommanderDecks(); pool = DeckProxy.getAllCommanderDecks();
config = ItemManagerConfig.COMMANDER_DECKS; config = ItemManagerConfig.COMMANDER_DECKS;
break; break;
case TINY_LEADERS_DECKS: case OATHBREAKER_DECK:
pool = DeckProxy.getAllOathbreakerDecks();
config = ItemManagerConfig.COMMANDER_DECKS;
break;
case TINY_LEADERS_DECK:
pool = DeckProxy.getAllTinyLeadersDecks(); pool = DeckProxy.getAllTinyLeadersDecks();
config = ItemManagerConfig.COMMANDER_DECKS; config = ItemManagerConfig.COMMANDER_DECKS;
break; break;
case BRAWL_DECKS: case BRAWL_DECK:
pool = DeckProxy.getAllBrawlDecks(); pool = DeckProxy.getAllBrawlDecks();
config = ItemManagerConfig.COMMANDER_DECKS; config = ItemManagerConfig.COMMANDER_DECKS;
break; break;
@@ -635,19 +661,19 @@ public class FDeckChooser extends FScreen {
} }
config = ItemManagerConfig.STRING_ONLY; config = ItemManagerConfig.STRING_ONLY;
break; break;
case SCHEME_DECKS: case SCHEME_DECK:
pool = DeckProxy.getAllSchemeDecks(); pool = DeckProxy.getAllSchemeDecks();
config = ItemManagerConfig.SCHEME_DECKS; config = ItemManagerConfig.SCHEME_DECKS;
break; break;
case PLANAR_DECKS: case PLANAR_DECK:
pool = DeckProxy.getAllPlanarDecks(); pool = DeckProxy.getAllPlanarDecks();
config = ItemManagerConfig.PLANAR_DECKS; config = ItemManagerConfig.PLANAR_DECKS;
break; break;
case DRAFT_DECKS: case DRAFT_DECK:
pool = DeckProxy.getAllDraftDecks(); pool = DeckProxy.getAllDraftDecks();
config = ItemManagerConfig.DRAFT_DECKS; config = ItemManagerConfig.DRAFT_DECKS;
break; break;
case SEALED_DECKS: case SEALED_DECK:
pool = DeckProxy.getAllSealedDecks(); pool = DeckProxy.getAllSealedDecks();
config = ItemManagerConfig.SEALED_DECKS; config = ItemManagerConfig.SEALED_DECKS;
break; break;
@@ -678,22 +704,21 @@ public class FDeckChooser extends FScreen {
config = ItemManagerConfig.STRING_ONLY; config = ItemManagerConfig.STRING_ONLY;
break; break;
case LEGACY_CARDGEN_DECK: case LEGACY_CARDGEN_DECK:
maxSelections = 1; maxSelections = 1;
pool= new ArrayList<>(); pool= new ArrayList<>();
if(FModel.isdeckGenMatrixLoaded()) { if(FModel.isdeckGenMatrixLoaded()) {
pool = ArchetypeDeckGenerator.getMatrixDecks(FModel.getFormats().get("Legacy"), isAi); pool = ArchetypeDeckGenerator.getMatrixDecks(FModel.getFormats().get("Legacy"), isAi);
} }
config = ItemManagerConfig.STRING_ONLY; config = ItemManagerConfig.STRING_ONLY;
break; break;
case VINTAGE_CARDGEN_DECK: case VINTAGE_CARDGEN_DECK:
maxSelections = 1; maxSelections = 1;
pool= new ArrayList<>(); pool= new ArrayList<>();
if(FModel.isdeckGenMatrixLoaded()) { if(FModel.isdeckGenMatrixLoaded()) {
pool = ArchetypeDeckGenerator.getMatrixDecks(FModel.getFormats().get("Vintage"), isAi); pool = ArchetypeDeckGenerator.getMatrixDecks(FModel.getFormats().get("Vintage"), isAi);
} }
config = ItemManagerConfig.STRING_ONLY; config = ItemManagerConfig.STRING_ONLY;
break; break;
case MODERN_COLOR_DECK: case MODERN_COLOR_DECK:
maxSelections = 3; maxSelections = 3;
pool = ColorDeckGenerator.getColorDecks(lstDecks, FModel.getFormats().getModern().getFilterPrinted(), isAi); pool = ColorDeckGenerator.getColorDecks(lstDecks, FModel.getFormats().getModern().getFilterPrinted(), isAi);
@@ -770,8 +795,8 @@ public class FDeckChooser extends FScreen {
btnRandom.setText("Test Deck"); btnRandom.setText("Test Deck");
switch (selectedDeckType) { switch (selectedDeckType) {
case SCHEME_DECKS: case SCHEME_DECK:
case PLANAR_DECKS: //don't allow testing secondary decks this way case PLANAR_DECK: //don't allow testing secondary decks this way
btnRandom.setEnabled(false); btnRandom.setEnabled(false);
break; break;
default: default:
@@ -794,6 +819,9 @@ public class FDeckChooser extends FScreen {
else { else {
lstDecks.setSelectedIndex(0); lstDecks.setSelectedIndex(0);
} }
if (lstDecks.getGameType() == GameType.DeckManager) {
DeckPreferences.setSelectedDeckType(deckType); //update saved Deck Manager type
}
} }
} }
@@ -1016,13 +1044,19 @@ public class FDeckChooser extends FScreen {
return; return;
} }
if (selectedDeckType == DeckType.TINY_LEADERS_DECKS) { if (selectedDeckType == DeckType.OATHBREAKER_DECK) {
//cannot create gauntlet for oathbreaker decks, so just start single match
testVariantDeck(userDeck, GameType.Oathbreaker);
return;
}
if (selectedDeckType == DeckType.TINY_LEADERS_DECK) {
//cannot create gauntlet for tiny leaders decks, so just start single match //cannot create gauntlet for tiny leaders decks, so just start single match
testVariantDeck(userDeck, GameType.TinyLeaders); testVariantDeck(userDeck, GameType.TinyLeaders);
return; return;
} }
if (selectedDeckType == DeckType.BRAWL_DECKS) { if (selectedDeckType == DeckType.BRAWL_DECK) {
//cannot create gauntlet for tiny leaders decks, so just start single match //cannot create gauntlet for tiny leaders decks, so just start single match
testVariantDeck(userDeck, GameType.Brawl); testVariantDeck(userDeck, GameType.Brawl);
return; return;

View File

@@ -79,6 +79,12 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
return new Deck(); return new Deck();
} }
}), null), }), null),
Oathbreaker(new DeckController<Deck>(FModel.getDecks().getOathbreaker(), new Supplier<Deck>() {
@Override
public Deck get() {
return new Deck();
}
}), null),
TinyLeaders(new DeckController<Deck>(FModel.getDecks().getTinyLeaders(), new Supplier<Deck>() { TinyLeaders(new DeckController<Deck>(FModel.getDecks().getTinyLeaders(), new Supplier<Deck>() {
@Override @Override
public Deck get() { public Deck get() {
@@ -185,6 +191,13 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
new DeckSectionPage(DeckSection.Commander, ItemManagerConfig.COMMANDER_SECTION), new DeckSectionPage(DeckSection.Commander, ItemManagerConfig.COMMANDER_SECTION),
new DeckSectionPage(DeckSection.Sideboard) new DeckSectionPage(DeckSection.Sideboard)
}; };
case Oathbreaker:
return new DeckEditorPage[] {
new CatalogPage(ItemManagerConfig.CARD_CATALOG),
new DeckSectionPage(DeckSection.Main),
new DeckSectionPage(DeckSection.Commander, ItemManagerConfig.OATHBREAKER_SECTION, "Oathbreaker", FSkinImage.COMMANDER),
new DeckSectionPage(DeckSection.Sideboard)
};
case Archenemy: case Archenemy:
return new DeckEditorPage[] { return new DeckEditorPage[] {
new CatalogPage(ItemManagerConfig.SCHEME_POOL), new CatalogPage(ItemManagerConfig.SCHEME_POOL),
@@ -509,6 +522,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
case QuestDraft: case QuestDraft:
return CardLimit.None; return CardLimit.None;
case Commander: case Commander:
case Oathbreaker:
case TinyLeaders: case TinyLeaders:
case Brawl: case Brawl:
case PlanarConquest: case PlanarConquest:
@@ -782,7 +796,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
return additions; return additions;
} }
private int getMaxMoveQuantity(boolean isAddMenu, boolean isAddSource) { protected int getMaxMoveQuantity(boolean isAddMenu, boolean isAddSource) {
ItemPool<PaperCard> selectedItemPool = cardManager.getSelectedItemPool(); ItemPool<PaperCard> selectedItemPool = cardManager.getSelectedItemPool();
if (isAddMenu) { if (isAddMenu) {
selectedItemPool = getAllowedAdditions(selectedItemPool, isAddSource); selectedItemPool = getAllowedAdditions(selectedItemPool, isAddSource);
@@ -820,6 +834,119 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
})); }));
} }
protected void addCommanderItems(final FDropDownMenu menu, final PaperCard card, boolean isAddMenu, boolean isAddSource) {
if (parentScreen.getCommanderPage() == null) {
return;
}
boolean isLegalCommander;
String captionSuffix = "Commander";
switch (parentScreen.editorType) {
case Brawl:
isLegalCommander = card.getRules().canBeBrawlCommander();
break;
case Oathbreaker:
isLegalCommander = card.getRules().canBeOathbreaker();
captionSuffix = "Oathbreaker";
break;
case PlanarConquest:
isLegalCommander = false; //don't set commander this way in Planar Conquest
break;
default:
isLegalCommander = DeckFormat.Commander.isLegalCommander(card.getRules());
break;
}
if (isLegalCommander && !parentScreen.getCommanderPage().cardManager.getPool().contains(card)) {
addItem(menu, "Set", "as " + captionSuffix, parentScreen.getCommanderPage().getIcon(), isAddMenu, isAddSource, new Callback<Integer>() {
@Override
public void run(Integer result) {
if (result == null || result <= 0) { return; }
setCommander(card);
}
});
}
if (canHavePartnerCommander() && card.getRules().canBePartnerCommander()) {
addItem(menu, "Set", "as Partner " + captionSuffix, parentScreen.getCommanderPage().getIcon(), isAddMenu, isAddSource, new Callback<Integer>() {
@Override
public void run(Integer result) {
if (result == null || result <= 0) { return; }
setPartnerCommander(card);
}
});
}
if (canHaveSignatureSpell() && card.getRules().canBeSignatureSpell()) {
addItem(menu, "Set", "as Signature Spell", FSkinImage.SORCERY, isAddMenu, isAddSource, new Callback<Integer>() {
@Override
public void run(Integer result) {
if (result == null || result <= 0) { return; }
setSignatureSpell(card);
}
});
}
}
protected boolean needsCommander() {
return parentScreen.getCommanderPage() != null && parentScreen.getDeck().getCommanders().isEmpty();
}
protected boolean canHavePartnerCommander() {
if (parentScreen.editorType == EditorType.Oathbreaker) {
return false; //at least for now, simplify Oathbreaker by not supporting partners, since there's only one set of partner planeswalkers anyway
}
return parentScreen.getCommanderPage() != null && parentScreen.getDeck().getCommanders().size() == 1
&& parentScreen.getDeck().getCommanders().get(0).getRules().canBePartnerCommander();
}
protected boolean canOnlyBePartnerCommander(final PaperCard card) {
if (parentScreen.getCommanderPage() == null) {
return false;
}
byte cmdCI = 0;
for (final PaperCard p : parentScreen.getDeck().getCommanders()) {
cmdCI |= p.getRules().getColorIdentity().getColor();
}
return !card.getRules().getColorIdentity().hasNoColorsExcept(cmdCI);
}
protected boolean canHaveSignatureSpell() {
return parentScreen.editorType == EditorType.Oathbreaker && parentScreen.getDeck().getOathbreaker() != null;
}
protected void setCommander(PaperCard card) {
if (!cardManager.isInfinite()) {
removeCard(card);
}
CardPool newPool = new CardPool();
newPool.add(card);
parentScreen.getCommanderPage().setCards(newPool);
refresh(); //refresh so cards shown that match commander's color identity
}
protected void setPartnerCommander(PaperCard card) {
if (!cardManager.isInfinite()) {
removeCard(card);
}
parentScreen.getCommanderPage().addCard(card);
refresh(); //refresh so cards shown that match commander's color identity
}
protected void setSignatureSpell(PaperCard card) {
if (!cardManager.isInfinite()) {
removeCard(card);
}
PaperCard signatureSpell = parentScreen.getDeck().getSignatureSpell();
if (signatureSpell != null) {
parentScreen.getCommanderPage().removeCard(signatureSpell); //remove existing signature spell if any
}
parentScreen.getCommanderPage().addCard(card);
//refreshing isn't needed since color identity won't change from signature spell
}
public void refresh() {
//not needed by default
}
@Override @Override
protected void doLayout(float width, float height) { protected void doLayout(float width, float height) {
float x = 0; float x = 0;
@@ -887,6 +1014,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
} }
} }
@Override
public void refresh() { public void refresh() {
Predicate<PaperCard> additionalFilter = null; Predicate<PaperCard> additionalFilter = null;
final EditorType editorType = parentScreen.getEditorType(); final EditorType editorType = parentScreen.getEditorType();
@@ -910,36 +1038,50 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
cardManager.setPool(ConquestUtil.getAvailablePool(parentScreen.getDeck())); cardManager.setPool(ConquestUtil.getAvailablePool(parentScreen.getDeck()));
break; break;
case Commander: case Commander:
case Oathbreaker:
case TinyLeaders: case TinyLeaders:
case Brawl: case Brawl:
final List<PaperCard> commanders = parentScreen.getDeck().getCommanders(); final List<PaperCard> commanders = parentScreen.getDeck().getCommanders();
if (commanders.isEmpty()) { if (commanders.isEmpty()) {
//if no commander set for deck, only show valid commanders //if no commander set for deck, only show valid commanders
switch (editorType) { switch (editorType) {
case TinyLeaders: case Commander:
case Commander: additionalFilter = DeckFormat.Commander.isLegalCommanderPredicate();
additionalFilter = DeckFormat.Commander.isLegalCommanderPredicate(); cardManager.setCaption("Commanders");
break; break;
case Brawl: case Oathbreaker:
additionalFilter = DeckFormat.Brawl.isLegalCommanderPredicate(); additionalFilter = DeckFormat.Oathbreaker.isLegalCommanderPredicate();
break; cardManager.setCaption("Oathbreakers");
default: break;
// Do nothing case TinyLeaders:
additionalFilter = DeckFormat.TinyLeaders.isLegalCommanderPredicate();
cardManager.setCaption("Commanders");
break;
case Brawl:
additionalFilter = DeckFormat.Brawl.isLegalCommanderPredicate();
cardManager.setCaption("Commanders");
break;
default:
// Do nothing
} }
cardManager.setCaption("Commanders");
} }
else { else {
//if a commander has been set, only show cards that match its color identity //if a commander has been set, only show cards that match its color identity
switch (editorType) { switch (editorType) {
case TinyLeaders: case Commander:
case Commander: additionalFilter = DeckFormat.Commander.isLegalCardForCommanderPredicate(commanders);
additionalFilter = DeckFormat.Commander.isLegalCardForCommanderOrLegalPartnerPredicate(commanders); break;
break; case Oathbreaker:
case Brawl: additionalFilter = DeckFormat.Oathbreaker.isLegalCardForCommanderPredicate(commanders);
additionalFilter = DeckFormat.Brawl.isLegalCardForCommanderOrLegalPartnerPredicate(commanders); break;
break; case TinyLeaders:
default: additionalFilter = DeckFormat.TinyLeaders.isLegalCardForCommanderPredicate(commanders);
// Do nothing break;
case Brawl:
additionalFilter = DeckFormat.Brawl.isLegalCardForCommanderPredicate(commanders);
break;
default:
// Do nothing
} }
cardManager.setCaption("Cards"); cardManager.setCaption("Cards");
} }
@@ -957,59 +1099,22 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
@Override @Override
protected void onCardActivated(PaperCard card) { protected void onCardActivated(PaperCard card) {
if (canOnlyBePartnerCommander(card)) { if (getMaxMoveQuantity(true, true) == 0) {
return; // don't auto-change commander unexpectedly return; //don't add card if maximum copies of card already in deck
} }
if (needsCommander()) { if (needsCommander()) {
setCommander(card); //handle special case of setting commander setCommander(card); //handle special case of setting commander
return; return;
} }
if (canOnlyBePartnerCommander(card)) {
return; //don't auto-change commander unexpectedly
}
if (!cardManager.isInfinite()) { if (!cardManager.isInfinite()) {
removeCard(card); removeCard(card);
} }
parentScreen.getMainDeckPage().addCard(card); parentScreen.getMainDeckPage().addCard(card);
} }
private boolean needsCommander() {
return parentScreen.getCommanderPage() != null && parentScreen.getDeck().getCommanders().isEmpty();
}
private boolean canHavePartnerCommander() {
return parentScreen.getCommanderPage() != null && parentScreen.getDeck().getCommanders().size() == 1
&& parentScreen.getDeck().getCommanders().get(0).getRules().canBePartnerCommander();
}
private boolean canOnlyBePartnerCommander(final PaperCard card) {
if (parentScreen.getCommanderPage() == null) {
return false;
}
byte cmdCI = 0;
for (final PaperCard p : parentScreen.getDeck().getCommanders()) {
cmdCI |= p.getRules().getColorIdentity().getColor();
}
return !card.getRules().getColorIdentity().hasNoColorsExcept(cmdCI);
}
private void setCommander(PaperCard card) {
if (!cardManager.isInfinite()) {
removeCard(card);
}
CardPool newPool = new CardPool();
newPool.add(card);
parentScreen.getCommanderPage().setCards(newPool);
refresh(); //refresh so cards shown that match commander's color identity
}
private void setPartnerCommander(PaperCard card) {
if (!cardManager.isInfinite()) {
removeCard(card);
}
parentScreen.getCommanderPage().addCard(card, 1);
refresh(); //refresh so cards shown that match commander's color identity
}
@Override @Override
protected void buildMenu(final FDropDownMenu menu, final PaperCard card) { protected void buildMenu(final FDropDownMenu menu, final PaperCard card) {
if (!needsCommander() && !canOnlyBePartnerCommander(card)) { if (!needsCommander() && !canOnlyBePartnerCommander(card)) {
@@ -1038,32 +1143,8 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
}); });
} }
} }
if (parentScreen.getCommanderPage() != null) {
boolean isLegalCommander; addCommanderItems(menu, card, true, true);
if(parentScreen.editorType.equals(EditorType.Brawl)){
isLegalCommander = card.getRules().canBeBrawlCommander();
}else{
isLegalCommander = DeckFormat.Commander.isLegalCommander(card.getRules());
}
if (parentScreen.editorType != EditorType.PlanarConquest && isLegalCommander && !parentScreen.getCommanderPage().cardManager.getPool().contains(card)) {
addItem(menu, "Set", "as Commander", parentScreen.getCommanderPage().getIcon(), true, true, new Callback<Integer>() {
@Override
public void run(Integer result) {
if (result == null || result <= 0) { return; }
setCommander(card);
}
});
}
if (canHavePartnerCommander() && card.getRules().canBePartnerCommander()) {
addItem(menu, "Set", "as Partner Commander", parentScreen.getCommanderPage().getIcon(), true, true, new Callback<Integer>() {
@Override
public void run(Integer result) {
if (result == null || result <= 0) { return; }
setPartnerCommander(card);
}
});
}
}
if (parentScreen.getEditorType() == EditorType.Constructed) { if (parentScreen.getEditorType() == EditorType.Constructed) {
//add option to add or remove card from favorites //add option to add or remove card from favorites
@@ -1277,6 +1358,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
} }
}); });
} }
addCommanderItems(menu, card, false, false);
break; break;
case Sideboard: case Sideboard:
addItem(menu, "Add", null, FSkinImage.PLUS, true, false, new Callback<Integer>() { addItem(menu, "Add", null, FSkinImage.PLUS, true, false, new Callback<Integer>() {
@@ -1315,6 +1397,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
parentScreen.getMainDeckPage().addCard(card, result); parentScreen.getMainDeckPage().addCard(card, result);
} }
}); });
addCommanderItems(menu, card, false, false);
break; break;
case Commander: case Commander:
if (parentScreen.editorType != EditorType.PlanarConquest || isPartnerCommander(card)) { if (parentScreen.editorType != EditorType.PlanarConquest || isPartnerCommander(card)) {
@@ -1379,24 +1462,6 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
}); });
break; break;
} }
if (parentScreen.editorType != EditorType.PlanarConquest && parentScreen.getCommanderPage() != null && deckSection != DeckSection.Commander) {
if (card.getRules().getType().isLegendary() && card.getRules().getType().isCreature() && !parentScreen.getCommanderPage().cardManager.getPool().contains(card)) {
addItem(menu, "Set", "as Commander", parentScreen.getCommanderPage().getIcon(), false, false, new Callback<Integer>() {
@Override
public void run(Integer result) {
if (result == null || result <= 0) { return; }
removeCard(card, result);
CardPool newPool = new CardPool();
newPool.add(card, result);
parentScreen.getCommanderPage().setCards(newPool);
parentScreen.getCatalogPage().refresh(); //ensure available cards updated based on color identity
}
});
}
}
} }
private boolean isPartnerCommander(final PaperCard card) { private boolean isPartnerCommander(final PaperCard card) {
@@ -1407,7 +1472,6 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
PaperCard firstCmdr = parentScreen.getDeck().getCommanders().get(0); PaperCard firstCmdr = parentScreen.getDeck().getCommanders().get(0);
return !card.getName().equals(firstCmdr.getName()); return !card.getName().equals(firstCmdr.getName());
} }
} }
private static class DraftPackPage extends CatalogPage { private static class DraftPackPage extends CatalogPage {
@@ -1629,6 +1693,9 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
case Commander: case Commander:
DeckPreferences.setCommanderDeck(deckStr); DeckPreferences.setCommanderDeck(deckStr);
break; break;
case Oathbreaker:
DeckPreferences.setOathbreakerDeck(deckStr);
break;
case TinyLeaders: case TinyLeaders:
DeckPreferences.setTinyLeadersDeck(deckStr); DeckPreferences.setTinyLeadersDeck(deckStr);
break; break;

View File

@@ -122,6 +122,7 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
cbVariants.addItem(GameType.MomirBasic); cbVariants.addItem(GameType.MomirBasic);
cbVariants.addItem(GameType.MoJhoSto); cbVariants.addItem(GameType.MoJhoSto);
cbVariants.addItem(GameType.Commander); cbVariants.addItem(GameType.Commander);
cbVariants.addItem(GameType.Oathbreaker);
cbVariants.addItem(GameType.TinyLeaders); cbVariants.addItem(GameType.TinyLeaders);
cbVariants.addItem(GameType.Brawl); cbVariants.addItem(GameType.Brawl);
cbVariants.addItem(GameType.Planechase); cbVariants.addItem(GameType.Planechase);
@@ -156,13 +157,13 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
FThreads.invokeInBackgroundThread(new Runnable() { FThreads.invokeInBackgroundThread(new Runnable() {
@Override @Override
public void run() { public void run() {
playerPanels.get(0).initialize(FPref.CONSTRUCTED_P1_DECK_STATE, FPref.COMMANDER_P1_DECK_STATE, FPref.TINY_LEADER_P1_DECK_STATE, FPref.BRAWL_P1_DECK_STATE, DeckType.PRECONSTRUCTED_DECK); playerPanels.get(0).initialize(FPref.CONSTRUCTED_P1_DECK_STATE, FPref.COMMANDER_P1_DECK_STATE, FPref.OATHBREAKER_P1_DECK_STATE, FPref.TINY_LEADER_P1_DECK_STATE, FPref.BRAWL_P1_DECK_STATE, DeckType.PRECONSTRUCTED_DECK);
playerPanels.get(1).initialize(FPref.CONSTRUCTED_P2_DECK_STATE, FPref.COMMANDER_P2_DECK_STATE, FPref.TINY_LEADER_P2_DECK_STATE, FPref.BRAWL_P2_DECK_STATE, DeckType.COLOR_DECK); playerPanels.get(1).initialize(FPref.CONSTRUCTED_P2_DECK_STATE, FPref.COMMANDER_P2_DECK_STATE, FPref.OATHBREAKER_P2_DECK_STATE, FPref.TINY_LEADER_P2_DECK_STATE, FPref.BRAWL_P2_DECK_STATE, DeckType.COLOR_DECK);
if (getNumPlayers() > 2) { if (getNumPlayers() > 2) {
playerPanels.get(2).initialize(FPref.CONSTRUCTED_P3_DECK_STATE, FPref.COMMANDER_P3_DECK_STATE, FPref.TINY_LEADER_P3_DECK_STATE, FPref.BRAWL_P3_DECK_STATE, DeckType.COLOR_DECK); playerPanels.get(2).initialize(FPref.CONSTRUCTED_P3_DECK_STATE, FPref.COMMANDER_P3_DECK_STATE, FPref.OATHBREAKER_P3_DECK_STATE, FPref.TINY_LEADER_P3_DECK_STATE, FPref.BRAWL_P3_DECK_STATE, DeckType.COLOR_DECK);
} }
if (getNumPlayers() > 3) { if (getNumPlayers() > 3) {
playerPanels.get(3).initialize(FPref.CONSTRUCTED_P4_DECK_STATE, FPref.COMMANDER_P4_DECK_STATE, FPref.TINY_LEADER_P4_DECK_STATE, FPref.BRAWL_P4_DECK_STATE, DeckType.COLOR_DECK); playerPanels.get(3).initialize(FPref.CONSTRUCTED_P4_DECK_STATE, FPref.COMMANDER_P4_DECK_STATE, FPref.OATHBREAKER_P3_DECK_STATE, FPref.TINY_LEADER_P4_DECK_STATE, FPref.BRAWL_P4_DECK_STATE, DeckType.COLOR_DECK);
} }
/*playerPanels.get(4).initialize(FPref.CONSTRUCTED_P5_DECK_STATE, DeckType.COLOR_DECK); /*playerPanels.get(4).initialize(FPref.CONSTRUCTED_P5_DECK_STATE, DeckType.COLOR_DECK);
playerPanels.get(5).initialize(FPref.CONSTRUCTED_P6_DECK_STATE, DeckType.COLOR_DECK); playerPanels.get(5).initialize(FPref.CONSTRUCTED_P6_DECK_STATE, DeckType.COLOR_DECK);
@@ -350,6 +351,7 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
lstVariants.addItem(new Variant(GameType.MomirBasic)); lstVariants.addItem(new Variant(GameType.MomirBasic));
lstVariants.addItem(new Variant(GameType.MoJhoSto)); lstVariants.addItem(new Variant(GameType.MoJhoSto));
lstVariants.addItem(new Variant(GameType.Commander)); lstVariants.addItem(new Variant(GameType.Commander));
lstVariants.addItem(new Variant(GameType.Oathbreaker));
lstVariants.addItem(new Variant(GameType.TinyLeaders)); lstVariants.addItem(new Variant(GameType.TinyLeaders));
lstVariants.addItem(new Variant(GameType.Brawl)); lstVariants.addItem(new Variant(GameType.Brawl));
lstVariants.addItem(new Variant(GameType.Planechase)); lstVariants.addItem(new Variant(GameType.Planechase));
@@ -497,9 +499,9 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
else { else {
panel = new PlayerPanel(this, allowNetworking, i, slot, lobby.mayEdit(i), lobby.hasControl()); panel = new PlayerPanel(this, allowNetworking, i, slot, lobby.mayEdit(i), lobby.hasControl());
if (i == 2) { if (i == 2) {
panel.initialize(FPref.CONSTRUCTED_P3_DECK_STATE, FPref.COMMANDER_P3_DECK_STATE, FPref.TINY_LEADER_P3_DECK_STATE, FPref.BRAWL_P3_DECK_STATE, DeckType.COLOR_DECK); panel.initialize(FPref.CONSTRUCTED_P3_DECK_STATE, FPref.COMMANDER_P3_DECK_STATE, FPref.OATHBREAKER_P3_DECK_STATE, FPref.TINY_LEADER_P3_DECK_STATE, FPref.BRAWL_P3_DECK_STATE, DeckType.COLOR_DECK);
} else if (i == 3) { } else if (i == 3) {
panel.initialize(FPref.CONSTRUCTED_P4_DECK_STATE, FPref.COMMANDER_P4_DECK_STATE, FPref.TINY_LEADER_P4_DECK_STATE, FPref.BRAWL_P4_DECK_STATE, DeckType.COLOR_DECK); panel.initialize(FPref.CONSTRUCTED_P4_DECK_STATE, FPref.COMMANDER_P4_DECK_STATE, FPref.OATHBREAKER_P4_DECK_STATE, FPref.TINY_LEADER_P4_DECK_STATE, FPref.BRAWL_P4_DECK_STATE, DeckType.COLOR_DECK);
} }
playerPanels.add(panel); playerPanels.add(panel);
playersScroll.add(panel); playersScroll.add(panel);
@@ -554,6 +556,12 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
playerPanel.getCommanderDeckChooser().saveState(); playerPanel.getCommanderDeckChooser().saveState();
} }
} }
else if (hasVariant(GameType.Oathbreaker)) {
deck = playerPanel.getOathbreakerDeck();
if (deck != null) {
playerPanel.getOathbreakerDeckChooser().saveState();
}
}
else if (hasVariant(GameType.TinyLeaders)) { else if (hasVariant(GameType.TinyLeaders)) {
deck = playerPanel.getTinyLeadersDeck(); deck = playerPanel.getTinyLeadersDeck();
if (deck != null) { if (deck != null) {

View File

@@ -71,12 +71,13 @@ public class PlayerPanel extends FContainer {
private final FLabel btnDeck = new FLabel.ButtonBuilder().text("Loading Deck...").build(); private final FLabel btnDeck = new FLabel.ButtonBuilder().text("Loading Deck...").build();
private final FLabel btnSchemeDeck = new FLabel.ButtonBuilder().text("Scheme Deck: Random Generated Deck").build(); private final FLabel btnSchemeDeck = new FLabel.ButtonBuilder().text("Scheme Deck: Random Generated Deck").build();
private final FLabel btnCommanderDeck = new FLabel.ButtonBuilder().text("Commander Deck: Random Generated Deck").build(); private final FLabel btnCommanderDeck = new FLabel.ButtonBuilder().text("Commander Deck: Random Generated Deck").build();
private final FLabel btnOathbreakDeck = new FLabel.ButtonBuilder().text("Oathbreaker Deck: Random Generated Deck").build();
private final FLabel btnTinyLeadersDeck = new FLabel.ButtonBuilder().text("Tiny Leaders Deck: Random Generated Deck").build(); private final FLabel btnTinyLeadersDeck = new FLabel.ButtonBuilder().text("Tiny Leaders Deck: Random Generated Deck").build();
private final FLabel btnBrawlDeck = new FLabel.ButtonBuilder().text("Brawl Deck: Random Generated Deck").build(); private final FLabel btnBrawlDeck = new FLabel.ButtonBuilder().text("Brawl Deck: Random Generated Deck").build();
private final FLabel btnPlanarDeck = new FLabel.ButtonBuilder().text("Planar Deck: Random Generated Deck").build(); private final FLabel btnPlanarDeck = new FLabel.ButtonBuilder().text("Planar Deck: Random Generated Deck").build();
private final FLabel btnVanguardAvatar = new FLabel.ButtonBuilder().text("Vanguard Avatar: Random").build(); private final FLabel btnVanguardAvatar = new FLabel.ButtonBuilder().text("Vanguard Avatar: Random").build();
private final FDeckChooser deckChooser, lstSchemeDecks, lstCommanderDecks, lstTinyLeadersDecks, lstBrawlDecks, lstPlanarDecks; private final FDeckChooser deckChooser, lstSchemeDecks, lstCommanderDecks, lstOathbreakerDecks, lstTinyLeadersDecks, lstBrawlDecks, lstPlanarDecks;
private final FVanguardChooser lstVanguardAvatars; private final FVanguardChooser lstVanguardAvatars;
public PlayerPanel(final LobbyScreen screen0, final boolean allowNetworking0, final int index0, final LobbySlot slot, final boolean mayEdit0, final boolean mayControl0) { public PlayerPanel(final LobbyScreen screen0, final boolean allowNetworking0, final int index0, final LobbySlot slot, final boolean mayEdit0, final boolean mayControl0) {
@@ -124,6 +125,17 @@ public class PlayerPanel extends FContainer {
} }
} }
}); });
lstOathbreakerDecks = new FDeckChooser(GameType.Oathbreaker, isAi, new FEventHandler() {
@Override
public void handleEvent(FEvent e) {
if( ((DeckManager)e.getSource()).getSelectedItem() != null) {
btnOathbreakDeck.setText("Oathbreaker Deck: " + ((DeckManager) e.getSource()).getSelectedItem().getName());
lstOathbreakerDecks.saveState();
}else{
btnOathbreakDeck.setText("Oathbreaker Deck");
}
}
});
lstTinyLeadersDecks = new FDeckChooser(GameType.TinyLeaders, isAi, new FEventHandler() { lstTinyLeadersDecks = new FDeckChooser(GameType.TinyLeaders, isAi, new FEventHandler() {
@Override @Override
public void handleEvent(FEvent e) { public void handleEvent(FEvent e) {
@@ -212,6 +224,14 @@ public class PlayerPanel extends FContainer {
Forge.openScreen(lstCommanderDecks); Forge.openScreen(lstCommanderDecks);
} }
}); });
add(btnOathbreakDeck);
btnOathbreakDeck.setCommand(new FEventHandler() {
@Override
public void handleEvent(FEvent e) {
lstOathbreakerDecks.setHeaderCaption("Select Oathbreaker Deck for " + txtPlayerName.getText());
Forge.openScreen(lstOathbreakerDecks);
}
});
add(btnTinyLeadersDeck); add(btnTinyLeadersDeck);
btnTinyLeadersDeck.setCommand(new FEventHandler() { btnTinyLeadersDeck.setCommand(new FEventHandler() {
@Override @Override
@@ -262,11 +282,12 @@ public class PlayerPanel extends FContainer {
setMayControl(mayControl0); setMayControl(mayControl0);
} }
public void initialize(FPref savedStateSetting, FPref savedStateSettingCommander, FPref savedStateSettingTinyLeader, FPref savedStateSettingBrawl, DeckType defaultDeckType) { public void initialize(FPref savedStateSetting, FPref savedStateSettingCommander, FPref savedStateSettingOathbreaker, FPref savedStateSettingTinyLeader, FPref savedStateSettingBrawl, DeckType defaultDeckType) {
deckChooser.initialize(savedStateSetting, defaultDeckType); deckChooser.initialize(savedStateSetting, defaultDeckType);
lstCommanderDecks.initialize(savedStateSettingCommander, DeckType.COMMANDER_DECK); lstCommanderDecks.initialize(savedStateSettingCommander, DeckType.COMMANDER_DECK);
lstTinyLeadersDecks.initialize(savedStateSettingTinyLeader, DeckType.TINY_LEADERS_DECKS); lstOathbreakerDecks.initialize(savedStateSettingOathbreaker, DeckType.OATHBREAKER_DECK);
lstBrawlDecks.initialize(savedStateSettingBrawl, DeckType.BRAWL_DECKS); lstTinyLeadersDecks.initialize(savedStateSettingTinyLeader, DeckType.TINY_LEADERS_DECK);
lstBrawlDecks.initialize(savedStateSettingBrawl, DeckType.BRAWL_DECK);
lstPlanarDecks.initialize(null, DeckType.RANDOM_DECK); lstPlanarDecks.initialize(null, DeckType.RANDOM_DECK);
lstSchemeDecks.initialize(null, DeckType.RANDOM_DECK); lstSchemeDecks.initialize(null, DeckType.RANDOM_DECK);
} }
@@ -312,6 +333,10 @@ public class PlayerPanel extends FContainer {
btnCommanderDeck.setBounds(x, y, w, fieldHeight); btnCommanderDeck.setBounds(x, y, w, fieldHeight);
y += dy; y += dy;
} }
else if (btnOathbreakDeck.isVisible()) {
btnOathbreakDeck.setBounds(x, y, w, fieldHeight);
y += dy;
}
else if (btnTinyLeadersDeck.isVisible()) { else if (btnTinyLeadersDeck.isVisible()) {
btnTinyLeadersDeck.setBounds(x, y, w, fieldHeight); btnTinyLeadersDeck.setBounds(x, y, w, fieldHeight);
y += dy; y += dy;
@@ -342,7 +367,7 @@ public class PlayerPanel extends FContainer {
if (!btnDeck.isVisible()) { if (!btnDeck.isVisible()) {
rows--; rows--;
} }
if (btnCommanderDeck.isVisible() || btnTinyLeadersDeck.isVisible() || btnBrawlDeck.isVisible()) { if (btnCommanderDeck.isVisible() || btnOathbreakDeck.isVisible() || btnTinyLeadersDeck.isVisible() || btnBrawlDeck.isVisible()) {
rows++; rows++;
} }
if (btnSchemeDeck.isVisible()) { if (btnSchemeDeck.isVisible()) {
@@ -460,6 +485,7 @@ public class PlayerPanel extends FContainer {
public void updateVariantControlsVisibility() { public void updateVariantControlsVisibility() {
boolean isCommanderApplied = false; boolean isCommanderApplied = false;
boolean isOathbreakerApplied = false;
boolean isTinyLeadersApplied = false; boolean isTinyLeadersApplied = false;
boolean isBrawlApplied = false; boolean isBrawlApplied = false;
boolean isPlanechaseApplied = false; boolean isPlanechaseApplied = false;
@@ -483,6 +509,10 @@ public class PlayerPanel extends FContainer {
isCommanderApplied = true; isCommanderApplied = true;
isDeckBuildingAllowed = false; //Commander deck replaces basic deck, so hide that isDeckBuildingAllowed = false; //Commander deck replaces basic deck, so hide that
break; break;
case Oathbreaker:
isOathbreakerApplied = true;
isDeckBuildingAllowed = false; //Oathbreaker deck replaces basic deck, so hide that
break;
case TinyLeaders: case TinyLeaders:
isTinyLeadersApplied = true; isTinyLeadersApplied = true;
isDeckBuildingAllowed = false; //Tiny Leaders deck replaces basic deck, so hide that isDeckBuildingAllowed = false; //Tiny Leaders deck replaces basic deck, so hide that
@@ -507,6 +537,7 @@ public class PlayerPanel extends FContainer {
btnDeck.setVisible(isDeckBuildingAllowed); btnDeck.setVisible(isDeckBuildingAllowed);
btnCommanderDeck.setVisible(isCommanderApplied && mayEdit); btnCommanderDeck.setVisible(isCommanderApplied && mayEdit);
btnOathbreakDeck.setVisible(isOathbreakerApplied && mayEdit);
btnTinyLeadersDeck.setVisible(isTinyLeadersApplied && mayEdit); btnTinyLeadersDeck.setVisible(isTinyLeadersApplied && mayEdit);
btnBrawlDeck.setVisible(isBrawlApplied && mayEdit); btnBrawlDeck.setVisible(isBrawlApplied && mayEdit);
@@ -760,6 +791,10 @@ public class PlayerPanel extends FContainer {
return lstCommanderDecks; return lstCommanderDecks;
} }
public FDeckChooser getOathbreakerDeckChooser() {
return lstOathbreakerDecks;
}
public FDeckChooser getTinyLeadersDeckChooser() { public FDeckChooser getTinyLeadersDeckChooser() {
return lstTinyLeadersDecks; return lstTinyLeadersDecks;
} }
@@ -768,13 +803,14 @@ public class PlayerPanel extends FContainer {
return lstBrawlDecks; return lstBrawlDecks;
} }
public Deck getDeck() { public Deck getDeck() {
return deckChooser.getDeck(); return deckChooser.getDeck();
} }
public Deck getCommanderDeck() { public Deck getCommanderDeck() { return lstCommanderDecks.getDeck(); }
return lstCommanderDecks.getDeck();
public Deck getOathbreakerDeck() {
return lstOathbreakerDecks.getDeck();
} }
public Deck getTinyLeadersDeck() { public Deck getTinyLeadersDeck() {

View File

@@ -15,6 +15,7 @@
<doc>EDITOR_CATALOG</doc> <doc>EDITOR_CATALOG</doc>
<doc>EDITOR_ALLDECKS</doc> <doc>EDITOR_ALLDECKS</doc>
<doc>EDITOR_COMMANDER</doc> <doc>EDITOR_COMMANDER</doc>
<doc>EDITOR_OATHBREAKER</doc>
<doc>EDITOR_BRAWL</doc> <doc>EDITOR_BRAWL</doc>
<doc>EDITOR_TINY_LEADERS</doc> <doc>EDITOR_TINY_LEADERS</doc>
<doc>EDITOR_DECKGEN</doc> <doc>EDITOR_DECKGEN</doc>

View File

@@ -0,0 +1,6 @@
[format]
Name:Oathbreaker
Type:Casual
Subtype:Commander
Order:141
Banned:Adriana's Valor; Advantageous Proclamation; Assemble the Rank and Vile; Backup Plan; Brago's Favor; Double Stroke; Echoing Boon; Emissary's Ploy; Hired Heist; Hold the Perimeter; Hymn of the Wilds; Immediate Action; Incendiary Dissent; Iterative Analysis; Muzzio's Preparations; Natural Unity; Power Play; Secret Summoning; Secrets of Paradise; Sentinel Dispatch; Sovereign's Realm; Summoner's Bond; Unexpected Potential; Weight Advantage; Worldknit; Amulet of Quoz; Bronze Tablet; Contract from Below; Darkpact; Demonic Attorney; Jeweled Bird; Rebirth; Tempest Efreet; Timmerian Fiends; Chaos Orb; Falling Star; Shahrazad; Ad Nauseam; Ancestral Recall; Balance; Biorhythm; Black Lotus; Channel; Doomsday; Emrakul, the Aeons Torn; Expropriate; Fastbond; Gifts Ungiven; Griselbrand; High Tide; Library of Alexandria; Limited Resources; Lions Eye Diamond; Mana Crypt; Mana Geyser; Mana Vault; Mox Emerald; Mox Jet; Mox Pearl; Mox Ruby; Mox Sapphire; Natural Order; Painter's Servant; Panoptic Mirror; Primal Surge; Recurring Nightmare; Saheeli, the Gifted; Sol Ring; Sundering Titan; Sway of the Stars; Sylvan Primordial; Time Vault; Time Walk; Tinker; Tolarian Academy; Tooth and Nail; Trade Secrets; Upheaval; Worldfire; Yawgmoth's Bargain

View File

@@ -23,6 +23,7 @@ lblBacktoHome=Zum Hauptmenü
lblDeckEditor=Deck-Editor lblDeckEditor=Deck-Editor
lblCloseEditor=Schließe Editor lblCloseEditor=Schließe Editor
lblCommanderDeckEditor=Commander-Deck-Editor lblCommanderDeckEditor=Commander-Deck-Editor
lblOathbreakerDeckEditor=Eidbrecher-Deck-Editor
lblTinyLeadersDeckEditor=Kleine-Anführer-Deck-Editor lblTinyLeadersDeckEditor=Kleine-Anführer-Deck-Editor
lblBrawlDeckEditor=Brawl-Deck-Editor lblBrawlDeckEditor=Brawl-Deck-Editor
lblDraftDeckEditor=Draft-Deck-Editor lblDraftDeckEditor=Draft-Deck-Editor
@@ -387,6 +388,8 @@ lblDeckManager=Deck Manager
lblVanguardDesc=Jeder Spieler hat eine eigene spielbeeinflussende \"Avatar\"-Karte. lblVanguardDesc=Jeder Spieler hat eine eigene spielbeeinflussende \"Avatar\"-Karte.
lblCommander=Commander lblCommander=Commander
lblCommanderDesc=Jeder Spieler hat eine legendäre \"General\"-Karte, welche (fast) jederzeit gespielt werden kann und die Farben des Decks bestimmt. lblCommanderDesc=Jeder Spieler hat eine legendäre \"General\"-Karte, welche (fast) jederzeit gespielt werden kann und die Farben des Decks bestimmt.
lblOathbreaker=Eidbrecher
lblOathbreakerDesc=Jeder Spieler hat eine Planeswalker-Karte als "Eidbrecher", die jederzeit gewirkt werden kann und die Deckfarben festlegt. Jeder Spieler hat auch einen Signaturzauber, der gewirkt werden kann, wenn sein Eidbrecher auf dem Schlachtfeld ist.
lblTinyLeaders=Kleine Anführer lblTinyLeaders=Kleine Anführer
lblTinyLeadersDesc=Jeder Spieler hat eine legendäre \"General\"-Karte, welche (fast) jederzeit gespielt werden kann und die Farben des Decks bestimmt. Alle Karten haben umgewandelte Manakosten von max. 3. lblTinyLeadersDesc=Jeder Spieler hat eine legendäre \"General\"-Karte, welche (fast) jederzeit gespielt werden kann und die Farben des Decks bestimmt. Alle Karten haben umgewandelte Manakosten von max. 3.
lblBrawl=Brawl lblBrawl=Brawl
@@ -525,6 +528,7 @@ lblConstructedDecks=Konstruierte Decks
lblCommanderDecks=Commander Decks lblCommanderDecks=Commander Decks
lblRandomCommanderDecks=Zufälliges Commander Deck lblRandomCommanderDecks=Zufälliges Commander Deck
lblRandomCommanderCard-basedDecks=Zufälliges Commander Deck (kartenbasiert) lblRandomCommanderCard-basedDecks=Zufälliges Commander Deck (kartenbasiert)
lblOathbreakerDecks=Eidbrecher-Decks
lblTinyLeadersDecks=Kleine-Anführer-Decks lblTinyLeadersDecks=Kleine-Anführer-Decks
lblBrawlDecks=Brawl Decks lblBrawlDecks=Brawl Decks
lblSchemeDecks=Komplott-Decks lblSchemeDecks=Komplott-Decks
@@ -781,6 +785,8 @@ lblfromdeck=vom Deck
lbltosideboard=zum Sideboard lbltosideboard=zum Sideboard
lblfromsideboard=vom Sideboard lblfromsideboard=vom Sideboard
lblascommander=als Kommandeur lblascommander=als Kommandeur
lblasoathbreaker=als Eidbrecher
lblassignaturespell=als Signaturzauber
lblasavatar=als Avatar lblasavatar=als Avatar
lblfromschemedeck=vom Komplottdeck lblfromschemedeck=vom Komplottdeck
lblfromplanardeck=vom Weltendeck lblfromplanardeck=vom Weltendeck

View File

@@ -23,7 +23,8 @@ lblBacktoHome=Back to Home
lblDeckEditor=Deck Editor lblDeckEditor=Deck Editor
lblCloseEditor=Close Editor lblCloseEditor=Close Editor
lblCommanderDeckEditor=Commander Deck Editor lblCommanderDeckEditor=Commander Deck Editor
lblTinyLeadersDeckEditor=Tiny Leaders DeckEditor lblOathbreakerDeckEditor=Oathbreaker Deck Editor
lblTinyLeadersDeckEditor=Tiny Leaders Deck Editor
lblBrawlDeckEditor=Brawl Deck Editor lblBrawlDeckEditor=Brawl Deck Editor
lblDraftDeckEditor=Draft Deck Editor lblDraftDeckEditor=Draft Deck Editor
lblSealedDeckEditor=Sealed Deck Editor lblSealedDeckEditor=Sealed Deck Editor
@@ -387,6 +388,8 @@ lblDeckManager=Deck Manager
lblVanguardDesc=Each player has a special \"Avatar\" card that affects the game. lblVanguardDesc=Each player has a special \"Avatar\" card that affects the game.
lblCommander=Commander lblCommander=Commander
lblCommanderDesc=Each player has a legendary "General" card which can be cast at any time and determines deck colors. lblCommanderDesc=Each player has a legendary "General" card which can be cast at any time and determines deck colors.
lblOathbreaker=Oathbreaker
lblOathbreakerDesc=Each player has a Planeswalker card as their "Oathbreaker" which can be cast at any time and determines deck colors. Each player also has a signature spell that can be cast when their Oathbreaker is on the battlefield.
lblTinyLeaders=Tiny Leaders lblTinyLeaders=Tiny Leaders
lblTinyLeadersDesc=Each player has a legendary \"General\" card which can be cast at any time and determines deck colors. Each card must have CMC less than 4. lblTinyLeadersDesc=Each player has a legendary \"General\" card which can be cast at any time and determines deck colors. Each card must have CMC less than 4.
lblBrawl=Brawl lblBrawl=Brawl
@@ -525,6 +528,7 @@ lblConstructedDecks=Constructed Decks
lblCommanderDecks=Commander Decks lblCommanderDecks=Commander Decks
lblRandomCommanderDecks=Random Commander Decks lblRandomCommanderDecks=Random Commander Decks
lblRandomCommanderCard-basedDecks=Random Commander Card-based Decks lblRandomCommanderCard-basedDecks=Random Commander Card-based Decks
lblOathbreakerDecks=Oathbreaker Decks
lblTinyLeadersDecks=Tiny Leaders Decks lblTinyLeadersDecks=Tiny Leaders Decks
lblBrawlDecks=Brawl Decks lblBrawlDecks=Brawl Decks
lblSchemeDecks=Scheme Decks lblSchemeDecks=Scheme Decks
@@ -781,6 +785,8 @@ lblfromdeck=from deck
lbltosideboard=to sideboard lbltosideboard=to sideboard
lblfromsideboard=from sideboard lblfromsideboard=from sideboard
lblascommander=as commander lblascommander=as commander
lblasoathbreaker=as oathbreaker
lblassignaturespell=as signature spell
lblasavatar=as avatar lblasavatar=as avatar
lblfromschemedeck=from scheme deck lblfromschemedeck=from scheme deck
lblfromplanardeck=from planar deck lblfromplanardeck=from planar deck

View File

@@ -23,6 +23,7 @@ lblBacktoHome=Volver a Inicio
lblDeckEditor=Editor de Mazos lblDeckEditor=Editor de Mazos
lblCloseEditor=Cerrar Editor lblCloseEditor=Cerrar Editor
lblCommanderDeckEditor=Editor Mazos Commander lblCommanderDeckEditor=Editor Mazos Commander
lblOathbreakerDeckEditor=Editor Mazos Oathbreaker
lblTinyLeadersDeckEditor=Editor Mazos Tiny Leaders lblTinyLeadersDeckEditor=Editor Mazos Tiny Leaders
lblBrawlDeckEditor=Editor Mazos Brawl lblBrawlDeckEditor=Editor Mazos Brawl
lblDraftDeckEditor=Editor Mazo Draft lblDraftDeckEditor=Editor Mazo Draft
@@ -387,6 +388,8 @@ lblDeckManager=Gestor de Mazos
lblVanguardDesc=Cada jugador tiene una carta especial de "Avatar" que afecta el juego. lblVanguardDesc=Cada jugador tiene una carta especial de "Avatar" que afecta el juego.
lblCommander=Commander lblCommander=Commander
lblCommanderDesc=Cada jugador tiene una carta legendaria "Comandante" que se puede lanzar en cualquier momento y determina los colores de la baraja. lblCommanderDesc=Cada jugador tiene una carta legendaria "Comandante" que se puede lanzar en cualquier momento y determina los colores de la baraja.
lblOathbreaker=Oathbreaker
lblOathbreakerDesc=Cada jugador tiene una carta de Planeswalker como su "Oathbreaker" que se puede lanzar en cualquier momento y determina los colores de la baraja. Cada jugador también tiene un hechizo de firma que se puede lanzar cuando su Oathbreaker está en el campo de batalla.
lblTinyLeaders=Tiny Leaders lblTinyLeaders=Tiny Leaders
lblTinyLeadersDesc=Cada jugador tiene una carta legendaria "Comandante" que se puede lanzar en cualquier momento y determina los colores de la baraja. Cada carta debe tener CMC menos de 4. lblTinyLeadersDesc=Cada jugador tiene una carta legendaria "Comandante" que se puede lanzar en cualquier momento y determina los colores de la baraja. Cada carta debe tener CMC menos de 4.
lblBrawl=Brawl lblBrawl=Brawl
@@ -525,6 +528,7 @@ lblConstructedDecks=Mazos Construido
lblCommanderDecks=Mazos Commander lblCommanderDecks=Mazos Commander
lblRandomCommanderDecks=Mazos Commander Aleatorios lblRandomCommanderDecks=Mazos Commander Aleatorios
lblRandomCommanderCard-basedDecks=Mazos Commander Aleatorios Basados en Cartas lblRandomCommanderCard-basedDecks=Mazos Commander Aleatorios Basados en Cartas
lblOathbreakerDecks=Mazos Oathbreaker
lblTinyLeadersDecks=Mazos Tiny Leaders lblTinyLeadersDecks=Mazos Tiny Leaders
lblBrawlDecks=Mazos Brawl lblBrawlDecks=Mazos Brawl
lblSchemeDecks=Mazos de Fenómenos (Scheme) lblSchemeDecks=Mazos de Fenómenos (Scheme)
@@ -781,6 +785,8 @@ lblfromdeck=del mazo
lbltosideboard=al banquillo lbltosideboard=al banquillo
lblfromsideboard=del banquillo lblfromsideboard=del banquillo
lblascommander=como comandante lblascommander=como comandante
lblasoathbreaker=como oathbreaker
lblassignaturespell=como hechizo de firma
lblasavatar=como avatar lblasavatar=como avatar
lblfromschemedeck=del mazo de escenario lblfromschemedeck=del mazo de escenario
lblfromplanardeck=del mazo planar lblfromplanardeck=del mazo planar

View File

@@ -15,6 +15,7 @@ public class ConstructedAchievements extends AchievementCollection {
add(new VariantWins(GameType.MomirBasic, 25, 50, 100)); add(new VariantWins(GameType.MomirBasic, 25, 50, 100));
add(new VariantWins(GameType.MoJhoSto, 25, 50, 100)); add(new VariantWins(GameType.MoJhoSto, 25, 50, 100));
add(new VariantWins(GameType.Commander, 25, 50, 100)); add(new VariantWins(GameType.Commander, 25, 50, 100));
add(new VariantWins(GameType.Oathbreaker, 25, 50, 100));
add(new VariantWins(GameType.TinyLeaders, 25, 50, 100)); add(new VariantWins(GameType.TinyLeaders, 25, 50, 100));
add(new VariantWins(GameType.Brawl, 25, 50, 100)); add(new VariantWins(GameType.Brawl, 25, 50, 100));
add(new VariantWins(GameType.Planechase, 25, 50, 100)); add(new VariantWins(GameType.Planechase, 25, 50, 100));

View File

@@ -34,42 +34,34 @@ public final class CardRelationMatrixGenerator {
public static final int MIN_REQUIRED_CONNECTIONS = 14; public static final int MIN_REQUIRED_CONNECTIONS = 14;
public static boolean initialize(){ public static boolean initialize(){
List<String> formatStrings = new ArrayList<>(); return initializeFormat(DeckFormat.Commander) && initializeFormat(DeckFormat.Oathbreaker);
/* formatStrings.add(FModel.getFormats().getStandard().getName());
formatStrings.add(FModel.getFormats().getModern().getName());*/
formatStrings.add(DeckFormat.Commander.toString());
for (String formatString : formatStrings){
if(!initializeFormat(formatString)){
return false;
}
}
return true;
} }
/** Try to load matrix .dat files, otherwise check for deck folders and build .dat, otherwise return false **/ /** Try to load matrix .dat files, otherwise check for deck folders and build .dat, otherwise return false **/
public static boolean initializeFormat(String format){ public static boolean initializeFormat(DeckFormat format){
HashMap<String,List<Map.Entry<PaperCard,Integer>>> formatMap = CardThemedMatrixIO.loadMatrix(format); String formatName = format.toString();
if(formatMap==null) { HashMap<String,List<Map.Entry<PaperCard,Integer>>> formatMap = CardThemedMatrixIO.loadMatrix(formatName);
if (CardThemedMatrixIO.getMatrixFolder(format).exists()) { if (formatMap==null) {
if(format.equals(FModel.getFormats().getStandard().getName())){ if (CardThemedMatrixIO.getMatrixFolder(formatName).exists()) {
if (formatName.equals(FModel.getFormats().getStandard().getName())){
formatMap=initializeFormat(FModel.getFormats().getStandard()); formatMap=initializeFormat(FModel.getFormats().getStandard());
}else if(format.equals(FModel.getFormats().getModern().getName())){
formatMap=initializeFormat(FModel.getFormats().getModern());
}else{
formatMap=initializeCommanderFormat();
} }
CardThemedMatrixIO.saveMatrix(format, formatMap); else if (formatName.equals(FModel.getFormats().getModern().getName())){
formatMap=initializeFormat(FModel.getFormats().getModern());
}
else{
formatMap=initializeCommanderFormat(format);
}
CardThemedMatrixIO.saveMatrix(formatName, formatMap);
} else { } else {
return false; return false;
} }
} }
cardPools.put(format, formatMap); cardPools.put(formatName, formatMap);
return true; return true;
} }
public static HashMap<String,List<Map.Entry<PaperCard,Integer>>> initializeFormat(GameFormat format){ public static HashMap<String,List<Map.Entry<PaperCard,Integer>>> initializeFormat(GameFormat format){
IStorage<Deck> decks = new StorageImmediatelySerialized<Deck>("Generator", new DeckStorage(new File(ForgeConstants.DECK_GEN_DIR+ForgeConstants.PATH_SEPARATOR+format.getName()), IStorage<Deck> decks = new StorageImmediatelySerialized<Deck>("Generator", new DeckStorage(new File(ForgeConstants.DECK_GEN_DIR+ForgeConstants.PATH_SEPARATOR+format.getName()),
ForgeConstants.DECK_GEN_DIR, false), ForgeConstants.DECK_GEN_DIR, false),
true); true);
@@ -100,7 +92,6 @@ public final class CardRelationMatrixGenerator {
//Todo: Not sure what was failing here //Todo: Not sure what was failing here
} }
} }
} }
} }
} }
@@ -137,10 +128,9 @@ public final class CardRelationMatrixGenerator {
return cardPools; return cardPools;
} }
public static HashMap<String,List<Map.Entry<PaperCard,Integer>>> initializeCommanderFormat(){ public static HashMap<String,List<Map.Entry<PaperCard,Integer>>> initializeCommanderFormat(DeckFormat format){
IStorage<Deck> decks = new StorageImmediatelySerialized<Deck>("Generator", IStorage<Deck> decks = new StorageImmediatelySerialized<Deck>("Generator",
new DeckStorage(new File(ForgeConstants.DECK_GEN_DIR,DeckFormat.Commander.toString()), new DeckStorage(new File(ForgeConstants.DECK_GEN_DIR, format.toString()),
ForgeConstants.DECK_GEN_DIR, false), ForgeConstants.DECK_GEN_DIR, false),
true); true);
@@ -164,7 +154,7 @@ public final class CardRelationMatrixGenerator {
new Predicate<CardRules>() { new Predicate<CardRules>() {
@Override @Override
public boolean apply(CardRules rules) { public boolean apply(CardRules rules) {
return DeckFormat.Commander.isLegalCommander(rules); return format.isLegalCommander(rules);
} }
}, PaperCard.FN_GET_RULES))); }, PaperCard.FN_GET_RULES)));

View File

@@ -19,17 +19,19 @@ import java.util.List;
*/ */
public class CommanderDeckGenerator extends DeckProxy implements Comparable<CommanderDeckGenerator> { public class CommanderDeckGenerator extends DeckProxy implements Comparable<CommanderDeckGenerator> {
public static List<DeckProxy> getCommanderDecks(final DeckFormat format, boolean isForAi, boolean isCardGen){ public static List<DeckProxy> getCommanderDecks(final DeckFormat format, boolean isForAi, boolean isCardGen){
if(format.equals(DeckFormat.Brawl)){ if (format.equals(DeckFormat.Brawl)){
return getBrawlDecks(format, isForAi, isCardGen); return getBrawlDecks(format, isForAi, isCardGen);
} }
ItemPool uniqueCards; ItemPool uniqueCards;
if(isCardGen){ if (isCardGen){
uniqueCards = new ItemPool<PaperCard>(PaperCard.class); uniqueCards = new ItemPool<PaperCard>(PaperCard.class);
Iterable<String> legendNames=CardRelationMatrixGenerator.cardPools.get(DeckFormat.Commander.toString()).keySet(); String matrixKey = (format.equals(DeckFormat.TinyLeaders) ? DeckFormat.Commander : format).toString(); //use Commander for Tiny Leaders
for(String legendName:legendNames) { Iterable<String> legendNames = CardRelationMatrixGenerator.cardPools.get(matrixKey).keySet();
for (String legendName : legendNames) {
uniqueCards.add(FModel.getMagicDb().getCommonCards().getUniqueByName(legendName)); uniqueCards.add(FModel.getMagicDb().getCommonCards().getUniqueByName(legendName));
} }
}else { }
else {
uniqueCards = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getUniqueCards(), PaperCard.class); uniqueCards = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getUniqueCards(), PaperCard.class);
} }
Predicate<CardRules> canPlay = isForAi ? DeckGeneratorBase.AI_CAN_PLAY : DeckGeneratorBase.HUMAN_CAN_PLAY; Predicate<CardRules> canPlay = isForAi ? DeckGeneratorBase.AI_CAN_PLAY : DeckGeneratorBase.HUMAN_CAN_PLAY;
@@ -43,7 +45,7 @@ public class CommanderDeckGenerator extends DeckProxy implements Comparable<Comm
}, },
canPlay), PaperCard.FN_GET_RULES)); canPlay), PaperCard.FN_GET_RULES));
final List<DeckProxy> decks = new ArrayList<DeckProxy>(); final List<DeckProxy> decks = new ArrayList<DeckProxy>();
for(PaperCard legend: legends) { for (PaperCard legend: legends) {
decks.add(new CommanderDeckGenerator(legend, format, isForAi, isCardGen)); decks.add(new CommanderDeckGenerator(legend, format, isForAi, isCardGen));
} }
return decks; return decks;
@@ -51,14 +53,15 @@ public class CommanderDeckGenerator extends DeckProxy implements Comparable<Comm
public static List<DeckProxy> getBrawlDecks(final DeckFormat format, boolean isForAi, boolean isCardGen){ public static List<DeckProxy> getBrawlDecks(final DeckFormat format, boolean isForAi, boolean isCardGen){
ItemPool uniqueCards; ItemPool uniqueCards;
if(isCardGen){ if (isCardGen){
uniqueCards = new ItemPool<PaperCard>(PaperCard.class); uniqueCards = new ItemPool<PaperCard>(PaperCard.class);
//TODO: upate to actual Brawl model from real Brawl decks //TODO: update to actual Brawl model from real Brawl decks
Iterable<String> legendNames=CardArchetypeLDAGenerator.ldaPools.get(FModel.getFormats().getStandard().getName()).keySet(); Iterable<String> legendNames=CardArchetypeLDAGenerator.ldaPools.get(FModel.getFormats().getStandard().getName()).keySet();
for(String legendName:legendNames) { for (String legendName : legendNames) {
uniqueCards.add(FModel.getMagicDb().getCommonCards().getUniqueByName(legendName)); uniqueCards.add(FModel.getMagicDb().getCommonCards().getUniqueByName(legendName));
} }
}else { }
else {
uniqueCards = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getUniqueCards(), PaperCard.class); uniqueCards = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getUniqueCards(), PaperCard.class);
} }
Predicate<CardRules> canPlay = isForAi ? DeckGeneratorBase.AI_CAN_PLAY : DeckGeneratorBase.HUMAN_CAN_PLAY; Predicate<CardRules> canPlay = isForAi ? DeckGeneratorBase.AI_CAN_PLAY : DeckGeneratorBase.HUMAN_CAN_PLAY;
@@ -68,7 +71,7 @@ public class CommanderDeckGenerator extends DeckProxy implements Comparable<Comm
CardRulesPredicates.Presets.CAN_BE_BRAWL_COMMANDER, CardRulesPredicates.Presets.CAN_BE_BRAWL_COMMANDER,
canPlay), PaperCard.FN_GET_RULES))); canPlay), PaperCard.FN_GET_RULES)));
final List<DeckProxy> decks = new ArrayList<DeckProxy>(); final List<DeckProxy> decks = new ArrayList<DeckProxy>();
for(PaperCard legend: legends) { for (PaperCard legend: legends) {
decks.add(new CommanderDeckGenerator(legend, format, isForAi, isCardGen)); decks.add(new CommanderDeckGenerator(legend, format, isForAi, isCardGen));
} }
return decks; return decks;
@@ -80,7 +83,6 @@ public class CommanderDeckGenerator extends DeckProxy implements Comparable<Comm
private final boolean isForAi; private final boolean isForAi;
private final boolean isCardgen; private final boolean isCardgen;
private CommanderDeckGenerator(PaperCard legend0, DeckFormat format0, boolean isForAi0, boolean isCardgen0) { private CommanderDeckGenerator(PaperCard legend0, DeckFormat format0, boolean isForAi0, boolean isCardgen0) {
super(); super();
legend = legend0; legend = legend0;
@@ -94,7 +96,6 @@ public class CommanderDeckGenerator extends DeckProxy implements Comparable<Comm
return CardEdition.UNKNOWN; return CardEdition.UNKNOWN;
} }
@Override @Override
public String getName() { public String getName() {
return legend.getName(); return legend.getName();
@@ -112,7 +113,6 @@ public class CommanderDeckGenerator extends DeckProxy implements Comparable<Comm
@Override @Override
public Deck getDeck() { public Deck getDeck() {
return DeckgenUtil.generateRandomCommanderDeck(legend, format,isForAi, isCardgen); return DeckgenUtil.generateRandomCommanderDeck(legend, format,isForAi, isCardgen);
} }

View File

@@ -364,6 +364,15 @@ public class DeckProxy implements InventoryItem {
return result; return result;
} }
public static Iterable<DeckProxy> getAllOathbreakerDecks() {
return getAllOathbreakerDecks(null);
}
public static Iterable<DeckProxy> getAllOathbreakerDecks(final Predicate<Deck> filter) {
final List<DeckProxy> result = new ArrayList<DeckProxy>();
addDecksRecursivelly("Oathbreaker", GameType.Oathbreaker, result, "", FModel.getDecks().getOathbreaker(), filter);
return result;
}
public static Iterable<DeckProxy> getAllTinyLeadersDecks() { public static Iterable<DeckProxy> getAllTinyLeadersDecks() {
return getAllTinyLeadersDecks(null); return getAllTinyLeadersDecks(null);
} }

View File

@@ -9,12 +9,13 @@ public enum DeckType {
COMMANDER_DECK("lblCommanderDecks"), COMMANDER_DECK("lblCommanderDecks"),
RANDOM_COMMANDER_DECK("lblRandomCommanderDecks"), RANDOM_COMMANDER_DECK("lblRandomCommanderDecks"),
RANDOM_CARDGEN_COMMANDER_DECK("lblRandomCommanderCard-basedDecks"), RANDOM_CARDGEN_COMMANDER_DECK("lblRandomCommanderCard-basedDecks"),
TINY_LEADERS_DECKS("lblTinyLeadersDecks"), OATHBREAKER_DECK("lblOathbreakerDecks"),
BRAWL_DECKS("lblBrawlDecks"), TINY_LEADERS_DECK("lblTinyLeadersDecks"),
SCHEME_DECKS("lblSchemeDecks"), BRAWL_DECK("lblBrawlDecks"),
PLANAR_DECKS("lblPlanarDecks"), SCHEME_DECK("lblSchemeDecks"),
DRAFT_DECKS("lblDraftDecks"), PLANAR_DECK("lblPlanarDecks"),
SEALED_DECKS("lblSealedDecks"), DRAFT_DECK("lblDraftDecks"),
SEALED_DECK("lblSealedDecks"),
PRECONSTRUCTED_DECK("lblPreconstructedDecks"), PRECONSTRUCTED_DECK("lblPreconstructedDecks"),
QUEST_OPPONENT_DECK("lblQuestOpponentDecks"), QUEST_OPPONENT_DECK("lblQuestOpponentDecks"),
COLOR_DECK("lblRandomColorDecks"), COLOR_DECK("lblRandomColorDecks"),

View File

@@ -603,7 +603,7 @@ public class DeckgenUtil {
final Deck deck; final Deck deck;
IDeckGenPool cardDb; IDeckGenPool cardDb;
DeckGeneratorBase gen = null; DeckGeneratorBase gen = null;
PaperCard selectedPartner=null; PaperCard selectedPartner = null;
List<PaperCard> preSelectedCards = new ArrayList<>(); List<PaperCard> preSelectedCards = new ArrayList<>();
if(isCardGen){ if(isCardGen){
if(format.equals(DeckFormat.Brawl)){//TODO: replace with actual Brawl based data if(format.equals(DeckFormat.Brawl)){//TODO: replace with actual Brawl based data
@@ -623,7 +623,8 @@ 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())); String matrixKey = (format.equals(DeckFormat.TinyLeaders) ? DeckFormat.Commander : format).toString(); //use Commander for Tiny Leaders
potentialCards.addAll(CardRelationMatrixGenerator.cardPools.get(matrixKey).get(commander.getName()));
Collections.shuffle(potentialCards, MyRandom.getRandom()); 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())) {
@@ -632,18 +633,33 @@ public class DeckgenUtil {
} }
} }
if (format.equals(DeckFormat.Oathbreaker)) {
//check for signature spells
List<PaperCard> signatureSpells = new ArrayList<>();
for (PaperCard c : preSelectedCards) {
if (c.getRules().canBeSignatureSpell()) {
signatureSpells.add(c);
}
}
//check for partner commanders if (signatureSpells.size() > 0) { //pass signature spell as partner for simplicity
List<PaperCard> partners=new ArrayList<>(); selectedPartner = signatureSpells.get(MyRandom.getRandom().nextInt(signatureSpells.size()));
for(PaperCard c:preSelectedCards){ preSelectedCards.removeAll(StaticData.instance().getCommonCards().getAllCards(selectedPartner.getName()));
if(c.getRules().canBePartnerCommander()){
partners.add(c);
} }
} }
else if (commander.getRules().canBePartnerCommander()) {
//check for partner commanders
List<PaperCard> partners = new ArrayList<>();
for (PaperCard c : preSelectedCards) {
if (c.getRules().canBePartnerCommander()) {
partners.add(c);
}
}
if(partners.size()>0&&commander.getRules().canBePartnerCommander()){ if (partners.size() > 0) {
selectedPartner=partners.get(MyRandom.getRandom().nextInt(partners.size())); selectedPartner = partners.get(MyRandom.getRandom().nextInt(partners.size()));
preSelectedCards.removeAll(StaticData.instance().getCommonCards().getAllCards(selectedPartner.getName())); preSelectedCards.removeAll(StaticData.instance().getCommonCards().getAllCards(selectedPartner.getName()));
}
} }
//randomly remove cards //randomly remove cards
int removeCount=0; int removeCount=0;
@@ -666,7 +682,7 @@ public class DeckgenUtil {
} }
preSelectedCards.removeAll(toRemove); preSelectedCards.removeAll(toRemove);
preSelectedCards.removeAll(StaticData.instance().getCommonCards().getAllCards(commander.getName())); preSelectedCards.removeAll(StaticData.instance().getCommonCards().getAllCards(commander.getName()));
gen = new CardThemedCommanderDeckBuilder(commander, selectedPartner,preSelectedCards,forAi,format); gen = new CardThemedCommanderDeckBuilder(commander, selectedPartner, preSelectedCards, forAi, format);
}else{ }else{
cardDb = FModel.getMagicDb().getCommonCards(); cardDb = FModel.getMagicDb().getCommonCards();
//shuffle first 400 random cards //shuffle first 400 random cards
@@ -674,9 +690,38 @@ public class DeckgenUtil {
Predicates.and(format.isLegalCardPredicate(),Predicates.compose(Predicates.or( Predicates.and(format.isLegalCardPredicate(),Predicates.compose(Predicates.or(
new CardThemedDeckBuilder.MatchColorIdentity(commander.getRules().getColorIdentity()), new CardThemedDeckBuilder.MatchColorIdentity(commander.getRules().getColorIdentity()),
DeckGeneratorBase.COLORLESS_CARDS), PaperCard.FN_GET_RULES))); DeckGeneratorBase.COLORLESS_CARDS), PaperCard.FN_GET_RULES)));
if(format.equals(DeckFormat.Brawl)){//for Brawl - add additional filterprinted rule to remove old reprints for a consistent look switch (format) {
Iterable<PaperCard> colorListFiltered = Iterables.filter(colorList,FModel.getFormats().getStandard().getFilterPrinted()); case Brawl: //for Brawl - add additional filterprinted rule to remove old reprints for a consistent look
colorList=colorListFiltered; colorList = Iterables.filter(colorList,FModel.getFormats().getStandard().getFilterPrinted());
break;
case Oathbreaker:
//check for signature spells
List<PaperCard> signatureSpells = new ArrayList<>();
for (PaperCard c : colorList) {
if (c.getRules().canBeSignatureSpell()) {
signatureSpells.add(c);
}
}
if (signatureSpells.size() > 0) { //pass signature spell as partner for simplicity
selectedPartner = signatureSpells.get(MyRandom.getRandom().nextInt(signatureSpells.size()));
}
break;
default:
if (commander.getRules().canBePartnerCommander()) {
//check for partner commanders
List<PaperCard> partners = new ArrayList<>();
for (PaperCard c : colorList) {
if (c.getRules().canBePartnerCommander()) {
partners.add(c);
}
}
if (partners.size() > 0) {
selectedPartner = partners.get(MyRandom.getRandom().nextInt(partners.size()));
}
}
break;
} }
List<PaperCard> cardList = Lists.newArrayList(colorList); List<PaperCard> cardList = Lists.newArrayList(colorList);
Collections.shuffle(cardList, MyRandom.getRandom()); Collections.shuffle(cardList, MyRandom.getRandom());
@@ -684,15 +729,16 @@ public class DeckgenUtil {
if(cardList.size()<shortlistlength){ if(cardList.size()<shortlistlength){
shortlistlength=cardList.size(); shortlistlength=cardList.size();
} }
List<PaperCard> shortList = cardList.subList(1, shortlistlength); List<PaperCard> shortList = cardList.subList(0, shortlistlength);
shortList.remove(commander); shortList.remove(commander);
shortList.removeAll(StaticData.instance().getCommonCards().getAllCards(commander.getName())); shortList.removeAll(StaticData.instance().getCommonCards().getAllCards(commander.getName()));
gen = new CardThemedCommanderDeckBuilder(commander, selectedPartner,shortList,forAi,format); if (selectedPartner != null) {
shortList.remove(selectedPartner);
shortList.removeAll(StaticData.instance().getCommonCards().getAllCards(selectedPartner.getName()));
}
gen = new CardThemedCommanderDeckBuilder(commander, selectedPartner, shortList, forAi, format);
} }
gen.setSingleton(true); gen.setSingleton(true);
gen.setUseArtifacts(!FModel.getPreferences().getPrefBoolean(FPref.DECKGEN_ARTIFACTS)); gen.setUseArtifacts(!FModel.getPreferences().getPrefBoolean(FPref.DECKGEN_ARTIFACTS));
CardPool cards = gen.getDeck(format.getMainRange().getMaximum(), forAi); CardPool cards = gen.getDeck(format.getMainRange().getMaximum(), forAi);
@@ -707,8 +753,8 @@ public class DeckgenUtil {
deck.setDirectory("generated/commander"); deck.setDirectory("generated/commander");
deck.getMain().addAll(cards); deck.getMain().addAll(cards);
deck.getOrCreate(DeckSection.Commander).add(commander); deck.getOrCreate(DeckSection.Commander).add(commander);
if(selectedPartner!=null){ if (selectedPartner!=null){
deck.getOrCreate(DeckSection.Commander).add(selectedPartner); deck.get(DeckSection.Commander).add(selectedPartner);
} }
return deck; return deck;

View File

@@ -78,6 +78,8 @@ public class RandomDeckGenerator extends DeckProxy implements Comparable<RandomD
switch (lstDecks.getGameType()) { switch (lstDecks.getGameType()) {
case Commander: case Commander:
return DeckgenUtil.generateCommanderDeck(isAi, GameType.Commander); return DeckgenUtil.generateCommanderDeck(isAi, GameType.Commander);
case Oathbreaker:
return DeckgenUtil.generateCommanderDeck(isAi, GameType.Oathbreaker);
case TinyLeaders: case TinyLeaders:
return DeckgenUtil.generateCommanderDeck(isAi, GameType.TinyLeaders); return DeckgenUtil.generateCommanderDeck(isAi, GameType.TinyLeaders);
case Brawl: case Brawl:
@@ -138,6 +140,9 @@ public class RandomDeckGenerator extends DeckProxy implements Comparable<RandomD
case Commander: case Commander:
decks = DeckProxy.getAllCommanderDecks(DeckFormat.Commander.isLegalDeckPredicate()); decks = DeckProxy.getAllCommanderDecks(DeckFormat.Commander.isLegalDeckPredicate());
break; break;
case Oathbreaker:
decks = DeckProxy.getAllOathbreakerDecks(DeckFormat.Oathbreaker.isLegalDeckPredicate());
break;
case TinyLeaders: case TinyLeaders:
decks = DeckProxy.getAllTinyLeadersDecks(DeckFormat.TinyLeaders.isLegalDeckPredicate()); decks = DeckProxy.getAllTinyLeadersDecks(DeckFormat.TinyLeaders.isLegalDeckPredicate());
break; break;
@@ -166,6 +171,9 @@ public class RandomDeckGenerator extends DeckProxy implements Comparable<RandomD
case Commander: case Commander:
decks = DeckProxy.getAllCommanderDecks(); decks = DeckProxy.getAllCommanderDecks();
break; break;
case Oathbreaker:
decks = DeckProxy.getAllOathbreakerDecks();
break;
case TinyLeaders: case TinyLeaders:
decks = DeckProxy.getAllTinyLeadersDecks(); decks = DeckProxy.getAllTinyLeadersDecks();
break; break;

View File

@@ -1,6 +1,7 @@
package forge.deck.io; package forge.deck.io;
import forge.deck.DeckProxy; import forge.deck.DeckProxy;
import forge.deck.DeckType;
import forge.properties.ForgeConstants; import forge.properties.ForgeConstants;
import forge.util.XmlUtil; import forge.util.XmlUtil;
@@ -21,9 +22,20 @@ import org.w3c.dom.NodeList;
* *
*/ */
public class DeckPreferences { public class DeckPreferences {
private static String currentDeck = "", draftDeck = "", sealedDeck = "", commanderDeck = "", tinyLeadersDeck = "", brawlDeck = "", planarDeck = "", schemeDeck = ""; private static String selectedDeckType = "", currentDeck = "", draftDeck = "", sealedDeck = "", commanderDeck = "",
oathbreakerDeck = "", tinyLeadersDeck = "", brawlDeck = "", planarDeck = "", schemeDeck = "";
private static Map<String, DeckPreferences> allPrefs = new HashMap<String, DeckPreferences>(); private static Map<String, DeckPreferences> allPrefs = new HashMap<String, DeckPreferences>();
public static DeckType getSelectedDeckType() {
return selectedDeckType.isEmpty() ? DeckType.CONSTRUCTED_DECK : DeckType.valueOf(selectedDeckType);
}
public static void setSelectedDeckType(DeckType selectedDeckType0) {
String selectedDeckTypeStr = selectedDeckType0 == DeckType.CONSTRUCTED_DECK ? "" : selectedDeckType0.name();
if (selectedDeckTypeStr.equals(selectedDeckType)) { return; }
selectedDeckType = selectedDeckTypeStr;
save();
}
public static String getCurrentDeck() { public static String getCurrentDeck() {
return currentDeck; return currentDeck;
} }
@@ -60,6 +72,15 @@ public class DeckPreferences {
save(); save();
} }
public static String getOathbreakerDeck() {
return oathbreakerDeck;
}
public static void setOathbreakerDeck(String oathbreakerDeck0) {
if (oathbreakerDeck.equals(oathbreakerDeck0)) { return; }
oathbreakerDeck = oathbreakerDeck0;
save();
}
public static String getTinyLeadersDeck() { public static String getTinyLeadersDeck() {
return tinyLeadersDeck; return tinyLeadersDeck;
} }
@@ -114,10 +135,12 @@ public class DeckPreferences {
final Document document = builder.parse(new File(ForgeConstants.DECK_PREFS_FILE)); final Document document = builder.parse(new File(ForgeConstants.DECK_PREFS_FILE));
final Element root = (Element)document.getElementsByTagName("preferences").item(0); final Element root = (Element)document.getElementsByTagName("preferences").item(0);
selectedDeckType = root.getAttribute("selectedDeckType");
currentDeck = root.getAttribute("currentDeck"); currentDeck = root.getAttribute("currentDeck");
draftDeck = root.getAttribute("draftDeck"); draftDeck = root.getAttribute("draftDeck");
sealedDeck = root.getAttribute("sealedDeck"); sealedDeck = root.getAttribute("sealedDeck");
commanderDeck = root.getAttribute("commanderDeck"); commanderDeck = root.getAttribute("commanderDeck");
oathbreakerDeck = root.getAttribute("oathbreakerDeck");
brawlDeck = root.getAttribute("brawlDeck"); brawlDeck = root.getAttribute("brawlDeck");
tinyLeadersDeck = root.getAttribute("tinyLeadersDeck"); tinyLeadersDeck = root.getAttribute("tinyLeadersDeck");
planarDeck = root.getAttribute("planarDeck"); planarDeck = root.getAttribute("planarDeck");
@@ -145,10 +168,12 @@ public class DeckPreferences {
Document document = builder.newDocument(); Document document = builder.newDocument();
Element root = document.createElement("preferences"); Element root = document.createElement("preferences");
root.setAttribute("type", "decks"); root.setAttribute("type", "decks");
root.setAttribute("selectedDeckType", selectedDeckType);
root.setAttribute("currentDeck", currentDeck); root.setAttribute("currentDeck", currentDeck);
root.setAttribute("draftDeck", draftDeck); root.setAttribute("draftDeck", draftDeck);
root.setAttribute("sealedDeck", sealedDeck); root.setAttribute("sealedDeck", sealedDeck);
root.setAttribute("commanderDeck", commanderDeck); root.setAttribute("commanderDeck", commanderDeck);
root.setAttribute("oathbreakerDeck", oathbreakerDeck);
root.setAttribute("brawlDeck", brawlDeck); root.setAttribute("brawlDeck", brawlDeck);
root.setAttribute("tinyLeadersDeck", tinyLeadersDeck); root.setAttribute("tinyLeadersDeck", tinyLeadersDeck);
root.setAttribute("planarDeck", planarDeck); root.setAttribute("planarDeck", planarDeck);

View File

@@ -70,6 +70,8 @@ public enum ItemManagerConfig {
null, null, 4, 0), null, null, 4, 0),
COMMANDER_SECTION(SColumnUtil.getCatalogDefaultColumns(true), true, false, true, COMMANDER_SECTION(SColumnUtil.getCatalogDefaultColumns(true), true, false, true,
null, null, 1, 1), null, null, 1, 1),
OATHBREAKER_SECTION(SColumnUtil.getCatalogDefaultColumns(true), true, false, true,
null, null, 2, 1),
WORKSHOP_CATALOG(SColumnUtil.getCatalogDefaultColumns(true), true, true, false, WORKSHOP_CATALOG(SColumnUtil.getCatalogDefaultColumns(true), true, true, false,
null, null, 4, 0), null, null, 4, 0),
DECK_VIEWER(SColumnUtil.getDeckViewerDefaultColumns(), false, false, false, DECK_VIEWER(SColumnUtil.getDeckViewerDefaultColumns(), false, false, false,

View File

@@ -34,13 +34,13 @@ public class CardThemedCommanderDeckBuilder extends CardThemedDeckBuilder {
targetSize=format.getMainRange().getMinimum(); targetSize=format.getMainRange().getMinimum();
colors = keyCard.getRules().getColorIdentity(); colors = keyCard.getRules().getColorIdentity();
colors = ColorSet.fromMask(colors.getColor() | keyCard.getRules().getColorIdentity().getColor()); colors = ColorSet.fromMask(colors.getColor() | keyCard.getRules().getColorIdentity().getColor());
if(secondKeyCard!=null) { if (secondKeyCard != null && !format.equals(DeckFormat.Oathbreaker)) {
colors = ColorSet.fromMask(colors.getColor() | secondKeyCard.getRules().getColorIdentity().getColor()); colors = ColorSet.fromMask(colors.getColor() | secondKeyCard.getRules().getColorIdentity().getColor());
targetSize--; targetSize--;
} }
numSpellsNeeded = ((Double)Math.floor(targetSize*(getCreaturePercentage()+getSpellPercentage()))).intValue(); numSpellsNeeded = ((Double)Math.floor(targetSize*(getCreaturePercentage()+getSpellPercentage()))).intValue();
numCreaturesToStart = ((Double)Math.ceil(targetSize*(getCreaturePercentage()))).intValue(); numCreaturesToStart = ((Double)Math.ceil(targetSize*(getCreaturePercentage()))).intValue();
landsNeeded = ((Double)Math.ceil(targetSize*(getLandPercentage()))).intValue();; landsNeeded = ((Double)Math.ceil(targetSize*(getLandPercentage()))).intValue();
if (logColorsToConsole) { if (logColorsToConsole) {
System.out.println(keyCard.getName()); System.out.println(keyCard.getName());
System.out.println("Pre Colors: " + colors.toEnumSet().toString()); System.out.println("Pre Colors: " + colors.toEnumSet().toString());

View File

@@ -231,6 +231,14 @@ public abstract class GameLobby implements IHasGameType {
data.appliedVariants.remove(GameType.Archenemy); data.appliedVariants.remove(GameType.Archenemy);
break; break;
case Commander: case Commander:
data.appliedVariants.remove(GameType.Oathbreaker);
data.appliedVariants.remove(GameType.TinyLeaders);
data.appliedVariants.remove(GameType.Brawl);
data.appliedVariants.remove(GameType.MomirBasic);
data.appliedVariants.remove(GameType.MoJhoSto);
break;
case Oathbreaker:
data.appliedVariants.remove(GameType.Commander);
data.appliedVariants.remove(GameType.TinyLeaders); data.appliedVariants.remove(GameType.TinyLeaders);
data.appliedVariants.remove(GameType.Brawl); data.appliedVariants.remove(GameType.Brawl);
data.appliedVariants.remove(GameType.MomirBasic); data.appliedVariants.remove(GameType.MomirBasic);
@@ -238,12 +246,14 @@ public abstract class GameLobby implements IHasGameType {
break; break;
case TinyLeaders: case TinyLeaders:
data.appliedVariants.remove(GameType.Commander); data.appliedVariants.remove(GameType.Commander);
data.appliedVariants.remove(GameType.Oathbreaker);
data.appliedVariants.remove(GameType.Brawl); data.appliedVariants.remove(GameType.Brawl);
data.appliedVariants.remove(GameType.MomirBasic); data.appliedVariants.remove(GameType.MomirBasic);
data.appliedVariants.remove(GameType.MoJhoSto); data.appliedVariants.remove(GameType.MoJhoSto);
break; break;
case Brawl: case Brawl:
data.appliedVariants.remove(GameType.Commander); data.appliedVariants.remove(GameType.Commander);
data.appliedVariants.remove(GameType.Oathbreaker);
data.appliedVariants.remove(GameType.TinyLeaders); data.appliedVariants.remove(GameType.TinyLeaders);
data.appliedVariants.remove(GameType.MomirBasic); data.appliedVariants.remove(GameType.MomirBasic);
data.appliedVariants.remove(GameType.MoJhoSto); data.appliedVariants.remove(GameType.MoJhoSto);
@@ -254,6 +264,7 @@ public abstract class GameLobby implements IHasGameType {
break; break;
case MomirBasic: case MomirBasic:
data.appliedVariants.remove(GameType.Commander); data.appliedVariants.remove(GameType.Commander);
data.appliedVariants.remove(GameType.Oathbreaker);
data.appliedVariants.remove(GameType.TinyLeaders); data.appliedVariants.remove(GameType.TinyLeaders);
data.appliedVariants.remove(GameType.Brawl); data.appliedVariants.remove(GameType.Brawl);
data.appliedVariants.remove(GameType.Vanguard); data.appliedVariants.remove(GameType.Vanguard);
@@ -261,6 +272,7 @@ public abstract class GameLobby implements IHasGameType {
break; break;
case MoJhoSto: case MoJhoSto:
data.appliedVariants.remove(GameType.Commander); data.appliedVariants.remove(GameType.Commander);
data.appliedVariants.remove(GameType.Oathbreaker);
data.appliedVariants.remove(GameType.TinyLeaders); data.appliedVariants.remove(GameType.TinyLeaders);
data.appliedVariants.remove(GameType.Brawl); data.appliedVariants.remove(GameType.Brawl);
data.appliedVariants.remove(GameType.Vanguard); data.appliedVariants.remove(GameType.Vanguard);
@@ -281,6 +293,8 @@ public abstract class GameLobby implements IHasGameType {
if (variant == currentGameType) { if (variant == currentGameType) {
if (hasVariant(GameType.Commander)) { if (hasVariant(GameType.Commander)) {
currentGameType = GameType.Commander; currentGameType = GameType.Commander;
} else if (hasVariant(GameType.Oathbreaker)) {
currentGameType = GameType.Oathbreaker;
} else if (hasVariant(GameType.TinyLeaders)) { } else if (hasVariant(GameType.TinyLeaders)) {
currentGameType = GameType.TinyLeaders; currentGameType = GameType.TinyLeaders;
} else if (hasVariant(GameType.Brawl)) { } else if (hasVariant(GameType.Brawl)) {
@@ -348,7 +362,7 @@ public abstract class GameLobby implements IHasGameType {
SOptionPane.showMessageDialog(TextUtil.concatNoSpace("Please specify a deck for ", slot.getName())); SOptionPane.showMessageDialog(TextUtil.concatNoSpace("Please specify a deck for ", slot.getName()));
return null; return null;
} }
if (hasVariant(GameType.Commander) || hasVariant(GameType.TinyLeaders) || hasVariant(GameType.Brawl)) { if (hasVariant(GameType.Commander) || hasVariant(GameType.Oathbreaker) || hasVariant(GameType.TinyLeaders) || hasVariant(GameType.Brawl)) {
if (!slot.getDeck().has(DeckSection.Commander)) { if (!slot.getDeck().has(DeckSection.Commander)) {
SOptionPane.showMessageDialog(TextUtil.concatNoSpace(slot.getName(), " doesn't have a commander")); SOptionPane.showMessageDialog(TextUtil.concatNoSpace(slot.getName(), " doesn't have a commander"));
return null; return null;
@@ -360,12 +374,14 @@ public abstract class GameLobby implements IHasGameType {
GameType autoGenerateVariant = null; GameType autoGenerateVariant = null;
boolean isCommanderMatch = false; boolean isCommanderMatch = false;
boolean isOathbreakerMatch = false;
boolean isTinyLeadersMatch = false; boolean isTinyLeadersMatch = false;
boolean isBrawlMatch = false; boolean isBrawlMatch = false;
if (!variantTypes.isEmpty()) { if (!variantTypes.isEmpty()) {
isOathbreakerMatch = variantTypes.contains(GameType.Oathbreaker);
isTinyLeadersMatch = variantTypes.contains(GameType.TinyLeaders); isTinyLeadersMatch = variantTypes.contains(GameType.TinyLeaders);
isBrawlMatch = variantTypes.contains(GameType.Brawl); isBrawlMatch = variantTypes.contains(GameType.Brawl);
isCommanderMatch = isBrawlMatch || isTinyLeadersMatch || variantTypes.contains(GameType.Commander); isCommanderMatch = isBrawlMatch || isTinyLeadersMatch || isOathbreakerMatch || variantTypes.contains(GameType.Commander);
if (!isCommanderMatch) { if (!isCommanderMatch) {
for (final GameType variant : variantTypes) { for (final GameType variant : variantTypes) {
if (variant.isAutoGenerated()) { if (variant.isAutoGenerated()) {
@@ -426,7 +442,11 @@ public abstract class GameLobby implements IHasGameType {
} }
else { else {
if (isCommanderMatch) { if (isCommanderMatch) {
final GameType commanderGameType = isTinyLeadersMatch ? GameType.TinyLeaders : isBrawlMatch ? GameType.Brawl : GameType.Commander; final GameType commanderGameType =
isOathbreakerMatch ? GameType.Oathbreaker :
isTinyLeadersMatch ? GameType.TinyLeaders :
isBrawlMatch ? GameType.Brawl :
GameType.Commander;
if (checkLegality) { if (checkLegality) {
final String errMsg = commanderGameType.getDeckFormat().getDeckConformanceProblem(deck); final String errMsg = commanderGameType.getDeckFormat().getDeckConformanceProblem(deck);
if (errMsg != null) { if (errMsg != null) {

View File

@@ -41,6 +41,7 @@ public class CardCollections {
private IStorage<Deck> scheme; private IStorage<Deck> scheme;
private IStorage<Deck> plane; private IStorage<Deck> plane;
private IStorage<Deck> commander; private IStorage<Deck> commander;
private IStorage<Deck> oathbreaker;
private IStorage<Deck> tinyLeaders; private IStorage<Deck> tinyLeaders;
private IStorage<Deck> brawl; private IStorage<Deck> brawl;
@@ -112,6 +113,14 @@ public class CardCollections {
return commander; return commander;
} }
public IStorage<Deck> getOathbreaker() {
if (oathbreaker == null) {
oathbreaker = new StorageImmediatelySerialized<Deck>("Oathbreaker decks",
new DeckStorage(new File(ForgeConstants.DECK_OATHBREAKER_DIR), ForgeConstants.DECK_BASE_DIR));
}
return oathbreaker;
}
public IStorage<Deck> getTinyLeaders() { public IStorage<Deck> getTinyLeaders() {
if (tinyLeaders == null) { if (tinyLeaders == null) {
tinyLeaders = new StorageImmediatelySerialized<Deck>("Tiny Leaders decks", tinyLeaders = new StorageImmediatelySerialized<Deck>("Tiny Leaders decks",

View File

@@ -166,8 +166,10 @@ public final class FModel {
new File(ForgeConstants.USER_FORMATS_DIR), preferences.getPrefBoolean(FPref.LOAD_HISTORIC_FORMATS))); new File(ForgeConstants.USER_FORMATS_DIR), preferences.getPrefBoolean(FPref.LOAD_HISTORIC_FORMATS)));
magicDb.setStandardPredicate(formats.getStandard().getFilterRules()); magicDb.setStandardPredicate(formats.getStandard().getFilterRules());
magicDb.setBrawlPredicate(formats.get("Brawl").getFilterRules());
magicDb.setModernPredicate(formats.getModern().getFilterRules()); magicDb.setModernPredicate(formats.getModern().getFilterRules());
magicDb.setCommanderPredicate(formats.get("Commander").getFilterRules());
magicDb.setOathbreakerPredicate(formats.get("Oathbreaker").getFilterRules());
magicDb.setBrawlPredicate(formats.get("Brawl").getFilterRules());
magicDb.setFilteredHandsEnabled(preferences.getPrefBoolean(FPref.FILTERED_HANDS)); magicDb.setFilteredHandsEnabled(preferences.getPrefBoolean(FPref.FILTERED_HANDS));
magicDb.setMulliganRule(MulliganDefs.MulliganRule.valueOf(preferences.getPref(FPref.MULLIGAN_RULE))); magicDb.setMulliganRule(MulliganDefs.MulliganRule.valueOf(preferences.getPref(FPref.MULLIGAN_RULE)));

View File

@@ -143,7 +143,7 @@ public class ConquestUtil {
//remove any cards that aren't allowed in deck due to color identity //remove any cards that aren't allowed in deck due to color identity
if (colorIdentity != MagicColor.ALL_COLORS) { if (colorIdentity != MagicColor.ALL_COLORS) {
Predicate<PaperCard> pred = DeckFormat.Commander.isLegalCardForCommanderOrLegalPartnerPredicate(deck.getCommanders()); Predicate<PaperCard> pred = DeckFormat.Commander.isLegalCardForCommanderPredicate(deck.getCommanders());
availableCards.retainAll(Lists.newArrayList(Iterables.filter(availableCards, pred))); availableCards.retainAll(Lists.newArrayList(Iterables.filter(availableCards, pred)));
} }

View File

@@ -217,6 +217,7 @@ public final class ForgeConstants {
public static final String DECK_SCHEME_DIR = DECK_BASE_DIR + "scheme" + PATH_SEPARATOR; public static final String DECK_SCHEME_DIR = DECK_BASE_DIR + "scheme" + PATH_SEPARATOR;
public static final String DECK_PLANE_DIR = DECK_BASE_DIR + "planar" + PATH_SEPARATOR; public static final String DECK_PLANE_DIR = DECK_BASE_DIR + "planar" + PATH_SEPARATOR;
public static final String DECK_COMMANDER_DIR = DECK_BASE_DIR + "commander" + PATH_SEPARATOR; public static final String DECK_COMMANDER_DIR = DECK_BASE_DIR + "commander" + PATH_SEPARATOR;
public static final String DECK_OATHBREAKER_DIR = DECK_BASE_DIR + "oathbreaker" + PATH_SEPARATOR;
public static final String DECK_NET_DIR = DECK_BASE_DIR + "net" + PATH_SEPARATOR; public static final String DECK_NET_DIR = DECK_BASE_DIR + "net" + PATH_SEPARATOR;
public static final String QUEST_SAVE_DIR = USER_QUEST_DIR + "saves" + PATH_SEPARATOR; public static final String QUEST_SAVE_DIR = USER_QUEST_DIR + "saves" + PATH_SEPARATOR;
public static final String CONQUEST_SAVE_DIR = USER_CONQUEST_DIR + "saves" + PATH_SEPARATOR; public static final String CONQUEST_SAVE_DIR = USER_CONQUEST_DIR + "saves" + PATH_SEPARATOR;
@@ -268,6 +269,7 @@ public final class ForgeConstants {
DECK_SCHEME_DIR, DECK_SCHEME_DIR,
DECK_PLANE_DIR, DECK_PLANE_DIR,
DECK_COMMANDER_DIR, DECK_COMMANDER_DIR,
DECK_OATHBREAKER_DIR,
DECK_NET_DIR, DECK_NET_DIR,
QUEST_SAVE_DIR, QUEST_SAVE_DIR,
CACHE_TOKEN_PICS_DIR, CACHE_TOKEN_PICS_DIR,

View File

@@ -43,6 +43,14 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
COMMANDER_P6_DECK_STATE(""), COMMANDER_P6_DECK_STATE(""),
COMMANDER_P7_DECK_STATE(""), COMMANDER_P7_DECK_STATE(""),
COMMANDER_P8_DECK_STATE(""), COMMANDER_P8_DECK_STATE(""),
OATHBREAKER_P1_DECK_STATE(""),
OATHBREAKER_P2_DECK_STATE(""),
OATHBREAKER_P3_DECK_STATE(""),
OATHBREAKER_P4_DECK_STATE(""),
OATHBREAKER_P5_DECK_STATE(""),
OATHBREAKER_P6_DECK_STATE(""),
OATHBREAKER_P7_DECK_STATE(""),
OATHBREAKER_P8_DECK_STATE(""),
TINY_LEADER_P1_DECK_STATE(""), TINY_LEADER_P1_DECK_STATE(""),
TINY_LEADER_P2_DECK_STATE(""), TINY_LEADER_P2_DECK_STATE(""),
TINY_LEADER_P3_DECK_STATE(""), TINY_LEADER_P3_DECK_STATE(""),
@@ -252,6 +260,12 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
COMMANDER_P5_DECK_STATE, COMMANDER_P6_DECK_STATE, COMMANDER_P5_DECK_STATE, COMMANDER_P6_DECK_STATE,
COMMANDER_P7_DECK_STATE, COMMANDER_P8_DECK_STATE }; COMMANDER_P7_DECK_STATE, COMMANDER_P8_DECK_STATE };
public static FPref[] OATHBREAKER_DECK_STATES = {
OATHBREAKER_P1_DECK_STATE, OATHBREAKER_P2_DECK_STATE,
OATHBREAKER_P3_DECK_STATE, OATHBREAKER_P4_DECK_STATE,
OATHBREAKER_P5_DECK_STATE, OATHBREAKER_P6_DECK_STATE,
OATHBREAKER_P7_DECK_STATE, OATHBREAKER_P8_DECK_STATE };
public static FPref[] TINY_LEADER_DECK_STATES = { public static FPref[] TINY_LEADER_DECK_STATES = {
TINY_LEADER_P1_DECK_STATE, TINY_LEADER_P2_DECK_STATE, TINY_LEADER_P1_DECK_STATE, TINY_LEADER_P2_DECK_STATE,
TINY_LEADER_P3_DECK_STATE, TINY_LEADER_P4_DECK_STATE, TINY_LEADER_P3_DECK_STATE, TINY_LEADER_P4_DECK_STATE,