diff --git a/dependencies.gradle b/dependencies.gradle index b207b6e..76cea7a 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,8 +1,7 @@ dependencies { api('com.github.GTNewHorizons:Navigator:1.0.12:dev') api('com.github.GTNewHorizons:GTNHLib:0.5.11:dev') - api('com.github.GTNewHorizons:GT5-Unofficial:5.09.49.105:dev') + api('com.github.GTNewHorizons:GT5-Unofficial:5.09.50.01:dev') - runtimeOnlyNonPublishable(rfg.deobf('maven.modrinth:journeymap:5.2.5')) runtimeOnlyNonPublishable(rfg.deobf('maven.modrinth:journeymap:5.2.6')) } diff --git a/src/main/java/com/sinthoras/visualprospecting/database/ClientCache.java b/src/main/java/com/sinthoras/visualprospecting/database/ClientCache.java index 3bda034..e225354 100644 --- a/src/main/java/com/sinthoras/visualprospecting/database/ClientCache.java +++ b/src/main/java/com/sinthoras/visualprospecting/database/ClientCache.java @@ -6,7 +6,6 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityClientPlayerMP; -import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ChatComponentTranslation; @@ -39,7 +38,7 @@ private void notifyNewOreVein(OreVeinPosition oreVeinPosition) { final String location = "(" + (oreVeinPosition.getBlockX() + 8) + "," + (oreVeinPosition.getBlockZ() + 8) + ")"; final IChatComponent veinNotification = new ChatComponentTranslation( "visualprospecting.vein.prospected", - I18n.format(oreVeinPosition.veinType.name), + oreVeinPosition.veinType.getPrimaryOreName(), location); veinNotification.getChatStyle().setItalic(true); veinNotification.getChatStyle().setColor(EnumChatFormatting.GRAY); diff --git a/src/main/java/com/sinthoras/visualprospecting/database/DimensionCache.java b/src/main/java/com/sinthoras/visualprospecting/database/DimensionCache.java index 73caded..9e1b1fc 100644 --- a/src/main/java/com/sinthoras/visualprospecting/database/DimensionCache.java +++ b/src/main/java/com/sinthoras/visualprospecting/database/DimensionCache.java @@ -18,8 +18,6 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.longs.LongOpenHashSet; -import it.unimi.dsi.fastutil.longs.LongSet; public class DimensionCache { @@ -31,8 +29,6 @@ public enum UpdateResult { private final Long2ObjectMap oreChunks = new Long2ObjectOpenHashMap<>(); private final Long2ObjectMap undergroundFluids = new Long2ObjectOpenHashMap<>(); - private final LongSet changedOrNewOreChunks = new LongOpenHashSet(); - private final LongSet changedOrNewUndergroundFluids = new LongOpenHashSet(); public final int dimensionId; private boolean isDirty = false; @@ -51,32 +47,30 @@ public NBTTagCompound saveToNbt() { private NBTTagCompound saveOres() { NBTTagCompound compound = new NBTTagCompound(); - for (long key : changedOrNewOreChunks) { - OreVeinPosition oreVeinPosition = oreChunks.get(key); + for (OreVeinPosition vein : oreChunks.values()) { NBTTagCompound veinCompound = new NBTTagCompound(); - veinCompound.setInteger("chunkX", oreVeinPosition.chunkX); - veinCompound.setInteger("chunkZ", oreVeinPosition.chunkZ); - veinCompound.setShort("veinTypeId", VeinTypeCaching.getVeinTypeId(oreVeinPosition.veinType)); - veinCompound.setBoolean("depleted", oreVeinPosition.isDepleted()); - compound.setTag(String.valueOf(key), veinCompound); + veinCompound.setInteger("chunkX", vein.chunkX); + veinCompound.setInteger("chunkZ", vein.chunkZ); + veinCompound.setShort("veinTypeId", vein.veinType.veinId); + veinCompound.setBoolean("depleted", vein.isDepleted()); + compound.setTag(String.valueOf(getOreVeinKey(vein.chunkX, vein.chunkZ)), veinCompound); } return compound; } private NBTTagCompound saveFluids() { NBTTagCompound compound = new NBTTagCompound(); - for (long key : changedOrNewUndergroundFluids) { - UndergroundFluidPosition undergroundFluidPosition = undergroundFluids.get(key); + for (UndergroundFluidPosition fluid : undergroundFluids.values()) { NBTTagCompound fluidCompound = new NBTTagCompound(); - fluidCompound.setInteger("chunkX", undergroundFluidPosition.chunkX); - fluidCompound.setInteger("chunkZ", undergroundFluidPosition.chunkZ); - fluidCompound.setString("fluidName", undergroundFluidPosition.fluid.getName()); + fluidCompound.setInteger("chunkX", fluid.chunkX); + fluidCompound.setInteger("chunkZ", fluid.chunkZ); + fluidCompound.setString("fluidName", fluid.fluid.getName()); NBTTagList chunkList = new NBTTagList(); for (int i = 0; i < VP.undergroundFluidSizeChunkX; i++) { - chunkList.appendTag(new NBTTagIntArray(undergroundFluidPosition.chunks[i])); + chunkList.appendTag(new NBTTagIntArray(fluid.chunks[i])); } fluidCompound.setTag("chunks", chunkList); - compound.setTag(String.valueOf(key), fluidCompound); + compound.setTag(String.valueOf(getUndergroundFluid(fluid.chunkX, fluid.chunkZ)), fluidCompound); } return compound; } @@ -125,7 +119,6 @@ void loadLegacy(ByteBuffer oreChunksBuffer, ByteBuffer undergroundFluidsBuffer) oreChunks.put( getOreVeinKey(chunkX, chunkZ), new OreVeinPosition(dimensionId, chunkX, chunkZ, veinType, depleted)); - changedOrNewOreChunks.add(getOreVeinKey(chunkX, chunkZ)); } } if (undergroundFluidsBuffer != null) { @@ -153,7 +146,6 @@ void loadLegacy(ByteBuffer oreChunksBuffer, ByteBuffer undergroundFluidsBuffer) undergroundFluids.put( getUndergroundFluidKey(chunkX, chunkZ), new UndergroundFluidPosition(dimensionId, chunkX, chunkZ, fluid, chunks)); - changedOrNewUndergroundFluids.add(getUndergroundFluidKey(chunkX, chunkZ)); } } } @@ -174,7 +166,6 @@ public void toggleOreVein(int chunkX, int chunkZ) { final OreVeinPosition oreVeinPosition = oreChunks.get(key); if (oreVeinPosition != null) { oreVeinPosition.toggleDepleted(); - changedOrNewOreChunks.add(key); markDirty(); } } @@ -184,13 +175,11 @@ public UpdateResult putOreVein(final OreVeinPosition oreVeinPosition) { final OreVeinPosition storedOreVeinPosition = oreChunks.get(key); if (storedOreVeinPosition == null) { oreChunks.put(key, oreVeinPosition); - changedOrNewOreChunks.add(key); markDirty(); return UpdateResult.New; } if (storedOreVeinPosition.veinType != oreVeinPosition.veinType) { oreChunks.put(key, oreVeinPosition.joinDepletedState(storedOreVeinPosition)); - changedOrNewOreChunks.add(key); markDirty(); return UpdateResult.New; } @@ -201,12 +190,10 @@ public UpdateResult putUndergroundFluid(final UndergroundFluidPosition undergrou final long key = getUndergroundFluidKey(undergroundFluid.chunkX, undergroundFluid.chunkZ); final UndergroundFluidPosition storedUndergroundFluid = undergroundFluids.get(key); if (storedUndergroundFluid == null) { - changedOrNewUndergroundFluids.add(key); undergroundFluids.put(key, undergroundFluid); markDirty(); return UpdateResult.New; } else if (!storedUndergroundFluid.equals(undergroundFluid)) { - changedOrNewUndergroundFluids.add(key); undergroundFluids.put(key, undergroundFluid); markDirty(); return UpdateResult.Updated; @@ -216,13 +203,12 @@ public UpdateResult putUndergroundFluid(final UndergroundFluidPosition undergrou public OreVeinPosition getOreVein(int chunkX, int chunkZ) { final long key = getOreVeinKey(chunkX, chunkZ); - return oreChunks.getOrDefault(key, new OreVeinPosition(dimensionId, chunkX, chunkZ, VeinType.NO_VEIN, true)); + return oreChunks.getOrDefault(key, OreVeinPosition.EMPTY_VEIN); } public UndergroundFluidPosition getUndergroundFluid(int chunkX, int chunkZ) { final long key = getUndergroundFluidKey(chunkX, chunkZ); - return undergroundFluids - .getOrDefault(key, UndergroundFluidPosition.getNotProspected(dimensionId, chunkX, chunkZ)); + return undergroundFluids.getOrDefault(key, UndergroundFluidPosition.NOT_PROSPECTED); } public Collection getAllOreVeins() { diff --git a/src/main/java/com/sinthoras/visualprospecting/database/OreVeinPosition.java b/src/main/java/com/sinthoras/visualprospecting/database/OreVeinPosition.java index bb9de4c..1fe1aa1 100644 --- a/src/main/java/com/sinthoras/visualprospecting/database/OreVeinPosition.java +++ b/src/main/java/com/sinthoras/visualprospecting/database/OreVeinPosition.java @@ -6,6 +6,7 @@ public class OreVeinPosition { public static final int MAX_BYTES = 3 * Integer.BYTES + Short.BYTES; + public static final OreVeinPosition EMPTY_VEIN = new OreVeinPosition(0, 0, 0, VeinType.NO_VEIN, true); public final int dimensionId; public final int chunkX; diff --git a/src/main/java/com/sinthoras/visualprospecting/database/RedoServerCacheCommand.java b/src/main/java/com/sinthoras/visualprospecting/database/RedoServerCacheCommand.java index bd71251..9d06e02 100644 --- a/src/main/java/com/sinthoras/visualprospecting/database/RedoServerCacheCommand.java +++ b/src/main/java/com/sinthoras/visualprospecting/database/RedoServerCacheCommand.java @@ -1,6 +1,8 @@ package com.sinthoras.visualprospecting.database; import java.io.IOException; +import java.util.Collections; +import java.util.List; import java.util.Objects; import java.util.zip.DataFormatException; @@ -29,6 +31,11 @@ public String getCommandUsage(ICommandSender sender) { return StatCollector.translateToLocal("visualprospecting.redoservercache.command"); } + @Override + public List getCommandAliases() { + return Collections.singletonList("vp_recache"); + } + @Override public void processCommand(ICommandSender sender, String[] parameters) { MinecraftServer server; diff --git a/src/main/java/com/sinthoras/visualprospecting/database/RedoServerSpawnCacheCommand.java b/src/main/java/com/sinthoras/visualprospecting/database/RedoServerSpawnCacheCommand.java index 03ca3ec..3df89ef 100644 --- a/src/main/java/com/sinthoras/visualprospecting/database/RedoServerSpawnCacheCommand.java +++ b/src/main/java/com/sinthoras/visualprospecting/database/RedoServerSpawnCacheCommand.java @@ -1,6 +1,8 @@ package com.sinthoras.visualprospecting.database; import java.io.IOException; +import java.util.Collections; +import java.util.List; import java.util.Objects; import java.util.zip.DataFormatException; @@ -29,6 +31,11 @@ public String getCommandUsage(ICommandSender sender) { return StatCollector.translateToLocal("visualprospecting.redoserverspawncache.command"); } + @Override + public List getCommandAliases() { + return Collections.singletonList("vp_recachespawn"); + } + @Override public void processCommand(ICommandSender sender, String[] parameters) { diff --git a/src/main/java/com/sinthoras/visualprospecting/database/UndergroundFluidPosition.java b/src/main/java/com/sinthoras/visualprospecting/database/UndergroundFluidPosition.java index fc58a50..bec9e4c 100644 --- a/src/main/java/com/sinthoras/visualprospecting/database/UndergroundFluidPosition.java +++ b/src/main/java/com/sinthoras/visualprospecting/database/UndergroundFluidPosition.java @@ -11,6 +11,7 @@ public class UndergroundFluidPosition { public static final int BYTES = (3 + 1 + VP.undergroundFluidSizeChunkX * VP.undergroundFluidSizeChunkZ) * Integer.BYTES; + public static final UndergroundFluidPosition NOT_PROSPECTED = new UndergroundFluidPosition(0, 0, 0, null, null); public final int dimensionId; public final int chunkX; @@ -18,10 +19,6 @@ public class UndergroundFluidPosition { public final Fluid fluid; public final int[][] chunks; - public static UndergroundFluidPosition getNotProspected(int dimensionId, int chunkX, int chunkZ) { - return new UndergroundFluidPosition(dimensionId, chunkX, chunkZ, null, null); - } - public UndergroundFluidPosition(int dimensionId, int chunkX, int chunkZ, Fluid fluid, int[][] chunks) { this.dimensionId = dimensionId; this.chunkX = Utils.mapToCornerUndergroundFluidChunkCoord(chunkX); diff --git a/src/main/java/com/sinthoras/visualprospecting/database/WorldCache.java b/src/main/java/com/sinthoras/visualprospecting/database/WorldCache.java index 447e8a9..c3d5502 100644 --- a/src/main/java/com/sinthoras/visualprospecting/database/WorldCache.java +++ b/src/main/java/com/sinthoras/visualprospecting/database/WorldCache.java @@ -12,7 +12,6 @@ import com.sinthoras.visualprospecting.Tags; import com.sinthoras.visualprospecting.Utils; -import com.sinthoras.visualprospecting.database.veintypes.VeinType; public abstract class WorldCache { @@ -31,8 +30,9 @@ public boolean loadVeinCache(String worldId) { if (loadLegacyVeinCache(worldCache)) return true; final File[] dimensionFiles = worldCache.listFiles(); - if (dimensionFiles == null) return false; + if (dimensionFiles == null || dimensionFiles.length == 0) return false; + boolean loadedAny = false; for (File dimensionFile : dimensionFiles) { final String fileName = dimensionFile.getName(); if (!dimensionFile.isFile() || !fileName.endsWith(".dat")) { @@ -46,9 +46,10 @@ public boolean loadVeinCache(String worldId) { final DimensionCache dimension = new DimensionCache(dimensionId); dimension.loadFromNbt(dimCompound); dimensions.put(dimensionId, dimension); + loadedAny = true; } - return true; + return loadedAny; } private boolean loadLegacyVeinCache(File worldCacheDirectory) { @@ -167,7 +168,7 @@ protected void toggleOreVein(int dimensionId, int chunkX, int chunkZ) { public OreVeinPosition getOreVein(int dimensionId, int chunkX, int chunkZ) { DimensionCache dimension = dimensions.get(dimensionId); if (dimension == null) { - return new OreVeinPosition(dimensionId, chunkX, chunkZ, VeinType.NO_VEIN, true); + return OreVeinPosition.EMPTY_VEIN; } return dimension.getOreVein(chunkX, chunkZ); } @@ -184,7 +185,7 @@ protected DimensionCache.UpdateResult putUndergroundFluids(final UndergroundFlui public UndergroundFluidPosition getUndergroundFluid(int dimensionId, int chunkX, int chunkZ) { DimensionCache dimension = dimensions.get(dimensionId); if (dimension == null) { - return UndergroundFluidPosition.getNotProspected(dimensionId, chunkX, chunkZ); + return UndergroundFluidPosition.NOT_PROSPECTED; } return dimension.getUndergroundFluid(chunkX, chunkZ); } diff --git a/src/main/java/com/sinthoras/visualprospecting/database/cachebuilder/ChunkAnalysis.java b/src/main/java/com/sinthoras/visualprospecting/database/cachebuilder/ChunkAnalysis.java index 19edd88..02af198 100644 --- a/src/main/java/com/sinthoras/visualprospecting/database/cachebuilder/ChunkAnalysis.java +++ b/src/main/java/com/sinthoras/visualprospecting/database/cachebuilder/ChunkAnalysis.java @@ -21,7 +21,12 @@ public class ChunkAnalysis { private final ObjectSet matchedVeins = new ObjectOpenHashSet<>(); private final Short2IntMap oreCounts = new Short2IntArrayMap(); private int minVeinBlockY = VP.minecraftWorldHeight; - private short primaryMeta, secondaryMeta; + private short primaryMeta; + private final String dimName; + + public ChunkAnalysis(String dimName) { + this.dimName = dimName; + } public void processMinecraftChunk(final NBTTagList tileEntities) { if (tileEntities == null || tileEntities.tagCount() == 0) return; @@ -29,7 +34,8 @@ public void processMinecraftChunk(final NBTTagList tileEntities) { final NBTTagCompound tile = tileEntities.getCompoundTagAt(i); if (tile == null || !tile.hasKey("m")) continue; - if (!"GT_TileEntity_Ores".equals(tile.getString("id"))) { + String id = tile.getString("id"); + if (!"GT_TileEntity_Ores".equals(id) && !"bw.blockoresTE".equals(id)) { continue; } @@ -46,35 +52,20 @@ public void processMinecraftChunk(final NBTTagList tileEntities) { } if (oreCounts.size() == 1) { - primaryMeta = secondaryMeta = oreCounts.keySet().iterator().nextShort(); + primaryMeta = oreCounts.keySet().iterator().nextShort(); } else if (oreCounts.size() > 1) { ShortList metaCounts = new ShortArrayList(oreCounts.keySet()); metaCounts.sort((a, b) -> Integer.compare(oreCounts.get(b), oreCounts.get(a))); primaryMeta = metaCounts.getShort(0); - secondaryMeta = metaCounts.getShort(1); } } public boolean matchesSingleVein() { if (oreCounts.isEmpty()) return true; if (oreCounts.size() > 4) return false; - ObjectSet veins = VeinTypeCaching.getVeinTypesForPrimaryMeta(primaryMeta); - if (veins.isEmpty()) return trySecondaryMeta(); - - veins.stream().filter(veinType -> veinType.matches(oreCounts.keySet())).forEach(matchedVeins::add); - - if (matchedVeins.size() != 1) { - matchedVeins.clear(); - return trySecondaryMeta(); - } - - return true; - } - - private boolean trySecondaryMeta() { - if (secondaryMeta == primaryMeta) return false; - VeinTypeCaching.getVeinTypesForPrimaryMeta(secondaryMeta).stream() - .filter(veinType -> veinType.matches(oreCounts.keySet())).forEach(matchedVeins::add); + VeinTypeCaching.veinTypes.stream() + .filter(vein -> vein.containsAllFoundOres(oreCounts.keySet(), dimName, primaryMeta, minVeinBlockY)) + .forEach(matchedVeins::add); return matchedVeins.size() <= 1; } diff --git a/src/main/java/com/sinthoras/visualprospecting/database/cachebuilder/DetailedChunkAnalysis.java b/src/main/java/com/sinthoras/visualprospecting/database/cachebuilder/DetailedChunkAnalysis.java index 51a353b..68958a9 100644 --- a/src/main/java/com/sinthoras/visualprospecting/database/cachebuilder/DetailedChunkAnalysis.java +++ b/src/main/java/com/sinthoras/visualprospecting/database/cachebuilder/DetailedChunkAnalysis.java @@ -28,21 +28,23 @@ public class DetailedChunkAnalysis { public final int chunkZ; // For each height we count how often a ore (short) has occured private final Short2IntMap[] oresPerY = new Short2IntOpenHashMap[VP.minecraftWorldHeight]; + private final String dimName; - public DetailedChunkAnalysis(int dimensionId, int chunkX, int chunkZ) { + public DetailedChunkAnalysis(int dimensionId, String dimName, int chunkX, int chunkZ) { this.dimensionId = dimensionId; this.chunkX = chunkX; this.chunkZ = chunkZ; + this.dimName = dimName; } public void processMinecraftChunk(final NBTTagList tileEntities) { if (tileEntities == null || tileEntities.tagCount() == 0) return; for (int i = 0; i < tileEntities.tagCount(); i++) { final NBTTagCompound tile = tileEntities.getCompoundTagAt(i); - if (tile == null || !tile.hasKey("id")) continue; - final String tagId = tile.getString("id"); + if (tile == null || !tile.hasKey("m")) continue; - if (!tagId.equals("GT_TileEntity_Ores")) { + String id = tile.getString("id"); + if (!"GT_TileEntity_Ores".equals(id) && !"bw.blockoresTE".equals(id)) { continue; } @@ -56,10 +58,6 @@ public void processMinecraftChunk(final NBTTagList tileEntities) { oresPerY[blockY] = new Short2IntOpenHashMap(); } - if (!oresPerY[blockY].containsKey(meta)) { - oresPerY[blockY].put(meta, 0); - } - oresPerY[blockY].put(meta, oresPerY[blockY].get(meta) + 1); } } @@ -120,12 +118,14 @@ public void cleanUpWithNeighbors(final Map veinChunkY) { // but that case is rare and therefore, neglected for (int neighborId = 0; neighborId < neighbors.length; neighborId++) { final OreVeinPosition neighbor = neighbors[neighborId]; + if (neighbor.veinType == VeinType.NO_VEIN) continue; + final boolean atCoordinateAxis = Math.abs(neighbor.chunkX - chunkX) < 3 || Math.abs(neighbor.chunkZ - chunkZ) < 3; final boolean canOverlap = atCoordinateAxis ? neighbor.veinType.canOverlapIntoNeighborOreChunkAtCoordinateAxis() : neighbor.veinType.canOverlapIntoNeighborOreChunk(); - if (neighbor.veinType != VeinType.NO_VEIN && canOverlap) { + if (canOverlap) { final int veinBlockY = neighborVeinBlockY[neighborId]; for (int layerBlockY = 0; layerBlockY < VeinType.veinHeight; layerBlockY++) { final int blockY = veinBlockY + layerBlockY; @@ -155,13 +155,15 @@ public VeinType getMatchedVein() { } } + if (allOres.isEmpty()) return VeinType.NO_VEIN; + final Optional dominantOre = allOres.short2IntEntrySet().stream() .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).map(Map.Entry::getKey).findFirst(); - if (dominantOre.isPresent()) { - for (VeinType veinType : VeinTypeCaching.veinTypes) { - if (veinType.matchesWithSpecificPrimaryOrSecondary(allOres.keySet(), dominantOre.get())) { - matchedVeins.add(veinType); - } + if (!dominantOre.isPresent()) return VeinType.NO_VEIN; + + for (VeinType veinType : VeinTypeCaching.veinTypes) { + if (veinType.matchesWithSpecificPrimaryOrSecondary(allOres.keySet(), dimName, dominantOre.get())) { + matchedVeins.add(veinType); } } diff --git a/src/main/java/com/sinthoras/visualprospecting/database/cachebuilder/DimensionAnalysis.java b/src/main/java/com/sinthoras/visualprospecting/database/cachebuilder/DimensionAnalysis.java index 0f18cea..620692a 100644 --- a/src/main/java/com/sinthoras/visualprospecting/database/cachebuilder/DimensionAnalysis.java +++ b/src/main/java/com/sinthoras/visualprospecting/database/cachebuilder/DimensionAnalysis.java @@ -9,6 +9,9 @@ import java.util.zip.DataFormatException; import net.minecraft.nbt.NBTTagList; +import net.minecraft.world.WorldProvider; +import net.minecraft.world.WorldServer; +import net.minecraftforge.common.DimensionManager; import com.sinthoras.visualprospecting.Config; import com.sinthoras.visualprospecting.Utils; @@ -19,9 +22,11 @@ public class DimensionAnalysis { public final int dimensionId; + public final String dimensionName; public DimensionAnalysis(int dimensionId) { this.dimensionId = dimensionId; + this.dimensionName = getDimensionName(); } private interface IChunkHandler { @@ -42,7 +47,7 @@ public void processMinecraftWorld(Collection regionFiles) { regionFiles.parallelStream().forEach(regionFile -> { executeForEachGeneratedOreChunk(regionFile, (root, chunkX, chunkZ) -> { - final ChunkAnalysis chunk = new ChunkAnalysis(); + final ChunkAnalysis chunk = new ChunkAnalysis(dimensionName); chunk.processMinecraftChunk(root); if (chunk.matchesSingleVein()) { @@ -52,6 +57,7 @@ public void processMinecraftWorld(Collection regionFiles) { } else { final DetailedChunkAnalysis detailedChunk = new DetailedChunkAnalysis( dimensionId, + dimensionName, chunkX, chunkZ); detailedChunk.processMinecraftChunk(root); @@ -71,7 +77,7 @@ public void processMinecraftWorld(Collection regionFiles) { regionFiles.parallelStream().forEach(regionFile -> { executeForEachGeneratedOreChunk(regionFile, (root, chunkX, chunkZ) -> { - final ChunkAnalysis chunk = new ChunkAnalysis(); + final ChunkAnalysis chunk = new ChunkAnalysis(dimensionName); chunk.processMinecraftChunk(root); if (chunk.matchesSingleVein()) { @@ -87,6 +93,7 @@ public void processMinecraftWorld(Collection regionFiles) { if (ServerCache.instance.getOreVein(dimensionId, chunkX, chunkZ).veinType == VeinType.NO_VEIN) { final DetailedChunkAnalysis detailedChunk = new DetailedChunkAnalysis( dimensionId, + dimensionName, chunkX, chunkZ); detailedChunk.processMinecraftChunk(root); @@ -134,4 +141,11 @@ private void executeForEachGeneratedOreChunk(File regionFile, IChunkHandler chun AnalysisProgressTracker.notifyCorruptFile(regionFile); } } + + private String getDimensionName() { + WorldServer world = DimensionManager.getWorld(dimensionId); + if (world == null) return ""; + WorldProvider provider = world.provider; + return provider == null ? "" : provider.getDimensionName(); + } } diff --git a/src/main/java/com/sinthoras/visualprospecting/database/veintypes/BartworksOreMaterialProvider.java b/src/main/java/com/sinthoras/visualprospecting/database/veintypes/BartworksOreMaterialProvider.java index 3f218a4..5221463 100644 --- a/src/main/java/com/sinthoras/visualprospecting/database/veintypes/BartworksOreMaterialProvider.java +++ b/src/main/java/com/sinthoras/visualprospecting/database/veintypes/BartworksOreMaterialProvider.java @@ -2,16 +2,17 @@ import static bartworks.util.BWColorUtil.getColorFromRGBArray; +import java.util.ArrayList; import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; -import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.IIcon; +import com.google.common.collect.ImmutableList; + import bartworks.system.material.Werkstoff; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import gregtech.api.GregTechAPI; import gregtech.api.enums.OrePrefixes; import it.unimi.dsi.fastutil.shorts.ShortCollection; @@ -21,6 +22,7 @@ public class BartworksOreMaterialProvider implements IOreMaterialProvider { private final int primaryOreColor; private final String primaryOreName; private IIcon primaryOreIcon; + private ImmutableList containedOres; public BartworksOreMaterialProvider(Werkstoff material) { this.material = material; @@ -48,9 +50,20 @@ public String getLocalizedName() { } @Override - public List getContainedOres(ShortCollection ores) { - return ores.intStream().mapToObj(metaData -> Werkstoff.werkstoffHashMap.get((short) metaData)) - .filter(Objects::nonNull).map(material -> EnumChatFormatting.GRAY + material.getLocalizedName()) - .collect(Collectors.toList()); + public ImmutableList getContainedOres(ShortCollection ores) { + if (containedOres == null) { + List oreNames = new ArrayList<>(); + for (short meta : ores) { + Werkstoff werkstoff = Werkstoff.werkstoffHashMap.get(meta); + if (werkstoff == null) { + oreNames.add(GregTechAPI.sGeneratedMaterials[meta].mLocalizedName); + } else { + oreNames.add(werkstoff.getLocalizedName()); + + } + } + containedOres = ImmutableList.copyOf(oreNames); + } + return containedOres; } } diff --git a/src/main/java/com/sinthoras/visualprospecting/database/veintypes/GregTechOreMaterialProvider.java b/src/main/java/com/sinthoras/visualprospecting/database/veintypes/GregTechOreMaterialProvider.java index b4e574a..8956c20 100644 --- a/src/main/java/com/sinthoras/visualprospecting/database/veintypes/GregTechOreMaterialProvider.java +++ b/src/main/java/com/sinthoras/visualprospecting/database/veintypes/GregTechOreMaterialProvider.java @@ -1,12 +1,12 @@ package com.sinthoras.visualprospecting.database.veintypes; +import java.util.ArrayList; import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; -import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.IIcon; +import com.google.common.collect.ImmutableList; + import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import gregtech.api.GregTechAPI; @@ -20,6 +20,7 @@ public class GregTechOreMaterialProvider implements IOreMaterialProvider { private final int primaryOreColor; private IIcon primaryOreIcon; private final String primaryOreName; + private ImmutableList containedOres; public GregTechOreMaterialProvider(Materials material) { this.material = material; @@ -27,6 +28,13 @@ public GregTechOreMaterialProvider(Materials material) { this.primaryOreName = material.mLocalizedName; } + GregTechOreMaterialProvider() { + material = Materials._NULL; + primaryOreColor = 0; + primaryOreName = ""; + containedOres = ImmutableList.of(); + } + @Override @SideOnly(Side.CLIENT) public IIcon getIcon() { @@ -47,8 +55,16 @@ public String getLocalizedName() { } @Override - public List getContainedOres(ShortCollection ores) { - return ores.intStream().mapToObj(metaData -> GregTechAPI.sGeneratedMaterials[metaData]).filter(Objects::nonNull) - .map(material -> EnumChatFormatting.GRAY + material.mLocalizedName).collect(Collectors.toList()); + public ImmutableList getContainedOres(ShortCollection ores) { + if (containedOres == null) { + List temp = new ArrayList<>(); + for (short meta : ores) { + Materials material = GregTechAPI.sGeneratedMaterials[meta]; + if (material == null) continue; + temp.add(material.mLocalizedName); + } + containedOres = ImmutableList.copyOf(temp); + } + return containedOres; } } diff --git a/src/main/java/com/sinthoras/visualprospecting/database/veintypes/IOreMaterialProvider.java b/src/main/java/com/sinthoras/visualprospecting/database/veintypes/IOreMaterialProvider.java index 173f4c6..29c66d7 100644 --- a/src/main/java/com/sinthoras/visualprospecting/database/veintypes/IOreMaterialProvider.java +++ b/src/main/java/com/sinthoras/visualprospecting/database/veintypes/IOreMaterialProvider.java @@ -1,9 +1,9 @@ package com.sinthoras.visualprospecting.database.veintypes; -import java.util.List; - import net.minecraft.util.IIcon; +import com.google.common.collect.ImmutableList; + import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import it.unimi.dsi.fastutil.shorts.ShortCollection; @@ -17,5 +17,5 @@ public interface IOreMaterialProvider { String getLocalizedName(); - List getContainedOres(ShortCollection ores); + ImmutableList getContainedOres(ShortCollection ores); } diff --git a/src/main/java/com/sinthoras/visualprospecting/database/veintypes/VeinType.java b/src/main/java/com/sinthoras/visualprospecting/database/veintypes/VeinType.java index 9d73ba3..4b3244f 100644 --- a/src/main/java/com/sinthoras/visualprospecting/database/veintypes/VeinType.java +++ b/src/main/java/com/sinthoras/visualprospecting/database/veintypes/VeinType.java @@ -3,12 +3,18 @@ import java.util.ArrayList; import java.util.List; +import javax.annotation.ParametersAreNonnullByDefault; + +import com.google.common.collect.ImmutableList; import com.sinthoras.visualprospecting.Tags; +import gregtech.common.OreMixBuilder; +import it.unimi.dsi.fastutil.shorts.ShortArraySet; import it.unimi.dsi.fastutil.shorts.ShortCollection; import it.unimi.dsi.fastutil.shorts.ShortOpenHashSet; import it.unimi.dsi.fastutil.shorts.ShortSet; +@ParametersAreNonnullByDefault public class VeinType { public static final int veinHeight = 9; @@ -23,25 +29,26 @@ public class VeinType { public final short sporadicOreMeta; public final int minBlockY; public final int maxBlockY; - public final ShortSet oresAsSet = new ShortOpenHashSet(); - private final List containedOres = new ArrayList<>(); + private final ShortSet oresAsSet = new ShortArraySet(); + private final List allowedDims = new ArrayList<>(); private boolean isHighlighted = true; - private String primaryOreName = ""; // Available after VisualProspecting post GT initialization public static final VeinType NO_VEIN = new VeinType( Tags.ORE_MIX_NONE_NAME, - null, + new GregTechOreMaterialProvider(), 0, (short) -1, (short) -1, (short) -1, (short) -1, 0, - 0); + 0, + ""); public VeinType(String name, IOreMaterialProvider oreMaterialProvider, int blockSize, short primaryOreMeta, - short secondaryOreMeta, short inBetweenOreMeta, short sporadicOreMeta, int minBlockY, int maxBlockY) { + short secondaryOreMeta, short inBetweenOreMeta, short sporadicOreMeta, int minBlockY, int maxBlockY, + String dimName) { this.name = name; this.oreMaterialProvider = oreMaterialProvider; this.blockSize = blockSize; @@ -51,18 +58,33 @@ public VeinType(String name, IOreMaterialProvider oreMaterialProvider, int block oresAsSet.add(this.secondaryOreMeta = secondaryOreMeta); oresAsSet.add(this.inBetweenOreMeta = inBetweenOreMeta); oresAsSet.add(this.sporadicOreMeta = sporadicOreMeta); - if (oreMaterialProvider != null) { - containedOres.addAll(oreMaterialProvider.getContainedOres(oresAsSet)); - primaryOreName = oreMaterialProvider.getLocalizedName(); - } + allowedDims.add(dimName); + } + + public VeinType(OreMixBuilder oreMix) { + name = oreMix.oreMixName; + oreMaterialProvider = new GregTechOreMaterialProvider(oreMix.primary); + blockSize = oreMix.size; + oresAsSet.add(primaryOreMeta = (short) oreMix.primary.mMetaItemSubID); + oresAsSet.add(secondaryOreMeta = (short) oreMix.secondary.mMetaItemSubID); + oresAsSet.add(inBetweenOreMeta = (short) oreMix.between.mMetaItemSubID); + oresAsSet.add(sporadicOreMeta = (short) oreMix.sporadic.mMetaItemSubID); + minBlockY = Math.max(0, oreMix.minY - 6); + maxBlockY = Math.min(255, oreMix.maxY - 6); + allowedDims.addAll(oreMix.dimsEnabled.keySet()); } - public boolean matches(ShortCollection foundOres) { - return foundOres.containsAll(oresAsSet); + public boolean containsAllFoundOres(ShortCollection foundOres, String dimName, short specificMeta, int minY) { + return minY >= minBlockY && (primaryOreMeta == specificMeta || secondaryOreMeta == specificMeta) + && (dimName.isEmpty() || allowedDims.contains(dimName)) + && oresAsSet.containsAll(foundOres); } - public boolean matchesWithSpecificPrimaryOrSecondary(ShortCollection foundOres, short specificMeta) { - return (primaryOreMeta == specificMeta || secondaryOreMeta == specificMeta) && foundOres.containsAll(oresAsSet); + public boolean matchesWithSpecificPrimaryOrSecondary(ShortCollection foundOres, String dimName, + short specificMeta) { + return (primaryOreMeta == specificMeta || secondaryOreMeta == specificMeta) + && (dimName.isEmpty() || allowedDims.contains(dimName)) + && foundOres.containsAll(oresAsSet); } public boolean canOverlapIntoNeighborOreChunk() { @@ -80,12 +102,12 @@ public boolean containsOre(short oreMetaData) { || sporadicOreMeta == oreMetaData; } - public List getOreMaterialNames() { - return containedOres; + public ImmutableList getOreMaterialNames() { + return oreMaterialProvider.getContainedOres(oresAsSet); } public String getPrimaryOreName() { - return primaryOreName; + return oreMaterialProvider.getLocalizedName(); } public ShortSet getOresAtLayer(int layerBlockY) { @@ -126,7 +148,7 @@ public boolean isHighlighted() { return isHighlighted; } - public void setNEISearchHeighlight(boolean isHighlighted) { + public void setNEISearchHighlight(boolean isHighlighted) { this.isHighlighted = isHighlighted; } } diff --git a/src/main/java/com/sinthoras/visualprospecting/database/veintypes/VeinTypeCaching.java b/src/main/java/com/sinthoras/visualprospecting/database/veintypes/VeinTypeCaching.java index 855c42f..f90a831 100644 --- a/src/main/java/com/sinthoras/visualprospecting/database/veintypes/VeinTypeCaching.java +++ b/src/main/java/com/sinthoras/visualprospecting/database/veintypes/VeinTypeCaching.java @@ -9,11 +9,8 @@ import java.util.OptionalInt; import java.util.regex.Pattern; -import net.minecraft.client.resources.I18n; import net.minecraft.util.EnumChatFormatting; -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; import com.sinthoras.visualprospecting.Tags; import com.sinthoras.visualprospecting.Utils; @@ -23,23 +20,20 @@ import codechicken.nei.SearchField; import gregtech.api.GregTechAPI; import gregtech.api.enums.Materials; -import gregtech.common.WorldgenGTOreLayer; +import gregtech.api.enums.OreMixes; import it.unimi.dsi.fastutil.objects.Object2ShortMap; import it.unimi.dsi.fastutil.objects.Object2ShortOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import it.unimi.dsi.fastutil.objects.ObjectSet; -import it.unimi.dsi.fastutil.objects.ObjectSets; import it.unimi.dsi.fastutil.shorts.Short2ObjectMap; import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap; public class VeinTypeCaching implements Runnable { - private static final BiMap veinTypeLookupTableForIds = HashBiMap.create(); + private static final Short2ObjectMap veinTypeLookupTableForIds = new Short2ObjectOpenHashMap<>(); private static final Map veinTypeLookupTableForNames = new HashMap<>(); private static final Object2ShortMap veinTypeStorageInfo = new Object2ShortOpenHashMap<>(); - private static final Short2ObjectMap> primaryMetaToVeinType = new Short2ObjectOpenHashMap<>(); public static ObjectSet veinTypes; - private static int longesOreName = 0; // BartWorks initializes veins in FML preInit // GalacticGreg initializes veins in FML postInit, but only copies all base game veins to make them available on all @@ -50,24 +44,8 @@ public void run() { veinTypes = new ObjectOpenHashSet<>(); veinTypes.add(VeinType.NO_VEIN); - for (WorldgenGTOreLayer vein : WorldgenGTOreLayer.sList) { - if (vein.mWorldGenName.equals(Tags.ORE_MIX_NONE_NAME)) { - break; - } - final Materials material = getGregTechMaterial(vein.mPrimaryMeta); - veinTypes.add( - new VeinType( - vein.mWorldGenName, - new GregTechOreMaterialProvider(material), - vein.mSize, - vein.mPrimaryMeta, - vein.mSecondaryMeta, - vein.mBetweenMeta, - vein.mSporadicMeta, - Math.max(0, vein.mMinY - 6), // GregTech ore veins start at layer -1 and the blockY RNG adds - // another -5 - // offset - Math.min(255, vein.mMaxY - 6))); + for (OreMixes mix : OreMixes.values()) { + veinTypes.add(new VeinType(mix.oreMixBuilder)); } for (BWOreLayer vein : BWOreLayer.sList) { @@ -84,7 +62,8 @@ public void run() { (short) vein.mBetweenMeta, (short) vein.mSporadicMeta, Math.max(0, vein.mMinY), - Math.min(255, vein.mMaxY))); + Math.min(255, vein.mMaxY), + vein.getDimName())); } // Assign veinTypeIds for efficient storage @@ -98,33 +77,20 @@ public void run() { veinTypeStorageInfo.putIfAbsent(veinType.name, veinType.veinId); veinTypeLookupTableForIds.put(veinType.veinId, veinType); veinTypeLookupTableForNames.put(veinType.name, veinType); - primaryMetaToVeinType.computeIfAbsent(veinType.primaryOreMeta, k -> new ObjectOpenHashSet<>()) - .add(veinType); } saveVeinTypeStorageInfo(); - - for (VeinType veinType : veinTypes) { - longesOreName = Math.max(longesOreName, veinType.name.length()); - } } private Materials getGregTechMaterial(short metaId) { final Materials material = GregTechAPI.sGeneratedMaterials[metaId]; if (material == null) { // Some materials are not registered in dev when their usage mod is not available. - return Materials.getAll().stream().filter(m -> m.mMetaItemSubID == metaId).findAny().get(); + return Materials.getAll().stream().filter(m -> m.mMetaItemSubID == metaId).findAny() + .orElse(Materials._NULL); } return material; } - public static int getLongesOreNameLength() { - return longesOreName; - } - - public static short getVeinTypeId(VeinType veinType) { - return veinTypeLookupTableForIds.inverse().get(veinType); - } - public static VeinType getVeinType(short veinTypeId) { return veinTypeLookupTableForIds.getOrDefault(veinTypeId, VeinType.NO_VEIN); } @@ -140,11 +106,6 @@ private static File getVeinTypeStorageInfoFile() { return new File(directory, "veintypesLUT"); } - public static ObjectSet getVeinTypesForPrimaryMeta(short primaryMeta) { - - return primaryMetaToVeinType.getOrDefault(primaryMeta, ObjectSets.emptySet()); - } - private static void loadVeinTypeStorageInfo() { veinTypeStorageInfo.putAll(Utils.readFileToMap(getVeinTypeStorageInfoFile())); } @@ -163,14 +124,13 @@ public static void recalculateNEISearch() { if (veinType == VeinType.NO_VEIN) continue; if (isSearchActive && !searchString.isEmpty()) { List searchableStrings = veinType.getOreMaterialNames(); - searchableStrings.add(I18n.format(veinType.name)); final boolean match = searchableStrings.stream() .map(EnumChatFormatting::getTextWithoutFormattingCodes).map(String::toLowerCase) .anyMatch(searchableString -> filterPattern.matcher(searchableString).find()); - veinType.setNEISearchHeighlight(match); + veinType.setNEISearchHighlight(match); } else { - veinType.setNEISearchHeighlight(true); + veinType.setNEISearchHighlight(true); } } } diff --git a/src/main/java/com/sinthoras/visualprospecting/integration/model/locations/OreVeinLocation.java b/src/main/java/com/sinthoras/visualprospecting/integration/model/locations/OreVeinLocation.java index 557ed16..0349a38 100644 --- a/src/main/java/com/sinthoras/visualprospecting/integration/model/locations/OreVeinLocation.java +++ b/src/main/java/com/sinthoras/visualprospecting/integration/model/locations/OreVeinLocation.java @@ -43,7 +43,7 @@ public Waypoint toWaypoint() { 65, oreVeinPosition.getBlockZ(), oreVeinPosition.dimensionId, - I18n.format("visualprospecting.tracked", I18n.format(oreVeinPosition.veinType.name)), + I18n.format("visualprospecting.tracked", oreVeinPosition.veinType.getPrimaryOreName()), getColor()); } diff --git a/src/main/java/com/sinthoras/visualprospecting/integration/voxelmap/VoxelMapEventHandler.java b/src/main/java/com/sinthoras/visualprospecting/integration/voxelmap/VoxelMapEventHandler.java index d11012d..80b4399 100644 --- a/src/main/java/com/sinthoras/visualprospecting/integration/voxelmap/VoxelMapEventHandler.java +++ b/src/main/java/com/sinthoras/visualprospecting/integration/voxelmap/VoxelMapEventHandler.java @@ -5,7 +5,6 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityClientPlayerMP; import net.minecraft.item.ItemStack; -import net.minecraft.util.StatCollector; import com.gtnewhorizons.navigator.api.voxelmap.VoxelMapWaypointManager; import com.sinthoras.visualprospecting.Config; @@ -30,7 +29,7 @@ public void onVeinProspected(ProspectingNotificationEvent.OreVein event) { TreeSet dim = new TreeSet<>(); dim.add(pos.dimensionId); VoxelMapWaypointManager.addVoxelMapWaypoint( - StatCollector.translateToLocal(pos.veinType.name), // name + pos.veinType.getPrimaryOreName(), // name pos.getBlockX(), // X pos.getBlockZ(), // Z getY(), // Y