Skip to content

Commit

Permalink
Rewrite Feature mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
UnRealDinnerbone committed Mar 1, 2024
1 parent c8edd6f commit 0cad941
Show file tree
Hide file tree
Showing 29 changed files with 101 additions and 183 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
### 4.1.0
### 4.2.0

- Add Support for Mekanism and Immersive Engineering ores
- Rewrite Features to support complex features

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

1 change: 1 addition & 0 deletions common/src/generated/resources/assets/jamd/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"block.jamd.end_portal": "End Mining Portal",
"block.jamd.nether_portal": "Nether Mining Portal",
"block.jamd.portal_block": "Mining Portal",
"jamd.argument.world_type.invalid": "Invalid World Type '%s'",
"jamd.invalid.pos": "Unable to find valid portal location",
"jamd.invalid.world": "Unable to find world '%s'"
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"description": {
"translate": "advancements.jamd.mining.description"
},
"hidden": true,
"icon": {
"item": "jamd:portal_block"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"minecraft:ore_infested"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
import com.mojang.serialization.codecs.RecordCodecBuilder;

import java.util.List;
import java.util.Optional;

public record ConfigCodec(int oreMultiplier, List<OresCodec> ores) {
public record ConfigCodec(int oreMultiplier, Boolean ignoreAirChance, List<OresCodec> ores) {
public static final Codec<ConfigCodec> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.INT.fieldOf("oreMultiplier").forGetter(ConfigCodec::oreMultiplier),
Codec.BOOL.optionalFieldOf("ignoreAirChance", false).forGetter(ConfigCodec::ignoreAirChance),
Codec.list(OresCodec.CODEC).fieldOf("ores").forGetter(ConfigCodec::ores)
).apply(instance, ConfigCodec::new));
}
7 changes: 3 additions & 4 deletions common/src/main/java/com/unrealdinnerbone/jamd/JAMD.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

import com.mojang.logging.LogUtils;
import com.unrealdinnerbone.jamd.api.FeatureTypeRegistry;
import com.unrealdinnerbone.jamd.compact.MinecraftOreCompact;
import com.unrealdinnerbone.jamd.compact.MinecraftScatteredOre;
import com.unrealdinnerbone.jamd.compact.minecraft.MinecraftOreCompact;
import com.unrealdinnerbone.jamd.util.OreRegistry;
import com.unrealdinnerbone.trenzalore.api.platform.Services;
import net.minecraft.server.MinecraftServer;
Expand All @@ -19,8 +18,8 @@ public class JAMD {
public static final String MOD_ID = "jamd";

public static void init() {
FeatureTypeRegistry.register("minecraft", MinecraftOreCompact::new);
FeatureTypeRegistry.register("minecraft", MinecraftScatteredOre::new);
FeatureTypeRegistry.register("minecraft", "ore", MinecraftOreCompact::new);
FeatureTypeRegistry.register("minecraft", "scattered_ore", MinecraftOreCompact::new);
}

public static void onServerStart(MinecraftServer server) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,8 @@ public class JAMDRegistry implements IRegistry {
private static final RegistryObjects<Block> BLOCKS = Regeneration.create(Registries.BLOCK);
private static final RegistryObjects<Item> ITEMS = Regeneration.create(Registries.ITEM);
private static final RegistryObjects<BlockEntityType<?>> TILES = Regeneration.create(Registries.BLOCK_ENTITY_TYPE);

private static final RegistryObjects<ArgumentTypeInfo<?, ?>> ARG_TYPE = Regeneration.create(Registries.COMMAND_ARGUMENT_TYPE);
private static final RegistryObjects<Codec<? extends ChunkGenerator>> CHUNK_GENERATORS = Regeneration.create(Registries.CHUNK_GENERATOR);


public static final RegistryEntry<Codec<? extends ChunkGenerator>> CUSTOM_FLAT_LEVEL_SOURCE = CHUNK_GENERATORS.register("mining", () -> CustomFlatLevelSource.CODEC);

public static final WorldType OVERWORLD = of("mining", "portal_block", "portal", OverworldPortalBlock::new, OverworldBlockEntity::new, BiomeTags.IS_OVERWORLD);
Expand Down
57 changes: 28 additions & 29 deletions common/src/main/java/com/unrealdinnerbone/jamd/WorldType.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,22 @@
import com.unrealdinnerbone.trenzalore.api.registry.RegistryEntry;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.worldgen.features.OreFeatures;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tags.TagKey;
import net.minecraft.util.GsonHelper;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -44,6 +45,7 @@ public class WorldType {
private final RegistryEntry<BlockItem> item;
private final RegistryEntry<BlockEntityType<PortalTileEntity>> blockEntity;

private final TagKey<ConfiguredFeature<?, ?>> ingoredFeatures;
private final Path configPath;

private final TagKey<Biome> biomeTag;
Expand All @@ -55,6 +57,7 @@ public WorldType(String name, RegistryEntry<Block> block, RegistryEntry<BlockIte
this.item = item;
this.blockEntity = blockEntity;
this.biomeTag = biomeTag;
this.ingoredFeatures = TagKey.create(Registries.CONFIGURED_FEATURE, new ResourceLocation(JAMD.MOD_ID, name));
this.configPath = JAMD.CONFIG_FOLDER.resolve(name + ".json");
TYPES.add(this);
}
Expand All @@ -75,6 +78,10 @@ public KeySet getKey() {
return key;
}

public TagKey<ConfiguredFeature<?, ?>> getIgnoredFeatures() {
return ingoredFeatures;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down Expand Up @@ -102,41 +109,33 @@ public void exportIfNotExist(MinecraftServer server) throws IllegalStateExceptio
}

public void export(MinecraftServer server) throws IllegalStateException, IOException {
List<String> loggedTypes = new ArrayList<>();
List<OresCodec> oresCodecs = new ArrayList<>();
List<PlacedFeature> placedFeatures = getFeatures(server);
for (PlacedFeature placedFeature : placedFeatures) {
List<PlacementModifier> placementModifiers = placedFeature.placement();
for (PlacementModifier modifier : placementModifiers) {
DataResult<JsonElement> dataResult = PlacementModifier.CODEC.encodeStart(JsonOps.INSTANCE, modifier);
Optional<JsonElement> result = dataResult.result();
if (result.isEmpty()) {
LOGGER.error("Failed to encode: {}", dataResult.error().get().message());
}
}
//Todo better way to do this
if (!placedFeature.feature().is(OreFeatures.ORE_INFESTED)) {
DataResult<JsonElement> json = PlacedFeature.DIRECT_CODEC.encodeStart(JsonOps.INSTANCE, placedFeature);
if (json.result().isPresent()) {
if (!placedFeature.feature().is(ingoredFeatures)) {
RegistryAccess.Frozen frozen = server.registryAccess();
ConfiguredFeature<?, ?> configuredFeatureReference = placedFeature.feature().value();
Feature<?> feature1 = configuredFeatureReference.feature();
ResourceLocation key1 = frozen.registryOrThrow(Registries.FEATURE).getKey(feature1);
FeatureTypeRegistry.getFeatureType(key1).ifPresentOrElse(iFeatureTypeCompact -> {
try {
JsonElement jsonElement = json.result().get();
JsonObject jsonObject = jsonElement.getAsJsonObject();
JsonObject feature = jsonObject.getAsJsonObject("feature");
String featureType = GsonHelper.getAsString(feature, "type");
FeatureTypeRegistry.getFeatureType(featureType).ifPresent(iFeatureTypeCompact -> {
try {
oresCodecs.add(iFeatureTypeCompact.getOreCodec(GsonHelper.getAsJsonObject(feature, "config"), placementModifiers));
} catch (Exception e) {
LOGGER.error("Failed to parse ore", e);
}
});
} catch (JsonSyntaxException e) {
LOGGER.error("Skipping ore", e);
oresCodecs.add(iFeatureTypeCompact.getOreCodec(configuredFeatureReference.config(), placedFeature.placement()));
} catch (ClassCastException e) {
LOGGER.error("Failed to parse ore Wrong Ore Config?", e);
} catch (Exception e) {
LOGGER.error("Failed to parse ore", e);
}

}
}, () -> {
if (!loggedTypes.contains(key1.toString())) {
loggedTypes.add(key1.toString());
LOGGER.debug("No Feature Mapping for: {}", key1);
}
});
}

DataResult<JsonElement> result = ConfigCodec.CODEC.encodeStart(JsonOps.INSTANCE, new ConfigCodec(1, oresCodecs));
DataResult<JsonElement> result = ConfigCodec.CODEC.encodeStart(JsonOps.INSTANCE, new ConfigCodec(1, false, oresCodecs));
if (result.result().isPresent()) {
if (!Files.exists(JAMD.CONFIG_FOLDER)) {
Files.createDirectories(JAMD.CONFIG_FOLDER);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
package com.unrealdinnerbone.jamd.api;

import com.unrealdinnerbone.trenzalore.api.platform.Services;
import net.minecraft.resources.ResourceLocation;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.*;
import java.util.function.Supplier;

public class FeatureTypeRegistry {
private static final Logger LOGGER = LogManager.getLogger();
public static final List<IFeatureTypeCompact<?>> FEATURES = new ArrayList<>();
public static final Map<ResourceLocation, IFeatureTypeCompact<?>> FEATURES = new HashMap<>();

public static void register(String modId, Supplier<IFeatureTypeCompact<?>> featureTypeCompact) {
public static void register(String modId, String id, Supplier<IFeatureTypeCompact<?>> featureTypeCompact) {
register(modId, new ResourceLocation(modId, id), featureTypeCompact);
}
public static void register(String modId, ResourceLocation id, Supplier<IFeatureTypeCompact<?>> featureTypeCompact) {
if (Services.PLATFORM.isModLoaded(modId)) {
IFeatureTypeCompact<?> iFeatureTypeCompact = featureTypeCompact.get();
LOGGER.debug("Registering Feature {} for {}", iFeatureTypeCompact.getFeatureType(), modId);
FEATURES.add(iFeatureTypeCompact);
LOGGER.debug("Registering Feature {} for {}", id, modId);
FEATURES.put(id, iFeatureTypeCompact);
} else {
LOGGER.debug("Skipping Feature for {} as mod is not loaded", modId);
}
}

public static Optional<IFeatureTypeCompact<?>> getFeatureType(String id) {
return FEATURES.stream().filter(featureTypeCompact -> featureTypeCompact.getFeatureType().toString().equalsIgnoreCase(id)).findFirst();
public static Optional<IFeatureTypeCompact<?>> getFeatureType(ResourceLocation id) {
return Optional.ofNullable(FEATURES.get(id));
}

}
Original file line number Diff line number Diff line change
@@ -1,40 +1,22 @@
package com.unrealdinnerbone.jamd.api;

import com.google.gson.JsonObject;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.JsonOps;
import com.unrealdinnerbone.jamd.OresCodec;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
import net.minecraft.world.level.levelgen.placement.PlacementModifier;

import java.util.List;

public interface IFeatureTypeCompact<T> {

default OresCodec getOreCodec(JsonObject config, List<PlacementModifier> modifiers) throws IllegalArgumentException {
DataResult<T> parse = getCodec().parse(JsonOps.INSTANCE, config);
if (parse.error().isPresent()) {
throw new IllegalArgumentException(parse.error().get().message());
} else {
return parse(parse.result().get(), modifiers);
}
default OresCodec getOreCodec(FeatureConfiguration feature, List<PlacementModifier> modifiers) throws IllegalArgumentException {
return parse((T) feature, modifiers);
}

/**
* @return The ore config codec
*/
Codec<T> getCodec();

/**
* @param value the parsed ore config codec
* @param placementModifiers the placement modifiers to create ore codec
* @return the ore codec
*/
OresCodec parse(T value, List<PlacementModifier> placementModifiers);

/**
* @return feature type id
*/
ResourceLocation getFeatureType();
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ public class JamdCommand {

public static void register(CommandDispatcher<CommandSourceStack> commandDispatcher) {
commandDispatcher.register(Commands.literal("jamd")
.then(Commands.literal("export")
.then(Commands.argument("type", StringArgumentType.string())
.suggests((context, builder) -> SharedSuggestionProvider.suggest(WorldType.TYPES.stream().map(WorldType::getName), builder))
.executes(JamdCommand::export)
.requires((commandSourceStack) -> commandSourceStack.hasPermission(Commands.LEVEL_GAMEMASTERS))
.then(Commands.literal("export")
.then(Commands.argument("type", StringArgumentType.string())
.suggests((context, builder) -> SharedSuggestionProvider.suggest(WorldType.TYPES.stream().map(WorldType::getName), builder))
.executes(JamdCommand::export)))
.then(Commands.literal("reload")
.executes(JamdCommand::reload)))));
.executes(JamdCommand::reload)));

}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.unrealdinnerbone.jamd.compact;
package com.unrealdinnerbone.jamd.compact.minecraft;

import com.mojang.serialization.Codec;
import com.unrealdinnerbone.jamd.OresCodec;
import com.unrealdinnerbone.jamd.api.IFeatureTypeCompact;
import net.minecraft.resources.ResourceLocation;
Expand All @@ -10,21 +9,9 @@
import java.util.List;

public class MinecraftOreCompact implements IFeatureTypeCompact<OreConfiguration> {

private static final ResourceLocation FEATURE_TYPE = new ResourceLocation("minecraft", "ore");

@Override
public OresCodec parse(OreConfiguration value, List<PlacementModifier> placementModifiers) {
return new OresCodec(value.size, value.discardChanceOnAirExposure, placementModifiers, value.targetStates);
}

@Override
public Codec<OreConfiguration> getCodec() {
return OreConfiguration.CODEC;
}

@Override
public ResourceLocation getFeatureType() {
return FEATURE_TYPE;
}
}
Loading

0 comments on commit 0cad941

Please sign in to comment.