Refactor achievement definitions to make them easier to implement

This commit is contained in:
drdev
2014-09-28 09:01:16 +00:00
parent cc920261d8
commit 2306524df1
24 changed files with 252 additions and 192 deletions

View File

@@ -10,20 +10,22 @@ import forge.game.player.Player;
import forge.interfaces.IGuiBase;
import forge.item.IPaperCard;
import forge.properties.ForgeConstants;
import forge.util.Lang;
public abstract class Achievement {
private final String key, displayName, sharedDesc, commonDesc, uncommonDesc, rareDesc, mythicDesc;
private final int commonThreshold, uncommonThreshold, rareThreshold, mythicThreshold;
private final boolean checkGreaterThan;
protected final int defaultValue;
private ISkinImage image;
protected int best, current;
private int best;
//use this constructor for special achievements without tiers
protected Achievement(String key0, String displayName0, String description0, String flavorText0) {
this(key0, displayName0, description0, null, 1, null, 1, null, 1, "(" + flavorText0 + ")", 1); //pass flavor text as mythic description so it appears below description faded out
protected Achievement(String key0, String displayName0, String description0, String flavorText0, int defaultValue0) {
this(key0, displayName0, description0, defaultValue0, null, 1, null, 1, null, 1, "(" + flavorText0 + ")", 1); //pass flavor text as mythic description so it appears below description faded out
}
//use this constructor for regular tiered achievements
protected Achievement(String key0, String displayName0, String sharedDesc0,
protected Achievement(String key0, String displayName0, String sharedDesc0, int defaultValue0,
String commonDesc0, int commonThreshold0,
String uncommonDesc0, int uncommonThreshold0,
String rareDesc0, int rareThreshold0,
@@ -40,6 +42,8 @@ public abstract class Achievement {
mythicDesc = mythicDesc0;
mythicThreshold = mythicThreshold0;
checkGreaterThan = rareThreshold0 >= uncommonThreshold0;
best = defaultValue0;
defaultValue = defaultValue0;
}
public String getKey() {
@@ -125,11 +129,9 @@ public abstract class Achievement {
}
else if (earnedUncommon()) {
background = FSkinProp.IMG_UNCOMMON_TROPHY;
//0.8f; //TODO: fade out slightly until rare earned
}
else if (earnedCommon()) {
background = FSkinProp.IMG_COMMON_TROPHY;
//0.6f; //TODO: fade out a bit more until uncommon earned
}
else {
opacity = 0.25f; //fade out if achievement hasn't been earned yet
@@ -143,12 +145,12 @@ public abstract class Achievement {
image = GuiBase.getInterface().createLayeredImage(background, ForgeConstants.CACHE_ACHIEVEMENTS_DIR + "/" + key + ".png", opacity);
}
public void update(IGuiBase gui, Player player) {
current = evaluate(player, player.getGame());
public int update(IGuiBase gui, Player player) {
int value = evaluate(player, player.getGame());
if (checkGreaterThan) {
if (current <= best) { return; }
if (value <= best) { return value; }
}
else if (current >= best) { return; }
else if (value >= best) { return value; }
boolean hadEarnedSpecial = earnedSpecial();
boolean hadEarnedMythic = earnedMythic();
@@ -156,14 +158,14 @@ public abstract class Achievement {
boolean hadEarnedUncommon = earnedUncommon();
boolean hadEarnedCommon = earnedCommon();
best = current;
best = value;
if (earnedSpecial()) {
if (!hadEarnedSpecial) {
updateTrophyImage();
gui.showImageDialog(image, displayName + "\n" + sharedDesc + "\n" + mythicDesc, "Achievement Earned");
}
return;
return value;
}
String type = null;
@@ -199,23 +201,22 @@ public abstract class Achievement {
}
gui.showImageDialog(image, displayName + " (" + type + ")\n" + desc, "Achievement Earned");
}
return value;
}
public boolean needSave() {
return best != 0 || current != 0;
public final boolean needSave() {
return best != defaultValue;
}
public void saveToXml(Element el) {
el.setAttribute("best", String.valueOf(best));
el.setAttribute("current", String.valueOf(current));
}
public void loadFromXml(Element el) {
best = getIntAttribute(el, "best");
current = getIntAttribute(el, "current");
}
private int getIntAttribute(Element el, String name) {
protected int getIntAttribute(Element el, String name) {
String value = el.getAttribute(name);
if (value.length() > 0) {
try {
@@ -226,5 +227,22 @@ public abstract class Achievement {
return 0;
}
public abstract String getSubTitle();
protected abstract String getNoun();
protected boolean pluralizeNoun() {
return best != 1;
}
protected boolean displayNounBefore() {
return false;
}
public String getSubTitle() {
if (best != defaultValue) {
if (displayNounBefore()) {
return "Best: " + getNoun() + " " + best;
}
return "Best: " + best + " " + (pluralizeNoun() ? Lang.getPlural(getNoun()) : getNoun());
}
return null;
}
}

View File

@@ -71,14 +71,14 @@ public class AltWinAchievements extends AchievementCollection {
}
}
private class AltWinAchievement extends Achievement {
private class AltWinAchievement extends ProgressiveAchievement {
private AltWinAchievement(String cardName0, String displayName0, String flavorText0) {
super(cardName0, displayName0, "Win a game with " + cardName0, flavorText0);
}
@Override
protected int evaluate(Player player, Game game) {
return current + 1; //if this reaches this point, it can be presumed that alternate win condition achieved
protected boolean eval(Player player, Game game) {
return true; //if this reaches this point, it can be presumed that alternate win condition achieved
}
@Override
@@ -87,8 +87,8 @@ public class AltWinAchievements extends AchievementCollection {
}
@Override
public String getSubTitle() {
return current + " Win" + (current != 1 ? "s" : "");
public String getNoun() {
return "Win";
}
}
}

View File

@@ -5,17 +5,11 @@ import forge.game.player.Player;
public class ArcaneMaster extends Achievement {
public ArcaneMaster() {
super("ArcaneMaster", "Arcane Master", "Win a game without casting",
super("ArcaneMaster", "Arcane Master", "Win a game without casting", Integer.MAX_VALUE,
"more than 3 spells", 3,
"more than 2 spells", 2,
"more than 1 spell", 1,
"any spells", 0);
best = Integer.MAX_VALUE; //initialize best to max value so any amount is smaller
}
@Override
public boolean needSave() {
return best < Integer.MAX_VALUE;
}
@Override
@@ -23,14 +17,11 @@ public class ArcaneMaster extends Achievement {
if (player.getOutcome().hasWon()) {
return player.getAchievementTracker().spellsCast;
}
return Integer.MAX_VALUE; //indicate that player didn't win
return defaultValue; //indicate that player didn't win
}
@Override
public String getSubTitle() {
if (best < Integer.MAX_VALUE) {
return "Best: " + best + " Spell" + (best != 1 ? "s" : "");
}
return null;
protected String getNoun() {
return "Spell";
}
}

View File

@@ -8,7 +8,7 @@ public class Blackjack extends Achievement {
private static final int THRESHOLD = 21;
public Blackjack(int silver0, int gold0, int mythic0) {
super("Blackjack", "Blackjack", "Win a game from your commander dealing",
super("Blackjack", "Blackjack", "Win a game from your commander dealing", 0,
String.format("%d combat damage", THRESHOLD), THRESHOLD,
String.format("%d combat damage", silver0), silver0,
String.format("%d combat damage", gold0), gold0,
@@ -31,10 +31,12 @@ public class Blackjack extends Achievement {
}
@Override
public String getSubTitle() {
if (best > 0) {
return "Best: " + best + " Damage";
}
return null;
public String getNoun() {
return "Damage";
}
@Override
protected boolean pluralizeNoun() {
return false;
}
}

View File

@@ -6,17 +6,11 @@ import forge.game.player.Player;
public class DeckedOut extends Achievement {
public DeckedOut(int silver0, int gold0, int mythic0) {
super("DeckedOut", "Decked Out", "Win a game from opponent",
super("DeckedOut", "Decked Out", "Win a game from opponent", Integer.MAX_VALUE,
"drawing into an empty library", Integer.MAX_VALUE - 1,
String.format("drawing into an empty library by turn %d", silver0), silver0,
String.format("drawing into an empty library by turn %d", gold0), gold0,
String.format("drawing into an empty library by turn %d", mythic0), mythic0);
best = Integer.MAX_VALUE;
}
@Override
public boolean needSave() {
return best < Integer.MAX_VALUE;
}
@Override
@@ -31,10 +25,12 @@ public class DeckedOut extends Achievement {
}
@Override
public String getSubTitle() {
if (best < Integer.MAX_VALUE) {
return "Best: Turn " + best;
}
return null;
protected String getNoun() {
return "Turn";
}
@Override
protected boolean displayNounBefore() {
return true;
}
}

View File

@@ -3,7 +3,7 @@ package forge.achievement;
import forge.game.Game;
import forge.game.player.Player;
public class GameWinStreak extends Achievement {
public class GameWinStreak extends StreakAchievement {
public GameWinStreak(int bronze0, int silver0, int gold0, int mythic0) {
super("GameWinStreak", "Game Win Streak", null,
String.format("Win %d games in a row", bronze0), bronze0,
@@ -13,15 +13,7 @@ public class GameWinStreak extends Achievement {
}
@Override
protected int evaluate(Player player, Game game) {
if (player.getOutcome().hasWon()) {
return current + 1;
}
return 0; //reset if player didn't win
}
@Override
public String getSubTitle() {
return "Best: " + best + " Active: " + current;
protected Boolean eval(Player player, Game game) {
return player.getOutcome().hasWon();
}
}

View File

@@ -6,7 +6,7 @@ import forge.game.zone.ZoneType;
public class Hellbent extends Achievement {
public Hellbent() {
super("Hellbent", "Hellbent", "Win a game with no cards in your",
super("Hellbent", "Hellbent", "Win a game with no cards in your", 0,
"hand", 1,
"hand or library", 2,
"hand, library, or graveyard", 3,
@@ -32,6 +32,11 @@ public class Hellbent extends Achievement {
return 0;
}
@Override
protected String getNoun() {
return null;
}
@Override
public String getSubTitle() {
return null;

View File

@@ -5,7 +5,7 @@ import forge.game.player.Player;
public class LifeToSpare extends Achievement {
public LifeToSpare(int bronze0, int silver0, int gold0, int mythic0) {
super("LifeToSpare", "Life to Spare", "Win a game with",
super("LifeToSpare", "Life to Spare", "Win a game with", 0,
String.format("%d life more than you started with", bronze0), bronze0,
String.format("%d life more than you started with", silver0), silver0,
String.format("%d life more than you started with", gold0), gold0,
@@ -24,10 +24,11 @@ public class LifeToSpare extends Achievement {
}
@Override
public String getSubTitle() {
if (best > 0) {
return "Best: " + best + " Life";
}
return null;
protected String getNoun() {
return "Life";
}
@Override
protected boolean pluralizeNoun() {
return false;
}
}

View File

@@ -7,7 +7,7 @@ import forge.game.zone.ZoneType;
public class ManaFlooded extends Achievement {
public ManaFlooded(int bronze0, int silver0, int gold0, int mythic0) {
super("ManaFlooded", "Mana Flooded", "Win a game with at least",
super("ManaFlooded", "Mana Flooded", "Win a game with at least", 0,
String.format("%d lands on the battlefield", bronze0), bronze0,
String.format("%d lands on the battlefield", silver0), silver0,
String.format("%d lands on the battlefield", gold0), gold0,
@@ -29,10 +29,7 @@ public class ManaFlooded extends Achievement {
}
@Override
public String getSubTitle() {
if (best > 0) {
return "Best: " + best + " Land" + (best != 1 ? "s" : "");
}
return null;
protected String getNoun() {
return "Land";
}
}

View File

@@ -5,17 +5,11 @@ import forge.game.player.Player;
public class ManaScrewed extends Achievement {
public ManaScrewed() {
super("ManaScrewed", "Mana Screwed", "Win a game despite playing only",
super("ManaScrewed", "Mana Screwed", "Win a game despite playing only", Integer.MAX_VALUE,
"3 lands", 3,
"2 lands", 2,
"1 land", 1,
"0 lands", 0);
best = Integer.MAX_VALUE; //initialize best to max value so any amount is smaller
}
@Override
public boolean needSave() {
return best < Integer.MAX_VALUE;
}
@Override
@@ -23,14 +17,11 @@ public class ManaScrewed extends Achievement {
if (player.getOutcome().hasWon()) {
return player.getNumLandsPlayed();
}
return Integer.MAX_VALUE; //indicate that player didn't win
return defaultValue; //indicate that player didn't win
}
@Override
public String getSubTitle() {
if (best < Integer.MAX_VALUE) {
return "Best: " + best + " Land" + (best != 1 ? "s" : "");
}
return null;
protected String getNoun() {
return "Land";
}
}

View File

@@ -3,7 +3,7 @@ package forge.achievement;
import forge.game.Game;
import forge.game.player.Player;
public class MatchWinStreak extends Achievement {
public class MatchWinStreak extends StreakAchievement {
public MatchWinStreak(int bronze0, int silver0, int gold0, int mythic0) {
super("MatchWinStreak", "Match Win Streak", null,
String.format("Win %d matches in a row", bronze0), bronze0,
@@ -13,18 +13,13 @@ public class MatchWinStreak extends Achievement {
}
@Override
protected int evaluate(Player player, Game game) {
protected Boolean eval(Player player, Game game) {
if (game.getMatch().isMatchOver()) {
if (game.getMatch().isWonBy(player.getLobbyPlayer())) {
return current + 1;
return true;
}
return 0; //reset if player didn't win
return false;
}
return current;
}
@Override
public String getSubTitle() {
return "Best: " + best + " Active: " + current;
return null;
}
}

View File

@@ -5,17 +5,11 @@ import forge.game.player.Player;
public class NeedForSpeed extends Achievement {
public NeedForSpeed(int bronze0, int silver0, int gold0, int mythic0) {
super("NeedForSpeed", "Need for Speed", null,
super("NeedForSpeed", "Need for Speed", null, Integer.MAX_VALUE,
String.format("Win a game by turn %d", bronze0), bronze0,
String.format("Win a game by turn %d", silver0), silver0,
String.format("Win a game by turn %d", gold0), gold0,
String.format("Win a game by turn %d", mythic0), mythic0);
best = Integer.MAX_VALUE; //initialize best to max value so any
}
@Override
public boolean needSave() {
return best < Integer.MAX_VALUE;
}
@Override
@@ -23,14 +17,16 @@ public class NeedForSpeed extends Achievement {
if (player.getOutcome().hasWon()) {
return player.getTurn();
}
return Integer.MAX_VALUE; //indicate that player didn't win
return defaultValue; //indicate that player didn't win
}
@Override
public String getSubTitle() {
if (best < Integer.MAX_VALUE) {
return "Best: Turn " + best;
}
return null;
protected String getNoun() {
return "Turn";
}
@Override
protected boolean displayNounBefore() {
return true;
}
}

View File

@@ -1,13 +1,11 @@
package forge.achievement;
import org.w3c.dom.Element;
import forge.game.Game;
import forge.game.player.Player;
public class Overkill extends Achievement {
public Overkill(int bronze0, int silver0, int gold0, int mythic0) {
super("Overkill", "Overkill", "Win a game with opponent at",
super("Overkill", "Overkill", "Win a game with opponent at", 0,
String.format("%d life", bronze0), bronze0,
String.format("%d life", silver0), silver0,
String.format("%d life", gold0), gold0,
@@ -26,23 +24,11 @@ public class Overkill extends Achievement {
}
@Override
public String getSubTitle() {
if (best < 0) {
return "Best: " + best + " Life";
}
return null;
protected String getNoun() {
return "Life";
}
@Override
public void loadFromXml(Element el) {
super.loadFromXml(el);
//perform conversion to handle data from old format before supporting negative thresholds
if (best > 0) {
best = -best;
}
if (current > 0) {
current = -current;
}
protected boolean pluralizeNoun() {
return false;
}
}

View File

@@ -96,14 +96,14 @@ public class PlaneswalkerAchievements extends AchievementCollection {
}
}
private class PlaneswalkerUltimate extends Achievement {
private class PlaneswalkerUltimate extends ProgressiveAchievement {
private PlaneswalkerUltimate(String cardName0, String displayName0, String flavorText0) {
super(cardName0, displayName0, "Win a game after activating " + cardName0 + "'s ultimate", flavorText0);
}
@Override
protected int evaluate(Player player, Game game) {
return current + 1; //if this reaches this point, it can be presumed that alternate win condition achieved
protected boolean eval(Player player, Game game) {
return true; //if this reaches this point, it can be presumed that alternate win condition achieved
}
@Override
@@ -112,8 +112,8 @@ public class PlaneswalkerAchievements extends AchievementCollection {
}
@Override
public String getSubTitle() {
return current + " Win" + (current != 1 ? "s" : "");
protected String getNoun() {
return "Win";
}
}
}

View File

@@ -8,7 +8,7 @@ public class Poisoned extends Achievement {
private static final int THRESHOLD = 10;
public Poisoned(int silver0, int gold0, int mythic0) {
super("Poisoned", "Poisoned", "Win a game by giving opponent",
super("Poisoned", "Poisoned", "Win a game by giving opponent", 0,
String.format("%d poison counters", THRESHOLD), THRESHOLD,
String.format("%d poison counters", silver0), silver0,
String.format("%d poison counters", gold0), gold0,
@@ -27,10 +27,7 @@ public class Poisoned extends Achievement {
}
@Override
public String getSubTitle() {
if (best > 0) {
return "Best: " + best + " Counters";
}
return null;
protected String getNoun() {
return "Counter";
}
}

View File

@@ -0,0 +1,52 @@
package forge.achievement;
import org.w3c.dom.Element;
import forge.game.Game;
import forge.game.player.Player;
import forge.util.Lang;
public abstract class ProgressiveAchievement extends Achievement {
private int current;
protected ProgressiveAchievement(String key0, String displayName0, String description0, String flavorText0) {
super(key0, displayName0, description0, flavorText0, 0);
}
//use this constructor for regular tiered achievements
protected ProgressiveAchievement(String key0, String displayName0, String sharedDesc0,
String commonDesc0, int commonThreshold0,
String uncommonDesc0, int uncommonThreshold0,
String rareDesc0, int rareThreshold0,
String mythicDesc0, int mythicThreshold0) {
super(key0, displayName0, sharedDesc0, 0, commonDesc0, commonThreshold0,
uncommonDesc0, uncommonThreshold0, rareDesc0, rareThreshold0,
mythicDesc0, mythicThreshold0);
}
protected abstract boolean eval(Player player, Game game);
@Override
protected final int evaluate(Player player, Game game) {
if (eval(player, game)) {
current++;
}
return current;
}
@Override
public final String getSubTitle() {
return current + " " + (current != 1 ? Lang.getPlural(getNoun()) : getNoun());
}
@Override
public void saveToXml(Element el) {
super.saveToXml(el);
el.setAttribute("current", String.valueOf(current));
}
@Override
public void loadFromXml(Element el) {
super.loadFromXml(el);
current = getIntAttribute(el, "current");
}
}

View File

@@ -4,35 +4,24 @@ import forge.game.Game;
import forge.game.player.Player;
public class RagsToRiches extends Achievement {
private static final int NO_MULLIGAN = 7;
public RagsToRiches() {
super("RagsToRiches", "Rags to Riches", "Win a game after mulliganing to",
super("RagsToRiches", "Rags to Riches", "Win a game after mulliganing to", 7,
"4 cards", 4,
"3 cards", 3,
"2 cards", 2,
"1 card", 1);
best = NO_MULLIGAN; //initialize best to max value so any amount of mulliganing is smaller
}
@Override
public boolean needSave() {
return best < NO_MULLIGAN;
}
@Override
protected int evaluate(Player player, Game game) {
if (player.getOutcome().hasWon() && player.getAchievementTracker().mulliganTo < NO_MULLIGAN) {
if (player.getOutcome().hasWon() && player.getAchievementTracker().mulliganTo < defaultValue) {
return player.getAchievementTracker().mulliganTo;
}
return NO_MULLIGAN; //indicate that player didn't win
return defaultValue; //indicate that player didn't win
}
@Override
public String getSubTitle() {
if (best < NO_MULLIGAN) {
return "Best: " + best + " Card" + (best != 1 ? "s" : "");
}
return null;
protected String getNoun() {
return "Card";
}
}

View File

@@ -5,7 +5,7 @@ import forge.game.player.Player;
public class StormChaser extends Achievement {
public StormChaser(int bronze0, int silver0, int gold0, int mythic0) {
super("StormChaser", "Storm Chaser", "Win a game after casting",
super("StormChaser", "Storm Chaser", "Win a game after casting", 0,
String.format("%d spells in a single turn", bronze0), bronze0,
String.format("%d spells in a single turn", silver0), silver0,
String.format("%d spells in a single turn", gold0), gold0,
@@ -21,10 +21,7 @@ public class StormChaser extends Achievement {
}
@Override
public String getSubTitle() {
if (best > 0) {
return "Best: " + best + " Spell" + (best != 1 ? "s" : "");
}
return null;
protected String getNoun() {
return "Spell";
}
}

View File

@@ -0,0 +1,61 @@
package forge.achievement;
import org.w3c.dom.Element;
import forge.game.Game;
import forge.game.player.Player;
public abstract class StreakAchievement extends Achievement {
private int current;
protected StreakAchievement(String key0, String displayName0, String description0, String flavorText0) {
super(key0, displayName0, description0, flavorText0, 0);
}
//use this constructor for regular tiered achievements
protected StreakAchievement(String key0, String displayName0, String sharedDesc0,
String commonDesc0, int commonThreshold0,
String uncommonDesc0, int uncommonThreshold0,
String rareDesc0, int rareThreshold0,
String mythicDesc0, int mythicThreshold0) {
super(key0, displayName0, sharedDesc0, 0, commonDesc0, commonThreshold0,
uncommonDesc0, uncommonThreshold0, rareDesc0, rareThreshold0,
mythicDesc0, mythicThreshold0);
}
protected abstract Boolean eval(Player player, Game game);
@Override
protected final int evaluate(Player player, Game game) {
Boolean val = eval(player, game);
if (val != null) { //null means don't increment or reset
if (val) {
current++;
}
else {
current = 0;
}
}
return current;
}
@Override
protected String getNoun() {
return "Active: " + current; //override here so active streak appears after best
}
@Override
protected boolean pluralizeNoun() {
return false;
}
@Override
public void saveToXml(Element el) {
super.saveToXml(el);
el.setAttribute("current", String.valueOf(current));
}
@Override
public void loadFromXml(Element el) {
super.loadFromXml(el);
current = getIntAttribute(el, "current");
}
}

View File

@@ -3,7 +3,7 @@ package forge.achievement;
import forge.game.Game;
import forge.game.player.Player;
public class TotalGameWins extends Achievement {
public class TotalGameWins extends ProgressiveAchievement {
public TotalGameWins(int bronze0, int silver0, int gold0, int mythic0) {
super("TotalGameWins", "Total Game Wins", null,
String.format("Win %d games", bronze0), bronze0,
@@ -13,15 +13,12 @@ public class TotalGameWins extends Achievement {
}
@Override
protected int evaluate(Player player, Game game) {
if (player.getOutcome().hasWon()) {
return current + 1;
}
return current;
protected boolean eval(Player player, Game game) {
return player.getOutcome().hasWon();
}
@Override
public String getSubTitle() {
return Integer.toString(current);
protected String getNoun() {
return "Game";
}
}

View File

@@ -3,7 +3,7 @@ package forge.achievement;
import forge.game.Game;
import forge.game.player.Player;
public class TotalMatchWins extends Achievement {
public class TotalMatchWins extends ProgressiveAchievement {
public TotalMatchWins(int bronze0, int silver0, int gold0, int mythic0) {
super("TotalMatchWins", "Total Match Wins", null,
String.format("Win %d matches", bronze0), bronze0,
@@ -13,17 +13,12 @@ public class TotalMatchWins extends Achievement {
}
@Override
protected int evaluate(Player player, Game game) {
if (game.getMatch().isMatchOver()) {
if (game.getMatch().isWonBy(player.getLobbyPlayer())) {
return current + 1;
}
}
return current;
protected boolean eval(Player player, Game game) {
return game.getMatch().isMatchOver() && game.getMatch().isWonBy(player.getLobbyPlayer());
}
@Override
public String getSubTitle() {
return Integer.toString(current);
protected String getNoun() {
return "Match";
}
}

View File

@@ -5,7 +5,7 @@ import forge.game.GameType;
import forge.game.player.Player;
import forge.util.Lang;
public class VariantWins extends Achievement {
public class VariantWins extends ProgressiveAchievement {
private GameType variant;
public VariantWins(GameType variant0, int silver0, int gold0, int mythic0) {
@@ -18,20 +18,20 @@ public class VariantWins extends Achievement {
}
@Override
protected int evaluate(Player player, Game game) {
protected boolean eval(Player player, Game game) {
if (player.getOutcome().hasWon()) {
if (game.getRules().hasAppliedVariant(variant)) {
return current + 1;
return true;
}
if (variant == GameType.Archenemy && game.getRules().hasAppliedVariant(GameType.ArchenemyRumble)) {
return current + 1; //lump Archenemy Rumble into same achievement as Archenemy
return true; //lump Archenemy Rumble into same achievement as Archenemy
}
}
return current;
return false;
}
@Override
public String getSubTitle() {
return current + " Win" + (current != 1 ? "s" : "");
protected String getNoun() {
return "Win";
}
}