diff options
| author | BlueWeabo <ilia.iliev2005@gmail.com> | 2023-02-26 13:16:07 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-02-26 12:16:07 +0100 |
| commit | b8d1ecf8b9b6348304392d09e4490d473dbb120d (patch) | |
| tree | 1cdc59a1b660510fe2abd40686b2abed8b0ab40f /src/main/java | |
| parent | ebd7df3a1ddba9105df008d44ab046d159279628 (diff) | |
| download | GT5-Unofficial-b8d1ecf8b9b6348304392d09e4490d473dbb120d.tar.gz GT5-Unofficial-b8d1ecf8b9b6348304392d09e4490d473dbb120d.tar.bz2 GT5-Unofficial-b8d1ecf8b9b6348304392d09e4490d473dbb120d.zip | |
Add a completely new system for late/endgame content (#1754)
* basic work
* typo fixes
* make an enum folder
* location enums
* space project manager
* implement the space project teams
* commands
* move things around and new things
* upgrade work
* requirement work
* if possible use an upgrades values
* cleanup
* more helpers in command
* fix AOOBE
* fix world saved data
* builder for requirements
* add command autocomplete
* fix command npe
* mark world saved data dirty
* switch to saving to json string. this is fine
* fix npe
* fix files not saving correctly. serialization
* spotless
* part 1 of fixing json saving
* working json file saving
* rename fields
* full implementation of SP_Upgrade
* fixes
* cleanup
* texture prep
* documentation part 1
* documentation part 2 and rework of json saving
* fix the missed conversions
* set texture when copying
* more interface usage and fixes
* rework saving.
* Added rudimentary NEI handler for projects
* Revert "Added rudimentary NEI handler for projects"
This reverts commit 6d8210e25b27fee7dc1865d1afa91708a8d9b875.
* address NPEs
* some textures
* higher quality textures, put in the moon as a temp texture
* add a check to create a team if one smt weird happens
* command work
* add ability to localize the space bodies
* Added disabled button and toggle button
* Added possibility to not render the original stacksize of item stacks in NEI
* Added NEI handler
* Fixes item count on tooltip always rendering as 1
* Fix refactor
* 5 new body textures
* fix misspelled texture name
---------
Co-authored-by: minecraft7771 <maxim235@gmx.de>
Diffstat (limited to 'src/main/java')
19 files changed, 2637 insertions, 6 deletions
diff --git a/src/main/java/gregtech/GT_Mod.java b/src/main/java/gregtech/GT_Mod.java index 7a8236c7b3..6622277cb0 100644 --- a/src/main/java/gregtech/GT_Mod.java +++ b/src/main/java/gregtech/GT_Mod.java @@ -83,6 +83,8 @@ import gregtech.common.covers.GT_Cover_FacadeAE; import gregtech.common.entities.GT_Entity_Arrow; import gregtech.common.entities.GT_Entity_Arrow_Potion; import gregtech.common.misc.GT_Command; +import gregtech.common.misc.spaceprojects.commands.SPM_Command; +import gregtech.common.misc.spaceprojects.commands.SP_Command; import gregtech.common.tileentities.storage.GT_MetaTileEntity_DigitalChestBase; import gregtech.crossmod.Waila; import gregtech.loaders.load.GT_CoverBehaviorLoader; @@ -708,6 +710,8 @@ public class GT_Mod implements IGT_Mod { } aEvent.registerServerCommand(new GT_Command()); + aEvent.registerServerCommand(new SP_Command()); + aEvent.registerServerCommand(new SPM_Command()); // Sets a new Machine Block Update Thread everytime a world is loaded GT_Runnable_MachineBlockUpdate.initExecutorService(); } diff --git a/src/main/java/gregtech/api/gui/modularui/GT_UITextures.java b/src/main/java/gregtech/api/gui/modularui/GT_UITextures.java index a480178002..d3b353e1ec 100644 --- a/src/main/java/gregtech/api/gui/modularui/GT_UITextures.java +++ b/src/main/java/gregtech/api/gui/modularui/GT_UITextures.java @@ -190,8 +190,12 @@ public class GT_UITextures { .adaptableTexture(MODID, "gui/tab/title_angular_%s", 28, 28, 4); public static final UITexture BUTTON_STANDARD = AdaptableUITexture.of(MODID, "gui/button/standard", 18, 18, 1); + public static final UITexture BUTTON_STANDARD_DISABLED = AdaptableUITexture + .of(MODID, "gui/button/standard_disabled", 18, 18, 1); public static final UITexture BUTTON_STANDARD_TOGGLE = AdaptableUITexture .of(MODID, "gui/button/standard_toggle", 18, 18, 1); + public static final UITexture BUTTON_STANDARD_TOGGLE_DISABLED = AdaptableUITexture + .of(MODID, "gui/button/standard_toggle_disabled", 18, 18, 1); public static final UITexture BUTTON_COVER_NORMAL = UITexture.fullImage(MODID, "gui/button/cover_normal"); public static final UITexture BUTTON_COVER_NORMAL_HOVERED = UITexture .fullImage(MODID, "gui/button/cover_normal_hovered"); diff --git a/src/main/java/gregtech/api/util/GT_Recipe.java b/src/main/java/gregtech/api/util/GT_Recipe.java index 506ab9ba6b..3b7f64aae8 100644 --- a/src/main/java/gregtech/api/util/GT_Recipe.java +++ b/src/main/java/gregtech/api/util/GT_Recipe.java @@ -3,6 +3,7 @@ package gregtech.api.util; import static gregtech.api.enums.GT_Values.*; import static gregtech.api.util.GT_Utility.formatNumbers; import static net.minecraft.util.EnumChatFormatting.GRAY; +import static net.minecraft.util.StatCollector.translateToLocal; import java.awt.*; import java.util.*; @@ -29,6 +30,8 @@ import net.minecraftforge.fluids.IFluidContainerItem; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; +import appeng.util.ReadableNumberConverter; +import codechicken.lib.gui.GuiDraw; import codechicken.nei.PositionedStack; import com.gtnewhorizons.modularui.api.GlStateManager; @@ -65,6 +68,9 @@ import gregtech.api.objects.ItemData; import gregtech.api.objects.MaterialStack; import gregtech.api.util.extensions.ArrayExt; import gregtech.common.gui.modularui.UIHelper; +import gregtech.common.items.GT_FluidDisplayItem; +import gregtech.common.misc.spaceprojects.SpaceProjectManager; +import gregtech.common.misc.spaceprojects.interfaces.ISpaceProject; import gregtech.common.power.EUPower; import gregtech.common.power.Power; import gregtech.common.power.UnspecifiedEUPower; @@ -1748,6 +1754,131 @@ public class GT_Recipe implements Comparable<GT_Recipe> { false, true); + public static class GT_FakeSpaceProjectRecipe extends GT_Recipe { + + public final String projectName; + + public GT_FakeSpaceProjectRecipe(boolean aOptimize, ItemStack[] aInputs, FluidStack[] aFluidInputs, + int aDuration, int aEUt, int aSpecialValue, String projectName) { + super(aOptimize, aInputs, null, null, null, aFluidInputs, null, aDuration, aEUt, aSpecialValue); + this.projectName = projectName; + } + } + + public static final GT_Recipe_Map sFakeSpaceProjectRecipes = new GT_Recipe_Map( + new HashSet<>(20), + "gt.recipe.fakespaceprojects", + "Space Projects", + null, + RES_PATH_GUI + "basicmachines/Default", + 12, + 0, + 0, + 0, + 1, + translateToLocal("gt.specialvalue.stages") + " ", + 1, + "", + false, + true) { + + IDrawable projectTexture; + + @Override + public ModularWindow.Builder createNEITemplate(IItemHandlerModifiable itemInputsInventory, + IItemHandlerModifiable itemOutputsInventory, IItemHandlerModifiable specialSlotInventory, + IItemHandlerModifiable fluidInputsInventory, IItemHandlerModifiable fluidOutputsInventory, + Supplier<Float> progressSupplier, Pos2d windowOffset) { + ModularWindow.Builder builder = super.createNEITemplate( + itemInputsInventory, + itemOutputsInventory, + specialSlotInventory, + fluidInputsInventory, + fluidOutputsInventory, + progressSupplier, + windowOffset); + addRecipeSpecificDrawable( + builder, + windowOffset, + () -> projectTexture, + new Pos2d(124, 28), + new Size(18, 18)); + return builder; + } + + @Override + public List<Pos2d> getItemInputPositions(int itemInputCount) { + return UIHelper.getGridPositions(itemInputCount, 16, 28, 3); + } + + @Override + public List<Pos2d> getFluidInputPositions(int fluidInputCount) { + return UIHelper.getGridPositions(fluidInputCount, 88, 28, 1); + } + + @Override + protected List<String> handleNEIItemInputTooltip(List<String> currentTip, + GT_NEI_DefaultHandler.FixedPositionedStack pStack) { + super.handleNEIItemOutputTooltip(currentTip, pStack); + if (pStack.item != null && pStack.item.getItem() instanceof GT_FluidDisplayItem) return currentTip; + currentTip.add(GRAY + translateToLocal("Item Count: ") + formatNumbers(pStack.realStackSize)); + return currentTip; + } + + @Override + public void drawNEIOverlays(GT_NEI_DefaultHandler.CachedDefaultRecipe neiCachedRecipe) { + for (PositionedStack stack : neiCachedRecipe.mInputs) { + if (stack instanceof GT_NEI_DefaultHandler.FixedPositionedStack && stack.item != null + && !(stack.item.getItem() instanceof GT_FluidDisplayItem)) { + int stackSize = ((GT_NEI_DefaultHandler.FixedPositionedStack) stack).realStackSize; + String displayString; + if (stack.item.stackSize > 9999) { + displayString = ReadableNumberConverter.INSTANCE.toWideReadableForm(stackSize); + } else { + displayString = String.valueOf(stackSize); + } + drawNEIOverlayText(displayString, stack, 0xffffff, 0.5f, true, Alignment.BottomRight); + } + } + if (neiCachedRecipe.mRecipe instanceof GT_FakeSpaceProjectRecipe) { + ISpaceProject project = SpaceProjectManager + .getProject(((GT_FakeSpaceProjectRecipe) neiCachedRecipe.mRecipe).projectName); + if (project != null) { + projectTexture = project.getTexture(); + GuiDraw.drawStringC( + EnumChatFormatting.BOLD + project.getLocalizedName(), + 85, + 0, + 0x404040, + false); + } + } + } + + @Override + public void addProgressBarUI(ModularWindow.Builder builder, Supplier<Float> progressSupplier, + Pos2d windowOffset) { + int bar1Width = 17; + int bar2Width = 18; + builder.widget( + new ProgressBar().setTexture(GT_UITextures.PROGRESSBAR_ASSEMBLY_LINE_1, 17) + .setDirection(ProgressBar.Direction.RIGHT) + .setProgress( + () -> progressSupplier.get() * ((float) (bar1Width + bar2Width) / bar1Width)) + .setSynced(false, false).setPos(new Pos2d(70, 28).add(windowOffset)) + .setSize(bar1Width, 72)); + builder.widget( + new ProgressBar().setTexture(GT_UITextures.PROGRESSBAR_ASSEMBLY_LINE_2, 18) + .setDirection(ProgressBar.Direction.RIGHT) + .setProgress( + () -> (progressSupplier.get() - ((float) bar1Width / (bar1Width + bar2Width))) + * ((float) (bar1Width + bar2Width) / bar2Width)) + .setSynced(false, false).setPos(new Pos2d(106, 28).add(windowOffset)) + .setSize(bar2Width, 72)); + } + }.useModularUI(true).setRenderRealStackSizes(false).setUsualFluidInputCount(4).setNEIBackgroundOffset(2, 23) + .setLogoPos(152, 83); + public static class TranscendentPlasmaMixerRecipeMap extends GT_Recipe_Map { public TranscendentPlasmaMixerRecipeMap(Collection<GT_Recipe> aRecipeList, String aUnlocalizedName, @@ -2624,6 +2755,11 @@ public class GT_Recipe implements Comparable<GT_Recipe> { public boolean useComparatorForNEI; /** + * Whether to render the actual size of stacks or a size of 1. + */ + public boolean renderRealStackSizes = true; + + /** * Initialises a new type of Recipe Handler. * * @param aRecipeList a List you specify as Recipe List. Usually just an ArrayList with a @@ -2712,6 +2848,11 @@ public class GT_Recipe implements Comparable<GT_Recipe> { return this; } + public GT_Recipe_Map setRenderRealStackSizes(boolean renderRealStackSizes) { + this.renderRealStackSizes = renderRealStackSizes; + return this; + } + public GT_Recipe_Map useModularUI(boolean use) { this.useModularUI = use; return this; @@ -3362,6 +3503,11 @@ public class GT_Recipe implements Comparable<GT_Recipe> { builder.widget(new DrawableWidget().setDrawable(logo).setSize(logoSize).setPos(logoPos.add(windowOffset))); } + public void addRecipeSpecificDrawable(ModularWindow.Builder builder, Pos2d windowOffset, + Supplier<IDrawable> supplier, Pos2d pos, Size size) { + builder.widget(new DrawableWidget().setDrawable(supplier).setSize(size).setPos(pos.add(windowOffset))); + } + /** * Overriding this method allows custom NEI stack placement */ diff --git a/src/main/java/gregtech/common/GT_Proxy.java b/src/main/java/gregtech/common/GT_Proxy.java index ccc04f171e..3f50da2230 100644 --- a/src/main/java/gregtech/common/GT_Proxy.java +++ b/src/main/java/gregtech/common/GT_Proxy.java @@ -141,6 +141,7 @@ import gregtech.common.entities.GT_Entity_Arrow; import gregtech.common.items.GT_MetaGenerated_Item_98; import gregtech.common.items.GT_MetaGenerated_Tool_01; import gregtech.common.misc.GlobalEnergyWorldSavedData; +import gregtech.common.misc.spaceprojects.SpaceProjectWorldSavedData; public abstract class GT_Proxy implements IGT_Mod, IGuiHandler, IFuelHandler, IGlobalWirelessEnergy { @@ -1051,6 +1052,7 @@ public abstract class GT_Proxy implements IGT_Mod, IGuiHandler, IFuelHandler, IG } MinecraftForge.EVENT_BUS.register(new GlobalEnergyWorldSavedData("")); + MinecraftForge.EVENT_BUS.register(new SpaceProjectWorldSavedData()); // IC2 Hazmat addFullHazmatToIC2Item("hazmatHelmet"); diff --git a/src/main/java/gregtech/common/misc/spaceprojects/SpaceProjectManager.java b/src/main/java/gregtech/common/misc/spaceprojects/SpaceProjectManager.java new file mode 100644 index 0000000000..81c7fac375 --- /dev/null +++ b/src/main/java/gregtech/common/misc/spaceprojects/SpaceProjectManager.java @@ -0,0 +1,278 @@ +package gregtech.common.misc.spaceprojects; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import net.minecraft.server.MinecraftServer; + +import org.apache.commons.lang3.tuple.Pair; + +import gregtech.api.util.GT_Recipe; +import gregtech.common.misc.spaceprojects.interfaces.ISpaceBody; +import gregtech.common.misc.spaceprojects.interfaces.ISpaceProject; + +/** + * @author BlueWeabo + */ +public class SpaceProjectManager { + + /** + * Do not use! Only meant to be used in SpaceProjectWorldSavedData.java + */ + public static Map<UUID, Map<Pair<ISpaceBody, String>, ISpaceProject>> spaceTeamProjects = new HashMap<>(); + /** + * Do not use! Only meant to be used in SpaceProjectWorldSavedData.java Stores a Players UUID to the Leader UUID, + * players in lone groups give back their own UUID. + */ + public static Map<UUID, UUID> spaceTeams = new HashMap<>(); + + /** + * Stores all the locations to a hash map to be accessed easier instead of through an enum + */ + private static final HashMap<String, ISpaceBody> spaceLocations = new HashMap<>(); + + /** + * Stores all projects that have been made. Only adds them to this map if {@link #addProject(ISpaceProject)} has + * been used + */ + private static final Map<String, ISpaceProject> spaceProjects = new HashMap<>(); + + // #region Space Project Team Helper methods + + /** + * Used to get a specific project of the team dependent on the location and the project's name + */ + public static ISpaceProject getTeamProject(UUID member, ISpaceBody location, String projectName) { + Map<Pair<ISpaceBody, String>, ISpaceProject> map = spaceTeamProjects.get(getLeader(member)); + if (map == null) { + return null; + } + return map.get(Pair.of(location, projectName)); + } + + /** + * Makes a new Map for the teams if they don't have one. Adds a project to the team's project map. + * + * @param member Member of the team. + * @param location The location of where the project will belong to. + * @param projectName The name of the project being added. + * @param project Project which will be added to the team. + * @return Returns true when a project was added to the map of the player. Returns false otherwise. + */ + public static boolean addTeamProject(UUID member, ISpaceBody location, String projectName, ISpaceProject project) { + if (!spaceTeamProjects.containsKey(getLeader(member)) || spaceTeamProjects.get(getLeader(member)) == null) { + spaceTeamProjects.put(getLeader(member), new HashMap<Pair<ISpaceBody, String>, ISpaceProject>()); + } + + Map<Pair<ISpaceBody, String>, ISpaceProject> map = spaceTeamProjects.get(getLeader(member)); + if (map.containsKey(Pair.of(location, projectName))) { + return false; + } + + project.setProjectLocation(location); + map.put(Pair.of(location, projectName), project); + SpaceProjectWorldSavedData.INSTANCE.markDirty(); + return true; + } + + /** + * Check whether a team has a project or not + * + * @param member Member of the team + * @param project The project, which you are checking for. This only compares the internal names of the project. + * @return True if the team has said project, false otherwise + */ + public static boolean teamHasProject(UUID member, ISpaceProject project) { + Map<Pair<ISpaceBody, String>, ISpaceProject> map = spaceTeamProjects.get(getLeader(member)); + if (map == null) { + return false; + } + + return map.containsValue(project); + } + + /** + * Used to handle when 2 players want to join together in a team. Player A can join player B's team. If player C + * gets an invite from A, C will join player B's team. + * + * @param teamMember Member which is joining the teamLeader + * @param teamLeader Leader of the party + */ + public static void putInTeam(UUID teamMember, UUID teamLeader) { + if (teamMember.equals(teamLeader)) { + spaceTeams.put(teamMember, teamLeader); + } else if (!spaceTeams.get(teamLeader).equals(teamLeader)) { + putInTeam(teamMember, spaceTeams.get(teamLeader)); + } else { + spaceTeams.put(teamMember, teamLeader); + } + + SpaceProjectWorldSavedData.INSTANCE.markDirty(); + } + + /** + * Used to give back the UUID of the team leader. + * + * @return The UUID of the team leader. + */ + public static UUID getLeader(UUID teamMember) { + checkOrCreateTeam(teamMember); + return spaceTeams.get(teamMember); + } + + /** + * Used the multiblocks to check whether a given player has a team or not. If they don't have a team create one + * where they are their own leader. + * + * @param teamMember Member to check for. + */ + public static void checkOrCreateTeam(UUID teamMember) { + if (spaceTeams.containsKey(teamMember)) { + return; + } + + spaceTeams.put(teamMember, teamMember); + SpaceProjectWorldSavedData.INSTANCE.markDirty(); + } + + /** + * Will give back all the projects a team has made or is making. + * + * @param member UUID of the team member, used to find the leader of the team. + * @return All the projects a team has. + */ + public static Collection<ISpaceProject> getTeamSpaceProjects(UUID member) { + Map<Pair<ISpaceBody, String>, ISpaceProject> map = spaceTeamProjects.get(getLeader(member)); + if (map == null) { + return null; + } + + return map.values(); + } + + /** + * Getting the project of a Team or a new copy. + * + * @param member UUID of the team member, which is used to find the team leader. + * @param projectName The name of the project, which needs to be found. + * @param location The location at which the project is found at. + * @return the project that the team has or a copy of a project. + */ + public static ISpaceProject getTeamProjectOrCopy(UUID member, String projectName, ISpaceBody location) { + Map<Pair<ISpaceBody, String>, ISpaceProject> map = spaceTeamProjects.get(getLeader(member)); + if (map == null) { + return getProject(projectName); + } + + return map.getOrDefault(Pair.of(location, projectName), getProject(projectName)); + } + + // #endregion + + // #region Project Helper methods + + /** + * Used to add projects to the internal map. + * + * @param project Newly created project. + */ + public static void addProject(ISpaceProject project) { + spaceProjects.put(project.getProjectName(), project); + GT_Recipe.GT_Recipe_Map.sFakeSpaceProjectRecipes.add( + new GT_Recipe.GT_Recipe_Map.GT_FakeSpaceProjectRecipe( + false, + project.getTotalItemsCost(), + project.getTotalFluidsCost(), + project.getProjectBuildTime(), + (int) project.getProjectVoltage(), + project.getTotalStages(), + project.getProjectName())); + } + + /** + * @param projectName Internal name of the project. + * @return a copy of the stored project. + */ + public static ISpaceProject getProject(String projectName) { + ISpaceProject tProject = spaceProjects.get(projectName); + return tProject != null ? tProject.copy() : null; + } + + /** + * Should only be used for GUIs! + * + * @return The Map that the projects are stored at. + */ + public static Map<String, ISpaceProject> getProjectsMap() { + return spaceProjects; + } + + /** + * Should only be used for GUIs! + * + * @return A Collection of all the projects contained in the map. + */ + public static Collection<ISpaceProject> getAllProjects() { + return spaceProjects.values(); + } + + // #endregion + + // #region Location Helper methods + + /** + * Adds a location to the internal map. For it to be used later + * + * @param location to add to the internal map + */ + public static void addLocation(ISpaceBody location) { + spaceLocations.put(location.getName(), location); + } + + /** + * + * @return a Collection of all locations, which have been registered. + */ + public static Collection<ISpaceBody> getLocations() { + return spaceLocations.values(); + } + + /** + * + * @return a Collection fo all location names, which have been registered + */ + public static Collection<String> getLocationNames() { + return spaceLocations.keySet(); + } + + /** + * + * @param locationName Name used to search for the location + * @return The location, which has been registered with said name + */ + public static ISpaceBody getLocation(String locationName) { + return spaceLocations.get(locationName); + } + + // #endregion + + // #region General Helper methods + + /** + * Gets the UUID using the player's username + */ + public static UUID getPlayerUUIDFromName(String playerName) { + return MinecraftServer.getServer().func_152358_ax().func_152655_a(playerName).getId(); + } + + /** + * Gets the player's name using their UUID + */ + public static String getPlayerNameFromUUID(UUID playerUUID) { + return MinecraftServer.getServer().func_152358_ax().func_152652_a(playerUUID).getName(); + } + + // #endregion +} diff --git a/src/main/java/gregtech/common/misc/spaceprojects/SpaceProjectWorldSavedData.java b/src/main/java/gregtech/common/misc/spaceprojects/SpaceProjectWorldSavedData.java new file mode 100644 index 0000000000..6dc80db3ec --- /dev/null +++ b/src/main/java/gregtech/common/misc/spaceprojects/SpaceProjectWorldSavedData.java @@ -0,0 +1,275 @@ +package gregtech.common.misc.spaceprojects; + +import static gregtech.common.misc.spaceprojects.SpaceProjectManager.spaceTeamProjects; +import static gregtech.common.misc.spaceprojects.SpaceProjectManager.spaceTeams; +import static gregtech.common.misc.spaceprojects.enums.JsonVariables.*; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; +import net.minecraft.world.WorldSavedData; +import net.minecraft.world.storage.MapStorage; +import net.minecraftforge.event.world.WorldEvent; + +import org.apache.commons.lang3.tuple.Pair; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import gregtech.common.misc.spaceprojects.enums.SolarSystem; +import gregtech.common.misc.spaceprojects.interfaces.ISpaceBody; +import gregtech.common.misc.spaceprojects.interfaces.ISpaceProject; +import gregtech.common.misc.spaceprojects.interfaces.ISpaceProject.ISP_Upgrade; + +/** + * This class is used so that I can write and read to a json file before the world is opened. On server starting is too + * late for this as the data stored in the files is needed before entities load their nbt data + * + * @author BlueWeabo + */ +public class SpaceProjectWorldSavedData extends WorldSavedData { + + public static SpaceProjectWorldSavedData INSTANCE; + + private static final Gson GSON_SPACE_PROJECT = new GsonBuilder().serializeNulls().enableComplexMapKeySerialization() + .registerTypeAdapter(spaceTeamProjects.getClass(), new SpaceTeamProjectsMapAdapter()) + .registerTypeAdapter(Map.class, new SpaceTeamProjectsMapAdapter()) + .registerTypeAdapter(Pair.of((ISpaceBody) SolarSystem.Ariel, "").getClass(), new PairAdapter()) + .registerTypeAdapter(Pair.class, new PairAdapter()) + .registerTypeAdapter(ISpaceProject.class, new SpaceProjectAdapter()) + .registerTypeAdapter(ISP_Upgrade.class, new SP_UpgradeAdapter()) + .registerTypeHierarchyAdapter(ISpaceProject.class, new SpaceProjectAdapter()) + .registerTypeHierarchyAdapter(ISP_Upgrade.class, new SP_UpgradeAdapter()).create(); + private static final Gson GSON_TEAMS = new GsonBuilder().serializeNulls().create(); + + private static final String DATA_NAME = "GT_SpaceProjectData"; + + private static final String SPACE_TEAM_PROJECTS_JSON = "spaceTeamProject.json"; + + private static final String SPACE_TEAMS_JSON = "spaceTeams.json"; + + private static File spaceTeamsFile; + private static File teamProjectsFile; + + public SpaceProjectWorldSavedData() { + super(DATA_NAME); + } + + public SpaceProjectWorldSavedData(String aData) { + super(aData); + } + + @Override + public void readFromNBT(NBTTagCompound aNBT) { + try (JsonReader reader = new JsonReader(new FileReader(teamProjectsFile))) { + spaceTeamProjects = GSON_SPACE_PROJECT.fromJson(reader, spaceTeamProjects.getClass()); + } catch (Exception e) { + System.out.print("FAILED TO LOAD: " + SPACE_TEAM_PROJECTS_JSON); + e.printStackTrace(); + } + + try (JsonReader reader = new JsonReader(new FileReader(spaceTeamsFile))) { + spaceTeams = GSON_TEAMS.fromJson(reader, spaceTeams.getClass()); + } catch (Exception e) { + System.out.print("FAILED TO LOAD: " + SPACE_TEAMS_JSON); + e.printStackTrace(); + } + + if (spaceTeams == null) { + spaceTeams = new HashMap<>(); + } + } + + @Override + public void writeToNBT(NBTTagCompound aNBT) { + try (JsonWriter writer = new JsonWriter(new FileWriter(teamProjectsFile))) { + GSON_SPACE_PROJECT.toJson(spaceTeamProjects, spaceTeamProjects.getClass(), writer); + } catch (Exception ex) { + System.out.print("FAILED TO SAVE: " + SPACE_TEAM_PROJECTS_JSON); + ex.printStackTrace(); + } + + try (JsonWriter writer = new JsonWriter(new FileWriter(spaceTeamsFile))) { + GSON_TEAMS.toJson(spaceTeams, spaceTeams.getClass(), writer); + } catch (Exception ex) { + System.out.print("FAILED TO SAVE: " + SPACE_TEAMS_JSON); + ex.printStackTrace(); + } + } + + private static void loadInstance(World aWorld) { + spaceTeamProjects.clear(); + spaceTeams.clear(); + spaceTeamsFile = new File(aWorld.getSaveHandler().getWorldDirectory(), SPACE_TEAMS_JSON); + teamProjectsFile = new File(aWorld.getSaveHandler().getWorldDirectory(), SPACE_TEAM_PROJECTS_JSON); + MapStorage tStorage = aWorld.mapStorage; + INSTANCE = (SpaceProjectWorldSavedData) tStorage.loadData(SpaceProjectWorldSavedData.class, DATA_NAME); + if (INSTANCE == null) { + INSTANCE = new SpaceProjectWorldSavedData(); + tStorage.setData(DATA_NAME, INSTANCE); + } + INSTANCE.markDirty(); + } + + @SubscribeEvent + public void onWorldLoad(WorldEvent.Load aEvent) { + if (!aEvent.world.isRemote && aEvent.world.provider.dimensionId == 0) { + loadInstance(aEvent.world); + } + } + + private static class PairAdapter + implements JsonSerializer<Pair<ISpaceBody, String>>, JsonDeserializer<Pair<ISpaceBody, String>> { + + @Override + public JsonElement serialize(Pair<ISpaceBody, String> src, Type typeOfSrc, JsonSerializationContext context) { + JsonObject pair = new JsonObject(); + pair.addProperty(PAIR_LEFT, src.getLeft().getName()); + pair.addProperty(PAIR_RIGHT, src.getRight()); + return pair; + } + + @Override + public Pair<ISpaceBody, String> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + Pair<ISpaceBody, String> pair = null; + if (json.isJsonObject()) { + JsonObject obj = json.getAsJsonObject(); + pair = Pair.of( + SpaceProjectManager.getLocation(obj.get(PAIR_L |
