Datageneration
This commit is contained in:
parent
df73be9c56
commit
3f83b88cde
72
build.gradle
72
build.gradle
|
@ -15,21 +15,15 @@ base {
|
||||||
// Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17.
|
// Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17.
|
||||||
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
|
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
|
||||||
|
|
||||||
|
// Include resources generated by data generators.
|
||||||
|
sourceSets {
|
||||||
|
data
|
||||||
|
main.resources { srcDirs += 'src/generated/resources' }
|
||||||
|
}
|
||||||
|
|
||||||
println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}"
|
println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}"
|
||||||
minecraft {
|
minecraft {
|
||||||
// The mappings can be changed at any time and must be in the following format.
|
|
||||||
// Channel: Version:
|
|
||||||
// official MCVersion Official field/method names from Mojang mapping files
|
|
||||||
// parchment YYYY.MM.DD-MCVersion Open community-sourced parameter names and javadocs layered on top of official
|
|
||||||
//
|
|
||||||
// You must be aware of the Mojang license when using the 'official' or 'parchment' mappings.
|
|
||||||
// See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md
|
|
||||||
//
|
|
||||||
// Parchment is an unofficial project maintained by ParchmentMC, separate from MinecraftForge
|
|
||||||
// Additional setup is needed to use their mappings: https://parchmentmc.org/docs/getting-started
|
|
||||||
//
|
|
||||||
// Use non-default mappings at your own risk. They may not always work.
|
|
||||||
// Simply re-run your setup task after changing the mappings to update your workspace.
|
|
||||||
mappings channel: mapping_channel, version: mapping_version
|
mappings channel: mapping_channel, version: mapping_version
|
||||||
|
|
||||||
// When true, this property will have all Eclipse/IntelliJ IDEA run configurations run the "prepareX" task for the given run configuration before launching the game.
|
// When true, this property will have all Eclipse/IntelliJ IDEA run configurations run the "prepareX" task for the given run configuration before launching the game.
|
||||||
|
@ -42,19 +36,6 @@ minecraft {
|
||||||
// See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html
|
// See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html
|
||||||
copyIdeResources = true
|
copyIdeResources = true
|
||||||
|
|
||||||
// When true, this property will add the folder name of all declared run configurations to generated IDE run configurations.
|
|
||||||
// The folder name can be set on a run configuration using the "folderName" property.
|
|
||||||
// By default, the folder name of a run configuration is the name of the Gradle project containing it.
|
|
||||||
// generateRunFolders = true
|
|
||||||
|
|
||||||
// This property enables access transformers for use in development.
|
|
||||||
// They will be applied to the Minecraft artifact.
|
|
||||||
// The access transformer file can be anywhere in the project.
|
|
||||||
// However, it must be at "META-INF/accesstransformer.cfg" in the final mod jar to be loaded by Forge.
|
|
||||||
// This default location is a best practice to automatically put the file in the right place in the final jar.
|
|
||||||
// See https://docs.minecraftforge.net/en/latest/advanced/accesstransformers/ for more information.
|
|
||||||
// accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
|
|
||||||
|
|
||||||
// Default run configurations.
|
// Default run configurations.
|
||||||
// These can be tweaked, removed, or duplicated as needed.
|
// These can be tweaked, removed, or duplicated as needed.
|
||||||
runs {
|
runs {
|
||||||
|
@ -99,27 +80,30 @@ minecraft {
|
||||||
}
|
}
|
||||||
|
|
||||||
data {
|
data {
|
||||||
|
ideaModule "${project.name}.data"
|
||||||
|
|
||||||
// example of overriding the workingDirectory set in configureEach above
|
// example of overriding the workingDirectory set in configureEach above
|
||||||
workingDirectory project.file('run-data')
|
workingDirectory project.file('run-data')
|
||||||
|
|
||||||
// Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
|
// Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
|
||||||
args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
|
args '--mod', 'engage', '--all'
|
||||||
|
args '--output', sourceSets.data.resources.srcDirs[0].toString()
|
||||||
|
args '--existing', sourceSets.main.resources.srcDirs[0].toString()
|
||||||
|
mods {
|
||||||
|
"${mod_id}" {
|
||||||
|
source sourceSets.main
|
||||||
|
source sourceSets.data
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include resources generated by data generators.
|
|
||||||
sourceSets.main.resources { srcDir 'src/generated/resources' }
|
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
// Put repositories for dependencies here
|
}
|
||||||
// ForgeGradle automatically adds the Forge maven and Maven Central for you
|
|
||||||
|
|
||||||
// If you have mod jar dependencies in ./libs, you can declare them as a repository like so.
|
configurations {
|
||||||
// See https://docs.gradle.org/current/userguide/declaring_repositories.html#sub:flat_dir_resolver
|
dataImplementation.extendsFrom implementation
|
||||||
// flatDir {
|
|
||||||
// dir 'libs'
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -130,20 +114,8 @@ dependencies {
|
||||||
// then special handling is done to allow a setup of a vanilla dependency without the use of an external repository.
|
// then special handling is done to allow a setup of a vanilla dependency without the use of an external repository.
|
||||||
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
|
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
|
||||||
|
|
||||||
// Example mod dependency with JEI - using fg.deobf() ensures the dependency is remapped to your development mappings
|
|
||||||
// The JEI API is declared for compile time use, while the full JEI artifact is used at runtime
|
|
||||||
// compileOnly fg.deobf("mezz.jei:jei-${mc_version}-common-api:${jei_version}")
|
|
||||||
// compileOnly fg.deobf("mezz.jei:jei-${mc_version}-forge-api:${jei_version}")
|
|
||||||
// runtimeOnly fg.deobf("mezz.jei:jei-${mc_version}-forge:${jei_version}")
|
|
||||||
|
|
||||||
// Example mod dependency using a mod jar from ./libs with a flat dir repository
|
dataImplementation sourceSets.main.output
|
||||||
// This maps to ./libs/coolmod-${mc_version}-${coolmod_version}.jar
|
|
||||||
// The group id is ignored when searching -- in this case, it is "blank"
|
|
||||||
// implementation fg.deobf("blank:coolmod-${mc_version}:${coolmod_version}")
|
|
||||||
|
|
||||||
// For more info:
|
|
||||||
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
|
|
||||||
// http://www.gradle.org/docs/current/userguide/dependency_management.html
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This block of code expands all declared replace properties in the specified resource targets.
|
// This block of code expands all declared replace properties in the specified resource targets.
|
||||||
|
|
45
src/data/java/uk/gemwire/engage/data/Datagen.java
Normal file
45
src/data/java/uk/gemwire/engage/data/Datagen.java
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
package uk.gemwire.engage.data;
|
||||||
|
|
||||||
|
import net.minecraft.data.DataGenerator;
|
||||||
|
import net.minecraftforge.common.data.BlockTagsProvider;
|
||||||
|
import net.minecraftforge.data.event.GatherDataEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.apache.logging.log4j.Marker;
|
||||||
|
import org.apache.logging.log4j.MarkerManager;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import uk.gemwire.engage.data.blockstate.BlockStateProvider;
|
||||||
|
import uk.gemwire.engage.data.lang.EnglishProvider;
|
||||||
|
import uk.gemwire.engage.data.loot_tables.LootTableProvider;
|
||||||
|
import uk.gemwire.engage.data.model.block.BlockModelProvider;
|
||||||
|
import uk.gemwire.engage.data.model.item.ItemModelProvider;
|
||||||
|
import uk.gemwire.engage.data.sprites.SpriteSourceProvider;
|
||||||
|
import uk.gemwire.engage.data.tags.block.BlockTagProvider;
|
||||||
|
|
||||||
|
@Mod.EventBusSubscriber(modid = "engage", bus = Mod.EventBusSubscriber.Bus.MOD)
|
||||||
|
public class Datagen {
|
||||||
|
public static final Marker DATAGEN = MarkerManager.getMarker("DATAGEN");
|
||||||
|
public static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onGatherData(@NotNull GatherDataEvent event) {
|
||||||
|
LOGGER.info(DATAGEN, "Gathering data providers");
|
||||||
|
DataGenerator generator = event.getGenerator();
|
||||||
|
LOGGER.info(DATAGEN, "Adding data providers for server data");
|
||||||
|
//generator.addProvider(event.includeServer(), new RecipeProviders(generator));
|
||||||
|
//generator.addProvider(event.includeServer(), new AdvancementsProvider(generator));
|
||||||
|
//generator.addProvider(event.includeServer(), new GLMProvider(generator));
|
||||||
|
generator.addProvider(event.includeServer(), new LootTableProvider(event.getGenerator().getPackOutput()));
|
||||||
|
generator.addProvider(event.includeServer(), new BlockTagProvider(event.getGenerator().getPackOutput(), event.getLookupProvider(), event.getExistingFileHelper()));
|
||||||
|
|
||||||
|
LOGGER.info(DATAGEN, "Adding data providers for client assets");
|
||||||
|
generator.addProvider(event.includeClient(), new EnglishProvider(event.getGenerator().getPackOutput()));
|
||||||
|
generator.addProvider(event.includeClient(), new SpriteSourceProvider(event.getGenerator().getPackOutput(), event.getExistingFileHelper()));
|
||||||
|
generator.addProvider(event.includeClient(), new ItemModelProvider(event.getGenerator().getPackOutput(), event.getExistingFileHelper()));
|
||||||
|
generator.addProvider(event.includeClient(), new BlockModelProvider(event.getGenerator().getPackOutput(), event.getExistingFileHelper()));
|
||||||
|
generator.addProvider(event.includeClient(), new BlockStateProvider(event.getGenerator().getPackOutput(), event.getExistingFileHelper()));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package uk.gemwire.engage.data.blockstate;
|
||||||
|
|
||||||
|
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.data.PackOutput;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||||
|
import net.minecraft.world.level.block.state.properties.Property;
|
||||||
|
import net.minecraftforge.client.model.generators.BlockStateProvider;
|
||||||
|
import net.minecraftforge.client.model.generators.ConfiguredModel;
|
||||||
|
import net.minecraftforge.client.model.generators.ModelFile;
|
||||||
|
import net.minecraftforge.client.model.generators.VariantBlockStateBuilder;
|
||||||
|
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import uk.gemwire.engage.data.model.block.BaseBlockModelProvider;
|
||||||
|
import uk.gemwire.engage.registries.fluid.FluidDeferredRegister;
|
||||||
|
import uk.gemwire.engage.registries.fluid.FluidRegistryObject;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public abstract class BaseBlockStateProvider<PROVIDER extends BaseBlockModelProvider> extends BlockStateProvider {
|
||||||
|
|
||||||
|
private final String modid;
|
||||||
|
private final PROVIDER modelProvider;
|
||||||
|
|
||||||
|
public BaseBlockStateProvider(PackOutput output, String modid, ExistingFileHelper existingFileHelper,
|
||||||
|
BiFunction<PackOutput, ExistingFileHelper, PROVIDER> providerCreator) {
|
||||||
|
super(output, modid, existingFileHelper);
|
||||||
|
this.modid = modid;
|
||||||
|
modelProvider = providerCreator.apply(output, existingFileHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Block state provider: " + modid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PROVIDER models() {
|
||||||
|
return modelProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void registerFluidBlockStates(List<FluidRegistryObject<? extends FluidDeferredRegister.MekanismFluidType, ?, ?, ?, ?>> fluidROs) {
|
||||||
|
for (FluidRegistryObject<? extends FluidDeferredRegister.MekanismFluidType, ?, ?, ?, ?> fluidRO : fluidROs) {
|
||||||
|
simpleBlock(fluidRO.getBlock(), models().getBuilder(ForgeRegistries.BLOCKS.getKey(fluidRO.getBlock()).getPath()).texture("particle",
|
||||||
|
fluidRO.getFluidType().stillTexture));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like directionalBlock but allows us to skip specific properties
|
||||||
|
*/
|
||||||
|
protected void directionalBlock(Block block, Function<BlockState, ModelFile> modelFunc, int angleOffset, Property<?>... toSkip) {
|
||||||
|
getVariantBuilder(block).forAllStatesExcept(state -> {
|
||||||
|
Direction dir = state.getValue(BlockStateProperties.FACING);
|
||||||
|
return ConfiguredModel.builder()
|
||||||
|
.modelFile(modelFunc.apply(state))
|
||||||
|
.rotationX(dir == Direction.DOWN ? 180 : dir.getAxis().isHorizontal() ? 90 : 0)
|
||||||
|
.rotationY(dir.getAxis().isVertical() ? 0 : (((int) dir.toYRot()) + angleOffset) % 360)
|
||||||
|
.build();
|
||||||
|
}, toSkip);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package uk.gemwire.engage.data.blockstate;
|
||||||
|
|
||||||
|
import net.minecraft.data.PackOutput;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
import uk.gemwire.engage.data.model.block.BlockModelProvider;
|
||||||
|
import uk.gemwire.engage.registries.Blocks;
|
||||||
|
import uk.gemwire.engage.registries.Fluids;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BlockStateProvider extends BaseBlockStateProvider<BlockModelProvider> {
|
||||||
|
|
||||||
|
public BlockStateProvider(PackOutput output, ExistingFileHelper existingFileHelper) {
|
||||||
|
super(output, "engage", existingFileHelper, BlockModelProvider::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResourceLocation key(Block block) {
|
||||||
|
return ForgeRegistries.BLOCKS.getKey(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String name(Block block) {
|
||||||
|
return key(block).getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void registerStatesAndModels() {
|
||||||
|
registerFluidBlockStates(List.of(Fluids.HEAVY_WATER_FLUID, Fluids.DEUTERIUM_FLUID, Fluids.DEUTERIUM_SLUSH_FLUID, Fluids.ANTIDEUTERIUM_FLUID, Fluids.WARP_PLASMA_FLUID, Fluids.PROPANE_FLUID));
|
||||||
|
simpleBlockWithItem(Blocks.BERYLLITE_ORE_BLOCK.get(), models().cubeAll(name(Blocks.BERYLLITE_ORE_BLOCK.get()), new ResourceLocation("minecraft:block/coal_ore")));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package uk.gemwire.engage.data.lang;
|
||||||
|
|
||||||
|
import net.minecraft.data.PackOutput;
|
||||||
|
import net.minecraftforge.common.data.LanguageProvider;
|
||||||
|
import uk.gemwire.engage.registries.Fluids;
|
||||||
|
import uk.gemwire.engage.registries.Items;
|
||||||
|
import uk.gemwire.engage.registries.fluid.FluidRegistryObject;
|
||||||
|
|
||||||
|
public class EnglishProvider extends LanguageProvider {
|
||||||
|
|
||||||
|
public EnglishProvider(PackOutput generatorIn) {
|
||||||
|
super(generatorIn, "engage", "en_us");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addTranslations() {
|
||||||
|
add(Items.BERYLLITE_ORE_ITEM.get(), "Beryllite Ore");
|
||||||
|
add(Fluids.HEAVY_WATER_FLUID, "Heavy Water");
|
||||||
|
add(Fluids.PROPANE_FLUID, "Propane");
|
||||||
|
add(Fluids.DEUTERIUM_FLUID, "Deuterium");
|
||||||
|
add(Fluids.DEUTERIUM_SLUSH_FLUID, "Supercooled Deuterium");
|
||||||
|
add(Fluids.ANTIDEUTERIUM_FLUID, "Antideuterium");
|
||||||
|
add(Fluids.WARP_PLASMA_FLUID, "Warp Plasma");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void add(FluidRegistryObject<?, ?, ?, ?, ?> fluid, String name) {
|
||||||
|
add(fluid.getBlock(), name);
|
||||||
|
add(fluid.getBucket(), name + " Bucket");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package uk.gemwire.engage.data.loot_tables;
|
||||||
|
|
||||||
|
import net.minecraft.data.PackOutput;
|
||||||
|
import net.minecraft.data.loot.LootTableProvider;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
// Yoinked from Mekanism
|
||||||
|
public abstract class BaseLootProvider extends LootTableProvider {
|
||||||
|
|
||||||
|
protected BaseLootProvider(PackOutput output, List<SubProviderEntry> subProviders) {
|
||||||
|
this(output, Collections.emptySet(), subProviders);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected BaseLootProvider(PackOutput output, Set<ResourceLocation> requiredTables, List<LootTableProvider.SubProviderEntry> subProviders) {
|
||||||
|
super(output, requiredTables, subProviders);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package uk.gemwire.engage.data.loot_tables;
|
||||||
|
|
||||||
|
import net.minecraft.data.PackOutput;
|
||||||
|
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
|
||||||
|
import uk.gemwire.engage.data.loot_tables.block.BlockLootTables;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class LootTableProvider extends BaseLootProvider {
|
||||||
|
|
||||||
|
public LootTableProvider(PackOutput pack) {
|
||||||
|
super(pack, List.of(
|
||||||
|
new SubProviderEntry(BlockLootTables::new, LootContextParamSets.BLOCK)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,183 @@
|
||||||
|
package uk.gemwire.engage.data.loot_tables.block;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.ReferenceArraySet;
|
||||||
|
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
|
||||||
|
import net.minecraft.advancements.critereon.EnchantmentPredicate;
|
||||||
|
import net.minecraft.advancements.critereon.ItemPredicate;
|
||||||
|
import net.minecraft.advancements.critereon.MinMaxBounds;
|
||||||
|
import net.minecraft.advancements.critereon.StatePropertiesPredicate;
|
||||||
|
import net.minecraft.data.loot.BlockLootSubProvider;
|
||||||
|
import net.minecraft.world.flag.FeatureFlags;
|
||||||
|
import net.minecraft.world.item.enchantment.Enchantments;
|
||||||
|
import net.minecraft.world.level.ItemLike;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.SlabBlock;
|
||||||
|
import net.minecraft.world.level.block.state.properties.SlabType;
|
||||||
|
import net.minecraft.world.level.storage.loot.LootPool;
|
||||||
|
import net.minecraft.world.level.storage.loot.LootTable;
|
||||||
|
import net.minecraft.world.level.storage.loot.entries.LootItem;
|
||||||
|
import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer;
|
||||||
|
import net.minecraft.world.level.storage.loot.functions.ApplyBonusCount;
|
||||||
|
import net.minecraft.world.level.storage.loot.functions.SetItemCountFunction;
|
||||||
|
import net.minecraft.world.level.storage.loot.predicates.*;
|
||||||
|
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
|
||||||
|
import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
|
||||||
|
import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import static net.minecraft.world.level.storage.loot.LootTable.Builder;
|
||||||
|
|
||||||
|
public abstract class BaseBlockLootTables extends BlockLootSubProvider {
|
||||||
|
|
||||||
|
private static final LootItemCondition.Builder HAS_SILK_TOUCH = MatchTool.toolMatches(ItemPredicate.Builder.item()
|
||||||
|
.hasEnchantment(new EnchantmentPredicate(Enchantments.SILK_TOUCH, MinMaxBounds.Ints.atLeast(1))));
|
||||||
|
|
||||||
|
private final Set<Block> knownBlocks = new ReferenceOpenHashSet<>();
|
||||||
|
//Note: We use an array set as we never expect this to have more than a few elements (in reality it only ever has one)
|
||||||
|
private final Set<Block> toSkip = new ReferenceArraySet<>();
|
||||||
|
|
||||||
|
protected BaseBlockLootTables() {
|
||||||
|
//Note: We manually handle explosion resistance on a case by case basis dynamically
|
||||||
|
super(Collections.emptySet(), FeatureFlags.VANILLA_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void add(@NotNull Block block, @NotNull LootTable.Builder table) {
|
||||||
|
//Overwrite the core register method to add to our list of known blocks
|
||||||
|
super.add(block, table);
|
||||||
|
knownBlocks.add(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
protected Iterable<Block> getKnownBlocks() {
|
||||||
|
return knownBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected boolean skipBlock(Block block) {
|
||||||
|
//Skip any blocks that we already registered a table for or have marked to skip
|
||||||
|
return knownBlocks.contains(block) || toSkip.contains(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected LootTable.Builder createOreDrop(Block block, ItemLike item) {
|
||||||
|
return createSilkTouchDispatchTable(block, applyExplosionDecay(block, LootItem.lootTableItem(item.asItem())
|
||||||
|
.apply(ApplyBonusCount.addOreBonusCount(Enchantments.BLOCK_FORTUNE))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected LootTable.Builder droppingWithFortuneOrRandomly(Block block, ItemLike item, UniformGenerator range) {
|
||||||
|
return createSilkTouchDispatchTable(block, applyExplosionDecay(block, LootItem.lootTableItem(item.asItem())
|
||||||
|
.apply(SetItemCountFunction.setCount(range))
|
||||||
|
.apply(ApplyBonusCount.addOreBonusCount(Enchantments.BLOCK_FORTUNE))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
//IBlockProvider versions of BlockLootTable methods, modified to support varargs
|
||||||
|
protected void dropSelf(List<Block> blocks) {
|
||||||
|
for (Block block : blocks) {
|
||||||
|
if (!skipBlock(block)) {
|
||||||
|
dropSelf(block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void add(Function<Block, LootTable.Builder> factory, Collection<? extends Block> blocks) {
|
||||||
|
for (Block block : blocks) {
|
||||||
|
add(block, factory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void add(Function<Block, Builder> factory, Block... blocks) {
|
||||||
|
for (Block block : blocks) {
|
||||||
|
add(block, factory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like vanilla's {@link BlockLootSubProvider#applyExplosionCondition(ItemLike, ConditionUserBuilder)} except with a boolean for if it is explosion resistant.
|
||||||
|
*/
|
||||||
|
private static <T extends ConditionUserBuilder<T>> T applyExplosionCondition(boolean explosionResistant, ConditionUserBuilder<T> condition) {
|
||||||
|
return explosionResistant ? condition.unwrap() : condition.when(ExplosionCondition.survivesExplosion());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like vanilla's {@link BlockLootSubProvider#createSlabItemTable(Block)} except with a named pool
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
protected LootTable.Builder createSlabItemTable(@NotNull Block slab) {
|
||||||
|
return LootTable.lootTable().withPool(LootPool.lootPool()
|
||||||
|
.name("main")
|
||||||
|
.setRolls(ConstantValue.exactly(1))
|
||||||
|
.add(applyExplosionDecay(slab, LootItem.lootTableItem(slab)
|
||||||
|
.apply(SetItemCountFunction.setCount(ConstantValue.exactly(2))
|
||||||
|
.when(LootItemBlockStatePropertyCondition.hasBlockStateProperties(slab)
|
||||||
|
.setProperties(StatePropertiesPredicate.Builder.properties().hasProperty(SlabBlock.TYPE, SlabType.DOUBLE)))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like vanilla's {@link BlockLootSubProvider#dropOther(Block, ItemLike)} except with a named pool
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void dropOther(@NotNull Block block, @NotNull ItemLike drop) {
|
||||||
|
add(block, createSingleItemTable(drop));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like vanilla's {@link BlockLootSubProvider#createSingleItemTable(ItemLike)} except with a named pool
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public LootTable.Builder createSingleItemTable(@NotNull ItemLike item) {
|
||||||
|
return LootTable.lootTable().withPool(applyExplosionCondition(item, LootPool.lootPool()
|
||||||
|
.name("main")
|
||||||
|
.setRolls(ConstantValue.exactly(1))
|
||||||
|
.add(LootItem.lootTableItem(item))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like vanilla's {@link BlockLootSubProvider#createSingleItemTableWithSilkTouch(Block, ItemLike, NumberProvider)} except with a named pool
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
protected LootTable.Builder createSingleItemTableWithSilkTouch(@NotNull Block block, @NotNull ItemLike item, @NotNull NumberProvider range) {
|
||||||
|
return createSilkTouchDispatchTable(block, applyExplosionDecay(block, LootItem.lootTableItem(item).apply(SetItemCountFunction.setCount(range))));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like vanilla's {@link BlockLootSubProvider#createSilkTouchDispatchTable(Block, LootPoolEntryContainer.Builder)} except with a named pool
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
protected static LootTable.Builder createSilkTouchDispatchTable(@NotNull Block block, @NotNull LootPoolEntryContainer.Builder<?> builder) {
|
||||||
|
return createSelfDropDispatchTable(block, HAS_SILK_TOUCH, builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like vanilla's {@link BlockLootSubProvider#createSelfDropDispatchTable(Block, LootItemCondition.Builder, LootPoolEntryContainer.Builder)} except with a named pool
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
protected static LootTable.Builder createSelfDropDispatchTable(@NotNull Block block, @NotNull LootItemCondition.Builder conditionBuilder,
|
||||||
|
@NotNull LootPoolEntryContainer.Builder<?> entry) {
|
||||||
|
return LootTable.lootTable().withPool(LootPool.lootPool()
|
||||||
|
.name("main")
|
||||||
|
.setRolls(ConstantValue.exactly(1))
|
||||||
|
.add(LootItem.lootTableItem(block)
|
||||||
|
.when(conditionBuilder)
|
||||||
|
.otherwise(entry)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package uk.gemwire.engage.data.loot_tables.block;
|
||||||
|
|
||||||
|
import uk.gemwire.engage.registries.Blocks;
|
||||||
|
import uk.gemwire.engage.registries.Items;
|
||||||
|
|
||||||
|
public class BlockLootTables extends BaseBlockLootTables {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void generate() {
|
||||||
|
add(block -> createOreDrop(block, Items.RAW_BERYLLITE_ITEM.get()), Blocks.BERYLLITE_ORE_BLOCK.get());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package uk.gemwire.engage.data.model.block;
|
||||||
|
|
||||||
|
|
||||||
|
import net.minecraft.data.PackOutput;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.server.packs.PackType;
|
||||||
|
import net.minecraftforge.client.model.generators.BlockModelBuilder;
|
||||||
|
import net.minecraftforge.client.model.generators.BlockModelProvider;
|
||||||
|
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public abstract class BaseBlockModelProvider extends BlockModelProvider {
|
||||||
|
|
||||||
|
public BaseBlockModelProvider(PackOutput output, String modid, ExistingFileHelper existingFileHelper) {
|
||||||
|
super(output, modid, existingFileHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Block model provider: " + modid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockModelBuilder sideBottomTop(String name, ResourceLocation parent, ResourceLocation texture) {
|
||||||
|
return withExistingParent(name, parent)
|
||||||
|
.texture("side", texture)
|
||||||
|
.texture("bottom", texture)
|
||||||
|
.texture("top", texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean textureExists(ResourceLocation texture) {
|
||||||
|
return existingFileHelper.exists(texture, PackType.CLIENT_RESOURCES, ".png", "textures");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package uk.gemwire.engage.data.model.block;
|
||||||
|
|
||||||
|
import net.minecraft.data.PackOutput;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||||
|
|
||||||
|
public class BlockModelProvider extends BaseBlockModelProvider {
|
||||||
|
|
||||||
|
public BlockModelProvider(PackOutput output, ExistingFileHelper existingFileHelper) {
|
||||||
|
super(output, "engage", existingFileHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void registerModels() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
package uk.gemwire.engage.data.model.item;
|
||||||
|
|
||||||
|
|
||||||
|
import net.minecraft.data.PackOutput;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.server.packs.PackType;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.level.ItemLike;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraftforge.client.model.generators.ItemModelBuilder;
|
||||||
|
import net.minecraftforge.client.model.generators.ItemModelProvider;
|
||||||
|
import net.minecraftforge.client.model.generators.loaders.DynamicFluidContainerModelBuilder;
|
||||||
|
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import uk.gemwire.engage.registries.fluid.FluidDeferredRegister;
|
||||||
|
import uk.gemwire.engage.registries.fluid.FluidRegistryObject;
|
||||||
|
|
||||||
|
public abstract class BaseItemModelProvider extends ItemModelProvider {
|
||||||
|
|
||||||
|
protected BaseItemModelProvider(PackOutput output, String modid, ExistingFileHelper existingFileHelper) {
|
||||||
|
super(output, modid, existingFileHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String blockPath(Block block) {
|
||||||
|
return ForgeRegistries.BLOCKS.getKey(block).getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String itemPath(Item item) {
|
||||||
|
return ForgeRegistries.ITEMS.getKey(item).getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Item model provider: " + modid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean textureExists(ResourceLocation texture) {
|
||||||
|
return existingFileHelper.exists(texture, PackType.CLIENT_RESOURCES, ".png", "textures");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ResourceLocation itemTexture(ItemLike itemProvider) {
|
||||||
|
return modLoc("item/" + itemPath(itemProvider.asItem()));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void registerGenerated(ItemLike... itemProviders) {
|
||||||
|
for (ItemLike itemProvider : itemProviders) {
|
||||||
|
generated(itemProvider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void registerBuckets(FluidDeferredRegister register) {
|
||||||
|
for (FluidRegistryObject<?, ?, ?, ?, ?> fluidRegistryObject : register.getAllFluids()) {
|
||||||
|
registerBucket(fluidRegistryObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ItemModelBuilder generated(ItemLike itemProvider) {
|
||||||
|
return generated(itemProvider, itemTexture(itemProvider));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ItemModelBuilder generated(ItemLike itemProvider, ResourceLocation texture) {
|
||||||
|
return withExistingParent(itemPath(itemProvider.asItem()), "item/generated").texture("layer0", texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ItemModelBuilder resource(ItemLike itemProvider, String type) {
|
||||||
|
//TODO: Try to come up with a better solution to this. Currently we have an empty texture for layer zero so that we can set
|
||||||
|
// the tint only on layer one so that we only end up having the tint show for this fallback texture
|
||||||
|
ItemModelBuilder modelBuilder = generated(itemProvider, modLoc("item/empty")).texture("layer1", modLoc("item/" + type));
|
||||||
|
ResourceLocation overlay = modLoc("item/" + type + "_overlay");
|
||||||
|
if (textureExists(overlay)) {
|
||||||
|
//If we have an overlay type for that resource type then add that as another layer
|
||||||
|
modelBuilder = modelBuilder.texture("layer2", overlay);
|
||||||
|
}
|
||||||
|
return modelBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void registerHandheld(ItemLike... itemProviders) {
|
||||||
|
for (ItemLike itemProvider : itemProviders) {
|
||||||
|
handheld(itemProvider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ItemModelBuilder handheld(ItemLike itemProvider) {
|
||||||
|
return handheld(itemProvider, itemTexture(itemProvider));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ItemModelBuilder handheld(ItemLike itemProvider, ResourceLocation texture) {
|
||||||
|
return withExistingParent(itemPath(itemProvider.asItem()), "item/handheld").texture("layer0", texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Note: This isn't the best way to do this in terms of model file validation, but it works
|
||||||
|
protected void registerBucket(FluidRegistryObject<?, ?, ?, ?, ?> fluidRO) {
|
||||||
|
withExistingParent(ForgeRegistries.ITEMS.getKey(fluidRO.getBucket()).getPath(), new ResourceLocation("forge", "item/bucket"))
|
||||||
|
.customLoader(DynamicFluidContainerModelBuilder::begin)
|
||||||
|
.fluid(fluidRO.getStillFluid());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package uk.gemwire.engage.data.model.item;
|
||||||
|
|
||||||
|
import net.minecraft.data.PackOutput;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
import net.minecraftforge.registries.RegistryObject;
|
||||||
|
import uk.gemwire.engage.registries.Blocks;
|
||||||
|
import uk.gemwire.engage.registries.Fluids;
|
||||||
|
import uk.gemwire.engage.registries.Items;
|
||||||
|
|
||||||
|
public class ItemModelProvider extends BaseItemModelProvider {
|
||||||
|
|
||||||
|
public ItemModelProvider(PackOutput output, ExistingFileHelper existingFileHelper) {
|
||||||
|
super(output, "engage", existingFileHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResourceLocation key(Block block) {
|
||||||
|
return ForgeRegistries.BLOCKS.getKey(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String name(Block block) {
|
||||||
|
return key(block).getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResourceLocation key(Item item) {
|
||||||
|
return ForgeRegistries.ITEMS.getKey(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String name(Item item) {
|
||||||
|
return key(item).getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void registerModels() {
|
||||||
|
registerBuckets(Fluids.FLUIDS_REGISTRY);
|
||||||
|
generated(Items.RAW_BERYLLITE_ITEM.get(), new ResourceLocation("minecraft:item/gold_ingot"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void blockParent(RegistryObject<Item> item, RegistryObject<Block> block) {
|
||||||
|
withExistingParent(name(item.get()), modLoc(BLOCK_FOLDER + name(block.get())));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package uk.gemwire.engage.data.sprites;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.texture.atlas.sources.DirectoryLister;
|
||||||
|
import net.minecraft.client.renderer.texture.atlas.sources.SingleFile;
|
||||||
|
import net.minecraft.data.PackOutput;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||||
|
import net.minecraftforge.common.data.SpriteSourceProvider;
|
||||||
|
import uk.gemwire.engage.registries.fluid.FluidDeferredRegister;
|
||||||
|
import uk.gemwire.engage.registries.fluid.FluidRegistryObject;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class BaseSpriteSourceProvider extends SpriteSourceProvider {
|
||||||
|
|
||||||
|
private final Set<ResourceLocation> trackedSingles = new HashSet<>();
|
||||||
|
|
||||||
|
protected BaseSpriteSourceProvider(PackOutput output, String modid, ExistingFileHelper fileHelper) {
|
||||||
|
super(output, fileHelper, modid);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addFiles(SourceList atlas, ResourceLocation... resourceLocations) {
|
||||||
|
for (ResourceLocation rl : resourceLocations) {
|
||||||
|
//Only add this source if we haven't already added it as a direct single file source
|
||||||
|
if (trackedSingles.add(rl)) {
|
||||||
|
atlas.addSource(new SingleFile(rl, Optional.empty()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addFluids(SourceList atlas, FluidDeferredRegister register) {
|
||||||
|
for (FluidRegistryObject<? extends FluidDeferredRegister.MekanismFluidType, ?, ?, ?, ?> fluidRO : register.getAllFluids()) {
|
||||||
|
FluidDeferredRegister.MekanismFluidType fluidType = fluidRO.getFluidType();
|
||||||
|
addFiles(atlas, fluidType.stillTexture, fluidType.flowingTexture, fluidType.overlayTexture, fluidType.renderOverlayTexture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addDirectory(SourceList atlas, String directory, String spritePrefix) {
|
||||||
|
atlas.addSource(new DirectoryLister(directory, spritePrefix));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addSources() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package uk.gemwire.engage.data.sprites;
|
||||||
|
|
||||||
|
import net.minecraft.data.PackOutput;
|
||||||
|
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||||
|
import uk.gemwire.engage.registries.Fluids;
|
||||||
|
|
||||||
|
public class SpriteSourceProvider extends BaseSpriteSourceProvider {
|
||||||
|
|
||||||
|
|
||||||
|
public SpriteSourceProvider(PackOutput output, ExistingFileHelper fileHelper) {
|
||||||
|
super(output, "engage", fileHelper);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void addSources() {
|
||||||
|
SourceList atlas = atlas(BLOCKS_ATLAS);
|
||||||
|
|
||||||
|
addFluids(atlas, Fluids.FLUIDS_REGISTRY);
|
||||||
|
}
|
||||||
|
}
|
202
src/data/java/uk/gemwire/engage/data/tags/BaseTagProvider.java
Normal file
202
src/data/java/uk/gemwire/engage/data/tags/BaseTagProvider.java
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
package uk.gemwire.engage.data.tags;
|
||||||
|
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
|
||||||
|
import net.minecraft.core.HolderLookup;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.core.registries.Registries;
|
||||||
|
import net.minecraft.data.CachedOutput;
|
||||||
|
import net.minecraft.data.DataProvider;
|
||||||
|
import net.minecraft.data.PackOutput;
|
||||||
|
import net.minecraft.data.tags.TagsProvider;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.tags.TagBuilder;
|
||||||
|
import net.minecraft.tags.TagKey;
|
||||||
|
import net.minecraft.world.damagesource.DamageType;
|
||||||
|
import net.minecraft.world.effect.MobEffect;
|
||||||
|
import net.minecraft.world.entity.EntityType;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.level.ItemLike;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
|
import net.minecraft.world.level.gameevent.GameEvent;
|
||||||
|
import net.minecraft.world.level.material.Fluid;
|
||||||
|
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
import net.minecraftforge.registries.IForgeRegistry;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import uk.gemwire.engage.registries.fluid.FluidRegistryObject;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public abstract class BaseTagProvider implements DataProvider {
|
||||||
|
|
||||||
|
private final Map<ResourceKey<? extends Registry<?>>, Map<TagKey<?>, TagBuilder>> supportedTagTypes = new Object2ObjectLinkedOpenHashMap<>();
|
||||||
|
private final Set<Block> knownHarvestRequirements = new ReferenceOpenHashSet<>();
|
||||||
|
private final CompletableFuture<HolderLookup.Provider> lookupProvider;
|
||||||
|
private final ExistingFileHelper existingFileHelper;
|
||||||
|
private final PackOutput output;
|
||||||
|
private final String modid;
|
||||||
|
|
||||||
|
protected BaseTagProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> lookupProvider, String modid, @Nullable ExistingFileHelper existingFileHelper) {
|
||||||
|
this.output = output;
|
||||||
|
this.modid = modid;
|
||||||
|
this.lookupProvider = lookupProvider;
|
||||||
|
this.existingFileHelper = existingFileHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Tags: " + modid;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void registerTags(HolderLookup.Provider registries);
|
||||||
|
|
||||||
|
protected List<Block> getAllBlocks() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void hasHarvestData(Block block) {
|
||||||
|
knownHarvestRequirements.add(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<?> run(@NotNull CachedOutput cache) {
|
||||||
|
return this.lookupProvider.thenApply(registries -> {
|
||||||
|
supportedTagTypes.values().forEach(Map::clear);
|
||||||
|
registerTags(registries);
|
||||||
|
return registries;
|
||||||
|
}).thenCompose(registries -> {
|
||||||
|
for (Block block : getAllBlocks()) {
|
||||||
|
if (block.defaultBlockState().requiresCorrectToolForDrops() && !knownHarvestRequirements.contains(block)) {
|
||||||
|
throw new IllegalStateException("Missing harvest tool type for block '" + ForgeRegistries.BLOCKS.getKey(block) + "' that requires the correct tool for drops.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<CompletableFuture<?>> futures = new ArrayList<>();
|
||||||
|
supportedTagTypes.forEach((registry, tagTypeMap) -> {
|
||||||
|
if (!tagTypeMap.isEmpty()) {
|
||||||
|
//Create a dummy provider and pass all our collected data through to it
|
||||||
|
futures.add(new TagsProvider(output, registry, lookupProvider, modid, existingFileHelper) {
|
||||||
|
@Override
|
||||||
|
protected void addTags(@NotNull HolderLookup.Provider lookupProvider) {
|
||||||
|
//Add each tag builder to the wrapped provider's builder
|
||||||
|
tagTypeMap.forEach((tag, tagBuilder) -> builders.put(tag.location(), tagBuilder));
|
||||||
|
}
|
||||||
|
}.run(cache));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private <TYPE> Map<TagKey<?>, TagBuilder> getTagTypeMap(ResourceKey<? extends Registry<TYPE>> registry) {
|
||||||
|
return supportedTagTypes.computeIfAbsent(registry, type -> new Object2ObjectLinkedOpenHashMap<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
private <TYPE> TagBuilder getTagBuilder(ResourceKey<? extends Registry<TYPE>> registry, TagKey<TYPE> tag) {
|
||||||
|
return getTagTypeMap(registry).computeIfAbsent(tag, ignored -> TagBuilder.create());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <TYPE> EngageTagBuilder<TYPE, ?> getBuilder(ResourceKey<? extends Registry<TYPE>> registry, TagKey<TYPE> tag) {
|
||||||
|
return new EngageTagBuilder<>(getTagBuilder(registry, tag), modid);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <TYPE> IntrinsicEngageTagBuilder<TYPE> getBuilder(ResourceKey<? extends Registry<TYPE>> registry, Function<TYPE, ResourceKey<TYPE>> keyExtractor, TagKey<TYPE> tag) {
|
||||||
|
return new IntrinsicEngageTagBuilder<>(keyExtractor, getTagBuilder(registry, tag), modid);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <TYPE> IntrinsicEngageTagBuilder<TYPE> getBuilder(IForgeRegistry<TYPE> registry, TagKey<TYPE> tag) {
|
||||||
|
return new IntrinsicEngageTagBuilder<>(element -> registry.getResourceKey(element).orElseThrow(), getTagBuilder(registry.getRegistryKey(), tag), modid);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IntrinsicEngageTagBuilder<Item> getItemBuilder(TagKey<Item> tag) {
|
||||||
|
return getBuilder(ForgeRegistries.ITEMS, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IntrinsicEngageTagBuilder<Block> getBlockBuilder(TagKey<Block> tag) {
|
||||||
|
return getBuilder(ForgeRegistries.BLOCKS, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IntrinsicEngageTagBuilder<EntityType<?>> getEntityTypeBuilder(TagKey<EntityType<?>> tag) {
|
||||||
|
return getBuilder(ForgeRegistries.ENTITY_TYPES, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IntrinsicEngageTagBuilder<Fluid> getFluidBuilder(TagKey<Fluid> tag) {
|
||||||
|
return getBuilder(ForgeRegistries.FLUIDS, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IntrinsicEngageTagBuilder<BlockEntityType<?>> getTileEntityTypeBuilder(TagKey<BlockEntityType<?>> tag) {
|
||||||
|
return getBuilder(ForgeRegistries.BLOCK_ENTITY_TYPES, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IntrinsicEngageTagBuilder<GameEvent> getGameEventBuilder(TagKey<GameEvent> tag) {
|
||||||
|
return getBuilder(Registries.GAME_EVENT, gameEvent -> gameEvent.builtInRegistryHolder().key(), tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected EngageTagBuilder<DamageType, ?> getDamageTypeBuilder(TagKey<DamageType> tag) {
|
||||||
|
return getBuilder(Registries.DAMAGE_TYPE, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IntrinsicEngageTagBuilder<MobEffect> getMobEffectBuilder(TagKey<MobEffect> tag) {
|
||||||
|
return getBuilder(ForgeRegistries.MOB_EFFECTS, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addToTag(TagKey<Item> tag, ItemLike... itemProviders) {
|
||||||
|
getItemBuilder(tag).addTyped(ItemLike::asItem, itemProviders);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addToTag(TagKey<Block> tag, Block... blocks) {
|
||||||
|
getBlockBuilder(tag).addTyped(b -> b, blocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
protected final void addToTag(TagKey<Block> blockTag, Map<?, ? extends Block>... blocks) {
|
||||||
|
IntrinsicEngageTagBuilder<Block> tagBuilder = getBlockBuilder(blockTag);
|
||||||
|
for (Map<?, ? extends Block> entry : blocks) {
|
||||||
|
for (Block value : entry.values()) {
|
||||||
|
tagBuilder.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addToHarvestTag(TagKey<Block> tag, Block... blockProviders) {
|
||||||
|
IntrinsicEngageTagBuilder<Block> tagBuilder = getBlockBuilder(tag);
|
||||||
|
for (Block block : blockProviders) {
|
||||||
|
tagBuilder.add(block);
|
||||||
|
hasHarvestData(block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
protected final void addToHarvestTag(TagKey<Block> blockTag, Map<?, ? extends Block>... blockProviders) {
|
||||||
|
IntrinsicEngageTagBuilder<Block> tagBuilder = getBlockBuilder(blockTag);
|
||||||
|
for (Map<?, ? extends Block> blockProvider : blockProviders) {
|
||||||
|
for (Block block : blockProvider.values()) {
|
||||||
|
tagBuilder.add(block);
|
||||||
|
hasHarvestData(block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addToTags(TagKey<Item> itemTag, TagKey<Block> blockTag, Block... blockProviders) {
|
||||||
|
IntrinsicEngageTagBuilder<Item> itemTagBuilder = getItemBuilder(itemTag);
|
||||||
|
IntrinsicEngageTagBuilder<Block> blockTagBuilder = getBlockBuilder(blockTag);
|
||||||
|
for (Block blockProvider : blockProviders) {
|
||||||
|
itemTagBuilder.add(blockProvider.asItem());
|
||||||
|
blockTagBuilder.add(blockProvider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addToTag(TagKey<Fluid> tag, FluidRegistryObject<?, ?, ?, ?, ?>... fluidRegistryObjects) {
|
||||||
|
IntrinsicEngageTagBuilder<Fluid> tagBuilder = getFluidBuilder(tag);
|
||||||
|
for (FluidRegistryObject<?, ?, ?, ?, ?> fluidRO : fluidRegistryObjects) {
|
||||||
|
tagBuilder.add(fluidRO.getStillFluid(), fluidRO.getFlowingFluid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
108
src/data/java/uk/gemwire/engage/data/tags/EngageTagBuilder.java
Normal file
108
src/data/java/uk/gemwire/engage/data/tags/EngageTagBuilder.java
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
package uk.gemwire.engage.data.tags;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.tags.TagBuilder;
|
||||||
|
import net.minecraft.tags.TagEntry;
|
||||||
|
import net.minecraft.tags.TagKey;
|
||||||
|
|
||||||
|
// Stolen from Mekanism
|
||||||
|
public class EngageTagBuilder<TYPE, BUILDER extends EngageTagBuilder<TYPE, BUILDER>> {
|
||||||
|
|
||||||
|
protected final TagBuilder builder;
|
||||||
|
protected final String modID;
|
||||||
|
|
||||||
|
public EngageTagBuilder(TagBuilder builder, String modID) {
|
||||||
|
this.builder = builder;
|
||||||
|
this.modID = modID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private BUILDER getThis() {
|
||||||
|
return (BUILDER) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public final BUILDER add(TagKey<TYPE>... tags) {
|
||||||
|
return apply(builder::addTag, TagKey::location, tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BUILDER add(TagEntry tag) {
|
||||||
|
builder.add(tag);
|
||||||
|
return getThis();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public final BUILDER add(ResourceKey<TYPE>... keys) {
|
||||||
|
return add(ResourceKey::location, keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public final <T> BUILDER add(Function<T, ResourceLocation> locationGetter, T... elements) {
|
||||||
|
return apply(builder::addElement, locationGetter, elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BUILDER replace() {
|
||||||
|
return replace(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BUILDER replace(boolean value) {
|
||||||
|
builder.replace(value);
|
||||||
|
return getThis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BUILDER addOptional(ResourceLocation... locations) {
|
||||||
|
return addOptional(Function.identity(), locations);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public final <T> BUILDER addOptional(Function<T, ResourceLocation> locationGetter, T... elements) {
|
||||||
|
return add(TagEntry::optionalElement, locationGetter, elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public final BUILDER addOptionalTag(TagKey<TYPE>... tags) {
|
||||||
|
return addOptionalTag(TagKey::location, tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BUILDER addOptionalTag(ResourceLocation... locations) {
|
||||||
|
return addOptionalTag(Function.identity(), locations);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public final <T> BUILDER addOptionalTag(Function<T, ResourceLocation> locationGetter, T... elements) {
|
||||||
|
return add(TagEntry::optionalTag, locationGetter, elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
private <T> BUILDER add(Function<ResourceLocation, TagEntry> entryCreator, Function<T, ResourceLocation> locationGetter, T... elements) {
|
||||||
|
return apply(rl -> add(entryCreator.apply(rl)), locationGetter, elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BUILDER remove(ResourceLocation... locations) {
|
||||||
|
return remove(Function.identity(), locations);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public final <T> BUILDER remove(Function<T, ResourceLocation> locationGetter, T... elements) {
|
||||||
|
return apply(rl -> builder.removeElement(rl, modID), locationGetter, elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public final BUILDER remove(TagKey<TYPE>... tags) {
|
||||||
|
for (TagKey<TYPE> tag : tags) {
|
||||||
|
builder.removeTag(tag.location(), modID);
|
||||||
|
}
|
||||||
|
return getThis();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
protected final <T> BUILDER apply(Consumer<ResourceLocation> consumer, Function<T, ResourceLocation> locationGetter, T... elements) {
|
||||||
|
for (T element : elements) {
|
||||||
|
consumer.accept(locationGetter.apply(element));
|
||||||
|
}
|
||||||
|
return getThis();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package uk.gemwire.engage.data.tags;
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.tags.TagBuilder;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class IntrinsicEngageTagBuilder<TYPE> extends EngageTagBuilder<TYPE, IntrinsicEngageTagBuilder<TYPE>> {
|
||||||
|
|
||||||
|
private final Function<TYPE, ResourceKey<TYPE>> keyExtractor;
|
||||||
|
|
||||||
|
public IntrinsicEngageTagBuilder (Function<TYPE, ResourceKey<TYPE>> keyExtractor, TagBuilder builder, String modID) {
|
||||||
|
super(builder, modID);
|
||||||
|
this.keyExtractor = keyExtractor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public final IntrinsicEngageTagBuilder<TYPE> add(Supplier<TYPE>... elements) {
|
||||||
|
return addTyped(Supplier::get, elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceLocation getKey(TYPE element) {
|
||||||
|
return keyExtractor.apply(element).location();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public final IntrinsicEngageTagBuilder<TYPE> add(TYPE... elements) {
|
||||||
|
return add(this::getKey, elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public final <T> IntrinsicEngageTagBuilder<TYPE> addTyped(Function<T, TYPE> converter, T... elements) {
|
||||||
|
return add(converter.andThen(this::getKey), elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public final IntrinsicEngageTagBuilder<TYPE> addOptional(TYPE... elements) {
|
||||||
|
return addOptional(this::getKey, elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public final IntrinsicEngageTagBuilder<TYPE> remove(TYPE... elements) {
|
||||||
|
return remove(this::getKey, elements);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package uk.gemwire.engage.data.tags.block;
|
||||||
|
|
||||||
|
|
||||||
|
import net.minecraft.core.HolderLookup;
|
||||||
|
import net.minecraft.data.PackOutput;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.tags.BlockTags;
|
||||||
|
import net.minecraft.tags.ItemTags;
|
||||||
|
import net.minecraft.tags.TagKey;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraftforge.common.Tags;
|
||||||
|
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
import net.minecraftforge.registries.RegistryObject;
|
||||||
|
import uk.gemwire.engage.data.tags.BaseTagProvider;
|
||||||
|
import uk.gemwire.engage.data.tags.IntrinsicEngageTagBuilder;
|
||||||
|
import uk.gemwire.engage.registries.Blocks;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class BlockTagProvider extends BaseTagProvider {
|
||||||
|
|
||||||
|
public BlockTagProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> lookupProvider, @Nullable ExistingFileHelper existingFileHelper) {
|
||||||
|
super(output, lookupProvider, "engage", existingFileHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<Block> getAllBlocks() {
|
||||||
|
return Blocks.BLOCKS_REGISTRY.getEntries().stream().map(RegistryObject::get).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void registerTags(HolderLookup.Provider registries) {
|
||||||
|
addOres();
|
||||||
|
addHarvests();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addOres() {
|
||||||
|
List<Block> ores = List.of(Blocks.BERYLLITE_ORE_BLOCK.get());
|
||||||
|
for (Block ore : ores) {
|
||||||
|
TagKey<Item> itemTag = ItemTags.create(new ResourceLocation("forge:ores/" + ForgeRegistries.ITEMS.getKey(ore.asItem()).getPath()));
|
||||||
|
TagKey<Block> blockTag = BlockTags.create(new ResourceLocation("forge:ores/" + ForgeRegistries.BLOCKS.getKey(ore).getPath()));
|
||||||
|
addToTags(itemTag, blockTag, ore);
|
||||||
|
getItemBuilder(Tags.Items.ORES).add(itemTag);
|
||||||
|
getBlockBuilder(Tags.Blocks.ORES).add(blockTag);
|
||||||
|
|
||||||
|
addToTags(Tags.Items.ORE_RATES_SINGULAR, Tags.Blocks.ORE_RATES_SINGULAR, ore);
|
||||||
|
|
||||||
|
//addToTags(Tags.Items.ORES_IN_GROUND_DEEPSLATE, Tags.Blocks.ORES_IN_GROUND_DEEPSLATE, oreBlockType.deepslate());
|
||||||
|
addToTags(Tags.Items.ORES_IN_GROUND_STONE, Tags.Blocks.ORES_IN_GROUND_STONE, ore);
|
||||||
|
addToTag(BlockTags.OVERWORLD_CARVER_REPLACEABLES, ore);
|
||||||
|
addToTag(BlockTags.SNAPS_GOAT_HORN, ore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addHarvests() {
|
||||||
|
addIronToolBlock(Blocks.BERYLLITE_ORE_BLOCK.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addIronToolBlock(Block b) {
|
||||||
|
addToHarvestTag(BlockTags.MINEABLE_WITH_PICKAXE, b);
|
||||||
|
getBlockBuilder(BlockTags.NEEDS_IRON_TOOL).add(b);
|
||||||
|
hasHarvestData(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
// 1.20.1 2023-06-30T03:19:18.0172666 Item model provider: engage
|
||||||
|
b3abd1796143a506e2c7f2ffdefeb61e235a8689 assets/engage/models/item/antideuterium_bucket.json
|
||||||
|
cfeee2aee8fab94a821a49be3ce0d110c857e1b1 assets/engage/models/item/beryllite_raw.json
|
||||||
|
ca322f154c4d4ab99647bfa2ebb939b9284fad9a assets/engage/models/item/deuterium_bucket.json
|
||||||
|
725bfdd287ed277d7b78d3a295ea5a71b63b40fa assets/engage/models/item/deuterium_slush_bucket.json
|
||||||
|
50ee03ab71a0bc46941091c9c8cb8f9b516368c7 assets/engage/models/item/heavy_water_bucket.json
|
||||||
|
226a78ddeaaecb840cb16d7b6236f62978adbb72 assets/engage/models/item/propane_bucket.json
|
||||||
|
2537ffcc0380ed93e47909ce598b76ee501bb5f3 assets/engage/models/item/warp_plasma_bucket.json
|
|
@ -0,0 +1,2 @@
|
||||||
|
// 1.20.1 2023-06-30T03:04:16.2684959 Loot Tables
|
||||||
|
22933ac7663f965e6fe3c560231b4bcb76c43bfa data/engage/loot_tables/blocks/beryllite_ore.json
|
|
@ -0,0 +1,2 @@
|
||||||
|
// 1.20.1 2023-06-30T03:04:16.2664787 atlases generator for engage
|
||||||
|
11e6e1f83c37071af466a42d29a662f54c2253c8 assets/minecraft/atlases/blocks.json
|
|
@ -0,0 +1 @@
|
||||||
|
// 1.20.1 2023-06-30T03:19:18.0192671 Block model provider: engage
|
|
@ -0,0 +1,16 @@
|
||||||
|
// 1.20.1 2023-06-30T03:19:18.0203012 Block state provider: engage
|
||||||
|
4af9c861d7727e9ee266ca6e10d9c78c9e4104ba assets/engage/blockstates/antideuterium.json
|
||||||
|
163e87835e33814e2cad190c2265142f42e18ba9 assets/engage/blockstates/beryllite_ore.json
|
||||||
|
38881f2039561be97bb6ea53d31ab9db54875fe5 assets/engage/blockstates/deuterium.json
|
||||||
|
620e8e678622f335115b86475f40e518de4f9cba assets/engage/blockstates/deuterium_slush.json
|
||||||
|
8c9558de31b0459d70da1d07b499138e6248e38c assets/engage/blockstates/heavy_water.json
|
||||||
|
b58e421acd852f85bc9fee8f837609c8471b90b7 assets/engage/blockstates/propane.json
|
||||||
|
9b31876df3da1b32ac5639c48cab2ce60cc876ad assets/engage/blockstates/warp_plasma.json
|
||||||
|
f077c95c66d98f808227df298031ba934827bbfc assets/engage/models/block/antideuterium.json
|
||||||
|
9356d6cfcd705b3474cec35599e7709fb9f0954a assets/engage/models/block/beryllite_ore.json
|
||||||
|
f077c95c66d98f808227df298031ba934827bbfc assets/engage/models/block/deuterium.json
|
||||||
|
f077c95c66d98f808227df298031ba934827bbfc assets/engage/models/block/deuterium_slush.json
|
||||||
|
f077c95c66d98f808227df298031ba934827bbfc assets/engage/models/block/heavy_water.json
|
||||||
|
f077c95c66d98f808227df298031ba934827bbfc assets/engage/models/block/propane.json
|
||||||
|
f077c95c66d98f808227df298031ba934827bbfc assets/engage/models/block/warp_plasma.json
|
||||||
|
45314b766210255f87067ff2a93913e89b07f7ec assets/engage/models/item/beryllite_ore.json
|
|
@ -0,0 +1,13 @@
|
||||||
|
// 1.20.1 2023-06-30T03:04:16.2714951 Tags: engage
|
||||||
|
36ddf7e815c8651764d9b434226769617f395c02 data/forge/tags/blocks/ores.json
|
||||||
|
af866d91e488f4393cdfb764b61ac425837ec4a6 data/forge/tags/blocks/ores/beryllite_ore.json
|
||||||
|
af866d91e488f4393cdfb764b61ac425837ec4a6 data/forge/tags/blocks/ores_in_ground/stone.json
|
||||||
|
af866d91e488f4393cdfb764b61ac425837ec4a6 data/forge/tags/blocks/ore_rates/singular.json
|
||||||
|
36ddf7e815c8651764d9b434226769617f395c02 data/forge/tags/items/ores.json
|
||||||
|
af866d91e488f4393cdfb764b61ac425837ec4a6 data/forge/tags/items/ores/beryllite_ore.json
|
||||||
|
af866d91e488f4393cdfb764b61ac425837ec4a6 data/forge/tags/items/ores_in_ground/stone.json
|
||||||
|
af866d91e488f4393cdfb764b61ac425837ec4a6 data/forge/tags/items/ore_rates/singular.json
|
||||||
|
af866d91e488f4393cdfb764b61ac425837ec4a6 data/minecraft/tags/blocks/mineable/pickaxe.json
|
||||||
|
af866d91e488f4393cdfb764b61ac425837ec4a6 data/minecraft/tags/blocks/needs_iron_tool.json
|
||||||
|
af866d91e488f4393cdfb764b61ac425837ec4a6 data/minecraft/tags/blocks/overworld_carver_replaceables.json
|
||||||
|
af866d91e488f4393cdfb764b61ac425837ec4a6 data/minecraft/tags/blocks/snaps_goat_horn.json
|
|
@ -0,0 +1,2 @@
|
||||||
|
// 1.20.1 2023-06-30T03:04:16.2694935 Languages: en_us
|
||||||
|
50b8d51f4adf81848b9ed702904feddb9c747a09 assets/engage/lang/en_us.json
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "engage:block/antideuterium"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "engage:block/deuterium"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "engage:block/deuterium_slush"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "engage:block/heavy_water"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "engage:block/propane"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "engage:block/warp_plasma"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
src/data/resources/assets/engage/lang/en_us.json
Normal file
15
src/data/resources/assets/engage/lang/en_us.json
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"block.engage.antideuterium": "Antideuterium",
|
||||||
|
"block.engage.beryllite_ore": "Beryllite Ore",
|
||||||
|
"block.engage.deuterium": "Deuterium",
|
||||||
|
"block.engage.deuterium_slush": "Supercooled Deuterium",
|
||||||
|
"block.engage.heavy_water": "Heavy Water",
|
||||||
|
"block.engage.propane": "Propane",
|
||||||
|
"block.engage.warp_plasma": "Warp Plasma",
|
||||||
|
"item.engage.antideuterium_bucket": "Antideuterium Bucket",
|
||||||
|
"item.engage.deuterium_bucket": "Deuterium Bucket",
|
||||||
|
"item.engage.deuterium_slush_bucket": "Supercooled Deuterium Bucket",
|
||||||
|
"item.engage.heavy_water_bucket": "Heavy Water Bucket",
|
||||||
|
"item.engage.propane_bucket": "Propane Bucket",
|
||||||
|
"item.engage.warp_plasma_bucket": "Warp Plasma Bucket"
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"textures": {
|
||||||
|
"particle": "engage:liquid/liquid"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"textures": {
|
||||||
|
"particle": "engage:liquid/liquid"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"textures": {
|
||||||
|
"particle": "engage:liquid/liquid"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"textures": {
|
||||||
|
"particle": "engage:liquid/liquid"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"textures": {
|
||||||
|
"particle": "engage:liquid/liquid"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"textures": {
|
||||||
|
"particle": "engage:liquid/liquid"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"parent": "forge:item/bucket",
|
||||||
|
"fluid": "engage:antideuterium",
|
||||||
|
"loader": "forge:fluid_container"
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"parent": "forge:item/bucket",
|
||||||
|
"fluid": "engage:deuterium",
|
||||||
|
"loader": "forge:fluid_container"
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"parent": "forge:item/bucket",
|
||||||
|
"fluid": "engage:deuterium_slush",
|
||||||
|
"loader": "forge:fluid_container"
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"parent": "forge:item/bucket",
|
||||||
|
"fluid": "engage:heavy_water",
|
||||||
|
"loader": "forge:fluid_container"
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"parent": "forge:item/bucket",
|
||||||
|
"fluid": "engage:propane",
|
||||||
|
"loader": "forge:fluid_container"
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"parent": "forge:item/bucket",
|
||||||
|
"fluid": "engage:warp_plasma",
|
||||||
|
"loader": "forge:fluid_container"
|
||||||
|
}
|
20
src/data/resources/assets/minecraft/atlases/blocks.json
Normal file
20
src/data/resources/assets/minecraft/atlases/blocks.json
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"sources": [
|
||||||
|
{
|
||||||
|
"type": "minecraft:single",
|
||||||
|
"resource": "engage:liquid/liquid"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "minecraft:single",
|
||||||
|
"resource": "engage:liquid/liquid_flow"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "minecraft:single",
|
||||||
|
"resource": "minecraft:block/water_overlay"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "minecraft:single",
|
||||||
|
"resource": "minecraft:misc/underwater"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
{
|
{
|
||||||
"replace": false,
|
|
||||||
"values": [
|
"values": [
|
||||||
"engage:beryllite_ore"
|
"engage:beryllite_ore"
|
||||||
]
|
]
|
5
src/data/resources/data/forge/tags/blocks/ores.json
Normal file
5
src/data/resources/data/forge/tags/blocks/ores.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"values": [
|
||||||
|
"#forge:ores/beryllite_ore"
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
{
|
{
|
||||||
"replace": false,
|
|
||||||
"values": [
|
"values": [
|
||||||
"engage:beryllite_ore"
|
"engage:beryllite_ore"
|
||||||
]
|
]
|
|
@ -1,5 +1,4 @@
|
||||||
{
|
{
|
||||||
"replace": false,
|
|
||||||
"values": [
|
"values": [
|
||||||
"engage:beryllite_ore"
|
"engage:beryllite_ore"
|
||||||
]
|
]
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"values": [
|
||||||
|
"engage:beryllite_ore"
|
||||||
|
]
|
||||||
|
}
|
5
src/data/resources/data/forge/tags/items/ores.json
Normal file
5
src/data/resources/data/forge/tags/items/ores.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"values": [
|
||||||
|
"#forge:ores/beryllite_ore"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"values": [
|
||||||
|
"engage:beryllite_ore"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"values": [
|
||||||
|
"engage:beryllite_ore"
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
{
|
{
|
||||||
"replace": false,
|
|
||||||
"values": [
|
"values": [
|
||||||
"engage:beryllite_ore"
|
"engage:beryllite_ore"
|
||||||
]
|
]
|
|
@ -1,5 +1,4 @@
|
||||||
{
|
{
|
||||||
"replace": false,
|
|
||||||
"values": [
|
"values": [
|
||||||
"engage:beryllite_ore"
|
"engage:beryllite_ore"
|
||||||
]
|
]
|
|
@ -1,5 +1,4 @@
|
||||||
{
|
{
|
||||||
"replace": false,
|
|
||||||
"values": [
|
"values": [
|
||||||
"engage:beryllite_ore"
|
"engage:beryllite_ore"
|
||||||
]
|
]
|
|
@ -1,5 +1,4 @@
|
||||||
{
|
{
|
||||||
"replace": false,
|
|
||||||
"values": [
|
"values": [
|
||||||
"engage:beryllite_ore"
|
"engage:beryllite_ore"
|
||||||
]
|
]
|
|
@ -4,8 +4,44 @@ import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
import uk.gemwire.engage.registries.Blocks;
|
import uk.gemwire.engage.registries.Blocks;
|
||||||
|
import uk.gemwire.engage.registries.Fluids;
|
||||||
import uk.gemwire.engage.registries.Items;
|
import uk.gemwire.engage.registries.Items;
|
||||||
|
import uk.gemwire.engage.registries.Worldgen;
|
||||||
|
import uk.gemwire.engage.registries.fluid.FluidDeferredRegister;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Engage adds four varieties of Warp Core for power generation, based on:
|
||||||
|
* - The Defiant
|
||||||
|
* - The Enterprise-D
|
||||||
|
* - Voyager
|
||||||
|
* - Kelvin-timeline Enterprise
|
||||||
|
*
|
||||||
|
* The Warp structure itself has 7 components:
|
||||||
|
* - Casing
|
||||||
|
* - Reaction Gel
|
||||||
|
* - Reaction Chamber
|
||||||
|
* - Beryllite Containment Unit
|
||||||
|
* - Input port
|
||||||
|
* - Output vent
|
||||||
|
* - Status Indicator / Control Unit
|
||||||
|
*
|
||||||
|
* To power the Warp Core, you need:
|
||||||
|
* - Supercooled Deuterium
|
||||||
|
* (obtained by putting deuterium gas through a coolant loop)
|
||||||
|
* (deuterium obtained by electrolysis of heavy water)
|
||||||
|
* (heavy water obtained from deep water)
|
||||||
|
* - Contained antideuterium
|
||||||
|
* (contained by magnetic containment unit)
|
||||||
|
* (obtained by ???)
|
||||||
|
*
|
||||||
|
* The reaction generates Warp Plasma, which must be vented through hollow tubes (EPS Conduit), towards a consumer.
|
||||||
|
* Large structures may be created that convert the plasma to usable power.
|
||||||
|
* Power Nacelles:
|
||||||
|
* - Casing
|
||||||
|
* - Warp Gel
|
||||||
|
* = Power port
|
||||||
|
*
|
||||||
|
*/
|
||||||
@Mod("engage")
|
@Mod("engage")
|
||||||
public class Engage {
|
public class Engage {
|
||||||
|
|
||||||
|
@ -14,5 +50,8 @@ public class Engage {
|
||||||
// registry classes
|
// registry classes
|
||||||
Items.ITEMS_REGISTRY.register(bus);
|
Items.ITEMS_REGISTRY.register(bus);
|
||||||
Blocks.BLOCKS_REGISTRY.register(bus);
|
Blocks.BLOCKS_REGISTRY.register(bus);
|
||||||
|
Fluids.FLUIDS_REGISTRY.register(bus);
|
||||||
|
Worldgen.CARVER_REGISTRY.register(bus);
|
||||||
|
Worldgen.BIOME_MODIFIER_SERIALIZERS.register(bus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
28
src/main/java/uk/gemwire/engage/registries/Fluids.java
Normal file
28
src/main/java/uk/gemwire/engage/registries/Fluids.java
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package uk.gemwire.engage.registries;
|
||||||
|
|
||||||
|
import uk.gemwire.engage.registries.fluid.FluidDeferredRegister;
|
||||||
|
import uk.gemwire.engage.registries.fluid.FluidRegistryObject;
|
||||||
|
|
||||||
|
public class Fluids {
|
||||||
|
|
||||||
|
public static final FluidDeferredRegister FLUIDS_REGISTRY = new FluidDeferredRegister("engage");
|
||||||
|
|
||||||
|
// Heavy Water
|
||||||
|
public static final FluidRegistryObject<? extends FluidDeferredRegister.MekanismFluidType, ?, ?, ?, ?> HEAVY_WATER_FLUID = FLUIDS_REGISTRY.register("heavy_water", properties -> properties.tint(0xFFFF3232));
|
||||||
|
|
||||||
|
// Deuterium
|
||||||
|
public static final FluidRegistryObject<? extends FluidDeferredRegister.MekanismFluidType, ?, ?, ?, ?> DEUTERIUM_FLUID = FLUIDS_REGISTRY.register("deuterium", properties -> properties.tint(0xFFFF3232));
|
||||||
|
|
||||||
|
// Deuterium Slush
|
||||||
|
public static final FluidRegistryObject<? extends FluidDeferredRegister.MekanismFluidType, ?, ?, ?, ?> DEUTERIUM_SLUSH_FLUID = FLUIDS_REGISTRY.register("deuterium_slush", properties -> properties.tint(0xFFFF3232));
|
||||||
|
|
||||||
|
// Antideuterium
|
||||||
|
public static final FluidRegistryObject<? extends FluidDeferredRegister.MekanismFluidType, ?, ?, ?, ?> ANTIDEUTERIUM_FLUID = FLUIDS_REGISTRY.register("antideuterium", properties -> properties.tint(0xFFFF3232));
|
||||||
|
|
||||||
|
// Warp Plasma
|
||||||
|
public static final FluidRegistryObject<? extends FluidDeferredRegister.MekanismFluidType, ?, ?, ?, ?> WARP_PLASMA_FLUID = FLUIDS_REGISTRY.register("warp_plasma", properties -> properties.tint(0xFFFF3232));
|
||||||
|
|
||||||
|
// Propane (refrigerant)
|
||||||
|
public static final FluidRegistryObject<? extends FluidDeferredRegister.MekanismFluidType, ?, ?, ?, ?> PROPANE_FLUID = FLUIDS_REGISTRY.register("propane", properties -> properties.tint(0xFFFF3232));
|
||||||
|
|
||||||
|
}
|
30
src/main/java/uk/gemwire/engage/registries/Worldgen.java
Normal file
30
src/main/java/uk/gemwire/engage/registries/Worldgen.java
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package uk.gemwire.engage.registries;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import net.minecraft.world.level.levelgen.GenerationStep;
|
||||||
|
import net.minecraft.world.level.levelgen.carver.ConfiguredWorldCarver;
|
||||||
|
import net.minecraft.world.level.levelgen.carver.WorldCarver;
|
||||||
|
import net.minecraftforge.common.world.BiomeModifier;
|
||||||
|
import net.minecraftforge.registries.DeferredRegister;
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
import net.minecraftforge.registries.RegistryObject;
|
||||||
|
import uk.gemwire.engage.worldgen.PropaneCaveCarver;
|
||||||
|
import uk.gemwire.engage.worldgen.PropaneCaveCarverConfiguration;
|
||||||
|
import uk.gemwire.engage.worldgen.modifiers.AddCarverBiomeModifier;
|
||||||
|
|
||||||
|
public class Worldgen {
|
||||||
|
public static final DeferredRegister<WorldCarver<?>> CARVER_REGISTRY = DeferredRegister.create(ForgeRegistries.WORLD_CARVERS, "engage");
|
||||||
|
public static final DeferredRegister<Codec<? extends BiomeModifier>> BIOME_MODIFIER_SERIALIZERS = DeferredRegister.create(ForgeRegistries.Keys.BIOME_MODIFIER_SERIALIZERS, "engage");
|
||||||
|
|
||||||
|
public static final RegistryObject<WorldCarver<?>> PROPANE_CARVER = CARVER_REGISTRY.register("propane_cave", () -> new PropaneCaveCarver(PropaneCaveCarverConfiguration.CODEC));
|
||||||
|
|
||||||
|
public static final RegistryObject<Codec<AddCarverBiomeModifier>> ADD_CARVERS_BIOME_MODIFIER_TYPE = Worldgen.BIOME_MODIFIER_SERIALIZERS.register("add_carvers", () ->
|
||||||
|
RecordCodecBuilder.create(builder -> builder.group(
|
||||||
|
Biome.LIST_CODEC.fieldOf("biomes").forGetter(AddCarverBiomeModifier::biomes),
|
||||||
|
ConfiguredWorldCarver.LIST_CODEC.fieldOf("carvers").forGetter(AddCarverBiomeModifier::carvers),
|
||||||
|
GenerationStep.Carving.CODEC.fieldOf("step").forGetter(AddCarverBiomeModifier::step)
|
||||||
|
).apply(builder, AddCarverBiomeModifier::new))
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,254 @@
|
||||||
|
package uk.gemwire.engage.registries.fluid;
|
||||||
|
|
||||||
|
|
||||||
|
import net.minecraft.Util;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.BlockSource;
|
||||||
|
import net.minecraft.core.dispenser.DefaultDispenseItemBehavior;
|
||||||
|
import net.minecraft.core.dispenser.DispenseItemBehavior;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.sounds.SoundEvents;
|
||||||
|
import net.minecraft.world.item.*;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.DispenserBlock;
|
||||||
|
import net.minecraft.world.level.block.LiquidBlock;
|
||||||
|
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||||
|
import net.minecraft.world.level.material.Fluid;
|
||||||
|
import net.minecraft.world.level.material.MapColor;
|
||||||
|
import net.minecraft.world.level.material.PushReaction;
|
||||||
|
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;
|
||||||
|
import net.minecraftforge.common.SoundActions;
|
||||||
|
import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
|
import net.minecraftforge.fluids.FluidType;
|
||||||
|
import net.minecraftforge.fluids.ForgeFlowingFluid;
|
||||||
|
import net.minecraftforge.registries.DeferredRegister;
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.function.UnaryOperator;
|
||||||
|
|
||||||
|
// Yoinked from https://github.com/mekanism/Mekanism/blob/1.20.x/src/main/java/mekanism/common/registration/impl/FluidDeferredRegister.java
|
||||||
|
public class FluidDeferredRegister {
|
||||||
|
|
||||||
|
private static final ResourceLocation OVERLAY = new ResourceLocation("block/water_overlay");
|
||||||
|
private static final ResourceLocation RENDER_OVERLAY = new ResourceLocation("misc/underwater");
|
||||||
|
private static final ResourceLocation LIQUID = new ResourceLocation("engage", "liquid/liquid");
|
||||||
|
private static final ResourceLocation LIQUID_FLOW = new ResourceLocation("engage", "liquid/liquid_flow");
|
||||||
|
//Copy of/based off of vanilla's lava/water bucket dispense behavior
|
||||||
|
private static final DispenseItemBehavior BUCKET_DISPENSE_BEHAVIOR = new DefaultDispenseItemBehavior() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public ItemStack execute(@NotNull BlockSource source, @NotNull ItemStack stack) {
|
||||||
|
Level world = source.getLevel();
|
||||||
|
DispensibleContainerItem bucket = (DispensibleContainerItem) stack.getItem();
|
||||||
|
BlockPos pos = source.getPos().relative(source.getBlockState().getValue(DispenserBlock.FACING));
|
||||||
|
if (bucket.emptyContents(null, world, pos, null)) {
|
||||||
|
bucket.checkExtraContent(null, world, stack, pos);
|
||||||
|
return new ItemStack(Items.BUCKET);
|
||||||
|
}
|
||||||
|
return super.execute(source, stack);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static FluidType.Properties getMekBaseBuilder() {
|
||||||
|
return FluidType.Properties.create()
|
||||||
|
.sound(SoundActions.BUCKET_FILL, SoundEvents.BUCKET_FILL)
|
||||||
|
.sound(SoundActions.BUCKET_EMPTY, SoundEvents.BUCKET_EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final List<FluidRegistryObject<? extends MekanismFluidType, ?, ?, ?, ?>> allFluids = new ArrayList<>();
|
||||||
|
|
||||||
|
private final DeferredRegister<FluidType> fluidTypeRegister;
|
||||||
|
private final DeferredRegister<Fluid> fluidRegister;
|
||||||
|
private final DeferredRegister<Block> blockRegister;
|
||||||
|
private final DeferredRegister<Item> itemRegister;
|
||||||
|
private final String modid;
|
||||||
|
|
||||||
|
public FluidDeferredRegister(String modid) {
|
||||||
|
this.modid = modid;
|
||||||
|
blockRegister = DeferredRegister.create(ForgeRegistries.BLOCKS, modid);
|
||||||
|
fluidRegister = DeferredRegister.create(ForgeRegistries.FLUIDS, modid);
|
||||||
|
fluidTypeRegister = DeferredRegister.create(ForgeRegistries.Keys.FLUID_TYPES, modid);
|
||||||
|
itemRegister = DeferredRegister.create(ForgeRegistries.ITEMS, modid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FluidRegistryObject<MekanismFluidType, ForgeFlowingFluid.Source, ForgeFlowingFluid.Flowing, LiquidBlock, BucketItem> registerLiquidChemical(IChemicalConstant constants) {
|
||||||
|
int density = Math.round(constants.getDensity());
|
||||||
|
return register(constants.getName(), properties -> properties
|
||||||
|
.temperature(Math.round(constants.getTemperature()))
|
||||||
|
.density(density)
|
||||||
|
.viscosity(density)
|
||||||
|
.lightLevel(constants.getLightLevel()), renderProperties -> renderProperties
|
||||||
|
.tint(constants.getColor())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FluidRegistryObject<MekanismFluidType, ForgeFlowingFluid.Source, ForgeFlowingFluid.Flowing, LiquidBlock, BucketItem> register(String name, UnaryOperator<FluidTypeRenderProperties> renderProperties) {
|
||||||
|
return register(name, UnaryOperator.identity(), renderProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FluidRegistryObject<MekanismFluidType, ForgeFlowingFluid.Source, ForgeFlowingFluid.Flowing, LiquidBlock, BucketItem> register(String name, UnaryOperator<FluidType.Properties> properties,
|
||||||
|
UnaryOperator<FluidTypeRenderProperties> renderProperties) {
|
||||||
|
return register(name, BucketItem::new, properties, renderProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <BUCKET extends BucketItem> FluidRegistryObject<MekanismFluidType, ForgeFlowingFluid.Source, ForgeFlowingFluid.Flowing, LiquidBlock, BUCKET> register(String name, BucketCreator<BUCKET> bucketCreator,
|
||||||
|
UnaryOperator<FluidType.Properties> fluidProperties, UnaryOperator<FluidTypeRenderProperties> renderProperties) {
|
||||||
|
return register(name, fluidProperties.apply(getMekBaseBuilder()), renderProperties.apply(FluidTypeRenderProperties.builder()), bucketCreator,
|
||||||
|
MekanismFluidType::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <TYPE extends MekanismFluidType, BUCKET extends BucketItem> FluidRegistryObject<TYPE, ForgeFlowingFluid.Source, ForgeFlowingFluid.Flowing, LiquidBlock, BUCKET> register(String name,
|
||||||
|
FluidType.Properties properties, FluidTypeRenderProperties renderProperties, BucketCreator<BUCKET> bucketCreator,
|
||||||
|
BiFunction<FluidType.Properties, FluidTypeRenderProperties, TYPE> fluidTypeCreator) {
|
||||||
|
String flowingName = "flowing_" + name;
|
||||||
|
String bucketName = name + "_bucket";
|
||||||
|
//Set the translation string to the same as the block
|
||||||
|
properties.descriptionId(Util.makeDescriptionId("block", new ResourceLocation(modid, name)));
|
||||||
|
//Create the registry object and let the values init to null as before we actually call get on them, we will update the backing values
|
||||||
|
FluidRegistryObject<TYPE, ForgeFlowingFluid.Source, ForgeFlowingFluid.Flowing, LiquidBlock, BUCKET> fluidRegistryObject = new FluidRegistryObject<>();
|
||||||
|
//Pass in suppliers that are wrapped instead of direct references to the registry objects, so that when we update the registry object to
|
||||||
|
// point to a new object it gets updated properly.
|
||||||
|
ForgeFlowingFluid.Properties fluidProperties = new ForgeFlowingFluid.Properties(fluidRegistryObject::getFluidType, fluidRegistryObject::getStillFluid,
|
||||||
|
fluidRegistryObject::getFlowingFluid).bucket(fluidRegistryObject::getBucket).block(fluidRegistryObject::getBlock);
|
||||||
|
//Update the references to objects that are retrieved from the deferred registers
|
||||||
|
fluidRegistryObject.updateFluidType(fluidTypeRegister.register(name, () -> fluidTypeCreator.apply(properties, renderProperties)));
|
||||||
|
fluidRegistryObject.updateStill(fluidRegister.register(name, () -> new ForgeFlowingFluid.Source(fluidProperties)));
|
||||||
|
fluidRegistryObject.updateFlowing(fluidRegister.register(flowingName, () -> new ForgeFlowingFluid.Flowing(fluidProperties)));
|
||||||
|
fluidRegistryObject.updateBucket(itemRegister.register(bucketName, () -> bucketCreator.create(fluidRegistryObject::getStillFluid,
|
||||||
|
new Item.Properties().stacksTo(1).craftRemainder(Items.BUCKET))));
|
||||||
|
//Note: The block properties used here is a copy of the ones for water
|
||||||
|
fluidRegistryObject.updateBlock(blockRegister.register(name, () -> new LiquidBlock(fluidRegistryObject::getStillFluid, BlockBehaviour.Properties.of()
|
||||||
|
.noCollission().strength(100.0F).noLootTable().replaceable().pushReaction(PushReaction.DESTROY).liquid().mapColor(MapColor.WATER))));
|
||||||
|
allFluids.add(fluidRegistryObject);
|
||||||
|
return fluidRegistryObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void register(IEventBus bus) {
|
||||||
|
blockRegister.register(bus);
|
||||||
|
fluidRegister.register(bus);
|
||||||
|
fluidTypeRegister.register(bus);
|
||||||
|
itemRegister.register(bus);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<FluidRegistryObject<? extends MekanismFluidType, ?, ?, ?, ?>> getAllFluids() {
|
||||||
|
return Collections.unmodifiableList(allFluids);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerBucketDispenserBehavior() {
|
||||||
|
for (FluidRegistryObject<?, ?, ?, ?, ?> fluidRO : getAllFluids()) {
|
||||||
|
DispenserBlock.registerBehavior(fluidRO.getBucket(), BUCKET_DISPENSE_BEHAVIOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface BucketCreator<BUCKET extends BucketItem> {
|
||||||
|
|
||||||
|
BUCKET create(Supplier<? extends Fluid> supplier, Item.Properties builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class FluidTypeRenderProperties {
|
||||||
|
|
||||||
|
private ResourceLocation stillTexture = LIQUID;
|
||||||
|
private ResourceLocation flowingTexture = LIQUID_FLOW;
|
||||||
|
//For now all our fluids use the same "overlay" for being against glass as vanilla water.
|
||||||
|
private ResourceLocation overlayTexture = OVERLAY;
|
||||||
|
private ResourceLocation renderOverlayTexture = RENDER_OVERLAY;
|
||||||
|
private int color = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
private FluidTypeRenderProperties() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FluidTypeRenderProperties builder() {
|
||||||
|
return new FluidTypeRenderProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FluidTypeRenderProperties texture(ResourceLocation still, ResourceLocation flowing) {
|
||||||
|
this.stillTexture = still;
|
||||||
|
this.flowingTexture = flowing;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FluidTypeRenderProperties texture(ResourceLocation still, ResourceLocation flowing, ResourceLocation overlay) {
|
||||||
|
this.stillTexture = still;
|
||||||
|
this.flowingTexture = flowing;
|
||||||
|
this.overlayTexture = overlay;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FluidTypeRenderProperties renderOverlay(ResourceLocation renderOverlay) {
|
||||||
|
this.renderOverlayTexture = renderOverlay;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FluidTypeRenderProperties tint(int color) {
|
||||||
|
this.color = color;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MekanismFluidType extends FluidType {
|
||||||
|
|
||||||
|
public final ResourceLocation stillTexture;
|
||||||
|
public final ResourceLocation flowingTexture;
|
||||||
|
public final ResourceLocation overlayTexture;
|
||||||
|
public final ResourceLocation renderOverlayTexture;
|
||||||
|
private final int color;
|
||||||
|
|
||||||
|
public MekanismFluidType(FluidType.Properties properties, FluidTypeRenderProperties renderProperties) {
|
||||||
|
super(properties);
|
||||||
|
this.stillTexture = renderProperties.stillTexture;
|
||||||
|
this.flowingTexture = renderProperties.flowingTexture;
|
||||||
|
this.overlayTexture = renderProperties.overlayTexture;
|
||||||
|
this.renderOverlayTexture = renderProperties.renderOverlayTexture;
|
||||||
|
this.color = renderProperties.color;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isVaporizedOnPlacement(Level level, BlockPos pos, FluidStack stack) {
|
||||||
|
//TODO - 1.19: Decide on this for our fluids for now default to not vaporizing
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initializeClient(Consumer<IClientFluidTypeExtensions> consumer) {
|
||||||
|
consumer.accept(new IClientFluidTypeExtensions() {
|
||||||
|
@Override
|
||||||
|
public ResourceLocation getStillTexture() {
|
||||||
|
return stillTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResourceLocation getFlowingTexture() {
|
||||||
|
return flowingTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResourceLocation getOverlayTexture() {
|
||||||
|
return overlayTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public ResourceLocation getRenderOverlayTexture(Minecraft mc) {
|
||||||
|
return renderOverlayTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTintColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package uk.gemwire.engage.registries.fluid;
|
||||||
|
|
||||||
|
|
||||||
|
import net.minecraft.world.item.BucketItem;
|
||||||
|
import net.minecraft.world.level.block.LiquidBlock;
|
||||||
|
import net.minecraft.world.level.material.Fluid;
|
||||||
|
import net.minecraftforge.fluids.FluidType;
|
||||||
|
import net.minecraftforge.registries.RegistryObject;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
// Yoinked from https://github.com/mekanism/Mekanism/blob/1.20.x/src/main/java/mekanism/common/registration/impl/FluidRegistryObject.java
|
||||||
|
public class FluidRegistryObject<TYPE extends FluidType, STILL extends Fluid, FLOWING extends Fluid, BLOCK extends LiquidBlock, BUCKET extends BucketItem> {
|
||||||
|
|
||||||
|
private RegistryObject<TYPE> fluidTypeRO;
|
||||||
|
private RegistryObject<STILL> stillRO;
|
||||||
|
private RegistryObject<FLOWING> flowingRO;
|
||||||
|
private RegistryObject<BLOCK> blockRO;
|
||||||
|
private RegistryObject<BUCKET> bucketRO;
|
||||||
|
|
||||||
|
public TYPE getFluidType() {
|
||||||
|
return fluidTypeRO.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public STILL getStillFluid() {
|
||||||
|
return stillRO.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FLOWING getFlowingFluid() {
|
||||||
|
return flowingRO.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BLOCK getBlock() {
|
||||||
|
return blockRO.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BUCKET getBucket() {
|
||||||
|
return bucketRO.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Make sure these update methods are package local as only the FluidDeferredRegister should be messing with them
|
||||||
|
void updateFluidType(RegistryObject<TYPE> fluidTypeRO) {
|
||||||
|
this.fluidTypeRO = Objects.requireNonNull(fluidTypeRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateStill(RegistryObject<STILL> stillRO) {
|
||||||
|
this.stillRO = Objects.requireNonNull(stillRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateFlowing(RegistryObject<FLOWING> flowingRO) {
|
||||||
|
this.flowingRO = Objects.requireNonNull(flowingRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateBlock(RegistryObject<BLOCK> blockRO) {
|
||||||
|
this.blockRO = Objects.requireNonNull(blockRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateBucket(RegistryObject<BUCKET> bucketRO) {
|
||||||
|
this.bucketRO = Objects.requireNonNull(bucketRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
public STILL getFluid() {
|
||||||
|
//Default our fluid to being the still variant
|
||||||
|
return getStillFluid();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package uk.gemwire.engage.registries.fluid;
|
||||||
|
|
||||||
|
// Yoinked from https://github.com/mekanism/Mekanism/blob/1.20.x/src/main/java/mekanism/common/base/IChemicalConstant.java
|
||||||
|
public interface IChemicalConstant {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The name of the chemical
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Visual color in ARGB format
|
||||||
|
*/
|
||||||
|
int getColor();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Temperature in Kelvin that the chemical exists as a liquid
|
||||||
|
*/
|
||||||
|
float getTemperature();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Density as a liquid in kg/m^3
|
||||||
|
*/
|
||||||
|
float getDensity();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Brightness
|
||||||
|
*/
|
||||||
|
int getLightLevel();
|
||||||
|
}
|
211
src/main/java/uk/gemwire/engage/worldgen/PropaneCaveCarver.java
Normal file
211
src/main/java/uk/gemwire/engage/worldgen/PropaneCaveCarver.java
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
package uk.gemwire.engage.worldgen;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.core.SectionPos;
|
||||||
|
import net.minecraft.util.Mth;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||||
|
import net.minecraft.world.level.chunk.CarvingMask;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
|
import net.minecraft.world.level.levelgen.Aquifer;
|
||||||
|
import net.minecraft.world.level.levelgen.DensityFunction;
|
||||||
|
import net.minecraft.world.level.levelgen.carver.CarverConfiguration;
|
||||||
|
import net.minecraft.world.level.levelgen.carver.CarvingContext;
|
||||||
|
import net.minecraft.world.level.levelgen.carver.WorldCarver;
|
||||||
|
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||||
|
import uk.gemwire.engage.registries.Fluids;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class PropaneCaveCarver extends WorldCarver<PropaneCaveCarverConfiguration> {
|
||||||
|
|
||||||
|
|
||||||
|
public PropaneCaveCarver(Codec<PropaneCaveCarverConfiguration> p_159194_) {
|
||||||
|
super(p_159194_);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStartChunk(PropaneCaveCarverConfiguration p_224894_, RandomSource p_224895_) {
|
||||||
|
return p_224895_.nextFloat() <= p_224894_.probability;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirect CarveState to place Propane instead of Lava.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private BlockState getCarveState(CarvingContext p_159419_, PropaneCaveCarverConfiguration p_159420_, BlockPos p_159421_, Aquifer p_159422_) {
|
||||||
|
if (p_159421_.getY() <= p_159420_.lavaLevel.resolveY(p_159419_)) {
|
||||||
|
return Fluids.PROPANE_FLUID.getBlock().defaultBlockState();
|
||||||
|
} else {
|
||||||
|
BlockState blockstate = p_159422_.computeSubstance(new DensityFunction.SinglePointContext(p_159421_.getX(), p_159421_.getY(), p_159421_.getZ()), 0.0D);
|
||||||
|
if (blockstate == null) {
|
||||||
|
return isDebugEnabled(p_159420_) ? p_159420_.debugSettings.getBarrierState() : null;
|
||||||
|
} else {
|
||||||
|
return isDebugEnabled(p_159420_) ? getDebugState(p_159420_, blockstate) : blockstate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean carveBlock(CarvingContext p_190744_, PropaneCaveCarverConfiguration p_190745_, ChunkAccess p_190746_, Function<BlockPos, Holder<Biome>> p_190747_, CarvingMask p_190748_, BlockPos.MutableBlockPos p_190749_, BlockPos.MutableBlockPos p_190750_, Aquifer p_190751_, MutableBoolean p_190752_) {
|
||||||
|
BlockState blockstate = p_190746_.getBlockState(p_190749_);
|
||||||
|
if (blockstate.is(Blocks.GRASS_BLOCK) || blockstate.is(Blocks.MYCELIUM)) {
|
||||||
|
p_190752_.setTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.canReplaceBlock(p_190745_, blockstate) && !isDebugEnabled(p_190745_)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
BlockState blockstate1 = (p_190749_.getY() <= p_190745_.lavaLevel.resolveY(p_190744_)) ? Fluids.PROPANE_FLUID.getBlock().defaultBlockState() :this.getCarveState(p_190744_, p_190745_, p_190749_, p_190751_);
|
||||||
|
if (blockstate1 == null) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
p_190746_.setBlockState(p_190749_, blockstate1, false);
|
||||||
|
if (p_190751_.shouldScheduleFluidUpdate() && !blockstate1.getFluidState().isEmpty()) {
|
||||||
|
p_190746_.markPosForPostprocessing(p_190749_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_190752_.isTrue()) {
|
||||||
|
p_190750_.setWithOffset(p_190749_, Direction.DOWN);
|
||||||
|
if (p_190746_.getBlockState(p_190750_).is(Blocks.DIRT)) {
|
||||||
|
p_190744_.topMaterial(p_190747_, p_190746_, p_190750_, !blockstate1.getFluidState().isEmpty()).ifPresent((p_284918_) -> {
|
||||||
|
p_190746_.setBlockState(p_190750_, p_284918_, false);
|
||||||
|
if (!p_284918_.getFluidState().isEmpty()) {
|
||||||
|
p_190746_.markPosForPostprocessing(p_190750_);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isDebugEnabled(CarverConfiguration p_159424_) {
|
||||||
|
return p_159424_.debugSettings.isDebugMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BlockState getDebugState(CarverConfiguration p_159382_, BlockState p_159383_) {
|
||||||
|
if (p_159383_.is(Blocks.AIR)) {
|
||||||
|
return p_159382_.debugSettings.getAirState();
|
||||||
|
} else if (p_159383_.is(Blocks.WATER)) {
|
||||||
|
BlockState blockstate = p_159382_.debugSettings.getWaterState();
|
||||||
|
return blockstate.hasProperty(BlockStateProperties.WATERLOGGED) ? blockstate.setValue(BlockStateProperties.WATERLOGGED, Boolean.valueOf(true)) : blockstate;
|
||||||
|
} else {
|
||||||
|
return p_159383_.is(Blocks.LAVA) ? p_159382_.debugSettings.getLavaState() : p_159383_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean carve(CarvingContext p_224885_, PropaneCaveCarverConfiguration p_224886_, ChunkAccess p_224887_, Function<BlockPos, Holder<Biome>> p_224888_, RandomSource p_224889_, Aquifer p_224890_, ChunkPos p_224891_, CarvingMask p_224892_) {
|
||||||
|
int i = SectionPos.sectionToBlockCoord(this.getRange() * 2 - 1);
|
||||||
|
int j = p_224889_.nextInt(p_224889_.nextInt(p_224889_.nextInt(this.getCaveBound()) + 1) + 1);
|
||||||
|
|
||||||
|
for(int k = 0; k < j; ++k) {
|
||||||
|
double d0 = (double)p_224891_.getBlockX(p_224889_.nextInt(16));
|
||||||
|
double d1 = (double)p_224886_.y.sample(p_224889_, p_224885_);
|
||||||
|
double d2 = (double)p_224891_.getBlockZ(p_224889_.nextInt(16));
|
||||||
|
double d3 = (double)p_224886_.horizontalRadiusMultiplier.sample(p_224889_);
|
||||||
|
double d4 = (double)p_224886_.verticalRadiusMultiplier.sample(p_224889_);
|
||||||
|
double d5 = (double)p_224886_.floorLevel.sample(p_224889_);
|
||||||
|
WorldCarver.CarveSkipChecker worldcarver$carveskipchecker = (p_159202_, p_159203_, p_159204_, p_159205_, p_159206_) -> {
|
||||||
|
return shouldSkip(p_159203_, p_159204_, p_159205_, d5);
|
||||||
|
};
|
||||||
|
int l = 1;
|
||||||
|
if (p_224889_.nextInt(4) == 0) {
|
||||||
|
double d6 = (double)p_224886_.yScale.sample(p_224889_);
|
||||||
|
float f1 = 1.0F + p_224889_.nextFloat() * 6.0F;
|
||||||
|
this.createRoom(p_224885_, p_224886_, p_224887_, p_224888_, p_224890_, d0, d1, d2, f1, d6, p_224892_, worldcarver$carveskipchecker);
|
||||||
|
l += p_224889_.nextInt(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int k1 = 0; k1 < l; ++k1) {
|
||||||
|
float f = p_224889_.nextFloat() * ((float)Math.PI * 2F);
|
||||||
|
float f3 = (p_224889_.nextFloat() - 0.5F) / 4.0F;
|
||||||
|
float f2 = this.getThickness(p_224889_);
|
||||||
|
int i1 = i - p_224889_.nextInt(i / 4);
|
||||||
|
int j1 = 0;
|
||||||
|
this.createTunnel(p_224885_, p_224886_, p_224887_, p_224888_, p_224889_.nextLong(), p_224890_, d0, d1, d2, d3, d4, f2, f, f3, 0, i1, this.getYScale(), p_224892_, worldcarver$carveskipchecker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getCaveBound() {
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected float getThickness(RandomSource p_224871_) {
|
||||||
|
float f = p_224871_.nextFloat() * 2.0F + p_224871_.nextFloat();
|
||||||
|
if (p_224871_.nextInt(10) == 0) {
|
||||||
|
f *= p_224871_.nextFloat() * p_224871_.nextFloat() * 3.0F + 1.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected double getYScale() {
|
||||||
|
return 1.0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void createRoom(CarvingContext p_190691_, PropaneCaveCarverConfiguration p_190692_, ChunkAccess p_190693_, Function<BlockPos, Holder<Biome>> p_190694_, Aquifer p_190695_, double p_190696_, double p_190697_, double p_190698_, float p_190699_, double p_190700_, CarvingMask p_190701_, WorldCarver.CarveSkipChecker p_190702_) {
|
||||||
|
double d0 = 1.5D + (double)(Mth.sin(((float)Math.PI / 2F)) * p_190699_);
|
||||||
|
double d1 = d0 * p_190700_;
|
||||||
|
this.carveEllipsoid(p_190691_, p_190692_, p_190693_, p_190694_, p_190695_, p_190696_ + 1.0D, p_190697_, p_190698_, d0, d1, p_190701_, p_190702_);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void createTunnel(CarvingContext p_190671_, PropaneCaveCarverConfiguration p_190672_, ChunkAccess p_190673_, Function<BlockPos, Holder<Biome>> p_190674_, long p_190675_, Aquifer p_190676_, double p_190677_, double p_190678_, double p_190679_, double p_190680_, double p_190681_, float p_190682_, float p_190683_, float p_190684_, int p_190685_, int p_190686_, double p_190687_, CarvingMask p_190688_, WorldCarver.CarveSkipChecker p_190689_) {
|
||||||
|
RandomSource randomsource = RandomSource.create(p_190675_);
|
||||||
|
int i = randomsource.nextInt(p_190686_ / 2) + p_190686_ / 4;
|
||||||
|
boolean flag = randomsource.nextInt(6) == 0;
|
||||||
|
float f = 0.0F;
|
||||||
|
float f1 = 0.0F;
|
||||||
|
|
||||||
|
for(int j = p_190685_; j < p_190686_; ++j) {
|
||||||
|
double d0 = 1.5D + (double)(Mth.sin((float)Math.PI * (float)j / (float)p_190686_) * p_190682_);
|
||||||
|
double d1 = d0 * p_190687_;
|
||||||
|
float f2 = Mth.cos(p_190684_);
|
||||||
|
p_190677_ += (double)(Mth.cos(p_190683_) * f2);
|
||||||
|
p_190678_ += (double)Mth.sin(p_190684_);
|
||||||
|
p_190679_ += (double)(Mth.sin(p_190683_) * f2);
|
||||||
|
p_190684_ *= flag ? 0.92F : 0.7F;
|
||||||
|
p_190684_ += f1 * 0.1F;
|
||||||
|
p_190683_ += f * 0.1F;
|
||||||
|
f1 *= 0.9F;
|
||||||
|
f *= 0.75F;
|
||||||
|
f1 += (randomsource.nextFloat() - randomsource.nextFloat()) * randomsource.nextFloat() * 2.0F;
|
||||||
|
f += (randomsource.nextFloat() - randomsource.nextFloat()) * randomsource.nextFloat() * 4.0F;
|
||||||
|
if (j == i && p_190682_ > 1.0F) {
|
||||||
|
this.createTunnel(p_190671_, p_190672_, p_190673_, p_190674_, randomsource.nextLong(), p_190676_, p_190677_, p_190678_, p_190679_, p_190680_, p_190681_, randomsource.nextFloat() * 0.5F + 0.5F, p_190683_ - ((float)Math.PI / 2F), p_190684_ / 3.0F, j, p_190686_, 1.0D, p_190688_, p_190689_);
|
||||||
|
this.createTunnel(p_190671_, p_190672_, p_190673_, p_190674_, randomsource.nextLong(), p_190676_, p_190677_, p_190678_, p_190679_, p_190680_, p_190681_, randomsource.nextFloat() * 0.5F + 0.5F, p_190683_ + ((float)Math.PI / 2F), p_190684_ / 3.0F, j, p_190686_, 1.0D, p_190688_, p_190689_);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (randomsource.nextInt(4) != 0) {
|
||||||
|
if (!canReach(p_190673_.getPos(), p_190677_, p_190679_, j, p_190686_, p_190682_)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.carveEllipsoid(p_190671_, p_190672_, p_190673_, p_190674_, p_190676_, p_190677_, p_190678_, p_190679_, d0 * p_190680_, d1 * p_190681_, p_190688_, p_190689_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean shouldSkip(double p_159196_, double p_159197_, double p_159198_, double p_159199_) {
|
||||||
|
if (p_159197_ <= p_159199_) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return p_159196_ * p_159196_ + p_159197_ * p_159197_ + p_159198_ * p_159198_ >= 1.0D;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package uk.gemwire.engage.worldgen;
|
||||||
|
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.core.HolderSet;
|
||||||
|
import net.minecraft.util.valueproviders.FloatProvider;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.levelgen.VerticalAnchor;
|
||||||
|
import net.minecraft.world.level.levelgen.carver.CarverConfiguration;
|
||||||
|
import net.minecraft.world.level.levelgen.carver.CarverDebugSettings;
|
||||||
|
import net.minecraft.world.level.levelgen.heightproviders.HeightProvider;
|
||||||
|
|
||||||
|
public class PropaneCaveCarverConfiguration extends CarverConfiguration {
|
||||||
|
public static final Codec<PropaneCaveCarverConfiguration> CODEC = RecordCodecBuilder.create((p_159184_) -> {
|
||||||
|
return p_159184_.group(CarverConfiguration.CODEC.forGetter((p_159192_) -> {
|
||||||
|
return p_159192_;
|
||||||
|
}), FloatProvider.CODEC.fieldOf("horizontal_radius_multiplier").forGetter((p_159190_) -> {
|
||||||
|
return p_159190_.horizontalRadiusMultiplier;
|
||||||
|
}), FloatProvider.CODEC.fieldOf("vertical_radius_multiplier").forGetter((p_159188_) -> {
|
||||||
|
return p_159188_.verticalRadiusMultiplier;
|
||||||
|
}), FloatProvider.codec(-1.0F, 1.0F).fieldOf("floor_level").forGetter((p_159186_) -> {
|
||||||
|
return p_159186_.floorLevel;
|
||||||
|
})).apply(p_159184_, PropaneCaveCarverConfiguration::new);
|
||||||
|
});
|
||||||
|
public final FloatProvider horizontalRadiusMultiplier;
|
||||||
|
public final FloatProvider verticalRadiusMultiplier;
|
||||||
|
public final FloatProvider floorLevel;
|
||||||
|
|
||||||
|
public PropaneCaveCarverConfiguration(float p_224853_, HeightProvider p_224854_, FloatProvider p_224855_, VerticalAnchor p_224856_, CarverDebugSettings p_224857_, HolderSet<Block> p_224858_, FloatProvider p_224859_, FloatProvider p_224860_, FloatProvider p_224861_) {
|
||||||
|
super(p_224853_, p_224854_, p_224855_, p_224856_, p_224857_, p_224858_);
|
||||||
|
this.horizontalRadiusMultiplier = p_224859_;
|
||||||
|
this.verticalRadiusMultiplier = p_224860_;
|
||||||
|
this.floorLevel = p_224861_;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PropaneCaveCarverConfiguration(float p_224863_, HeightProvider p_224864_, FloatProvider p_224865_, VerticalAnchor p_224866_, HolderSet<Block> p_224867_, FloatProvider p_224868_, FloatProvider p_224869_, FloatProvider p_224870_) {
|
||||||
|
this(p_224863_, p_224864_, p_224865_, p_224866_, CarverDebugSettings.DEFAULT, p_224867_, p_224868_, p_224869_, p_224870_);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PropaneCaveCarverConfiguration(CarverConfiguration p_159179_, FloatProvider p_159180_, FloatProvider p_159181_, FloatProvider p_159182_) {
|
||||||
|
this(p_159179_.probability, p_159179_.y, p_159179_.yScale, p_159179_.lavaLevel, p_159179_.debugSettings, p_159179_.replaceable, p_159180_, p_159181_, p_159182_);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package uk.gemwire.engage.worldgen.modifiers;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.core.HolderSet;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import net.minecraft.world.level.levelgen.GenerationStep;
|
||||||
|
import net.minecraft.world.level.levelgen.carver.ConfiguredWorldCarver;
|
||||||
|
import net.minecraftforge.common.world.BiomeGenerationSettingsBuilder;
|
||||||
|
import net.minecraftforge.common.world.BiomeModifier;
|
||||||
|
import net.minecraftforge.common.world.ModifiableBiomeInfo;
|
||||||
|
import uk.gemwire.engage.registries.Worldgen;
|
||||||
|
|
||||||
|
public record AddCarverBiomeModifier(HolderSet<Biome> biomes, HolderSet<ConfiguredWorldCarver<?>> carvers, GenerationStep.Carving step) implements BiomeModifier {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void modify(Holder<Biome> biome, Phase phase, ModifiableBiomeInfo.BiomeInfo.Builder builder)
|
||||||
|
{
|
||||||
|
if (phase == Phase.ADD && this.biomes.contains(biome))
|
||||||
|
{
|
||||||
|
BiomeGenerationSettingsBuilder generationSettings = builder.getGenerationSettings();
|
||||||
|
this.carvers.forEach(holder -> generationSettings.addCarver(this.step, holder));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Codec<? extends BiomeModifier> codec()
|
||||||
|
{
|
||||||
|
return Worldgen.ADD_CARVERS_BIOME_MODIFIER_TYPE.get();
|
||||||
|
}
|
||||||
|
}
|
BIN
src/main/resources/assets/engage/textures/liquid/liquid.png
Normal file
BIN
src/main/resources/assets/engage/textures/liquid/liquid.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.0 KiB |
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"animation": {
|
||||||
|
"frametime": 2
|
||||||
|
}
|
||||||
|
}
|
BIN
src/main/resources/assets/engage/textures/liquid/liquid_flow.png
Normal file
BIN
src/main/resources/assets/engage/textures/liquid/liquid_flow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"animation": {
|
||||||
|
"frametime": 2
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"type": "engage:add_carvers",
|
||||||
|
"biomes": "#minecraft:is_overworld",
|
||||||
|
"carvers": "engage:propane_cave",
|
||||||
|
"step": "air"
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
{
|
||||||
|
"type": "engage:propane_cave",
|
||||||
|
"config": {
|
||||||
|
"debug_settings": {
|
||||||
|
},
|
||||||
|
"floor_level": {
|
||||||
|
"type": "minecraft:uniform",
|
||||||
|
"value": {
|
||||||
|
"max_exclusive": -0.4,
|
||||||
|
"min_inclusive": -1.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"horizontal_radius_multiplier": {
|
||||||
|
"type": "minecraft:uniform",
|
||||||
|
"value": {
|
||||||
|
"max_exclusive": 1.4,
|
||||||
|
"min_inclusive": 0.7
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lava_level": {
|
||||||
|
"below_top": 3
|
||||||
|
},
|
||||||
|
"probability": 0.005,
|
||||||
|
"replaceable": "#minecraft:overworld_carver_replaceables",
|
||||||
|
"vertical_radius_multiplier": {
|
||||||
|
"type": "minecraft:uniform",
|
||||||
|
"value": {
|
||||||
|
"max_exclusive": 1.3,
|
||||||
|
"min_inclusive": 0.8
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"y": {
|
||||||
|
"type": "minecraft:uniform",
|
||||||
|
"max_inclusive": {
|
||||||
|
"absolute": 180
|
||||||
|
},
|
||||||
|
"min_inclusive": {
|
||||||
|
"above_bottom": 8
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"yScale": {
|
||||||
|
"type": "minecraft:uniform",
|
||||||
|
"value": {
|
||||||
|
"max_exclusive": 0.9,
|
||||||
|
"min_inclusive": 0.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user