Commit first set of alternate win achievements

This commit is contained in:
drdev
2014-09-21 15:22:59 +00:00
parent d6fa02582b
commit b5aa3b429e
16 changed files with 138 additions and 58 deletions

1
.gitattributes vendored
View File

@@ -16885,6 +16885,7 @@ forge-gui/src/main/java/forge/GuiBase.java -text
forge-gui/src/main/java/forge/UiCommand.java svneol=native#text/plain
forge-gui/src/main/java/forge/achievement/Achievement.java -text
forge-gui/src/main/java/forge/achievement/AchievementCollection.java -text
forge-gui/src/main/java/forge/achievement/AltWinAchievements.java -text
forge-gui/src/main/java/forge/achievement/Blackjack.java -text
forge-gui/src/main/java/forge/achievement/ConstructedAchievements.java -text
forge-gui/src/main/java/forge/achievement/DeckedOut.java -text

View File

@@ -322,6 +322,19 @@ public class Player extends GameEntity implements Comparable<Player> {
return result;
}
//get single opponent for player if only one, otherwise returns null
//meant to be used after game ends for the sake of achievements
public Player getSingleOpponent() {
if (game.getRegisteredPlayers().size() == 2) {
for (Player p : game.getRegisteredPlayers()) {
if (p.isOpponentOf(this)) {
return p;
}
}
}
return null;
}
/**
* Find the smallest life total amongst this player's opponents.
*

View File

@@ -398,12 +398,12 @@ public enum VSubmenuAchievements implements IVSubmenu<CSubmenuAchievements> {
}
y += PADDING;
if (sharedDesc != null) {
g2d.drawString(sharedDesc + "...", x, y);
g2d.drawString(selectedAchievement.isSpecial() ? sharedDesc : sharedDesc + "...", x, y);
y += descHeight;
}
if (mythicDesc != null) {
FSkin.setGraphicsColor(g2d, selectedAchievement.earnedMythic() ? TEXT_COLOR : NOT_EARNED_COLOR);
g2d.drawString("(Mythic) " + mythicDesc, x, y);
g2d.drawString(selectedAchievement.isSpecial() ? mythicDesc : "(Mythic) " + mythicDesc, x, y); //handle flavor text here too
y += descHeight;
}
if (rareDesc != null) {

View File

@@ -306,13 +306,13 @@ public class AchievementsPage extends TabPage<SettingsScreen> {
}
y += PADDING;
if (sharedDesc != null) {
g.drawText(sharedDesc + "...", DESC_FONT, TEXT_COLOR,
g.drawText(selectedAchievement.isSpecial() ? sharedDesc : sharedDesc + "...", DESC_FONT, TEXT_COLOR,
x, y, w, h, false, HAlignment.LEFT, false);
y += DESC_FONT.getLineHeight();
}
if (mythicDesc != null) {
g.drawText("(Mythic) " + mythicDesc, DESC_FONT,
selectedAchievement.earnedRare() ? TEXT_COLOR : NOT_EARNED_COLOR,
g.drawText(selectedAchievement.isSpecial() ? mythicDesc : "(Mythic) " + mythicDesc, DESC_FONT, //handle flavor text here too
selectedAchievement.earnedMythic() ? TEXT_COLOR : NOT_EARNED_COLOR,
x, y, w, h, false, HAlignment.LEFT, false);
y += DESC_FONT.getLineHeight();
}

View File

@@ -18,8 +18,8 @@ public abstract class Achievement {
protected int best, current;
//use this constructor for special achievements without tiers
protected Achievement(String displayName0, String description0, FSkinProp overlayImage0) {
this(displayName0, description0, null, 1, null, 1, null, 1, null, 1, overlayImage0);
protected Achievement(String displayName0, String description0, String flavorText0, FSkinProp overlayImage0) {
this(displayName0, description0, null, 1, null, 1, null, 1, "(" + flavorText0 + ")", 1, overlayImage0); //pass flavor text as mythic description so it appears below description faded out
}
//use this constructor for regular tiered achievements
protected Achievement(String displayName0, String sharedDesc0,
@@ -39,7 +39,7 @@ public abstract class Achievement {
mythicDesc = mythicDesc0;
mythicThreshold = mythicThreshold0;
overlayImage = overlayImage0;
checkGreaterThan = rareThreshold0 > uncommonThreshold0;
checkGreaterThan = rareThreshold0 >= uncommonThreshold0;
}
public String getDisplayName() {
@@ -66,8 +66,11 @@ public abstract class Achievement {
}
return image;
}
public boolean isSpecial() {
return mythicThreshold == commonThreshold;
}
private boolean earnedSpecial() {
return (mythicThreshold == commonThreshold && best > 1);
return (isSpecial() && best > 0);
}
public boolean earnedMythic() {
if (checkGreaterThan) {
@@ -96,17 +99,6 @@ public abstract class Achievement {
protected abstract int evaluate(Player player, Game game);
protected Player getSingleOpponent(Player player) {
if (player.getGame().getRegisteredPlayers().size() == 2) {
for (Player p : player.getGame().getRegisteredPlayers()) {
if (p.isOpponentOf(player)) {
return p;
}
}
}
return null;
}
private void updateTrophyImage() {
FSkinProp background;
float opacity = 1;

View File

@@ -24,9 +24,9 @@ import forge.util.FileUtil;
import forge.util.XmlUtil;
public abstract class AchievementCollection implements Iterable<Achievement> {
private final Map<String, Achievement> achievements = new LinkedHashMap<String, Achievement>();
private final String name, filename;
private final boolean isLimitedFormat;
protected final Map<String, Achievement> achievements = new LinkedHashMap<String, Achievement>();
protected final String name, filename;
protected final boolean isLimitedFormat;
static {
FileUtil.ensureDirectoryExists(ForgeConstants.ACHIEVEMENTS_DIR);
@@ -37,19 +37,19 @@ public abstract class AchievementCollection implements Iterable<Achievement> {
cb.addItem(FModel.getAchievements(GameType.Draft));
cb.addItem(FModel.getAchievements(GameType.Sealed));
cb.addItem(FModel.getAchievements(GameType.Quest));
cb.addItem(AltWinAchievements.instance);
}
protected AchievementCollection(String name0, String filename0, boolean isLimitedFormat0) {
name = name0;
filename = filename0;
isLimitedFormat = isLimitedFormat0;
buildTopShelf();
buildCoreShelves();
buildBottomShelf();
addSharedAchivements();
addAchievements();
load();
}
private void buildCoreShelves() {
protected void addSharedAchivements() {
add("GameWinStreak", new GameWinStreak(10, 25, 50, 100));
add("MatchWinStreak", new MatchWinStreak(10, 25, 50, 100));
add("TotalGameWins", new TotalGameWins(250, 500, 1000, 2000));
@@ -65,8 +65,7 @@ public abstract class AchievementCollection implements Iterable<Achievement> {
add("Hellbent", new Hellbent());
}
protected abstract void buildTopShelf();
protected abstract void buildBottomShelf();
protected abstract void addAchievements();
protected void add(String key, Achievement achievement) {
achievements.put(key, achievement);
@@ -103,7 +102,7 @@ public abstract class AchievementCollection implements Iterable<Achievement> {
}
}
private void save() {
protected void save() {
try {
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = builder.newDocument();

View File

@@ -0,0 +1,81 @@
package forge.achievement;
import org.apache.commons.lang3.StringUtils;
import forge.assets.FSkinProp;
import forge.game.Game;
import forge.game.player.Player;
import forge.interfaces.IGuiBase;
import forge.properties.ForgeConstants;
public class AltWinAchievements extends AchievementCollection {
public static final AltWinAchievements instance = new AltWinAchievements();
private AltWinAchievements() {
super("Alternate Win Conditions", ForgeConstants.ACHIEVEMENTS_DIR + "altwin.xml", false);
}
@Override
protected void addSharedAchivements() {
//prevent including shared achievements
}
@Override
protected void addAchievements() {
add("Azor's Elocutors", "The Filibuster", "Talk might be cheap, but it can buy you victory!", FSkinProp.IMG_THE_FILIBUSTER);
add("Barren Glory", "The Clean Slate", "When you have nothing, you can lose nothing... so you can win everything!", FSkinProp.IMG_THE_CLEAN_SLATE);
add("Battle of Wits", "The Library of Congress", "So many answers, so little time to look through them...", FSkinProp.IMG_THE_LIBRARY_OF_CONGRESS);
add("Biovisionary", "The Clique", "And now my... I mean our plan is complete!", FSkinProp.IMG_THE_CLIQUE);
add("Chance Encounter", "The Accident", "This victory was brought to you by a series of fortunate events.", FSkinProp.IMG_THE_ACCIDENT);
add("Coalition Victory", "The Teamwork", "Let's all be friends!", FSkinProp.IMG_THE_TEAMWORK);
add("Darksteel Reactor", "The Machine", "What are you going to do with all this power? Whatever you want!", FSkinProp.IMG_THE_MACHINE);
add("Epic Struggle", "The Army", "Let's just trample them into the ground already!", FSkinProp.IMG_THE_ARMY);
add("Felidar Sovereign", "The Cat's Life", "Just wait for his other eight lives!", FSkinProp.IMG_THE_CATS_LIFE);
add("Helix Pinnacle", "The Tower", "The view from the top is great!", FSkinProp.IMG_THE_TOWER);
add("Hellkite Tyrant", "The Hoard", "You made your bed of treasure, now lie in it!", FSkinProp.IMG_THE_HOARD);
add("Laboratory Maniac", "The Insanity", "No more questions? I'm omniscient now!", FSkinProp.IMG_THE_INSANITY);
add("Mayael's Aria", "The Gargantuan", "Just my shadow weighs a ton!", FSkinProp.IMG_THE_GARGANTUAN);
add("Maze's End", "The Labyrinth", "What? No bossfight?", FSkinProp.IMG_THE_LABYRINTH);
add("Mortal Combat", "The Boneyard", "So peaceful...", FSkinProp.IMG_THE_BONEYARD);
add("Near-Death Experience", "The Edge", "Phew... I thought I was going to die!", FSkinProp.IMG_THE_EDGE);
}
private void add(String cardName0, String displayName0, String flavorText0, FSkinProp overlayImage0) {
add(getKey(cardName0), new AltWinAchievement(displayName0, cardName0, flavorText0, overlayImage0));
}
private String getKey(String cardName0) {
return cardName0.replaceAll(" ", "");
}
@Override
public void updateAll(IGuiBase gui, Player player) {
//only call update on achievement for alternate win condition (if any)
if (player.getOutcome().hasWon()) {
String altWinCondition = player.getOutcome().altWinSourceName;
if (!StringUtils.isEmpty(altWinCondition)) {
Achievement achievement = achievements.get(getKey(altWinCondition));
if (achievement != null) {
achievement.update(gui, player);
save();
}
}
}
}
private class AltWinAchievement extends Achievement {
private AltWinAchievement(String displayName0, String cardName0, String flavorText0, FSkinProp overlayImage0) {
super(displayName0, "Win a game with " + cardName0, flavorText0, overlayImage0);
}
@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
}
@Override
public String getSubTitle() {
return current + " Win" + (current != 1 ? "s" : "");
}
}
}

View File

@@ -9,14 +9,9 @@ public class ConstructedAchievements extends AchievementCollection {
super("Constructed", ForgeConstants.ACHIEVEMENTS_DIR + "constructed.xml", false);
}
//add achievements that should appear at the top above core achievements for each game mode
@Override
protected void buildTopShelf() {
}
//add achievements that should appear at the bottom below core achievements for each game mode
@Override
protected void buildBottomShelf() {
protected void addAchievements() {
add("Vanguard", new VariantWins(GameType.Vanguard, 25, 50, 100, FSkinProp.IMG_VANGUARD));
add("MomirBasic", new VariantWins(GameType.MomirBasic, 25, 50, 100, FSkinProp.IMG_MOMIR_BASIC));
add("Commander", new VariantWins(GameType.Commander, 25, 50, 100, FSkinProp.IMG_COMMANDER));

View File

@@ -24,7 +24,7 @@ public class DeckedOut extends Achievement {
@Override
protected int evaluate(Player player, Game game) {
if (player.getOutcome().hasWon()) {
Player opponent = getSingleOpponent(player);
Player opponent = player.getSingleOpponent();
if (opponent != null && opponent.getOutcome().lossState == GameLossReason.Milled) {
return player.getTurn();
}

View File

@@ -7,13 +7,8 @@ public class DraftAchievements extends AchievementCollection {
super("Booster Draft", ForgeConstants.ACHIEVEMENTS_DIR + "draft.xml", true);
}
//add achievements that should appear at the top above core achievements for each game mode
@Override
protected void buildTopShelf() {
}
//add achievements that should appear at the bottom below core achievements for each game mode
@Override
protected void buildBottomShelf() {
protected void addAchievements() {
}
}

View File

@@ -19,7 +19,7 @@ public class Overkill extends Achievement {
@Override
protected int evaluate(Player player, Game game) {
if (player.getOutcome().hasWon()) {
Player opponent = getSingleOpponent(player);
Player opponent = player.getSingleOpponent();
if (opponent != null && opponent.getLife() < 0) {
return opponent.getLife();
}

View File

@@ -20,7 +20,7 @@ public class Poisoned extends Achievement {
@Override
protected int evaluate(Player player, Game game) {
if (player.getOutcome().hasWon()) {
Player opponent = getSingleOpponent(player);
Player opponent = player.getSingleOpponent();
if (opponent != null && opponent.getOutcome().lossState == GameLossReason.Poisoned) {
return opponent.getPoisonCounters();
}

View File

@@ -7,14 +7,9 @@ public class QuestAchievements extends AchievementCollection {
super("Quest Mode", ForgeConstants.ACHIEVEMENTS_DIR + "quest.xml", false);
}
//add achievements that should appear at the top above core achievements for each game mode
@Override
protected void buildTopShelf() {
}
//add achievements that should appear at the bottom below core achievements for each game mode
@Override
protected void buildBottomShelf() {
protected void addAchievements() {
add("Poisoned", new Poisoned(15, 25, 40));
add("DeckedOut", new DeckedOut(8, 4, 2));
}

View File

@@ -7,13 +7,8 @@ public class SealedAchievements extends AchievementCollection {
super("Sealed Deck", ForgeConstants.ACHIEVEMENTS_DIR + "sealed.xml", true);
}
//add achievements that should appear at the top above core achievements for each game mode
@Override
protected void buildTopShelf() {
}
//add achievements that should appear at the bottom below core achievements for each game mode
@Override
protected void buildBottomShelf() {
protected void addAchievements() {
}
}

View File

@@ -4,6 +4,7 @@ import forge.GuiBase;
import forge.LobbyPlayer;
import forge.ai.AiProfileUtil;
import forge.ai.LobbyPlayerAi;
import forge.game.player.Player;
import forge.interfaces.IGuiBase;
import forge.model.FModel;
import forge.properties.ForgePreferences.FPref;
@@ -59,6 +60,17 @@ public final class GamePlayerUtil {
return player;
}
public Player getSingleOpponent(Player player) {
if (player.getGame().getRegisteredPlayers().size() == 2) {
for (Player p : player.getGame().getRegisteredPlayers()) {
if (p.isOpponentOf(player)) {
return p;
}
}
}
return null;
}
public static void setPlayerName(final IGuiBase gui) {
String oldPlayerName = FModel.getPreferences().getPref(FPref.PLAYER_NAME);
String newPlayerName = null;

View File

@@ -32,6 +32,7 @@ import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import forge.LobbyPlayer;
import forge.achievement.AltWinAchievements;
import forge.card.CardCharacteristicName;
import forge.card.ColorSet;
import forge.card.MagicColor;
@@ -1344,13 +1345,14 @@ public class PlayerControllerHuman extends PlayerController {
}
public void updateAchievements() {
if (hasCheated()) { return; } //don't update achievements if player cheated during game
//if (hasCheated()) { return; } //don't update achievements if player cheated during game
//update all achievements for GUI player after game finished
ThreadUtil.invokeInGameThread(new Runnable() {
@Override
public void run() {
FModel.getAchievements(game.getRules().getGameType()).updateAll(gui, player);
AltWinAchievements.instance.updateAll(gui, player);
}
});
}