/*
* Copyright (c) 2012. HappyDroids LLC, All rights reserved.
*/
package com.happydroids.droidtowers.achievements;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.utils.Pools;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Maps;
import com.google.common.eventbus.EventBus;
import com.happydroids.droidtowers.TowerConsts;
import com.happydroids.droidtowers.events.AchievementCompletionEvent;
import com.happydroids.droidtowers.events.SafeEventBus;
import com.happydroids.droidtowers.gamestate.server.TowerGameService;
import com.happydroids.droidtowers.grid.GameGrid;
import com.happydroids.droidtowers.gui.AchievementNotification;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import static com.happydroids.droidtowers.achievements.RequirementType.ADD_NEIGHBOR;
import static com.happydroids.droidtowers.achievements.RequirementType.HAPPYDROIDS_CONNECT;
public class AchievementEngine {
private static final String TAG = AchievementEngine.class.getSimpleName();
protected static AchievementEngine instance;
protected List<Achievement> achievements;
protected EventBus eventBus;
protected Map<String, Achievement> achievementsById;
public static AchievementEngine instance() {
if (instance == null) {
instance = new AchievementEngine();
}
return instance;
}
protected AchievementEngine() {
try {
eventBus = new SafeEventBus();
ObjectMapper mapper = TowerGameService.instance().getObjectMapper();
achievements = mapper.readValue(Gdx.files.internal("params/achievements.json").reader(), mapper.getTypeFactory()
.constructCollectionType(ArrayList.class, Achievement.class));
//noinspection PointlessBooleanExpression
if (!TowerConsts.ENABLE_HAPPYDROIDS_CONNECT) {
Iterator<Achievement> achievementIterator = achievements.iterator();
while (achievementIterator.hasNext()) {
Achievement achievement = achievementIterator.next();
for (Requirement requirement : achievement.getRequirements()) {
if (requirement.getType().equals(ADD_NEIGHBOR) || requirement.getType().equals(HAPPYDROIDS_CONNECT)) {
achievementIterator.remove();
}
}
}
}
achievementsById = Maps.newHashMap();
for (Achievement achievement : achievements) {
achievementsById.put(achievement.getId(), achievement);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public List<Achievement> getAchievements() {
return achievements;
}
public void checkAchievements(GameGrid gameGrid) {
Gdx.app.debug(TAG, "Checking achievements...");
for (int i = 0, achievementsSize = achievements.size(); i < achievementsSize; i++) {
Achievement achievement = achievements.get(i);
achievement.checkRequirements(gameGrid);
if (achievement.isCompleted()) {
complete(achievement);
}
}
}
protected void complete(Achievement achievement) {
if (achievement.isLocked() || achievement.hasGivenReward()) {
return;
}
achievement.setCompleted(true);
}
public void displayNotification(Achievement achievement) {
new AchievementNotification(achievement).show();
AchievementCompletionEvent event = Pools.obtain(AchievementCompletionEvent.class);
event.setAchievement(achievement);
eventBus.post(event);
Pools.free(event);
}
public void complete(String achievementId) {
Achievement achievement = findById(achievementId);
if (achievement != null) {
complete(achievement);
return;
}
throw new RuntimeException("Could not find achievement called: " + achievementId);
}
public void loadCompletedAchievements(List<String> achievementIds, GameGrid gameGrid) {
resetState();
if (achievementIds == null) {
return;
}
for (Achievement achievement : achievements) {
achievement.checkRequirements(gameGrid);
if (achievementIds.contains(achievement.getId())) {
achievement.setCompleted(true);
achievement.unlockReward();
}
}
}
public void add(Achievement achievement) {
achievements.add(achievement);
}
public void resetState() {
for (Achievement achievement : achievements) {
achievement.resetState();
}
}
public void completeAll() {
for (Achievement achievement : achievements) {
achievement.setCompleted(true);
achievement.unlockReward();
}
}
public Achievement findById(String achievementId) {
return achievementsById.get(achievementId);
}
public boolean hasPendingAwards() {
for (int i = 0, achievementsSize = achievements.size(); i < achievementsSize; i++) {
Achievement achievement = achievements.get(i);
if (achievement.isCompleted() && !achievement.hasGivenReward()) {
return true;
}
}
return false;
}
public EventBus eventBus() {
return eventBus;
}
}