Skip to content

Commit dc273dd

Browse files
committed
Merge upstream/master with curated conflict resolution
2 parents 307b57c + eb1feeb commit dc273dd

20 files changed

Lines changed: 316 additions & 23 deletions

File tree

buildSrc/src/main/java/dev/xpple/seedmapper/buildscript/CreateJavaBindingsTask.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
import org.apache.tools.ant.taskdefs.condition.Os;
44
import org.gradle.api.tasks.Exec;
55

6+
import java.io.File;
7+
import java.util.Arrays;
8+
import java.util.stream.Collectors;
9+
610
public abstract class CreateJavaBindingsTask extends Exec {
711

812
private static final String EXTENSION = Os.isFamily(Os.FAMILY_WINDOWS) ? ".bat" : "";
@@ -13,6 +17,20 @@ public abstract class CreateJavaBindingsTask extends Exec {
1317

1418
this.setWorkingDir(this.getProject().getRootDir());
1519
this.setStandardOutput(System.out);
20+
// Avoid inheriting MSYS/MinGW include env vars that conflict with jextract's clang on Windows.
21+
this.environment("INCLUDE", "");
22+
this.environment("CPATH", "");
23+
this.environment("C_INCLUDE_PATH", "");
24+
this.environment("CPLUS_INCLUDE_PATH", "");
25+
this.environment("LIBRARY_PATH", "");
26+
String path = System.getenv("PATH");
27+
if (path != null && !path.isBlank()) {
28+
String separator = File.pathSeparator;
29+
String sanitizedPath = Arrays.stream(path.split(java.util.regex.Pattern.quote(separator)))
30+
.filter(entry -> !entry.toLowerCase().contains("msys64"))
31+
.collect(Collectors.joining(separator));
32+
this.environment("PATH", sanitizedPath);
33+
}
1634
this.commandLine(
1735
"./jextract/build/jextract/bin/jextract" + EXTENSION,
1836
"--include-dir", "src/main/c/cubiomes/jextract-compat",

changelog.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
## Changelog
2-
- Re-enabled Baritone integration.
3-
- Fixed carver highlighting on 1.17.1 and below.
2+
- Made block colors configurable (`/sm:config BlockColors`).
3+
- Added ore debug highlighting (`/sm:highlight ore`).
4+
- Fixed Pale Garden biome issue for 1.21.5+.
45

56
## Mod compatibility
67
| | Mod JAR | Biomes | Structures | Loot | Ores | Slime chunks |

gradle.properties

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

55
# Mod Properties
6-
mod_version=2.22.3-CevAPI
7-
fork_release_version=v0.20
6+
mod_version=2.23.0-CevAPI
7+
fork_release_version=v0.21
88
maven_group=dev.xpple
99
archives_base_name=SeedMapper
1010

src/main/c/cubiomes

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.mojang.brigadier.CommandDispatcher;
55
import com.mojang.logging.LogUtils;
66
import dev.xpple.betterconfig.api.ModConfigBuilder;
7+
import dev.xpple.seedmapper.command.arguments.ColorWrapperArgument;
78
import dev.xpple.seedmapper.command.arguments.DurationArgument;
89
import dev.xpple.seedmapper.command.arguments.MapFeatureArgument;
910
import dev.xpple.seedmapper.command.arguments.SeedIdentifierArgument;
@@ -21,6 +22,8 @@
2122
import dev.xpple.seedmapper.command.commands.SourceCommand;
2223
import dev.xpple.seedmapper.command.commands.StopTaskCommand;
2324
import dev.xpple.seedmapper.command.commands.DatapackImportCommand;
25+
import dev.xpple.seedmapper.config.ColorWrapper;
26+
import dev.xpple.seedmapper.config.ColorWrapperAdapter;
2427
import dev.xpple.seedmapper.config.Configs;
2528
import dev.xpple.seedmapper.config.DurationAdapter;
2629
import dev.xpple.seedmapper.config.MapFeatureAdapter;
@@ -88,6 +91,7 @@ public void onInitializeClient() {
8891
.registerType(SeedResolutionArgument.SeedResolution.class, new SeedResolutionAdapter(), SeedResolutionArgument::seedResolution)
8992
.registerTypeHierarchy(MapFeature.class, new MapFeatureAdapter(), MapFeatureArgument::mapFeature)
9093
.registerType(Duration.class, new DurationAdapter(), DurationArgument::duration)
94+
.registerType(ColorWrapper.class, new ColorWrapperAdapter(), ColorWrapperArgument::colorWrapper)
9195
.registerGlobalChangeHook(event -> {
9296
if (event.config().equals("DevMode")) {
9397
try {

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ private CommandExceptions() {
1919
public static final DynamicCommandExceptionType UNKNOWN_STRUCTURE_PIECE_EXCEPTION = new DynamicCommandExceptionType(arg -> Component.translatable("commands.exceptions.unknownStructurePiece", arg));
2020
public static final DynamicCommandExceptionType UNKNOWN_VARIANT_KEY_EXCEPTION = new DynamicCommandExceptionType(arg -> Component.translatable("commands.exceptions.unknownVariantKey", arg));
2121
public static final DynamicCommandExceptionType UNKNOWN_VARIANT_VALUE_EXCEPTION = new DynamicCommandExceptionType(arg -> Component.translatable("commands.exceptions.unknownVariantValue", arg));
22-
public static final DynamicCommandExceptionType UNKNOWN_BLOCK_EXCEPTION = new DynamicCommandExceptionType(arg -> Component.translatable("commands.exceptions.unknownOre", arg));
22+
public static final DynamicCommandExceptionType UNKNOWN_BLOCK_EXCEPTION = new DynamicCommandExceptionType(arg -> Component.translatable("commands.exceptions.unknownBlock", arg));
23+
public static final DynamicCommandExceptionType UNKNOWN_ORE_EXCEPTION = new DynamicCommandExceptionType(arg -> Component.translatable("commands.exceptions.unknownOre", arg));
2324
public static final DynamicCommandExceptionType UNKNOWN_ITEM_EXCEPTION = new DynamicCommandExceptionType(arg -> Component.translatable("commands.exceptions.unknownItem", arg));
2425
public static final DynamicCommandExceptionType UNKNOWN_ENCHANTMENT_EXCEPTION = new DynamicCommandExceptionType(arg -> Component.translatable("commands.exceptions.unknownEnchantment", arg));
2526
public static final DynamicCommandExceptionType UNKNOWN_CANYON_CARVER_EXCEPTION = new DynamicCommandExceptionType(arg -> Component.translatable("commands.exceptions.unknownCanyonCarver", arg));
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package dev.xpple.seedmapper.command.arguments;
2+
3+
import com.mojang.brigadier.context.CommandContext;
4+
import dev.xpple.betterconfig.util.WrappedArgumentType;
5+
import dev.xpple.seedmapper.config.ColorWrapper;
6+
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
7+
import net.minecraft.commands.arguments.HexColorArgument;
8+
9+
public class ColorWrapperArgument extends WrappedArgumentType.Converted<ColorWrapper, Integer> {
10+
private ColorWrapperArgument() {
11+
super(HexColorArgument.hexColor());
12+
}
13+
14+
public static ColorWrapperArgument colorWrapper() {
15+
return new ColorWrapperArgument();
16+
}
17+
18+
public static ColorWrapper getBlock(CommandContext<FabricClientCommandSource> context, String name) {
19+
return context.getArgument(name, ColorWrapper.class);
20+
}
21+
22+
@Override
23+
public ColorWrapper convert(Integer nativeType) {
24+
return new ColorWrapper(nativeType);
25+
}
26+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package dev.xpple.seedmapper.command.arguments;
2+
3+
import com.github.cubiomes.Cubiomes;
4+
import com.mojang.brigadier.StringReader;
5+
import com.mojang.brigadier.arguments.ArgumentType;
6+
import com.mojang.brigadier.context.CommandContext;
7+
import com.mojang.brigadier.exceptions.CommandSyntaxException;
8+
import com.mojang.brigadier.suggestion.Suggestions;
9+
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
10+
import dev.xpple.seedmapper.command.CommandExceptions;
11+
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
12+
import net.minecraft.commands.SharedSuggestionProvider;
13+
14+
import java.util.Collection;
15+
import java.util.List;
16+
import java.util.Map;
17+
import java.util.concurrent.CompletableFuture;
18+
import java.util.stream.Collectors;
19+
import java.util.stream.IntStream;
20+
21+
public class OreArgument implements ArgumentType<Integer> {
22+
23+
private static final Collection<String> EXAMPLES = List.of("ore_quartz_deltas", "ore_redstone_lower", "ore_tuff");
24+
25+
public static final Map<String, Integer> ORES = IntStream.range(0, Cubiomes.ORE_NUM())
26+
.boxed()
27+
.collect(Collectors.toUnmodifiableMap(ore -> Cubiomes.ore2str(ore).getString(0), ore -> ore));
28+
29+
public static OreArgument ore() {
30+
return new OreArgument();
31+
}
32+
33+
public static Integer getOre(CommandContext<FabricClientCommandSource> context, String name) {
34+
return context.getArgument(name, Integer.class);
35+
}
36+
37+
@Override
38+
public Integer parse(StringReader reader) throws CommandSyntaxException {
39+
int cursor = reader.getCursor();
40+
String oreString = reader.readUnquotedString();
41+
Integer ore = ORES.get(oreString);
42+
if (ore == null) {
43+
reader.setCursor(cursor);
44+
throw CommandExceptions.UNKNOWN_ORE_EXCEPTION.create(oreString);
45+
}
46+
return ore;
47+
}
48+
49+
@Override
50+
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
51+
return SharedSuggestionProvider.suggest(ORES.keySet(), builder);
52+
}
53+
54+
@Override
55+
public Collection<String> getExamples() {
56+
return EXAMPLES;
57+
}
58+
}

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

Lines changed: 80 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
import dev.xpple.seedmapper.SeedMapper;
1818
import dev.xpple.seedmapper.command.CommandExceptions;
1919
import dev.xpple.seedmapper.command.CustomClientCommandSource;
20+
import dev.xpple.seedmapper.command.arguments.OreArgument;
2021
import dev.xpple.seedmapper.config.Configs;
21-
import dev.xpple.seedmapper.feature.OreTypes;
2222
import dev.xpple.seedmapper.render.RenderManager;
2323
import dev.xpple.seedmapper.render.esp.EspStyle;
2424
import dev.xpple.seedmapper.util.BaritoneIntegration;
@@ -45,7 +45,6 @@
4545
import java.util.HashSet;
4646
import java.util.List;
4747
import java.util.Map;
48-
import java.util.Objects;
4948
import java.util.Set;
5049
import java.util.stream.Collectors;
5150
import java.util.stream.IntStream;
@@ -54,6 +53,7 @@
5453
import static dev.xpple.seedmapper.command.arguments.BlockArgument.*;
5554
import static dev.xpple.seedmapper.command.arguments.CanyonCarverArgument.*;
5655
import static dev.xpple.seedmapper.command.arguments.CaveCarverArgument.*;
56+
import static dev.xpple.seedmapper.command.arguments.OreArgument.*;
5757
import static dev.xpple.seedmapper.thread.LocatorThreadHelper.*;
5858
import static dev.xpple.seedmapper.util.ChatBuilder.*;
5959
import static net.fabricmc.fabric.api.client.command.v2.ClientCommands.*;
@@ -67,6 +67,12 @@ public static void register(CommandDispatcher<FabricClientCommandSource> dispatc
6767
.executes(ctx -> highlightBlock(CustomClientCommandSource.of(ctx.getSource()), getBlock(ctx, "block")))
6868
.then(argument("chunks", integer(0, 20))
6969
.executes(ctx -> submit(() -> highlightBlock(CustomClientCommandSource.of(ctx.getSource()), getBlock(ctx, "block"), getInteger(ctx, "chunks")))))))
70+
.then(literal("ore")
71+
.requires(_ -> Configs.DevMode)
72+
.then(argument("ore", ore())
73+
.executes(ctx -> highlightOre(CustomClientCommandSource.of(ctx.getSource()), getOre(ctx, "ore").intValue()))
74+
.then(argument("chunks", integer(0, 20))
75+
.executes(ctx -> submit(() -> highlightOre(CustomClientCommandSource.of(ctx.getSource()), getOre(ctx, "ore").intValue(), getInteger(ctx, "chunks")))))))
7076
.then(literal("orevein")
7177
.executes(ctx -> submit(() -> highlightOreVein(CustomClientCommandSource.of(ctx.getSource()))))
7278
.then(argument("chunks", integer(0, 20))
@@ -96,6 +102,7 @@ private static int highlightBlock(CustomClientCommandSource source, Pair<Integer
96102

97103
private static int highlightBlock(CustomClientCommandSource source, Pair<Integer, Integer> blockPair, int chunkRange) throws CommandSyntaxException {
98104
RenderManager.clear();
105+
int block = blockPair.getFirst();
99106
SeedIdentifier seed = source.getSeed().getSecond();
100107
int version = source.getVersion();
101108
int dimension = source.getDimension();
@@ -124,7 +131,7 @@ private static int highlightBlock(CustomClientCommandSource source, Pair<Integer
124131
.boxed()
125132
.toList();
126133
}
127-
OreTypes.ORE_TYPES.stream()
134+
OreArgument.ORES.values().stream()
128135
.filter(oreType -> biomes.stream().anyMatch(biome -> Cubiomes.isViableOreBiome(version, oreType, biome) != 0))
129136
.<MemorySegment>mapMulti((oreType, consumer) -> {
130137
MemorySegment oreConfig = OreConfig.allocate(arena);
@@ -145,10 +152,11 @@ private static int highlightBlock(CustomClientCommandSource source, Pair<Integer
145152
for (int i = 0; i < size; i++) {
146153
MemorySegment pos3 = Pos3.asSlice(pos3s, i);
147154
BlockPos pos = new BlockPos(Pos3.x(pos3), Pos3.y(pos3), Pos3.z(pos3));
148-
if (doAirCheck && isAirOrLava(chunk, pos)) {
155+
if (doAirCheck && !chunk.getBlockState(pos).canOcclude()) {
149156
continue;
150157
}
151158
Integer previouslyGeneratedOre = generatedOres.get(pos);
159+
// if there is already an ore at this position, check if this ore can replace it
152160
if (previouslyGeneratedOre != null) {
153161
boolean contains = false;
154162
for (int j = 0; j < numReplaceBlocks; j++) {
@@ -169,15 +177,14 @@ private static int highlightBlock(CustomClientCommandSource source, Pair<Integer
169177
}
170178
});
171179

172-
int block = blockPair.getFirst();
173-
int colour = blockPair.getSecond();
180+
int color = Configs.BlockColors.getOrDefault(block, 0xFFFFFF);
174181
List<BlockPos> blockOres = generatedOres.entrySet().stream()
175182
.filter(entry -> entry.getValue() == block)
176183
.map(Map.Entry::getKey)
177184
.toList();
178185
count[0] += blockOres.size();
179186
source.getClient().schedule(() -> {
180-
RenderManager.drawBoxes(blockOres, Configs.BlockHighlightESP, colour);
187+
RenderManager.drawBoxes(blockOres, color);
181188
if (SeedMapper.BARITONE_AVAILABLE && Configs.AutoMine) {
182189
BaritoneIntegration.addGoals(blockOres);
183190
}
@@ -192,6 +199,70 @@ private static int highlightBlock(CustomClientCommandSource source, Pair<Integer
192199
}
193200
}
194201

202+
private static int highlightOre(CustomClientCommandSource source, int ore) throws CommandSyntaxException {
203+
return highlightOre(source, ore, 0);
204+
}
205+
206+
private static int highlightOre(CustomClientCommandSource source, int ore, int chunkRange) throws CommandSyntaxException {
207+
SeedIdentifier seed = source.getSeed().getSecond();
208+
int version = source.getVersion();
209+
int dimension = source.getDimension();
210+
211+
try (Arena arena = Arena.ofConfined()) {
212+
MemorySegment generator = Generator.allocate(arena);
213+
Cubiomes.setupGenerator(generator, version, source.getGeneratorFlags());
214+
Cubiomes.applySeed(generator, dimension, seed.seed());
215+
MemorySegment surfaceNoise = SurfaceNoise.allocate(arena);
216+
Cubiomes.initSurfaceNoise(surfaceNoise, dimension, seed.seed());
217+
218+
ChunkPos center = ChunkPos.containing(BlockPos.containing(source.getPosition()));
219+
220+
int[] count = {0};
221+
SpiralLoop.spiral(center.x(), center.z(), chunkRange, (chunkX, chunkZ) -> {
222+
List<Integer> biomes;
223+
if (version <= Cubiomes.MC_1_17()) {
224+
biomes = List.of(Cubiomes.getBiomeForOreGen(generator, chunkX, chunkZ, 0));
225+
} else {
226+
// check certain Y-coordinates that matter for ore generation
227+
// Minecraft checks _all_ biomes in a 3x3 square of chunks, which is not necessary
228+
biomes = IntStream.of(-30, 64, 120)
229+
.map(y -> Cubiomes.getBiomeForOreGen(generator, chunkX, chunkZ, y))
230+
.boxed()
231+
.toList();
232+
}
233+
234+
if (biomes.stream().noneMatch(biome -> Cubiomes.isViableOreBiome(version, ore, biome) != 0)) {
235+
return false;
236+
}
237+
238+
MemorySegment oreConfig = OreConfig.allocate(arena);
239+
// just do biomes.getFirst() because in 1.17 there is only one, and in 1.18 it does not matter
240+
if (Cubiomes.getOreConfig(ore, version, biomes.getFirst(), oreConfig) == 0) {
241+
return false;
242+
}
243+
244+
Set<BlockPos> ores = new HashSet<>();
245+
MemorySegment pos3List = Cubiomes.generateOres(arena, generator, surfaceNoise, oreConfig, chunkX, chunkZ);
246+
try {
247+
MemorySegment pos3s = Pos3List.pos3s(pos3List);
248+
for (int i = 0; i < Pos3List.size(pos3List); i++) {
249+
MemorySegment pos3 = Pos3.asSlice(pos3s, i);
250+
ores.add(new BlockPos(Pos3.x(pos3), Pos3.y(pos3), Pos3.z(pos3)));
251+
}
252+
} finally {
253+
Cubiomes.freePos3List(pos3List);
254+
}
255+
count[0] += ores.size();
256+
RenderManager.drawBoxes(ores, Configs.BlockColors.getOrDefault(OreConfig.oreBlock(oreConfig), 0xFFFFFF));
257+
source.sendFeedback(Component.translatable("command.highlight.block.chunkSuccess", accent(String.valueOf(ores.size())), ComponentUtils.formatXZ(chunkX, chunkZ)));
258+
return false;
259+
});
260+
261+
source.getClient().schedule(() -> source.sendFeedback(Component.translatable("command.highlight.block.success", accent(String.valueOf(count[0])))));
262+
return count[0];
263+
}
264+
}
265+
195266
private static int highlightOreVein(CustomClientCommandSource source) throws CommandSyntaxException {
196267
return highlightOreVein(source, 0);
197268
}
@@ -240,8 +311,8 @@ private static int highlightOreVein(CustomClientCommandSource source, int chunkR
240311
return;
241312
}
242313
count[0] += positions.size();
243-
int colour = BLOCKS.values().stream().filter(pair -> Objects.equals(block, pair.getFirst())).findAny().orElseThrow().getSecond();
244-
RenderManager.drawBoxes(positions, Configs.OreVeinESP, colour);
314+
int color = Configs.BlockColors.getOrDefault(block, 0xFFFFFF);
315+
RenderManager.drawBoxes(positions, color);
245316
if (SeedMapper.BARITONE_AVAILABLE && Configs.AutoMine) {
246317
BaritoneIntegration.addGoals(positions);
247318
}

0 commit comments

Comments
 (0)