aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLulonaut <67191924+Lulonaut@users.noreply.github.com>2021-11-18 18:29:28 +0100
committerGitHub <noreply@github.com>2021-11-18 12:29:28 -0500
commit18be3d697a2b2dd4bebea48ef476053d3b4b72f3 (patch)
tree914e1580d986ba9167d3407349f91b7fccd30c3d
parentf7e8edf3357db624212af5f24b74e7763c678fba (diff)
downloadNotEnoughUpdates-18be3d697a2b2dd4bebea48ef476053d3b4b72f3.tar.gz
NotEnoughUpdates-18be3d697a2b2dd4bebea48ef476053d3b4b72f3.tar.bz2
NotEnoughUpdates-18be3d697a2b2dd4bebea48ef476053d3b4b72f3.zip
Make Fairy souls progress track for each profile (#18)
* Make fairy souls save per profile * fix commands * Add back support for toggling in /neu * add patch notes
-rw-r--r--Update Notes/2.1.md1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java329
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("");
- }
-
}