package mhfc.net.client.quests;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import mhfc.net.MHFCMain;
import mhfc.net.client.gui.hud.QuestStatusDisplay;
import mhfc.net.client.gui.quests.GuiQuestBoard;
import mhfc.net.client.quests.api.IMissionInformation;
import mhfc.net.client.quests.api.IVisualDefinition;
import mhfc.net.common.core.data.QuestDescriptionRegistry;
import mhfc.net.common.core.registry.RegistryWrapper;
import mhfc.net.common.network.NetworkTracker;
import mhfc.net.common.network.message.quest.MessageQuestInit;
import mhfc.net.common.quests.api.QuestDefinition;
import mhfc.net.common.util.lib.MHFCReference;
import mhfc.net.common.util.services.IServiceKey;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.MinecraftForge;
@SideOnly(Side.CLIENT)
public class MHFCRegQuestVisual {
public static void staticInit() {}
public static final ResourceLocation QUEST_BOARD_BACKGROUND = new ResourceLocation(MHFCReference.gui_board_tex);
public static final ResourceLocation CLICKABLE_LIST = new ResourceLocation(MHFCReference.gui_list_tex);
private static final IServiceKey<MHFCRegQuestVisual> serviceAccess = RegistryWrapper.registerService(
"quest visuals",
MHFCRegQuestVisual::new,
MHFCRegQuestVisual::shutdown,
NetworkTracker.clientConnectedPhase);
public static MHFCRegQuestVisual getService() {
return serviceAccess.getService();
}
public static Set<String> getAvailableQuestIDs(String groupId) {
return getService().getQuestIdentifiers(groupId);
}
public static Set<String> getRunningMissionIDs() {
return Collections.unmodifiableSet(getService().getMissionIdentifiers());
}
/**
*
* @param questID
* of the quest in which you are interested
* @return Either the visual representation of the requested quest or a replacement <br>
* representing loading.
*/
public static IVisualDefinition getQuestInformation(String questID) {
MHFCRegQuestVisual service = getService();
QuestDefinition staticDescription = service.clientDataObject.getQuestDescription(questID);
if (staticDescription != null) {
return staticDescription.getVisualInformation();
}
return DefaultQuestVisualDefinition.IDENTIFIER_ERROR;
}
/**
* Gets the dynamic information for a running mission. If the mission is unavailable, it is lazily initialized with
* a loading replacement, and a refresh is polled from the server.
*
* @param missionID
* the mission you are interested in.
* @return
*/
public static IMissionInformation getMissionInformation(String missionID) {
return getService().missionVisuals.get(missionID);
}
public static boolean hasPlayerQuest() {
return getPlayerVisual().isPresent();
}
public static Optional<IMissionInformation> getPlayerVisual() {
return getService().playerVisual;
}
public static void startNewMission(String questID, String missionID) {
getService().createMission(questID, missionID);
}
public static void joinMission(String missionID) {
getService().setPlayerMission(missionID);
}
public static void departMission(String missionID) {
getService().unsetPlayerMission(missionID);
}
public static void endMission(String missionID) {
getService().destroyMission(missionID);
}
private Set<String> missionIDs = new HashSet<>();
private Map<String, IMissionInformation> missionVisuals = new HashMap<>();
private QuestDescriptionRegistry clientDataObject = new QuestDescriptionRegistry();
private Optional<IMissionInformation> playerVisual = Optional.empty();
private QuestStatusDisplay display = new QuestStatusDisplay();
public MHFCRegQuestVisual() {
initialize();
}
/**
* (Re-)initializes the registry with the quest received in the init message.
*
* @param message
*/
public void onInitializationMessage(MessageQuestInit message) {
reset();
message.initialize(clientDataObject);
}
public Set<String> getQuestIdentifiers(String group) {
return Collections.unmodifiableSet(clientDataObject.getQuestIdentifiersFor(group));
}
public Set<String> getMissionIdentifiers() {
return Collections.unmodifiableSet(missionIDs);
}
public void createMission(String questID, String missionID) {
if (missionIDs.contains(missionID)) {
return;
}
IMissionInformation info = clientDataObject.getQuestDescription(questID).getVisualInformation().build();
missionIDs.add(missionID);
missionVisuals.put(missionID, info);
GuiQuestBoard.questBoard.addQuest(missionID, info);
}
public void destroyMission(String missionID) {
if (!missionIDs.contains(missionID)) {
return;
}
missionIDs.remove(missionID);
missionVisuals.remove(missionID);
GuiQuestBoard.questBoard.removeQuest(missionID);
}
public void setPlayerMission(String missionID) {
IMissionInformation info = missionVisuals.get(missionID);
setVisual(Optional.ofNullable(info));
}
public void unsetPlayerMission(String missionID) {
// TODO: maybe check that the active mission actually has the missionID?
setVisual(Optional.empty());
}
protected void logStats() {
QuestDescriptionRegistry dataObject = clientDataObject;
int numberQuests = dataObject.getFullQuestDescriptionMap().size();
int numberGroups = dataObject.getGroupsInOrder().size();
String output = String.format("Client loaded %d quests in %d groups.", numberQuests, numberGroups);
MHFCMain.logger().debug(output);
}
private void setVisual(Optional<IMissionInformation> newVisual) {
Objects.requireNonNull(newVisual);
playerVisual.ifPresent(IMissionInformation::cleanUp);
playerVisual = newVisual;
}
private void initialize() {
reset();
MinecraftForge.EVENT_BUS.register(display);
}
private void shutdown() {
reset();
MinecraftForge.EVENT_BUS.unregister(display);
}
private void reset() {
this.missionIDs.clear();
this.missionVisuals.clear();
this.clientDataObject.clearData();
this.setVisual(Optional.empty());
}
}