/* * Copyright 2015 Daniel Dittmar * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package dan.dit.whatsthat.riddle.achievement.holders; import android.content.res.Resources; import java.util.TreeMap; import dan.dit.whatsthat.R; import dan.dit.whatsthat.achievement.AchievementDataEvent; import dan.dit.whatsthat.achievement.AchievementDataTimer; import dan.dit.whatsthat.achievement.AchievementManager; import dan.dit.whatsthat.riddle.achievement.AchievementDataRiddleGame; import dan.dit.whatsthat.riddle.achievement.GameAchievement; import dan.dit.whatsthat.riddle.games.RiddleTriangle; import dan.dit.whatsthat.riddle.types.PracticalRiddleType; import dan.dit.whatsthat.riddle.types.TypesHolder; /** * Created by daniel on 23.07.15. */ public class AchievementTriangle extends TypeAchievementHolder { public static final String KEY_TRIANGLE_COUNT = "triangle_count"; public static final String KEY_TRIANGLE_DIVIDED_BY_CLICK = "divided_by_click"; public static final String KEY_TRIANGLE_DIVIDED_BY_MOVE = "divided_by_move"; public static final String KEY_TRIANGLE_COUNT_BEFORE_LAST_INTERACTION = "triangle_count_before"; public AchievementTriangle(PracticalRiddleType type) { super(type); } @Override public void makeAchievements(AchievementManager manager) { mAchievements = new TreeMap<>(); mAchievements.put(Achievement1.NUMBER, new Achievement1(manager, mType)); mAchievements.put(Achievement2.NUMBER, new Achievement2(manager, mType)); mAchievements.put(Achievement3.NUMBER, new Achievement3(manager, mType)); mAchievements.put(Achievement4.NUMBER, new Achievement4(manager, mType)); mAchievements.put(Achievement5.NUMBER, new Achievement5(manager, mType)); mAchievements.put(Achievement6.NUMBER, new Achievement6(manager, mType)); } private static class Achievement1 extends GameAchievement { public static final int NUMBER = 1; public static final int LEVEL = 0; public static final int REWARD = 75; public static final boolean DISCOVERED = true; private static final int REQUIRED_GAMES_COUNT = 5; private static final String KEY_TIMER_SOLVED = TypesHolder.Triangle.NAME + NUMBER + "games_solved"; private static final long MAX_TIME_DURATION = 180000L; public Achievement1(AchievementManager manager, PracticalRiddleType type) { super(type, R.string.achievement_triangle_1_name, R.string.achievement_triangle_1_descr, 0, NUMBER, manager, LEVEL, REWARD, 1, DISCOVERED); } @Override public CharSequence getDescription(Resources res) { if (!isAchieved() || isRewardClaimable()) { return super.getDescription(res); } return res.getString(R.string.achievement_triangle_1_descr_unachieved, REQUIRED_GAMES_COUNT); } @Override public void onInit() { super.onInit(); mTimerData.ensureTimeKeeper(KEY_TIMER_SOLVED, REQUIRED_GAMES_COUNT); mTimerData.addListener(this); } @Override protected void onAchieved() { super.onAchieved(); mTimerData.removeTimerKeeper(KEY_TIMER_SOLVED); mTimerData.removeListener(this); } @Override public void onNonCustomDataEvent(AchievementDataEvent event) { if (event.getChangedData() == mGameData && event.getEventType() == AchievementDataEvent.EVENT_TYPE_DATA_CLOSE && mGameData.isSolved() && mGameData.getState() == AchievementDataRiddleGame.STATE_CLOSED) { if (areDependenciesFulfilled()) { // game data closed, game is solved, mark this event mTimerData.onTimeKeeperUpdate(KEY_TIMER_SOLVED, mGameData.getValue(AchievementDataRiddleGame.KEY_PLAYED_TIME, 0L)); } } if (event.getChangedData() == mTimerData && event.getEventType() == AchievementDataEvent.EVENT_TYPE_DATA_UPDATE && event.hasChangedKey(KEY_TIMER_SOLVED)) { AchievementDataTimer.TimeKeeper keeper = mTimerData.getTimeKeeper(KEY_TIMER_SOLVED); if (keeper != null && keeper.getTimesCount() == REQUIRED_GAMES_COUNT) { long duration = keeper.getTotalTimeConsumed(); if (duration > 0L && duration <= MAX_TIME_DURATION) { achieve(); } } } } } private static class Achievement2 extends GameAchievement { public static final int NUMBER = 2; public static final int LEVEL = 0; public static final int REWARD = 50; public static final boolean DISCOVERED = true; private static final int TRIANGLES_TO_DIVIDE = Math.min(8, RiddleTriangle.MAX_SPLIT_PER_CLICK); private static final int MAX_TRIANGLES_THRESHOLD = 20; public Achievement2(AchievementManager manager, PracticalRiddleType type) { super(type, R.string.achievement_triangle_2_name, R.string.achievement_triangle_2_descr, 0, NUMBER, manager, LEVEL, REWARD, 1, DISCOVERED); } @Override public CharSequence getDescription(Resources res) { if (!isAchieved() || isRewardClaimable()) { return super.getDescription(res); } return res.getString(R.string.achievement_triangle_2_descr_unachieved); } @Override public void onNonCustomDataEvent(AchievementDataEvent event) { if (event.getChangedData() == mGameData && event.hasChangedKey(KEY_TRIANGLE_COUNT)) { long totalTriangles = mGameData.getValue(KEY_TRIANGLE_COUNT, 0L); long changedAmount = totalTriangles - mGameData.getValue(KEY_TRIANGLE_COUNT_BEFORE_LAST_INTERACTION, 0L); if (changedAmount >= TRIANGLES_TO_DIVIDE && totalTriangles <= MAX_TRIANGLES_THRESHOLD) { achieveAfterDependencyCheck(); } } } } public static class Achievement3 extends GameAchievement { public static final int NUMBER = 3; public static final int LEVEL = 0; public static final int REWARD = 80; public static final boolean DISCOVERED = true; private static final int MAX_TRIANGLES = 100; public Achievement3(AchievementManager manager, PracticalRiddleType type) { super(type, R.string.achievement_triangle_3_name, R.string.achievement_triangle_3_descr, 0, NUMBER, manager, LEVEL, REWARD, 1, DISCOVERED); } @Override public CharSequence getDescription(Resources res) { if (!isAchieved() || isRewardClaimable()) { return super.getDescription(res); } return res.getString(R.string.achievement_triangle_3_descr_unachieved); } @Override public void onNonCustomDataEvent(AchievementDataEvent event) { if (event.getChangedData() == mGameData && event.getEventType() == AchievementDataEvent.EVENT_TYPE_DATA_CLOSE && mGameData.isSolved() && mGameData.getState() == AchievementDataRiddleGame.STATE_CLOSED) { if (mGameData.getValue(KEY_TRIANGLE_COUNT, MAX_TRIANGLES + 1) <= MAX_TRIANGLES) { achieveAfterDependencyCheck(); } } } } private static class Achievement4 extends GameAchievement { public static final int NUMBER = 4; public static final int LEVEL = 0; public static final int REWARD = 85; public static final boolean DISCOVERED = true; private static final int MIN_TRIANGLES = 8000; public Achievement4(AchievementManager manager, PracticalRiddleType type) { super(type, R.string.achievement_triangle_4_name, R.string.achievement_triangle_4_descr, 0, NUMBER, manager, LEVEL, REWARD, 1, DISCOVERED); } @Override public CharSequence getDescription(Resources res) { if (!isAchieved() || isRewardClaimable()) { return super.getDescription(res); } return res.getString(R.string.achievement_triangle_4_descr_unachieved); } @Override public void onNonCustomDataEvent(AchievementDataEvent event) { if (event.getChangedData() == mGameData && event.getEventType() == AchievementDataEvent.EVENT_TYPE_DATA_CLOSE && mGameData.isSolved() && mGameData.getState() == AchievementDataRiddleGame.STATE_CLOSED) { if (mGameData.getValue(KEY_TRIANGLE_COUNT, MIN_TRIANGLES - 1) >= MIN_TRIANGLES) { achieveAfterDependencyCheck(); } } } } private static class Achievement5 extends GameAchievement { public static final int NUMBER = 5; public static final int LEVEL = 0; public static final int REWARD = 200; public static final boolean DISCOVERED = true; private static final int GAMES_SOLVE_COUNT = 25; public Achievement5(AchievementManager manager, PracticalRiddleType type) { super(type, R.string.achievement_triangle_5_name, R.string.achievement_triangle_5_descr, 0, NUMBER, manager, LEVEL, REWARD, GAMES_SOLVE_COUNT, DISCOVERED); } @Override public CharSequence getDescription(Resources res) { if (!isAchieved() || isRewardClaimable()) { return super.getDescription(res); } return res.getString(R.string.achievement_triangle_5_descr_unachieved); } @Override public void onNonCustomDataEvent(AchievementDataEvent event) { if (event.getChangedData() == mGameData && event.getEventType() == AchievementDataEvent.EVENT_TYPE_DATA_CLOSE && mGameData.isSolved() && mGameData.getState() == AchievementDataRiddleGame.STATE_CLOSED && areDependenciesFulfilled()) { achieveDelta(1); } } } private static class Achievement6 extends GameAchievement { public static final int NUMBER = 6; public static final int LEVEL = 2; //displayed as 3 public static final int REWARD = 333; public static final boolean DISCOVERED = true; private static final int ILLUMINATI = 3; private static final String KEY_TIMER_SOLVED = PracticalRiddleType.TRIANGLE_INSTANCE .getFullName() + NUMBER + "_solved_experiments"; private static final long SOLVED_MAX_TIME = 3 * 33L * 1000L; //ms public Achievement6(AchievementManager manager, PracticalRiddleType type) { super(type, R.string.achievement_triangle_6_name, R.string .achievement_triangle_6_descr, 0, NUMBER, manager, LEVEL, REWARD, 1, DISCOVERED); } @Override public void onInit() { super.onInit(); mTimerData.ensureTimeKeeper(KEY_TIMER_SOLVED, ILLUMINATI); mTimerData.addListener(this); } @Override public int getIconResIdByState() { if (isAchieved()) { return R.drawable.illuminati_eye; } return super.getIconResIdByState(); } @Override protected void onAchieved() { super.onAchieved(); mTimerData.removeTimerKeeper(KEY_TIMER_SOLVED); mTimerData.removeListener(this); } @Override public void onNonCustomDataEvent(AchievementDataEvent event) { if (event.getChangedData() == mGameData && event.getEventType() == AchievementDataEvent.EVENT_TYPE_DATA_CLOSE && mGameData.isSolved() && mGameData.getState() == AchievementDataRiddleGame.STATE_CLOSED && areDependenciesFulfilled()) { mTimerData.onTimeKeeperUpdate(KEY_TIMER_SOLVED, mGameData.getValue(AchievementDataRiddleGame.KEY_PLAYED_TIME, 0L)); } if (event.getChangedData() == mTimerData && event.getEventType() == AchievementDataEvent.EVENT_TYPE_DATA_UPDATE && event.hasChangedKey(KEY_TIMER_SOLVED)) { AchievementDataTimer.TimeKeeper keeper = mTimerData.getTimeKeeper(KEY_TIMER_SOLVED); if (keeper != null && keeper.getTimesCount() == ILLUMINATI) { long duration = keeper.sumDurations(); // breaks allowed if (duration > 0L && duration <= SOLVED_MAX_TIME) { confirmIlluminati(); } } } } private void confirmIlluminati() { achieve(); } } }