diff options
-rw-r--r-- | Update Notes/2.1.md | 1 | ||||
-rw-r--r-- | src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java | 329 |
2 files changed, 212 insertions, 118 deletions
diff --git a/Update Notes/2.1.md b/Update Notes/2.1.md index 9cffdcbe..87e322ef 100644 --- a/Update Notes/2.1.md +++ b/Update Notes/2.1.md @@ -17,6 +17,7 @@ - Make it so tab completion in ah search GUI goes down the items - Lulonaut - Added a toggle for enchant glint in storage gui (ty ery for texture) - Added fairy souls option to /neu misc +- Make it so fairy souls are tracked independently for each profile - Lulonaut - Added a button in storage menu to open the settings - Added an option to change the click names for /pv to /ah - Added a help menu to /neuec diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java index faef1bcf..968a9f95 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java @@ -1,8 +1,10 @@ package io.github.moulberry.notenoughupdates.miscfeatures; +import com.google.common.reflect.TypeToken; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonObject; +import com.google.gson.JsonSyntaxException; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.commands.SimpleCommand; import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; @@ -19,77 +21,185 @@ import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import java.io.*; +import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.util.*; +import java.util.stream.Collectors; public class FairySouls { - private static HashMap<String, Set<Integer>> foundSouls = new HashMap<>(); + private static final String unknownProfile = "unknown"; private static List<BlockPos> currentSoulList = null; private static List<BlockPos> currentSoulListClose = null; + private static HashMap<String, HashMap<String, Set<Integer>>> loadedFoundSouls = new HashMap<>(); - private static boolean enabled = false; + private static final SimpleCommand.ProcessCommandRunnable fairysoulRunnable = new SimpleCommand.ProcessCommandRunnable() { + @Override + public void processCommand(ICommandSender sender, String[] args) { + if (args.length != 1) { + printHelp(); + return; + } + String subcommand = args[0].toLowerCase(); - @SubscribeEvent - public void onWorldUnload(WorldEvent.Unload event) { - currentSoulList = null; + switch (subcommand) { + case "help": + printHelp(); + return; + case "on": + case "enable": + print(EnumChatFormatting.DARK_PURPLE + "Enabled fairy soul waypoints"); + NotEnoughUpdates.INSTANCE.config.misc.fariySoul = true; + return; + case "off": + case "disable": + print(EnumChatFormatting.DARK_PURPLE + "Disabled fairy soul waypoints"); + NotEnoughUpdates.INSTANCE.config.misc.fariySoul = false; + return; + case "clear": { + String location = SBInfo.getInstance().getLocation(); + if (currentSoulList == null || location == null) { + print(EnumChatFormatting.RED + "No fairy souls found in your current world"); + } else { + HashMap<String, Set<Integer>> foundSouls = getFoundSoulsForProfile(); + Set<Integer> found = foundSouls.computeIfAbsent(location, k -> new HashSet<>()); + for (int i = 0; i < currentSoulList.size(); i++) { + found.add(i); + } + String profileName = SBInfo.getInstance().currentProfile; + if (profileName == null) { + if (loadedFoundSouls.containsKey(unknownProfile)) { + loadedFoundSouls.get(unknownProfile).put(location, found); + } + } else { + profileName = profileName.toLowerCase(); + if (!loadedFoundSouls.containsKey(profileName)) { + HashMap<String, Set<Integer>> profileData = new HashMap<>(); + loadedFoundSouls.put(profileName, profileData); + } + loadedFoundSouls.get(profileName).put(location, found); + } + print(EnumChatFormatting.DARK_PURPLE + "Marked all fairy souls as found"); + } + } + return; + case "unclear": + String location = SBInfo.getInstance().getLocation(); + if (location == null) { + print(EnumChatFormatting.RED + "No fairy souls found in your current world"); + } else { + String profileName = SBInfo.getInstance().currentProfile; + if (profileName == null) { + if (loadedFoundSouls.containsKey(unknownProfile)) { + loadedFoundSouls.get(unknownProfile).remove(location); + } + } else { + profileName = profileName.toLowerCase(); + if (!loadedFoundSouls.containsKey(profileName)) { + HashMap<String, Set<Integer>> profileData = new HashMap<>(); + loadedFoundSouls.put(profileName, profileData); + } + loadedFoundSouls.get(profileName).remove(location); + } + print(EnumChatFormatting.DARK_PURPLE + "Marked all fairy souls as not found"); + } + return; + } + + print(EnumChatFormatting.RED + "Unknown subcommand: " + subcommand); + } + }; + + private static HashMap<String, Set<Integer>> getFoundSoulsForProfile() { + String profile = SBInfo.getInstance().currentProfile; + if (profile == null) { + if (loadedFoundSouls.containsKey(unknownProfile)) + return loadedFoundSouls.get(unknownProfile); + } else { + profile = profile.toLowerCase(Locale.getDefault()); + if (loadedFoundSouls.containsKey(unknownProfile)) { + HashMap<String, Set<Integer>> unknownProfileData = loadedFoundSouls.remove(unknownProfile); + loadedFoundSouls.put(profile, unknownProfileData); + return unknownProfileData; + } + if (loadedFoundSouls.containsKey(profile)) { + return loadedFoundSouls.get(profile); + } else { + //create a new entry for this profile + HashMap<String, Set<Integer>> profileData = new HashMap<>(); + loadedFoundSouls.put(profile, profileData); + return profileData; + } + } + return new HashMap<>(); } public static void load(File file, Gson gson) { + HashMap<String, HashMap<String, Set<Integer>>> foundSoulsList; + BufferedReader reader; + try { + reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); + } catch (FileNotFoundException e) { + loadedFoundSouls = new HashMap<>(); + return; + } + String fileContent = reader + .lines() + .collect(Collectors.joining(System.lineSeparator())); + if (file.exists()) { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) { - HashMap<String, List<Number>> foundSoulsList = gson.fromJson(reader, HashMap.class); - - foundSouls = new HashMap<>(); - for (Map.Entry<String, List<Number>> entry : foundSoulsList.entrySet()) { - HashSet<Integer> set = new HashSet<>(); - for (Number n : entry.getValue()) { - set.add(n.intValue()); + try { + //noinspection UnstableApiUsage + Type type = new TypeToken<HashMap<String, HashMap<String, Set<Integer>>>>() { + }.getType(); + + foundSoulsList = gson.fromJson(fileContent, type); + for (Map.Entry<String, HashMap<String, Set<Integer>>> soulsJson : foundSoulsList.entrySet()) { + String profileName = soulsJson.getKey(); + for (Map.Entry<String, Set<Integer>> souls : soulsJson.getValue().entrySet()) { + HashMap<String, Set<Integer>> map = new HashMap<>(); + map.put(souls.getKey(), souls.getValue()); + loadedFoundSouls.put(profileName, map); } - foundSouls.put(entry.getKey(), set); } - return; - } catch (Exception ignored) {} + } catch (JsonSyntaxException e) { + //The file is in the old format, convert it to the new one and set the profile to unknown + try { + //noinspection UnstableApiUsage + Type type = new TypeToken<HashMap<String, Set<Integer>>>() { + }.getType(); + + HashMap<String, Set<Number>> foundSoulsListOldFormat = gson.fromJson(fileContent, type); + HashMap<String, Set<Integer>> map = new HashMap<>(); + for (Map.Entry<String, Set<Number>> entry : foundSoulsListOldFormat.entrySet()) { + HashSet<Integer> set = new HashSet<>(); + for (Number n : entry.getValue()) { + set.add(n.intValue()); + } + map.put(entry.getKey(), set); + } + loadedFoundSouls.put(unknownProfile, map); + return; + } catch (JsonSyntaxException e2) { + System.err.println("Can't read file containing collected fairy souls, resetting."); + loadedFoundSouls = new HashMap<>(); + return; + } + } } - foundSouls = new HashMap<>(); + loadedFoundSouls = new HashMap<>(); } public static void save(File file, Gson gson) { try { + //noinspection ResultOfMethodCallIgnored file.createNewFile(); try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) { - writer.write(gson.toJson(foundSouls)); - } - } catch (IOException ignored) {} - } - - @SubscribeEvent - public void onChatReceived(ClientChatReceivedEvent event) { - if (currentSoulList == null) return; - - if (event.message.getFormattedText().equals("\u00A7r\u00A7dYou have already found that Fairy Soul!\u00A7r") || - event.message.getFormattedText().equals("\u00A7d\u00A7lSOUL! \u00A7fYou found a \u00A7r\u00A7dFairy Soul\u00A7r\u00A7f!\u00A7r")) { - String location = SBInfo.getInstance().getLocation(); - if (location == null) return; - - int closestIndex = -1; - double closestDistSq = 10 * 10; - for (int i = 0; i < currentSoulList.size(); i++) { - BlockPos pos = currentSoulList.get(i); - - double distSq = pos.distanceSq(Minecraft.getMinecraft().thePlayer.getPosition()); - - if (distSq < closestDistSq) { - closestDistSq = distSq; - closestIndex = i; - } - } - if (closestIndex != -1) { - Set<Integer> found = foundSouls.computeIfAbsent(location, k -> new HashSet<>()); - found.add(closestIndex); + writer.write(gson.toJson(loadedFoundSouls)); } + } catch (IOException ignored) { } } @@ -139,6 +249,8 @@ public class FairySouls { if (currentSoulList != null && !currentSoulList.isEmpty()) { TreeMap<Double, BlockPos> distanceSqMap = new TreeMap<>(); + HashMap<String, Set<Integer>> foundSouls = getFoundSoulsForProfile(); + Set<Integer> found = foundSouls.computeIfAbsent(location, k -> new HashSet<>()); for (int i = 0; i < currentSoulList.size(); i++) { @@ -159,6 +271,59 @@ public class FairySouls { } } + private static void print(String s) { + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(s)); + } + + private static void printHelp() { + print(""); + print(EnumChatFormatting.DARK_PURPLE.toString() + EnumChatFormatting.BOLD + " NEU Fairy Soul Waypoint Guide"); + print(EnumChatFormatting.LIGHT_PURPLE + "Shows waypoints for every fairy soul in your world"); + print(EnumChatFormatting.LIGHT_PURPLE + "Clicking a fairy soul automatically removes it from the list"); + if (!NotEnoughUpdates.INSTANCE.config.hidden.dev) { + print(EnumChatFormatting.DARK_RED + "" + EnumChatFormatting.OBFUSCATED + "Ab" + EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + "!" + EnumChatFormatting.RESET + EnumChatFormatting.RED + " This feature cannot and will not work in Dungeons. " + EnumChatFormatting.DARK_RED + "!" + EnumChatFormatting.OBFUSCATED + "Ab"); + } + print(EnumChatFormatting.GOLD.toString() + EnumChatFormatting.BOLD + " Commands:"); + print(EnumChatFormatting.YELLOW + "/neusouls help - Display this message"); + print(EnumChatFormatting.YELLOW + "/neusouls on/off - Enable/disable the waypoint markers"); + print(EnumChatFormatting.YELLOW + "/neusouls clear/unclear - Marks every waypoint in your current world as completed/uncompleted"); + print(""); + } + + @SubscribeEvent + public void onWorldUnload(WorldEvent.Unload event) { + currentSoulList = null; + } + + @SubscribeEvent + public void onChatReceived(ClientChatReceivedEvent event) { + if (currentSoulList == null) return; + + if (event.message.getFormattedText().equals("\u00A7r\u00A7dYou have already found that Fairy Soul!\u00A7r") || + event.message.getFormattedText().equals("\u00A7d\u00A7lSOUL! \u00A7fYou found a \u00A7r\u00A7dFairy Soul\u00A7r\u00A7f!\u00A7r")) { + String location = SBInfo.getInstance().getLocation(); + if (location == null) return; + + int closestIndex = -1; + double closestDistSq = 10 * 10; + for (int i = 0; i < currentSoulList.size(); i++) { + BlockPos pos = currentSoulList.get(i); + + double distSq = pos.distanceSq(Minecraft.getMinecraft().thePlayer.getPosition()); + + if (distSq < closestDistSq) { + closestDistSq = distSq; + closestIndex = i; + } + } + if (closestIndex != -1) { + HashMap<String, Set<Integer>> foundSouls = getFoundSoulsForProfile(); + Set<Integer> found = foundSouls.computeIfAbsent(location, k -> new HashSet<>()); + found.add(closestIndex); + } + } + } + @SubscribeEvent public void onRenderLast(RenderWorldLastEvent event) { if (!NotEnoughUpdates.INSTANCE.config.misc.fariySoul) return; @@ -167,7 +332,6 @@ public class FairySouls { if (location == null) return; if (currentSoulList == null || currentSoulList.isEmpty()) return; - Set<Integer> found = foundSouls.computeIfAbsent(location, k -> new HashSet<>()); int rgb = 0xa839ce; for (BlockPos currentSoul : currentSoulListClose) { @@ -182,80 +346,9 @@ public class FairySouls { } public static class FairySoulsCommand extends SimpleCommand { - public FairySoulsCommand() { super("neusouls", fairysoulRunnable); } } - private static final SimpleCommand.ProcessCommandRunnable fairysoulRunnable = new SimpleCommand.ProcessCommandRunnable() { - @Override - public void processCommand(ICommandSender sender, String[] args) { - if (args.length != 1) { - printHelp(); - return; - } - String subcommand = args[0].toLowerCase(); - - switch (subcommand) { - case "help": - printHelp(); - return; - case "on": - case "enable": - print(EnumChatFormatting.DARK_PURPLE + "Enabled fairy soul waypoints"); - NotEnoughUpdates.INSTANCE.config.misc.fariySoul = true; - return; - case "off": - case "disable": - print(EnumChatFormatting.DARK_PURPLE + "Disabled fairy soul waypoints"); - NotEnoughUpdates.INSTANCE.config.misc.fariySoul = false; - return; - case "clear": { - String location = SBInfo.getInstance().getLocation(); - if (currentSoulList == null || location == null) { - print(EnumChatFormatting.RED + "No fairy souls found in your current world"); - } else { - Set<Integer> found = foundSouls.computeIfAbsent(location, k -> new HashSet<>()); - for (int i = 0; i < currentSoulList.size(); i++) { - found.add(i); - } - print(EnumChatFormatting.DARK_PURPLE + "Marked all fairy souls as found"); - } - } - return; - case "unclear": - String location = SBInfo.getInstance().getLocation(); - if (location == null) { - print(EnumChatFormatting.RED + "No fairy souls found in your current world"); - } else { - print(EnumChatFormatting.DARK_PURPLE + "Marked all fairy souls as not found"); - foundSouls.remove(location); - } - return; - } - - print(EnumChatFormatting.RED + "Unknown subcommand: " + subcommand); - } - }; - - private static void print(String s) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(s)); - } - - private static void printHelp() { - print(""); - print(EnumChatFormatting.DARK_PURPLE.toString() + EnumChatFormatting.BOLD + " NEU Fairy Soul Waypoint Guide"); - print(EnumChatFormatting.LIGHT_PURPLE + "Shows waypoints for every fairy soul in your world"); - print(EnumChatFormatting.LIGHT_PURPLE + "Clicking a fairy soul automatically removes it from the list"); - if (!NotEnoughUpdates.INSTANCE.config.hidden.dev) { - print(EnumChatFormatting.DARK_RED + "" + EnumChatFormatting.OBFUSCATED + "Ab" + EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + "!" + EnumChatFormatting.RESET + EnumChatFormatting.RED + " This feature cannot and will not work in Dungeons. " + EnumChatFormatting.DARK_RED + "!" + EnumChatFormatting.OBFUSCATED + "Ab"); - } - print(EnumChatFormatting.GOLD.toString() + EnumChatFormatting.BOLD + " Commands:"); - print(EnumChatFormatting.YELLOW + "/neusouls help - Display this message"); - print(EnumChatFormatting.YELLOW + "/neusouls on/off - Enable/disable the waypoint markers"); - print(EnumChatFormatting.YELLOW + "/neusouls clear/unclear - Marks every waypoint in your current world as completed/uncompleted"); - print(""); - } - } |