Skip to content

Commit 708dfb8

Browse files
committed
World Presets
1 parent 5475304 commit 708dfb8

File tree

11 files changed

+579
-12
lines changed

11 files changed

+579
-12
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import dev.xpple.seedmapper.config.Configs;
2020
import dev.xpple.seedmapper.config.MapFeatureAdapter;
2121
import dev.xpple.seedmapper.config.SeedResolutionAdapter;
22+
import dev.xpple.seedmapper.command.commands.WorldPresetCommand;
23+
import dev.xpple.seedmapper.world.WorldPresetManager;
2224
import dev.xpple.seedmapper.render.RenderManager;
2325
import dev.xpple.seedmapper.seedmap.MapFeature;
2426
import dev.xpple.seedmapper.seedmap.SeedMapMinimapManager;
@@ -93,6 +95,7 @@ public void onInitializeClient() {
9395
});
9496

9597
ClientCommandRegistrationCallback.EVENT.register(SeedMapper::registerCommands);
98+
WorldPresetManager.init();
9699
RenderManager.registerEvents();
97100
SeedMapMinimapManager.registerHud();
98101
}
@@ -107,6 +110,7 @@ private static void registerCommands(CommandDispatcher<FabricClientCommandSource
107110
StopTaskCommand.register(dispatcher);
108111
SeedMapCommand.register(dispatcher);
109112
MinimapCommand.register(dispatcher);
113+
WorldPresetCommand.register(dispatcher);
110114
DiscordCommand.register(dispatcher);
111115
SampleCommand.register(dispatcher);
112116
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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.Identifier;
14+
15+
import java.util.Collection;
16+
import java.util.List;
17+
import java.util.concurrent.CompletableFuture;
18+
19+
public class WorldPresetArgument implements ArgumentType<String> {
20+
21+
private static final Collection<String> EXAMPLES = List.of("minecraft:default", "minecraft:superflat");
22+
23+
public static WorldPresetArgument worldPreset() {
24+
return new WorldPresetArgument();
25+
}
26+
27+
public static String getWorldPreset(CommandContext<FabricClientCommandSource> context, String name) {
28+
return context.getArgument(name, String.class);
29+
}
30+
31+
@Override
32+
public String parse(StringReader reader) throws CommandSyntaxException {
33+
Identifier id = Identifier.read(reader);
34+
return id.toString();
35+
}
36+
37+
@Override
38+
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
39+
return SharedSuggestionProvider.suggest(WorldPresetManager.presets().stream()
40+
.map(WorldPreset::id)
41+
.map(Identifier::toString), builder);
42+
}
43+
44+
@Override
45+
public Collection<String> getExamples() {
46+
return EXAMPLES;
47+
}
48+
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.github.cubiomes.CanyonCarverConfig;
44
import com.github.cubiomes.CaveCarverConfig;
55
import com.github.cubiomes.Cubiomes;
6+
import dev.xpple.seedmapper.world.WorldPresetManager;
67
import com.github.cubiomes.Generator;
78
import com.github.cubiomes.OreConfig;
89
import com.github.cubiomes.OreVeinParameters;
@@ -92,7 +93,7 @@ private static int highlightBlock(CustomClientCommandSource source, Pair<Integer
9293
long seed = source.getSeed().getSecond();
9394
try (Arena arena = Arena.ofConfined()) {
9495
MemorySegment generator = Generator.allocate(arena);
95-
Cubiomes.setupGenerator(generator, version, 0);
96+
Cubiomes.setupGenerator(generator, version, WorldPresetManager.activePreset().generatorFlags());
9697
Cubiomes.applySeed(generator, dimension, seed);
9798
MemorySegment surfaceNoise = SurfaceNoise.allocate(arena);
9899
Cubiomes.initSurfaceNoise(surfaceNoise, dimension, seed);

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.github.cubiomes.CanyonCarverConfig;
44
import com.github.cubiomes.Cubiomes;
5+
import dev.xpple.seedmapper.world.WorldPresetManager;
56
import com.github.cubiomes.Generator;
67
import com.github.cubiomes.ItemStack;
78
import com.github.cubiomes.LootTableContext;
@@ -104,7 +105,7 @@ private static int locateBiome(CustomClientCommandSource source, int biome) thro
104105
}
105106
try (Arena arena = Arena.ofConfined()) {
106107
MemorySegment generator = Generator.allocate(arena);
107-
Cubiomes.setupGenerator(generator, source.getVersion(), 0);
108+
Cubiomes.setupGenerator(generator, source.getVersion(), WorldPresetManager.activePreset().generatorFlags());
108109
Cubiomes.applySeed(generator, dimension, source.getSeed().getSecond());
109110

110111
BlockPos center = BlockPos.containing(source.getPosition());
@@ -141,7 +142,7 @@ private static int locateStructure(CustomClientCommandSource source, StructureAn
141142
long seed = source.getSeed().getSecond();
142143

143144
MemorySegment generator = Generator.allocate(arena);
144-
Cubiomes.setupGenerator(generator, version, 0);
145+
Cubiomes.setupGenerator(generator, version, WorldPresetManager.activePreset().generatorFlags());
145146
Cubiomes.applySeed(generator, dimension, seed);
146147

147148
// currently only used for end cities
@@ -229,7 +230,7 @@ private static int locateStronghold(CustomClientCommandSource source) throws Com
229230

230231
BlockPos position = BlockPos.containing(source.getPosition());
231232

232-
TwoDTree tree = SeedMapScreen.strongholdDataCache.computeIfAbsent(new WorldIdentifier(seed, dimension, version), _ -> calculateStrongholds(seed, dimension, version));
233+
TwoDTree tree = SeedMapScreen.strongholdDataCache.computeIfAbsent(new WorldIdentifier(seed, dimension, version, dev.xpple.seedmapper.world.WorldPresetManager.activePreset().cacheKey()), _ -> calculateStrongholds(seed, dimension, version));
233234

234235
BlockPos pos = tree.nearestTo(position.atY(0));
235236

@@ -243,7 +244,7 @@ public static TwoDTree calculateStrongholds(long seed, int dimension, int versio
243244
MemorySegment strongholdIter = StrongholdIter.allocate(arena);
244245
Cubiomes.initFirstStronghold(arena, strongholdIter, version, seed);
245246
MemorySegment generator = Generator.allocate(arena);
246-
Cubiomes.setupGenerator(generator, version, 0);
247+
Cubiomes.setupGenerator(generator, version, WorldPresetManager.activePreset().generatorFlags());
247248
Cubiomes.applySeed(generator, dimension, seed);
248249

249250
final int count = version <= Cubiomes.MC_1_8() ? 3 : 128;
@@ -289,7 +290,7 @@ private static int locateLoot(CustomClientCommandSource source, int amount, Ench
289290

290291
try (Arena arena = Arena.ofConfined()) {
291292
MemorySegment generator = Generator.allocate(arena);
292-
Cubiomes.setupGenerator(generator, version, 0);
293+
Cubiomes.setupGenerator(generator, version, WorldPresetManager.activePreset().generatorFlags());
293294
Cubiomes.applySeed(generator, dimension, seed);
294295

295296
// currently only used for end cities
@@ -542,8 +543,8 @@ static ToIntBiFunction<Integer, Integer> getCarverBiomeFunction(Arena arena, lon
542543
if (version > Cubiomes.MC_1_17_1()) {
543544
return (_, _) -> -1;
544545
}
545-
MemorySegment generator = Generator.allocate(arena);
546-
Cubiomes.setupGenerator(generator, version, 0);
546+
MemorySegment generator = Generator.allocate(arena);
547+
Cubiomes.setupGenerator(generator, version, WorldPresetManager.activePreset().generatorFlags());
547548
Cubiomes.applySeed(generator, dimension, seed);
548549
return (chunkX, chunkZ) -> Cubiomes.getBiomeAt(generator, 4, chunkX << 2, 0, chunkZ << 2);
549550
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package dev.xpple.seedmapper.command.commands;
2+
3+
import com.mojang.brigadier.Command;
4+
import com.mojang.brigadier.CommandDispatcher;
5+
import dev.xpple.seedmapper.command.CustomClientCommandSource;
6+
import dev.xpple.seedmapper.command.arguments.WorldPresetArgument;
7+
import dev.xpple.seedmapper.config.Configs;
8+
import dev.xpple.seedmapper.world.WorldPreset;
9+
import dev.xpple.seedmapper.world.WorldPresetManager;
10+
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
11+
import net.minecraft.ChatFormatting;
12+
import net.minecraft.network.chat.Component;
13+
import net.minecraft.network.chat.MutableComponent;
14+
15+
import java.util.Comparator;
16+
import java.util.List;
17+
18+
import static dev.xpple.seedmapper.command.arguments.WorldPresetArgument.*;
19+
import static dev.xpple.seedmapper.util.ChatBuilder.accent;
20+
import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;
21+
import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument;
22+
23+
public class WorldPresetCommand {
24+
25+
public static void register(CommandDispatcher<FabricClientCommandSource> dispatcher) {
26+
var root = literal("sm:preset");
27+
root.executes(ctx -> listPresets(CustomClientCommandSource.of(ctx.getSource())));
28+
root.then(literal("list").executes(ctx -> listPresets(CustomClientCommandSource.of(ctx.getSource()))));
29+
root.then(literal("set").then(argument("preset", worldPreset()).executes(ctx -> setPreset(CustomClientCommandSource.of(ctx.getSource()), getWorldPreset(ctx, "preset")))));
30+
dispatcher.register(root);
31+
}
32+
33+
private static int listPresets(CustomClientCommandSource source) {
34+
WorldPreset active = WorldPresetManager.activePreset();
35+
List<WorldPreset> presets = WorldPresetManager.presets().stream()
36+
.sorted(Comparator.comparing(preset -> preset.id().toString()))
37+
.toList();
38+
presets.forEach(preset -> {
39+
MutableComponent clickableId = Component.literal(preset.id().toString())
40+
.withStyle(style -> style
41+
.withColor(ChatFormatting.AQUA)
42+
.withClickEvent(new net.minecraft.network.chat.ClickEvent.SuggestCommand("/sm:preset set " + preset.id())));
43+
MutableComponent line = Component.literal("")
44+
.append(clickableId)
45+
.append(Component.literal(" - ").withStyle(ChatFormatting.DARK_GRAY))
46+
.append(preset.displayName());
47+
if (preset.id().equals(active.id())) {
48+
line = Component.literal("* ").withStyle(ChatFormatting.GREEN).append(line);
49+
}
50+
source.sendFeedback(line);
51+
});
52+
return Command.SINGLE_SUCCESS;
53+
}
54+
55+
private static int setPreset(CustomClientCommandSource source, String presetId) {
56+
if (!WorldPresetManager.selectPreset(presetId)) {
57+
source.sendError(Component.translatable("command.worldpreset.unknown", presetId));
58+
return 0;
59+
}
60+
Configs.WorldPresetId = presetId;
61+
Configs.save();
62+
WorldPreset preset = WorldPresetManager.activePreset();
63+
source.sendFeedback(Component.translatable("command.worldpreset.set", accent(preset.displayName().getString())));
64+
// also send a literal confirmation (fallback if translation missing) and refresh minimap
65+
source.sendFeedback(Component.literal("Preset set: " + preset.displayName().getString()));
66+
try {
67+
dev.xpple.seedmapper.seedmap.SeedMapMinimapManager.refreshIfOpen();
68+
} catch (Throwable ignored) {}
69+
try {
70+
dev.xpple.seedmapper.seedmap.SeedMapScreen.clearCachesForPresetChange();
71+
} catch (Throwable ignored) {}
72+
try {
73+
dev.xpple.seedmapper.seedmap.SeedMapMinimapManager.debugNotifyPreset();
74+
} catch (Throwable ignored) {}
75+
return Command.SINGLE_SUCCESS;
76+
}
77+
}

src/main/java/dev/xpple/seedmapper/config/Configs.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,26 @@ public static Component listToggledFeatures() {
140140
public static Component getDevModeComment() {
141141
return Component.translatable("config.devMode.comment");
142142
}
143+
144+
@Config(setter = @Config.Setter("setWorldPresetId"))
145+
public static String WorldPresetId = "minecraft:default";
146+
147+
private static void setWorldPresetId(String presetId) {
148+
WorldPresetId = presetId;
149+
try {
150+
dev.xpple.seedmapper.world.WorldPresetManager.selectPreset(presetId);
151+
// refresh minimap if open so it picks up new preset
152+
try {
153+
dev.xpple.seedmapper.seedmap.SeedMapMinimapManager.refreshIfOpen();
154+
} catch (Throwable ignored) {
155+
}
156+
try {
157+
dev.xpple.seedmapper.seedmap.SeedMapScreen.clearCachesForPresetChange();
158+
} catch (Throwable ignored) {}
159+
} catch (Throwable ignored) {
160+
}
161+
}
162+
163+
@Config
164+
public static String SingleBiome = "minecraft:plains";
143165
}

src/main/java/dev/xpple/seedmapper/seedmap/SeedMapScreen.java

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.github.cubiomes.CanyonCarverConfig;
44
import com.github.cubiomes.Cubiomes;
5+
import dev.xpple.seedmapper.world.WorldPresetManager;
56
import com.github.cubiomes.EnchantInstance;
67
import com.github.cubiomes.Generator;
78
import com.github.cubiomes.ItemStack;
@@ -191,6 +192,16 @@ public class SeedMapScreen extends Screen {
191192
private static final Object2ObjectMap<WorldIdentifier, Object2ObjectMap<TilePos, BitSet>> slimeChunkDataCache = new Object2ObjectOpenHashMap<>();
192193
private static final Object2ObjectMap<WorldIdentifier, BlockPos> spawnDataCache = new Object2ObjectOpenHashMap<>();
193194

195+
public static void clearCachesForPresetChange() {
196+
biomeDataCache.clear();
197+
structureDataCache.clear();
198+
strongholdDataCache.clear();
199+
oreVeinDataCache.clear();
200+
canyonDataCache.clear();
201+
slimeChunkDataCache.clear();
202+
spawnDataCache.clear();
203+
}
204+
194205
private final SeedMapExecutor seedMapExecutor = new SeedMapExecutor();
195206

196207
private final Arena arena = Arena.ofShared();
@@ -262,10 +273,10 @@ public SeedMapScreen(long seed, int dimension, int version, BlockPos playerPos,
262273
this.seed = seed;
263274
this.dimension = dimension;
264275
this.version = version;
265-
this.worldIdentifier = new WorldIdentifier(this.seed, this.dimension, this.version);
276+
this.worldIdentifier = new WorldIdentifier(this.seed, this.dimension, this.version, dev.xpple.seedmapper.world.WorldPresetManager.activePreset().cacheKey());
266277

267278
this.biomeGenerator = Generator.allocate(this.arena);
268-
Cubiomes.setupGenerator(this.biomeGenerator, this.version, 0);
279+
Cubiomes.setupGenerator(this.biomeGenerator, this.version, WorldPresetManager.activePreset().generatorFlags());
269280
Cubiomes.applySeed(this.biomeGenerator, this.dimension, this.seed);
270281

271282
this.structureGenerator = Generator.allocate(this.arena);
@@ -349,6 +360,12 @@ protected void init() {
349360
this.createWaypointNameField();
350361

351362
this.enchantmentsRegistry = this.minecraft.player.registryAccess().lookupOrThrow(Registries.ENCHANTMENT);
363+
if (dev.xpple.seedmapper.config.Configs.DevMode) {
364+
try {
365+
var preset = dev.xpple.seedmapper.world.WorldPresetManager.activePreset();
366+
this.minecraft.gui.getChat().addMessage(net.minecraft.network.chat.Component.literal("SeedMap using preset: " + preset.id() + " flags=" + preset.generatorFlags()));
367+
} catch (Throwable ignored) {}
368+
}
352369
}
353370

354371
@Override
@@ -487,7 +504,15 @@ private int[] calculateBiomeData(TilePos tilePos) {
487504
Range.y(range, 63 / Range.scale(range)); // sea level
488505
Range.sy(range, 1);
489506

490-
long cacheSize = Cubiomes.getMinCacheSize(this.biomeGenerator, Range.scale(range), Range.sx(range), Range.sy(range), Range.sz(range));
507+
long cacheSize = Cubiomes.getMinCacheSize(this.biomeGenerator, Range.scale(range), Range.sx(range), Range.sy(range), Range.sz(range));
508+
// if active preset is single-biome, just fill with forced biome id
509+
var preset = dev.xpple.seedmapper.world.WorldPresetManager.activePreset();
510+
if (preset.isSingleBiome()) {
511+
int forced = dev.xpple.seedmapper.world.WorldPresetManager.biomeIdentifierToCubiomesId(preset.forcedBiome());
512+
int[] arr = new int[(int) cacheSize];
513+
java.util.Arrays.fill(arr, forced);
514+
return arr;
515+
}
491516
MemorySegment biomeIds = tempArena.allocate(Cubiomes.C_INT, cacheSize);
492517
if (Cubiomes.genBiomes(this.biomeGenerator, biomeIds, range) == 0) {
493518
return biomeIds.toArray(Cubiomes.C_INT);

0 commit comments

Comments
 (0)