Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions docs/content/Modpacks/Changes/v8.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,34 @@ The constructors for a large number of machines have changed in order to simply
- Removed `createRecipeLogic` method
- Constructor now has an optional `Supplier<RecipeLogic>` argument, defaults to the standard `RecipeLogic` class


## World gen layer changes

`IWorldGenLayer` was changed to use `ResourceKey<Level>`s instead of `ResourceLocation`s for matching dimensions.
_Layers created with KubeJS require no changes._
That means **addon mods** using custom world gen layers have to change their code:
```java
/////// OLD
public static final IWorldGenLayer MY_LAYER = new SimpleWorldGenLayer("my_layer", () -> /*Your RuleTest here*/, MyDimensions.CUSTOM_DIMENSION.location());
// (you could also have something akin this, in an enum or not)
MY_LAYER("my_layer", /*Your RuleTest here*/, new ResourceLocation("my_addon", "dimension_id"));

/////// NEW
public static final IWorldGenLayer MY_LAYER = new SimpleWorldGenLayer("my_layer", () -> /*Your RuleTest here*/, MyDimensions.CUSTOM_DIMENSION);
// (or something akin to this)
MY_LAYER("my_layer", /*Your RuleTest here*/, ResourceKey.create(Registries.DIMENSION, new ResourceLocation("my_addon", "dimension_id")));
```

!!! Note
If your custom world gen layers use an enum class for them,
you have to also change the `levels`/`dimensions` field's type to `Set<ResourceKey<Level>>`, rename its getter to `getDimensions()`,
and change `isApplicableForLevel`'s signature to be as such: `boolean isApplicableForLevel(ResourceKey<Level> dimension)`.
You may reference [this diff](https://github.com/GregTechCEu/GregTech-Modern/pull/4527/changes/a0500ee1bc3b08f7c590a99fef420a1c4d3e8a12#diff-93160870600b334f76bd226ad1c27798a12fdcd7a00871e26421830eb0392289) for a 'guide' on all the necessary changes.

!!! Note
It's highly recommended to use constants for any `ResourceKey` instances, as creating them isn't cheap because they're interned.


## Machine Trait Refactor

A new system for attaching traits and custom behaviour to machines has been added, and many machine interfaces and traits now use this new system.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import lombok.Setter;
import lombok.experimental.Accessors;
import lombok.experimental.Tolerate;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

import java.util.*;
Expand Down Expand Up @@ -178,18 +179,26 @@ public GTOreDefinition weight(int weight) {
public GTOreDefinition layer(IWorldGenLayer layer) {
this.layer = layer;
if (this.dimensionFilter == null || this.dimensionFilter.isEmpty()) {
dimensions(layer.getLevels().toArray(ResourceLocation[]::new));
dimensions(layer.getDimensions());
}
return this;
}

public GTOreDefinition dimensions(ResourceLocation... dimensions) {
this.dimensionFilter = Arrays.stream(dimensions)
.map(location -> ResourceKey.create(Registries.DIMENSION, location))
.collect(Collectors.toSet());
@HideFromJS
public final GTOreDefinition dimensions(Set<ResourceKey<Level>> dimensions) {
this.dimensionFilter = dimensions;
return this;
}

/// This method should <b>only</b> be used in KubeJS.
@ApiStatus.Internal
@SuppressWarnings("unused")
public GTOreDefinition kjs$dimensions(ResourceLocation... dimensions) {
return this.dimensions(Arrays.stream(dimensions)
.map(location -> ResourceKey.create(Registries.DIMENSION, location))
.collect(Collectors.toSet()));
}

public GTOreDefinition biomes(String first, String... biomes) {
// The first param is separate to avoid method confusion with the Lombok-generated fluent getter
List<String> biomeList = Stream.of(Stream.of(first), Arrays.stream(biomes))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.gregtechceu.gtceu.api.data.worldgen;

import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.ResourceKey;
import net.minecraft.util.ExtraCodecs;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.levelgen.structure.templatesystem.AlwaysTrueTest;
import net.minecraft.world.level.levelgen.structure.templatesystem.RuleTest;

import com.mojang.serialization.Codec;
import org.jetbrains.annotations.NotNull;

import java.util.Set;

Expand All @@ -15,9 +17,9 @@ public interface IWorldGenLayer extends StringRepresentable {
Codec<IWorldGenLayer> CODEC = ExtraCodecs.stringResolverCodec(StringRepresentable::getSerializedName,
WorldGeneratorUtils.WORLD_GEN_LAYERS::get);

boolean isApplicableForLevel(ResourceLocation level);
boolean isApplicableForLevel(ResourceKey<Level> dimension);

Set<ResourceLocation> getLevels();
Set<ResourceKey<Level>> getDimensions();

RuleTest getTarget();

Expand All @@ -30,12 +32,12 @@ interface RuleTestSupplier {
IWorldGenLayer NOWHERE = new IWorldGenLayer() {

@Override
public boolean isApplicableForLevel(ResourceLocation level) {
public boolean isApplicableForLevel(ResourceKey<Level> dimension) {
return false;
}

@Override
public Set<ResourceLocation> getLevels() {
public Set<ResourceKey<Level>> getDimensions() {
return Set.of();
}

Expand All @@ -45,7 +47,7 @@ public RuleTest getTarget() {
}

@Override
public String getSerializedName() {
public @NotNull String getSerializedName() {
return "nowhere";
}
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,52 @@
package com.gregtechceu.gtceu.api.data.worldgen;

import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.levelgen.structure.templatesystem.RuleTest;

import com.mojang.serialization.JsonOps;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Set;
import java.util.stream.Collectors;

public class SimpleWorldGenLayer implements IWorldGenLayer {

private final String name;
private final IWorldGenLayer.RuleTestSupplier target;
@Getter
private final Set<ResourceLocation> levels;
private final Set<ResourceKey<Level>> dimensions;

public SimpleWorldGenLayer(String name, IWorldGenLayer.RuleTestSupplier target, Set<ResourceLocation> levels) {
public SimpleWorldGenLayer(String name, IWorldGenLayer.RuleTestSupplier target,
Set<ResourceKey<Level>> dimensions) {
this.name = name;
this.target = target;
this.levels = levels;
this.dimensions = dimensions;
WorldGeneratorUtils.WORLD_GEN_LAYERS.put(name, this);
}

@Override
public String getSerializedName() {
public @NotNull String getSerializedName() {
return name;
}

private @Nullable String cachedToString;

@Override
public String toString() {
return getSerializedName() + "[" +
RuleTest.CODEC.encodeStart(JsonOps.INSTANCE, target.get()).result().orElse(null) + "]" +
",dimensions=" + levels.toString();
if (this.cachedToString == null) {
String serializedTarget = String
.valueOf(RuleTest.CODEC.encodeStart(JsonOps.INSTANCE, target.get()).result().orElse(null));
String dimensionsString = this.dimensions.stream()
.map(key -> key.location().toString())
.collect(Collectors.joining(", ", "[", "]"));

this.cachedToString = getSerializedName() + "[" + serializedTarget + "]" +
",dimensions=" + dimensionsString;
}
return this.cachedToString;
}

@Override
Expand All @@ -48,11 +63,11 @@ public boolean equals(Object o) {
}

public RuleTest getTarget() {
return target.get();
return this.target.get();
}

@Override
public boolean isApplicableForLevel(ResourceLocation level) {
return levels.contains(level);
public boolean isApplicableForLevel(ResourceKey<Level> dimension) {
return this.dimensions.contains(dimension);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.gregtechceu.gtceu.api.addon.IGTAddon;
import com.gregtechceu.gtceu.integration.kjs.GTRegistryInfo;

import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.ResourceKey;
import net.minecraft.tags.BlockTags;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.level.Level;
Expand All @@ -20,35 +20,28 @@

public enum WorldGenLayers implements IWorldGenLayer, StringRepresentable {

STONE(
"stone", new TagMatchTest(BlockTags.STONE_ORE_REPLACEABLES),
Set.of(Level.OVERWORLD.location())),
DEEPSLATE(
"deepslate", new TagMatchTest(BlockTags.DEEPSLATE_ORE_REPLACEABLES),
Set.of(Level.OVERWORLD.location())),
NETHERRACK(
"netherrack", new TagMatchTest(BlockTags.NETHER_CARVER_REPLACEABLES),
Set.of(Level.NETHER.location())),
ENDSTONE(
"endstone", WorldGeneratorUtils.END_ORE_REPLACEABLES,
Set.of(Level.END.location()));
STONE("stone", new TagMatchTest(BlockTags.STONE_ORE_REPLACEABLES), Level.OVERWORLD),
DEEPSLATE("deepslate", new TagMatchTest(BlockTags.DEEPSLATE_ORE_REPLACEABLES), Level.OVERWORLD),
NETHERRACK("netherrack", new TagMatchTest(BlockTags.NETHER_CARVER_REPLACEABLES), Level.NETHER),
ENDSTONE("endstone", WorldGeneratorUtils.END_ORE_REPLACEABLES, Level.END);

private final String name;

@SuppressWarnings("NonFinalFieldInEnum")
@Getter
@Setter
private Set<ResourceLocation> levels;
private Set<ResourceKey<Level>> dimensions;

@SuppressWarnings("NonFinalFieldInEnum")
@Getter
@Setter
private RuleTest target;

WorldGenLayers(String name, RuleTest target, Set<ResourceLocation> levels) {
@SafeVarargs
WorldGenLayers(String name, RuleTest target, ResourceKey<Level>... dimensions) {
this.name = name;
this.target = target;
this.levels = levels;
this.dimensions = Set.of(dimensions);
WorldGeneratorUtils.WORLD_GEN_LAYERS.put(name, this);
}

Expand All @@ -66,11 +59,11 @@ public static IWorldGenLayer getByName(String name) {
@Override
@NotNull
public String getSerializedName() {
return name;
return this.name;
}

@Override
public boolean isApplicableForLevel(ResourceLocation level) {
return levels.contains(level);
public boolean isApplicableForLevel(ResourceKey<Level> dimension) {
return this.dimensions.contains(dimension);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,6 @@ public static List<WeightedVein> getCachedBiomeVeins(ServerLevel level, Holder<B
return oreVeinCache.computeIfAbsent(level, WorldOreVeinCache::new).getEntry(biome);
}

public static Optional<String> getWorldGenLayerKey(IWorldGenLayer layer) {
return WORLD_GEN_LAYERS.entrySet().stream()
.filter(entry -> entry.getValue().equals(layer))
.map(Entry::getKey)
.findFirst();
}

public static boolean isSameDimension(ResourceKey<Level> first, ResourceKey<Level> second) {
return first == second;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ private List<VeinConfiguration> createConfigs(WorldGenLevel level, ChunkGenerato

private Stream<GTOreDefinition> getEntries(WorldGenLevel level, BlockPos veinCenter, XoroshiroRandomSource random) {
return WorldGeneratorUtils.WORLD_GEN_LAYERS.values().stream()
.filter(layer -> layer.isApplicableForLevel(level.getLevel().dimension().location()))
.filter(layer -> layer.isApplicableForLevel(level.getLevel().dimension()))
.map(layer -> getEntry(level, level.getBiome(veinCenter), random, layer))
.filter(Objects::nonNull);
}
Expand All @@ -152,9 +152,7 @@ private GTOreDefinition getEntry(WorldGenLevel level, Holder<Biome> biome, Rando
private static Optional<BlockPos> computeVeinOrigin(WorldGenLevel level, ChunkGenerator generator, ChunkPos pos,
RandomSource random, BlockPos veinCenter,
GTOreDefinition entry) {
int layerSeed = WorldGeneratorUtils.getWorldGenLayerKey(entry.layer())
.map(String::hashCode)
.orElse(0);
int layerSeed = entry.layer().getSerializedName().hashCode();
var layeredRandom = new XoroshiroRandomSource(random.nextLong() ^ ((long) layerSeed));

veinCenter = OreVeinUtil.getVeinCenter(pos, layeredRandom).orElse(veinCenter);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,12 @@ public void load(CompoundTag tag) {
super.load(tag);
}

@Override
public void load(CompoundTag tag) {
TagCompatibilityFixer.fixMachineAutoOutputTag(tag);
super.load(tag);
}

@MustBeInvokedByOverriders
public void onLoad() {
getTraitHolder().getAllTraits().forEach(MachineTrait::onMachineLoad);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;

import lombok.Getter;
import org.jetbrains.annotations.NotNull;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@
import com.gregtechceu.gtceu.api.data.worldgen.SimpleWorldGenLayer;
import com.gregtechceu.gtceu.api.registry.registrate.BuilderBase;

import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;

import dev.latvian.mods.kubejs.level.gen.ruletest.AnyMatchRuleTest;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import lombok.experimental.Accessors;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.*;

@Accessors(fluent = true, chain = true)
public class WorldGenLayerBuilder extends BuilderBase<SimpleWorldGenLayer> {

public transient List<IWorldGenLayer.RuleTestSupplier> targets = new ObjectArrayList<>();
public transient List<ResourceLocation> dimensions = new ObjectArrayList<>();
public transient Set<ResourceKey<Level>> dimensions = new HashSet<>();

public WorldGenLayerBuilder(ResourceLocation id) {
super(id);
Expand All @@ -29,8 +29,8 @@ public WorldGenLayerBuilder(ResourceLocation id) {
public SimpleWorldGenLayer register() {
this.value = new SimpleWorldGenLayer(
this.id.getPath(),
() -> new AnyMatchRuleTest(targets.stream().map(IWorldGenLayer.RuleTestSupplier::get).toList()),
Set.copyOf(dimensions));
() -> new AnyMatchRuleTest(this.targets.stream().map(IWorldGenLayer.RuleTestSupplier::get).toList()),
this.dimensions);
return value;
}

Expand All @@ -39,8 +39,10 @@ public WorldGenLayerBuilder targets(IWorldGenLayer.RuleTestSupplier... targets)
return this;
}

public WorldGenLayerBuilder dimensions(ResourceLocation... dimension) {
this.dimensions.addAll(Arrays.asList(dimension));
public WorldGenLayerBuilder dimensions(ResourceLocation... dimensions) {
for (ResourceLocation id : dimensions) {
this.dimensions.add(ResourceKey.create(Registries.DIMENSION, id));
}
return this;
}
}
Loading