package org.mafagafogigante.dungeon.achievements; import org.mafagafogigante.dungeon.game.Id; import org.mafagafogigante.dungeon.game.PartOfDay; import org.mafagafogigante.dungeon.io.JsonObjectFactory; import org.mafagafogigante.dungeon.logging.DungeonLogger; import org.mafagafogigante.dungeon.stats.CauseOfDeath; import org.mafagafogigante.dungeon.stats.TypeOfCauseOfDeath; import org.mafagafogigante.dungeon.util.CounterMap; import com.eclipsesource.json.JsonObject; import com.eclipsesource.json.JsonObject.Member; import com.eclipsesource.json.JsonValue; import java.util.Collection; /** * A static factory of locked AchievementStores. */ public class AchievementStoreFactory { private static volatile AchievementStore defaultStore; private AchievementStoreFactory() { throw new AssertionError(); // Shouldn't be instantiated. } /** * Makes a locked AchievementStore with the specified Achievements. */ public static AchievementStore makeAchievementStore(Collection<Achievement> achievements) { AchievementStore achievementStore = new AchievementStore(); for (Achievement achievement : achievements) { achievementStore.addAchievement(achievement); } achievementStore.lock(); return achievementStore; } /** * Retrieves the default AchievementStore of the application. */ public static AchievementStore getDefaultStore() { if (defaultStore == null) { synchronized (AchievementStoreFactory.class) { if (defaultStore == null) { AchievementStore achievementStore = makeDefaultStore(); achievementStore.lock(); defaultStore = achievementStore; } } } return defaultStore; } private static AchievementStore makeDefaultStore() { AchievementStore store = new AchievementStore(); loadAchievements(store); return store; } private static CounterMap<Id> idCounterMapFromJsonObject(JsonObject jsonObject) { CounterMap<Id> counterMap = new CounterMap<>(); for (Member member : jsonObject) { counterMap.incrementCounter(new Id(member.getName()), member.getValue().asInt()); } return counterMap; } /** * Loads all provided achievements into the provided AchievementStore. * * <p>Throws an IllegalStateException if the AchievementStore is not empty when this method is called */ private static void loadAchievements(AchievementStore store) { if (!store.getAchievements().isEmpty()) { throw new IllegalStateException("called loadAchievements on a not empty AchievementStore"); } JsonObject jsonObject = JsonObjectFactory.makeJsonObject("achievements.json"); for (JsonValue achievementValue : jsonObject.get("achievements").asArray()) { JsonObject achievementObject = achievementValue.asObject(); AchievementBuilder builder = new AchievementBuilder(); builder.setId(achievementObject.get("id").asString()); builder.setName(achievementObject.get("name").asString()); builder.setInfo(achievementObject.get("info").asString()); builder.setText(achievementObject.get("text").asString()); JsonValue battleRequirements = achievementObject.get("battleRequirements"); if (battleRequirements != null) { for (JsonValue requirementValue : battleRequirements.asArray()) { JsonObject requirementObject = requirementValue.asObject(); JsonObject queryObject = requirementObject.get("query").asObject(); BattleStatisticsQuery query = new BattleStatisticsQuery(); JsonValue idValue = queryObject.get("id"); if (idValue != null) { query.setId(new Id(idValue.asString())); } JsonValue typeValue = queryObject.get("type"); if (typeValue != null) { query.setType(typeValue.asString()); } JsonValue causeOfDeathValue = queryObject.get("causeOfDeath"); if (causeOfDeathValue != null) { JsonObject causeOfDeathObject = causeOfDeathValue.asObject(); TypeOfCauseOfDeath type = TypeOfCauseOfDeath.valueOf(causeOfDeathObject.get("type").asString()); Id id = new Id(causeOfDeathObject.get("id").asString()); query.setCauseOfDeath(new CauseOfDeath(type, id)); } JsonValue partOfDayValue = queryObject.get("partOfDay"); if (partOfDayValue != null) { query.setPartOfDay(PartOfDay.valueOf(partOfDayValue.asString())); } int count = requirementObject.get("count").asInt(); BattleStatisticsRequirement requirement = new BattleStatisticsRequirement(query, count); builder.addBattleStatisticsRequirement(requirement); } } JsonValue explorationRequirements = achievementObject.get("explorationRequirements"); if (explorationRequirements != null) { JsonValue killsByLocationId = explorationRequirements.asObject().get("killsByLocationID"); if (killsByLocationId != null) { builder.setKillsByLocationId(idCounterMapFromJsonObject(killsByLocationId.asObject())); } JsonValue maximumNumberOfVisits = explorationRequirements.asObject().get("maximumNumberOfVisits"); if (maximumNumberOfVisits != null) { builder.setMaximumNumberOfVisits(idCounterMapFromJsonObject(maximumNumberOfVisits.asObject())); } JsonValue visitedLocations = explorationRequirements.asObject().get("visitedLocations"); if (visitedLocations != null) { builder.setVisitedLocations(idCounterMapFromJsonObject(visitedLocations.asObject())); } } store.addAchievement(builder.createAchievement()); } DungeonLogger.info("Loaded " + store.getAchievements().size() + " achievements."); } }