Skip to content

Commit f4884f3

Browse files
committed
Added World Presets, Fixed End City Icons
1 parent facb495 commit f4884f3

24 files changed

+853
-150
lines changed

README.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,20 @@ Original Repo: https://github.com/xpple/SeedMapper/
66

77
This project is a friendly, independent fork of Seedmapper. I have not proposed any improvements or features to the upstream but I am welcome to them incorporating my changes. I will sporatically maintain this project and re-base/sync with the upstream project.
88

9-
## Compiling
9+
## Compiling & Running
1010

1111
Original instructions do not apply. Clone and compile as normal. I have included the Cubiome and JExtract files already.
1212

13+
As for running the mod, the main difference between this mod and upstream is that it will NOT function under Java 23, it must be on Java 21 with the enable preview flag. See below.
14+
1315
## Improvements
1416

1517
### Java 21
1618
Project now builds against Java 21 LTS, however, Minecraft/Fabric must have the flag ```--enable-preview``` added to the Java arguments.
1719

1820
This tells the JVM to accept preview bytecode and APIs. Functionally nothing else changes in Minecraft, Fabric or any of the other mods you have installed.
1921

22+
2023
![Flag](https://i.imgur.com/rOsP2H0.png)
2124

2225
### Zoom
@@ -29,6 +32,13 @@ Around your player icon in the SeedMap there will be a little arrow showing you
2932

3033
![Arrow](https://i.imgur.com/pkodE8d.png)
3134

35+
### World Presets
36+
37+
If the server you're on uses anything other than the default world preset (Amplified, Superflat, Large Biomes, Single Biome) this will greatly change the world generation. Change the preset to match the server in order to produce an accurate seedmap.
38+
39+
- /sm:preset list — show available presets
40+
- /sm:preset set <id> — set SeedMapper’s preset
41+
3242
### Seed Map Minimap
3343

3444
- Run ``` /sm:minimap ``` to open a live SeedMap minimap in the top-left corner of the HUD.
@@ -37,22 +47,21 @@ Around your player icon in the SeedMap there will be a little arrow showing you
3747
- The minimap:
3848
- Renders the same features you selected on the main map.
3949
- Tracks your current position in real time.
40-
- Ideal for overlaying over Xaeros Minimap (See Screenshots).
50+
- Ideal for overlaying over Xaeros Minimap (Default settings suits size 152).
4151

4252
- Position & size:
4353
- Move it horizontally with ``` /sm:config SeedMapMinimapOffsetX ```
4454
- Move it vertically with ``` /sm:config SeedMapMinimapOffsetY ```
4555
- Change width with ``` /sm:config SeedMapMinimapWidth ```
4656
- Change height with ``` /sm:config SeedMapMinimapHeight ```
47-
- Can be resized to cover other minimaps if needed.
4857

4958
- Display options:
5059
- Rotate the map with the player’s facing using ``` /sm:config SeedMapMinimapRotateWithPlayer ```
5160
- Adjust zoom independently from the main map via ``` /sm:config SeedMapMinimapPixelsPerBiome ```
5261
- Scale feature icons with ``` /sm:config SeedMapMinimapIconScale ```
5362
- Fine tune the background opacity with ``` /sm:config SeedMapMinimapOpacity ``` without affecting icon readability.
5463

55-
![Map1](https://i.imgur.com/gIGgOB7.png) ![Map2](https://i.imgur.com/rNwiWhy.png)
64+
![Map1](https://i.imgur.com/w5U6Aux.png) ![Map2](https://i.imgur.com/MXqXY5n.png)
5665

5766
### Memory Handling
5867
Added a config option ```/sm:config ClearSeedMapCachesOnClose``` to clear tiles, per‑world locations and any other relevant caches. When enabled, this prevents FPS dips from garbage collection on large caches after zooming out far and then closing the map. Opening the map again will result it in being loaded like its the first time, at smaller zoom levels this isn't a problem.
@@ -65,9 +74,9 @@ When hovering over location icons in the SeedMap it will display text telling yo
6574
### Added Elytra/End Ship Locations
6675
~~Can now find Elytra via locating End Ships with the locate command ```/sm:locate feature end_city_ship``` or simply selecting the Elytra icon in the SeedMap~~
6776

68-
This has now been implemented by upstream. They have unified both End City Ships and End Cities together. I have utilised their change but kept my original Elytra icon, because we aren't going to the ships for anything else are we? The command ```/sm:locate feature end_city_ship``` still applies.
77+
This has now been implemented by upstream. They have unified both End City Ships and End Cities together. I have accepted this change but altered it to retain my Elytra icon, this allows you to explicitly look only for Elytras. The command ```/sm:locate feature end_city_ship``` also still applies.
6978

70-
![Elytra](https://i.imgur.com/Zr2rBcN.png)
79+
![Elytra](https://i.imgur.com/fFxoFX4.png)
7180

7281
### Export SeedMap
7382
- Added **Export JSON** button on the top right of the SeedMap screen which will export all selected locations to a JSON

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ org.gradle.jvmargs=-Xmx1G
33
org.gradle.parallel=true
44

55
# Mod Properties
6-
mod_version=2.17.0
6+
mod_version=CevAPI-2.17.0
77
maven_group=dev.xpple
8-
archives_base_name=seedmapper
8+
archives_base_name=SeedMapper
99

1010
# Minecraft properties
1111
minecraft_version=1.21.10

src/main/java/dev/xpple/seedmapper/SeedMapper.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@
1717
import dev.xpple.seedmapper.command.commands.SeedMapCommand;
1818
import dev.xpple.seedmapper.command.commands.SourceCommand;
1919
import dev.xpple.seedmapper.command.commands.StopTaskCommand;
20+
import dev.xpple.seedmapper.command.commands.WorldPresetCommand;
2021
import dev.xpple.seedmapper.config.Configs;
2122
import dev.xpple.seedmapper.config.MapFeatureAdapter;
2223
import dev.xpple.seedmapper.config.SeedResolutionAdapter;
24+
2325
import dev.xpple.seedmapper.render.RenderManager;
2426
import dev.xpple.seedmapper.seedmap.MapFeature;
2527
import dev.xpple.seedmapper.seedmap.SeedMapMinimapManager;
2628
import dev.xpple.seedmapper.util.SeedDatabaseHelper;
29+
import dev.xpple.seedmapper.world.WorldPresetManager;
2730
import dev.xpple.simplewaypoints.api.SimpleWaypointsAPI;
2831
import net.fabricmc.api.ClientModInitializer;
2932
import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager;
@@ -78,6 +81,8 @@ public void onInitializeClient() {
7881
})
7982
.build();
8083

84+
WorldPresetManager.init();
85+
8186
SimpleWaypointsAPI.getInstance().registerCommandAlias("sm:waypoint");
8287

8388
SeedDatabaseHelper.fetchSeeds();
@@ -111,5 +116,6 @@ private static void registerCommands(CommandDispatcher<FabricClientCommandSource
111116
MinimapCommand.register(dispatcher);
112117
DiscordCommand.register(dispatcher);
113118
SampleCommand.register(dispatcher);
119+
WorldPresetCommand.register(dispatcher);
114120
}
115121
}

src/main/java/dev/xpple/seedmapper/command/CustomClientCommandSource.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import dev.xpple.seedmapper.command.arguments.VersionArgument;
99
import dev.xpple.seedmapper.config.Configs;
1010
import dev.xpple.seedmapper.util.SeedDatabaseHelper;
11+
import dev.xpple.seedmapper.world.WorldPreset;
12+
import dev.xpple.seedmapper.world.WorldPresetManager;
1113
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
1214
import net.minecraft.SharedConstants;
1315
import net.minecraft.client.Minecraft;
@@ -156,4 +158,15 @@ public int getVersion() throws CommandSyntaxException {
156158
}
157159
return VersionArgument.version().parse(new StringReader(SharedConstants.getCurrentVersion().name()));
158160
}
161+
162+
public WorldPreset getWorldPreset() {
163+
Object presetMeta = this.getMeta("world_preset");
164+
if (presetMeta instanceof String presetId) {
165+
WorldPreset preset = WorldPresetManager.findPreset(presetId);
166+
if (preset != null) {
167+
return preset;
168+
}
169+
}
170+
return WorldPresetManager.activePreset();
171+
}
159172
}

src/main/java/dev/xpple/seedmapper/command/arguments/DimensionArgument.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ public static int getDimension(CommandContext<FabricClientCommandSource> context
3535
return context.getArgument(name, Integer.class);
3636
}
3737

38+
public static Integer resolveDimensionId(String name) {
39+
return DIMENSIONS.get(name);
40+
}
41+
3842
@Override
3943
public Integer parse(StringReader reader) throws CommandSyntaxException {
4044
int cursor = reader.getCursor();

src/main/java/dev/xpple/seedmapper/command/arguments/VersionArgument.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ public static int getVersion(CommandContext<FabricClientCommandSource> context,
142142
return context.getArgument(name, Integer.class);
143143
}
144144

145+
public static Integer resolveVersionId(String value) {
146+
return VERSIONS.get(value);
147+
}
148+
145149
@Override
146150
public Integer parse(StringReader reader) throws CommandSyntaxException {
147151
int cursor = reader.getCursor();
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package dev.xpple.seedmapper.command.arguments;
2+
3+
import com.mojang.brigadier.StringReader;
4+
import com.mojang.brigadier.arguments.ArgumentType;
5+
import com.mojang.brigadier.context.CommandContext;
6+
import com.mojang.brigadier.exceptions.CommandSyntaxException;
7+
import com.mojang.brigadier.suggestion.Suggestions;
8+
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
9+
import dev.xpple.seedmapper.world.WorldPreset;
10+
import dev.xpple.seedmapper.world.WorldPresetManager;
11+
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
12+
import net.minecraft.commands.SharedSuggestionProvider;
13+
import net.minecraft.resources.ResourceLocation;
14+
15+
import java.util.Collection;
16+
import java.util.List;
17+
import java.util.Locale;
18+
import java.util.concurrent.CompletableFuture;
19+
20+
public class WorldPresetArgument implements ArgumentType<String> {
21+
22+
private static final Collection<String> EXAMPLES = List.of("minecraft:default", "minecraft:superflat");
23+
24+
public static WorldPresetArgument worldPreset() {
25+
return new WorldPresetArgument();
26+
}
27+
28+
public static String getWorldPreset(CommandContext<FabricClientCommandSource> context, String name) {
29+
return context.getArgument(name, String.class);
30+
}
31+
32+
@Override
33+
public String parse(StringReader reader) throws CommandSyntaxException {
34+
ResourceLocation id = ResourceLocation.read(reader);
35+
return id.toString();
36+
}
37+
38+
@Override
39+
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
40+
return SharedSuggestionProvider.suggest(WorldPresetManager.presets().stream()
41+
.map(WorldPreset::id)
42+
.map(ResourceLocation::toString), builder);
43+
}
44+
45+
@Override
46+
public Collection<String> getExamples() {
47+
return EXAMPLES;
48+
}
49+
}

src/main/java/dev/xpple/seedmapper/command/commands/HighlightCommand.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import dev.xpple.seedmapper.render.esp.EspStyle;
2222
import dev.xpple.seedmapper.util.ComponentUtils;
2323
import dev.xpple.seedmapper.util.SpiralLoop;
24+
import dev.xpple.seedmapper.world.WorldPreset;
2425
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
2526
import net.minecraft.core.BlockPos;
2627
import net.minecraft.network.chat.Component;
@@ -91,9 +92,10 @@ private static int highlightBlock(CustomClientCommandSource source, Pair<Integer
9192
int version = source.getVersion();
9293
int dimension = source.getDimension();
9394
long seed = source.getSeed().getSecond();
95+
WorldPreset preset = source.getWorldPreset();
9496
try (Arena arena = Arena.ofConfined()) {
9597
MemorySegment generator = Generator.allocate(arena);
96-
Cubiomes.setupGenerator(generator, version, 0);
98+
Cubiomes.setupGenerator(generator, version, preset.generatorFlags());
9799
Cubiomes.applySeed(generator, dimension, seed);
98100
MemorySegment surfaceNoise = SurfaceNoise.allocate(arena);
99101
Cubiomes.initSurfaceNoise(surfaceNoise, dimension, seed);
@@ -301,7 +303,7 @@ private static int highlightCanyon(CustomClientCommandSource source, int canyonC
301303
if (CanyonCarverConfig.dim(ccc) != dimension) {
302304
throw CommandExceptions.INVALID_DIMENSION_EXCEPTION.create();
303305
}
304-
var biomeFunction = LocateCommand.getCarverBiomeFunction(arena, seed, dimension, version);
306+
var biomeFunction = LocateCommand.getCarverBiomeFunction(arena, seed, dimension, version, source.getWorldPreset());
305307
return highlightCarver(source, chunkRange, Configs.CanyonESP, (chunkX, chunkZ) -> {
306308
int biome = biomeFunction.applyAsInt(chunkX, chunkZ);
307309
if (Cubiomes.isViableCanyonBiome(canyonCarver, biome) == 0) {
@@ -329,7 +331,7 @@ private static int highlightCave(CustomClientCommandSource source, int caveCarve
329331
if (CaveCarverConfig.dim(ccc) != dimension) {
330332
throw CommandExceptions.INVALID_DIMENSION_EXCEPTION.create();
331333
}
332-
var biomeFunction = LocateCommand.getCarverBiomeFunction(arena, seed, dimension, version);
334+
var biomeFunction = LocateCommand.getCarverBiomeFunction(arena, seed, dimension, version, source.getWorldPreset());
333335
return highlightCarver(source, chunkRange, Configs.CaveESP, (chunkX, chunkZ) -> {
334336
int biome = biomeFunction.applyAsInt(chunkX, chunkZ);
335337
if (Cubiomes.isViableCaveBiome(caveCarver, biome) == 0) {

src/main/java/dev/xpple/seedmapper/command/commands/LocateCommand.java

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import dev.xpple.seedmapper.util.SpiralSpliterator;
3030
import dev.xpple.seedmapper.util.TwoDTree;
3131
import dev.xpple.seedmapper.util.WorldIdentifier;
32+
import dev.xpple.seedmapper.world.WorldPreset;
3233
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
3334
import net.minecraft.core.BlockPos;
3435
import net.minecraft.core.SectionPos;
@@ -104,8 +105,9 @@ private static int locateBiome(CustomClientCommandSource source, int biome) thro
104105
throw CommandExceptions.INVALID_DIMENSION_EXCEPTION.create();
105106
}
106107
try (Arena arena = Arena.ofConfined()) {
108+
WorldPreset preset = source.getWorldPreset();
107109
MemorySegment generator = Generator.allocate(arena);
108-
Cubiomes.setupGenerator(generator, source.getVersion(), 0);
110+
Cubiomes.setupGenerator(generator, source.getVersion(), preset.generatorFlags());
109111
Cubiomes.applySeed(generator, dimension, source.getSeed().getSecond());
110112

111113
BlockPos center = BlockPos.containing(source.getPosition());
@@ -130,6 +132,7 @@ private static int locateStructure(CustomClientCommandSource source, StructureAn
130132
try (Arena arena = Arena.ofConfined()) {
131133
int version = source.getVersion();
132134
int dimension = source.getDimension();
135+
WorldPreset preset = source.getWorldPreset();
133136
int structure = structureAndPredicate.structure();
134137
MemorySegment structureConfig = StructureConfig.allocate(arena);
135138
int config = Cubiomes.getStructureConfig(structure, version, structureConfig);
@@ -142,7 +145,7 @@ private static int locateStructure(CustomClientCommandSource source, StructureAn
142145
long seed = source.getSeed().getSecond();
143146

144147
MemorySegment generator = Generator.allocate(arena);
145-
Cubiomes.setupGenerator(generator, version, 0);
148+
Cubiomes.setupGenerator(generator, version, preset.generatorFlags());
146149
Cubiomes.applySeed(generator, dimension, seed);
147150

148151
// currently only used for end cities
@@ -225,26 +228,26 @@ private static int locateStronghold(CustomClientCommandSource source) throws Com
225228
throw CommandExceptions.INVALID_DIMENSION_EXCEPTION.create();
226229
}
227230
int version = source.getVersion();
228-
231+
WorldPreset preset = source.getWorldPreset();
229232
long seed = source.getSeed().getSecond();
230233

231234
BlockPos position = BlockPos.containing(source.getPosition());
232235

233-
TwoDTree tree = SeedMapScreen.strongholdDataCache.computeIfAbsent(new WorldIdentifier(seed, dimension, version), ignored -> calculateStrongholds(seed, dimension, version));
236+
TwoDTree tree = SeedMapScreen.strongholdDataCache.computeIfAbsent(new WorldIdentifier(seed, dimension, version, preset.cacheKey()), ignored -> calculateStrongholds(seed, dimension, version, preset));
234237

235238
BlockPos pos = tree.nearestTo(position.atY(0));
236239

237240
source.getClient().schedule(() -> source.sendFeedback(Component.translatable("command.locate.feature.stronghold.success", ComponentUtils.formatXZ(pos.getX(), pos.getZ()))));
238241
return Command.SINGLE_SUCCESS;
239242
}
240243

241-
public static TwoDTree calculateStrongholds(long seed, int dimension, int version) {
244+
public static TwoDTree calculateStrongholds(long seed, int dimension, int version, WorldPreset preset) {
242245
TwoDTree tree = new TwoDTree();
243246
try (Arena arena = Arena.ofConfined()) {
244247
MemorySegment strongholdIter = StrongholdIter.allocate(arena);
245248
Cubiomes.initFirstStronghold(arena, strongholdIter, version, seed);
246249
MemorySegment generator = Generator.allocate(arena);
247-
Cubiomes.setupGenerator(generator, version, 0);
250+
Cubiomes.setupGenerator(generator, version, preset.generatorFlags());
248251
Cubiomes.applySeed(generator, dimension, seed);
249252

250253
final int count = version <= Cubiomes.MC_1_8() ? 3 : 128;
@@ -287,10 +290,11 @@ private static int locateLoot(CustomClientCommandSource source, int amount, Ench
287290
}
288291
int dimension = source.getDimension();
289292
long seed = source.getSeed().getSecond();
293+
WorldPreset preset = source.getWorldPreset();
290294

291295
try (Arena arena = Arena.ofConfined()) {
292296
MemorySegment generator = Generator.allocate(arena);
293-
Cubiomes.setupGenerator(generator, version, 0);
297+
Cubiomes.setupGenerator(generator, version, preset.generatorFlags());
294298
Cubiomes.applySeed(generator, dimension, seed);
295299

296300
// currently only used for end cities
@@ -455,8 +459,9 @@ record StructureIterationState(MemorySegment structureConfig, StructureChecks.Ge
455459

456460
private static int locateSpawn(CustomClientCommandSource source) throws CommandSyntaxException {
457461
try (Arena arena = Arena.ofConfined()) {
462+
WorldPreset preset = source.getWorldPreset();
458463
MemorySegment generator = Generator.allocate(arena);
459-
Cubiomes.setupGenerator(generator, source.getVersion(), 0);
464+
Cubiomes.setupGenerator(generator, source.getVersion(), preset.generatorFlags());
460465
Cubiomes.applySeed(generator, source.getDimension(), source.getSeed().getSecond());
461466
MemorySegment pos = Cubiomes.getSpawn(arena, generator);
462467

@@ -516,9 +521,10 @@ private static int locateCanyon(CustomClientCommandSource source) throws Command
516521
if (version < Cubiomes.MC_1_13()) {
517522
throw CommandExceptions.CANYON_WRONG_VERSION_EXCEPTION.create();
518523
}
524+
WorldPreset preset = source.getWorldPreset();
519525
ChunkPos center = new ChunkPos(BlockPos.containing(source.getPosition()));
520526
try (Arena arena = Arena.ofConfined()) {
521-
ToIntBiFunction<Integer, Integer> biomeFunction = getCarverBiomeFunction(arena, seed, dimension, version);
527+
ToIntBiFunction<Integer, Integer> biomeFunction = getCarverBiomeFunction(arena, seed, dimension, version, preset);
522528
MemorySegment ccc = CanyonCarverConfig.allocate(arena);
523529
MemorySegment rnd = NativeAccess.allocate(arena, Cubiomes.C_LONG_LONG, 1);
524530
SpiralLoop.Coordinate pos = SpiralLoop.spiral(center.x, center.z, 6400, (chunkX, chunkZ) -> {
@@ -545,12 +551,12 @@ private static int locateCanyon(CustomClientCommandSource source) throws Command
545551
}
546552
}
547553

548-
static ToIntBiFunction<Integer, Integer> getCarverBiomeFunction(Arena arena, long seed, int dimension, int version) {
554+
static ToIntBiFunction<Integer, Integer> getCarverBiomeFunction(Arena arena, long seed, int dimension, int version, WorldPreset preset) {
549555
if (version > Cubiomes.MC_1_17_1()) {
550556
return (chunkX, chunkZ) -> -1;
551557
}
552558
MemorySegment generator = Generator.allocate(arena);
553-
Cubiomes.setupGenerator(generator, version, 0);
559+
Cubiomes.setupGenerator(generator, version, preset.generatorFlags());
554560
Cubiomes.applySeed(generator, dimension, seed);
555561
return (chunkX, chunkZ) -> Cubiomes.getBiomeAt(generator, 4, chunkX << 2, 0, chunkZ << 2);
556562
}

0 commit comments

Comments
 (0)