mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
Refactor achievement definitions to make them easier to implement
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user