From 3f83b88cdef61967d1ef450c9dd6b404501d79a0 Mon Sep 17 00:00:00 2001 From: Curle Date: Fri, 30 Jun 2023 03:22:41 +0100 Subject: [PATCH] Datageneration --- build.gradle | 72 ++--- .../java/uk/gemwire/engage/data/Datagen.java | 45 ++++ .../blockstate/BaseBlockStateProvider.java | 68 +++++ .../data/blockstate/BlockStateProvider.java | 33 +++ .../engage/data/lang/EnglishProvider.java | 31 +++ .../data/loot_tables/BaseLootProvider.java | 21 ++ .../data/loot_tables/LootTableProvider.java | 16 ++ .../block/BaseBlockLootTables.java | 183 +++++++++++++ .../loot_tables/block/BlockLootTables.java | 12 + .../model/block/BaseBlockModelProvider.java | 34 +++ .../data/model/block/BlockModelProvider.java | 17 ++ .../model/item/BaseItemModelProvider.java | 100 +++++++ .../data/model/item/ItemModelProvider.java | 45 ++++ .../sprites/BaseSpriteSourceProvider.java | 48 ++++ .../data/sprites/SpriteSourceProvider.java | 19 ++ .../engage/data/tags/BaseTagProvider.java | 202 ++++++++++++++ .../engage/data/tags/EngageTagBuilder.java | 108 ++++++++ .../data/tags/IntrinsicEngageTagBuilder.java | 47 ++++ .../data/tags/block/BlockTagProvider.java | 69 +++++ .../25bd38b64d05cf6fc0314ea079b987c6b7e5e687 | 8 + .../59eb3dbb5f86130e09b3c62d89b9525ee01cf52d | 2 + .../66a165d3767db9e7e553407f2f645b3cc5ca9de9 | 2 + .../7b0d0541763a0d94f474a7a474c958ce2416d969 | 1 + .../8a3dba5a712aa838300c907fbeebb5313f8fde21 | 16 ++ .../94dbe45e11443c880589aa262160b67ceb23d4f4 | 13 + .../c622617f6fabf890a00b9275cd5f643584a8a2c8 | 2 + .../engage/blockstates/antideuterium.json | 7 + .../engage/blockstates/beryllite_ore.json | 0 .../assets/engage/blockstates/deuterium.json | 7 + .../engage/blockstates/deuterium_slush.json | 7 + .../engage/blockstates/heavy_water.json | 7 + .../assets/engage/blockstates/propane.json | 7 + .../engage/blockstates/warp_plasma.json | 7 + .../resources/assets/engage/lang/en_us.json | 15 ++ .../engage/models/block/antideuterium.json | 5 + .../engage/models/block/beryllite_ore.json | 0 .../assets/engage/models/block/deuterium.json | 5 + .../engage/models/block/deuterium_slush.json | 5 + .../engage/models/block/heavy_water.json | 5 + .../assets/engage/models/block/propane.json | 5 + .../engage/models/block/warp_plasma.json | 5 + .../models/item/antideuterium_bucket.json | 5 + .../engage/models/item/beryllite_ore.json | 0 .../engage/models/item/beryllite_raw.json | 0 .../engage/models/item/deuterium_bucket.json | 5 + .../models/item/deuterium_slush_bucket.json | 5 + .../models/item/heavy_water_bucket.json | 5 + .../engage/models/item/propane_bucket.json | 5 + .../models/item/warp_plasma_bucket.json | 5 + .../assets/minecraft/atlases/blocks.json | 20 ++ .../loot_tables/blocks/beryllite_ore.json | 0 .../forge/tags/blocks/ore_rates/singular.json | 1 - .../data/forge/tags/blocks/ores.json | 5 + .../tags/blocks/ores/beryllite_ore.json} | 1 - .../tags/blocks/ores_in_ground/stone.json | 1 - .../forge/tags/items/ore_rates/singular.json | 5 + .../resources/data/forge/tags/items/ores.json | 5 + .../forge/tags/items/ores/beryllite_ore.json | 5 + .../tags/items/ores_in_ground/stone.json | 5 + .../tags/blocks/mineable/pickaxe.json | 1 - .../tags/blocks/needs_iron_tool.json | 1 - .../blocks/overworld_carver_replaceables.json | 1 - .../tags/blocks/snaps_goat_horn.json | 1 - src/main/java/uk/gemwire/engage/Engage.java | 39 +++ .../uk/gemwire/engage/registries/Fluids.java | 28 ++ .../gemwire/engage/registries/Worldgen.java | 30 +++ .../fluid/FluidDeferredRegister.java | 254 ++++++++++++++++++ .../registries/fluid/FluidRegistryObject.java | 66 +++++ .../registries/fluid/IChemicalConstant.java | 30 +++ .../engage/worldgen/PropaneCaveCarver.java | 211 +++++++++++++++ .../PropaneCaveCarverConfiguration.java | 44 +++ .../modifiers/AddCarverBiomeModifier.java | 31 +++ .../assets/engage/textures/liquid/liquid.png | Bin 0 -> 5136 bytes .../engage/textures/liquid/liquid.png.mcmeta | 5 + .../engage/textures/liquid/liquid_flow.png | Bin 0 -> 4518 bytes .../textures/liquid/liquid_flow.png.mcmeta | 5 + .../forge/biome_modifier/propane_cave.json | 6 + .../configured_carver/propane_cave.json | 49 ++++ 78 files changed, 2124 insertions(+), 57 deletions(-) create mode 100644 src/data/java/uk/gemwire/engage/data/Datagen.java create mode 100644 src/data/java/uk/gemwire/engage/data/blockstate/BaseBlockStateProvider.java create mode 100644 src/data/java/uk/gemwire/engage/data/blockstate/BlockStateProvider.java create mode 100644 src/data/java/uk/gemwire/engage/data/lang/EnglishProvider.java create mode 100644 src/data/java/uk/gemwire/engage/data/loot_tables/BaseLootProvider.java create mode 100644 src/data/java/uk/gemwire/engage/data/loot_tables/LootTableProvider.java create mode 100644 src/data/java/uk/gemwire/engage/data/loot_tables/block/BaseBlockLootTables.java create mode 100644 src/data/java/uk/gemwire/engage/data/loot_tables/block/BlockLootTables.java create mode 100644 src/data/java/uk/gemwire/engage/data/model/block/BaseBlockModelProvider.java create mode 100644 src/data/java/uk/gemwire/engage/data/model/block/BlockModelProvider.java create mode 100644 src/data/java/uk/gemwire/engage/data/model/item/BaseItemModelProvider.java create mode 100644 src/data/java/uk/gemwire/engage/data/model/item/ItemModelProvider.java create mode 100644 src/data/java/uk/gemwire/engage/data/sprites/BaseSpriteSourceProvider.java create mode 100644 src/data/java/uk/gemwire/engage/data/sprites/SpriteSourceProvider.java create mode 100644 src/data/java/uk/gemwire/engage/data/tags/BaseTagProvider.java create mode 100644 src/data/java/uk/gemwire/engage/data/tags/EngageTagBuilder.java create mode 100644 src/data/java/uk/gemwire/engage/data/tags/IntrinsicEngageTagBuilder.java create mode 100644 src/data/java/uk/gemwire/engage/data/tags/block/BlockTagProvider.java create mode 100644 src/data/resources/.cache/25bd38b64d05cf6fc0314ea079b987c6b7e5e687 create mode 100644 src/data/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d create mode 100644 src/data/resources/.cache/66a165d3767db9e7e553407f2f645b3cc5ca9de9 create mode 100644 src/data/resources/.cache/7b0d0541763a0d94f474a7a474c958ce2416d969 create mode 100644 src/data/resources/.cache/8a3dba5a712aa838300c907fbeebb5313f8fde21 create mode 100644 src/data/resources/.cache/94dbe45e11443c880589aa262160b67ceb23d4f4 create mode 100644 src/data/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 create mode 100644 src/data/resources/assets/engage/blockstates/antideuterium.json rename src/{main => data}/resources/assets/engage/blockstates/beryllite_ore.json (100%) create mode 100644 src/data/resources/assets/engage/blockstates/deuterium.json create mode 100644 src/data/resources/assets/engage/blockstates/deuterium_slush.json create mode 100644 src/data/resources/assets/engage/blockstates/heavy_water.json create mode 100644 src/data/resources/assets/engage/blockstates/propane.json create mode 100644 src/data/resources/assets/engage/blockstates/warp_plasma.json create mode 100644 src/data/resources/assets/engage/lang/en_us.json create mode 100644 src/data/resources/assets/engage/models/block/antideuterium.json rename src/{main => data}/resources/assets/engage/models/block/beryllite_ore.json (100%) create mode 100644 src/data/resources/assets/engage/models/block/deuterium.json create mode 100644 src/data/resources/assets/engage/models/block/deuterium_slush.json create mode 100644 src/data/resources/assets/engage/models/block/heavy_water.json create mode 100644 src/data/resources/assets/engage/models/block/propane.json create mode 100644 src/data/resources/assets/engage/models/block/warp_plasma.json create mode 100644 src/data/resources/assets/engage/models/item/antideuterium_bucket.json rename src/{main => data}/resources/assets/engage/models/item/beryllite_ore.json (100%) rename src/{main => data}/resources/assets/engage/models/item/beryllite_raw.json (100%) create mode 100644 src/data/resources/assets/engage/models/item/deuterium_bucket.json create mode 100644 src/data/resources/assets/engage/models/item/deuterium_slush_bucket.json create mode 100644 src/data/resources/assets/engage/models/item/heavy_water_bucket.json create mode 100644 src/data/resources/assets/engage/models/item/propane_bucket.json create mode 100644 src/data/resources/assets/engage/models/item/warp_plasma_bucket.json create mode 100644 src/data/resources/assets/minecraft/atlases/blocks.json rename src/{main => data}/resources/data/engage/loot_tables/blocks/beryllite_ore.json (100%) rename src/{main => data}/resources/data/forge/tags/blocks/ore_rates/singular.json (69%) create mode 100644 src/data/resources/data/forge/tags/blocks/ores.json rename src/{main/resources/data/forge/tags/blocks/ores.json => data/resources/data/forge/tags/blocks/ores/beryllite_ore.json} (69%) rename src/{main => data}/resources/data/forge/tags/blocks/ores_in_ground/stone.json (69%) create mode 100644 src/data/resources/data/forge/tags/items/ore_rates/singular.json create mode 100644 src/data/resources/data/forge/tags/items/ores.json create mode 100644 src/data/resources/data/forge/tags/items/ores/beryllite_ore.json create mode 100644 src/data/resources/data/forge/tags/items/ores_in_ground/stone.json rename src/{main => data}/resources/data/minecraft/tags/blocks/mineable/pickaxe.json (69%) rename src/{main => data}/resources/data/minecraft/tags/blocks/needs_iron_tool.json (69%) rename src/{main => data}/resources/data/minecraft/tags/blocks/overworld_carver_replaceables.json (69%) rename src/{main => data}/resources/data/minecraft/tags/blocks/snaps_goat_horn.json (69%) create mode 100644 src/main/java/uk/gemwire/engage/registries/Fluids.java create mode 100644 src/main/java/uk/gemwire/engage/registries/Worldgen.java create mode 100644 src/main/java/uk/gemwire/engage/registries/fluid/FluidDeferredRegister.java create mode 100644 src/main/java/uk/gemwire/engage/registries/fluid/FluidRegistryObject.java create mode 100644 src/main/java/uk/gemwire/engage/registries/fluid/IChemicalConstant.java create mode 100644 src/main/java/uk/gemwire/engage/worldgen/PropaneCaveCarver.java create mode 100644 src/main/java/uk/gemwire/engage/worldgen/PropaneCaveCarverConfiguration.java create mode 100644 src/main/java/uk/gemwire/engage/worldgen/modifiers/AddCarverBiomeModifier.java create mode 100644 src/main/resources/assets/engage/textures/liquid/liquid.png create mode 100644 src/main/resources/assets/engage/textures/liquid/liquid.png.mcmeta create mode 100644 src/main/resources/assets/engage/textures/liquid/liquid_flow.png create mode 100644 src/main/resources/assets/engage/textures/liquid/liquid_flow.png.mcmeta create mode 100644 src/main/resources/data/engage/forge/biome_modifier/propane_cave.json create mode 100644 src/main/resources/data/engage/worldgen/configured_carver/propane_cave.json diff --git a/build.gradle b/build.gradle index 5fa3a32..a95e55c 100644 --- a/build.gradle +++ b/build.gradle @@ -15,21 +15,15 @@ base { // Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 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'}" 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 // 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 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. // These can be tweaked, removed, or duplicated as needed. runs { @@ -99,27 +80,30 @@ minecraft { } data { + ideaModule "${project.name}.data" + // example of overriding the workingDirectory set in configureEach above workingDirectory project.file('run-data') // 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 { - // 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. - // See https://docs.gradle.org/current/userguide/declaring_repositories.html#sub:flat_dir_resolver - // flatDir { - // dir 'libs' - // } +configurations { + dataImplementation.extendsFrom implementation } 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. 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 - // 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 + dataImplementation sourceSets.main.output } // This block of code expands all declared replace properties in the specified resource targets. diff --git a/src/data/java/uk/gemwire/engage/data/Datagen.java b/src/data/java/uk/gemwire/engage/data/Datagen.java new file mode 100644 index 0000000..3e39bc2 --- /dev/null +++ b/src/data/java/uk/gemwire/engage/data/Datagen.java @@ -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())); + + } +} \ No newline at end of file diff --git a/src/data/java/uk/gemwire/engage/data/blockstate/BaseBlockStateProvider.java b/src/data/java/uk/gemwire/engage/data/blockstate/BaseBlockStateProvider.java new file mode 100644 index 0000000..f6284d5 --- /dev/null +++ b/src/data/java/uk/gemwire/engage/data/blockstate/BaseBlockStateProvider.java @@ -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 extends BlockStateProvider { + + private final String modid; + private final PROVIDER modelProvider; + + public BaseBlockStateProvider(PackOutput output, String modid, ExistingFileHelper existingFileHelper, + BiFunction 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> fluidROs) { + for (FluidRegistryObject 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 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); + } +} \ No newline at end of file diff --git a/src/data/java/uk/gemwire/engage/data/blockstate/BlockStateProvider.java b/src/data/java/uk/gemwire/engage/data/blockstate/BlockStateProvider.java new file mode 100644 index 0000000..bea5706 --- /dev/null +++ b/src/data/java/uk/gemwire/engage/data/blockstate/BlockStateProvider.java @@ -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 { + + 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"))); + } +} diff --git a/src/data/java/uk/gemwire/engage/data/lang/EnglishProvider.java b/src/data/java/uk/gemwire/engage/data/lang/EnglishProvider.java new file mode 100644 index 0000000..ad34936 --- /dev/null +++ b/src/data/java/uk/gemwire/engage/data/lang/EnglishProvider.java @@ -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"); + } +} diff --git a/src/data/java/uk/gemwire/engage/data/loot_tables/BaseLootProvider.java b/src/data/java/uk/gemwire/engage/data/loot_tables/BaseLootProvider.java new file mode 100644 index 0000000..3c4b96a --- /dev/null +++ b/src/data/java/uk/gemwire/engage/data/loot_tables/BaseLootProvider.java @@ -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 subProviders) { + this(output, Collections.emptySet(), subProviders); + } + + protected BaseLootProvider(PackOutput output, Set requiredTables, List subProviders) { + super(output, requiredTables, subProviders); + } +} \ No newline at end of file diff --git a/src/data/java/uk/gemwire/engage/data/loot_tables/LootTableProvider.java b/src/data/java/uk/gemwire/engage/data/loot_tables/LootTableProvider.java new file mode 100644 index 0000000..6090024 --- /dev/null +++ b/src/data/java/uk/gemwire/engage/data/loot_tables/LootTableProvider.java @@ -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) + )); + } +} diff --git a/src/data/java/uk/gemwire/engage/data/loot_tables/block/BaseBlockLootTables.java b/src/data/java/uk/gemwire/engage/data/loot_tables/block/BaseBlockLootTables.java new file mode 100644 index 0000000..bca9fa0 --- /dev/null +++ b/src/data/java/uk/gemwire/engage/data/loot_tables/block/BaseBlockLootTables.java @@ -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 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 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 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 blocks) { + for (Block block : blocks) { + if (!skipBlock(block)) { + dropSelf(block); + } + } + } + + protected void add(Function factory, Collection blocks) { + for (Block block : blocks) { + add(block, factory); + } + } + + protected void add(Function 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 applyExplosionCondition(boolean explosionResistant, ConditionUserBuilder 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) + ) + ); + } +} \ No newline at end of file diff --git a/src/data/java/uk/gemwire/engage/data/loot_tables/block/BlockLootTables.java b/src/data/java/uk/gemwire/engage/data/loot_tables/block/BlockLootTables.java new file mode 100644 index 0000000..b66c0b8 --- /dev/null +++ b/src/data/java/uk/gemwire/engage/data/loot_tables/block/BlockLootTables.java @@ -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()); + } +} diff --git a/src/data/java/uk/gemwire/engage/data/model/block/BaseBlockModelProvider.java b/src/data/java/uk/gemwire/engage/data/model/block/BaseBlockModelProvider.java new file mode 100644 index 0000000..a805bee --- /dev/null +++ b/src/data/java/uk/gemwire/engage/data/model/block/BaseBlockModelProvider.java @@ -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"); + } +} diff --git a/src/data/java/uk/gemwire/engage/data/model/block/BlockModelProvider.java b/src/data/java/uk/gemwire/engage/data/model/block/BlockModelProvider.java new file mode 100644 index 0000000..0d9fe5c --- /dev/null +++ b/src/data/java/uk/gemwire/engage/data/model/block/BlockModelProvider.java @@ -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() { + } +} + diff --git a/src/data/java/uk/gemwire/engage/data/model/item/BaseItemModelProvider.java b/src/data/java/uk/gemwire/engage/data/model/item/BaseItemModelProvider.java new file mode 100644 index 0000000..4fa21d3 --- /dev/null +++ b/src/data/java/uk/gemwire/engage/data/model/item/BaseItemModelProvider.java @@ -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()); + } +} \ No newline at end of file diff --git a/src/data/java/uk/gemwire/engage/data/model/item/ItemModelProvider.java b/src/data/java/uk/gemwire/engage/data/model/item/ItemModelProvider.java new file mode 100644 index 0000000..42c25b7 --- /dev/null +++ b/src/data/java/uk/gemwire/engage/data/model/item/ItemModelProvider.java @@ -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, RegistryObject block) { + withExistingParent(name(item.get()), modLoc(BLOCK_FOLDER + name(block.get()))); + } +} \ No newline at end of file diff --git a/src/data/java/uk/gemwire/engage/data/sprites/BaseSpriteSourceProvider.java b/src/data/java/uk/gemwire/engage/data/sprites/BaseSpriteSourceProvider.java new file mode 100644 index 0000000..d13ea44 --- /dev/null +++ b/src/data/java/uk/gemwire/engage/data/sprites/BaseSpriteSourceProvider.java @@ -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 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 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() { + + } +} diff --git a/src/data/java/uk/gemwire/engage/data/sprites/SpriteSourceProvider.java b/src/data/java/uk/gemwire/engage/data/sprites/SpriteSourceProvider.java new file mode 100644 index 0000000..29d3cee --- /dev/null +++ b/src/data/java/uk/gemwire/engage/data/sprites/SpriteSourceProvider.java @@ -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); + } +} diff --git a/src/data/java/uk/gemwire/engage/data/tags/BaseTagProvider.java b/src/data/java/uk/gemwire/engage/data/tags/BaseTagProvider.java new file mode 100644 index 0000000..281231a --- /dev/null +++ b/src/data/java/uk/gemwire/engage/data/tags/BaseTagProvider.java @@ -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>, Map, TagBuilder>> supportedTagTypes = new Object2ObjectLinkedOpenHashMap<>(); + private final Set knownHarvestRequirements = new ReferenceOpenHashSet<>(); + private final CompletableFuture lookupProvider; + private final ExistingFileHelper existingFileHelper; + private final PackOutput output; + private final String modid; + + protected BaseTagProvider(PackOutput output, CompletableFuture 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 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> 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 Map, TagBuilder> getTagTypeMap(ResourceKey> registry) { + return supportedTagTypes.computeIfAbsent(registry, type -> new Object2ObjectLinkedOpenHashMap<>()); + } + + private TagBuilder getTagBuilder(ResourceKey> registry, TagKey tag) { + return getTagTypeMap(registry).computeIfAbsent(tag, ignored -> TagBuilder.create()); + } + + protected EngageTagBuilder getBuilder(ResourceKey> registry, TagKey tag) { + return new EngageTagBuilder<>(getTagBuilder(registry, tag), modid); + } + + protected IntrinsicEngageTagBuilder getBuilder(ResourceKey> registry, Function> keyExtractor, TagKey tag) { + return new IntrinsicEngageTagBuilder<>(keyExtractor, getTagBuilder(registry, tag), modid); + } + + protected IntrinsicEngageTagBuilder getBuilder(IForgeRegistry registry, TagKey tag) { + return new IntrinsicEngageTagBuilder<>(element -> registry.getResourceKey(element).orElseThrow(), getTagBuilder(registry.getRegistryKey(), tag), modid); + } + + protected IntrinsicEngageTagBuilder getItemBuilder(TagKey tag) { + return getBuilder(ForgeRegistries.ITEMS, tag); + } + + protected IntrinsicEngageTagBuilder getBlockBuilder(TagKey tag) { + return getBuilder(ForgeRegistries.BLOCKS, tag); + } + + protected IntrinsicEngageTagBuilder> getEntityTypeBuilder(TagKey> tag) { + return getBuilder(ForgeRegistries.ENTITY_TYPES, tag); + } + + protected IntrinsicEngageTagBuilder getFluidBuilder(TagKey tag) { + return getBuilder(ForgeRegistries.FLUIDS, tag); + } + + protected IntrinsicEngageTagBuilder> getTileEntityTypeBuilder(TagKey> tag) { + return getBuilder(ForgeRegistries.BLOCK_ENTITY_TYPES, tag); + } + + protected IntrinsicEngageTagBuilder getGameEventBuilder(TagKey tag) { + return getBuilder(Registries.GAME_EVENT, gameEvent -> gameEvent.builtInRegistryHolder().key(), tag); + } + + protected EngageTagBuilder getDamageTypeBuilder(TagKey tag) { + return getBuilder(Registries.DAMAGE_TYPE, tag); + } + + protected IntrinsicEngageTagBuilder getMobEffectBuilder(TagKey tag) { + return getBuilder(ForgeRegistries.MOB_EFFECTS, tag); + } + + protected void addToTag(TagKey tag, ItemLike... itemProviders) { + getItemBuilder(tag).addTyped(ItemLike::asItem, itemProviders); + } + + protected void addToTag(TagKey tag, Block... blocks) { + getBlockBuilder(tag).addTyped(b -> b, blocks); + } + + @SafeVarargs + protected final void addToTag(TagKey blockTag, Map... blocks) { + IntrinsicEngageTagBuilder tagBuilder = getBlockBuilder(blockTag); + for (Map entry : blocks) { + for (Block value : entry.values()) { + tagBuilder.add(value); + } + } + } + + protected void addToHarvestTag(TagKey tag, Block... blockProviders) { + IntrinsicEngageTagBuilder tagBuilder = getBlockBuilder(tag); + for (Block block : blockProviders) { + tagBuilder.add(block); + hasHarvestData(block); + } + } + + @SafeVarargs + protected final void addToHarvestTag(TagKey blockTag, Map... blockProviders) { + IntrinsicEngageTagBuilder tagBuilder = getBlockBuilder(blockTag); + for (Map blockProvider : blockProviders) { + for (Block block : blockProvider.values()) { + tagBuilder.add(block); + hasHarvestData(block); + } + } + } + + protected void addToTags(TagKey itemTag, TagKey blockTag, Block... blockProviders) { + IntrinsicEngageTagBuilder itemTagBuilder = getItemBuilder(itemTag); + IntrinsicEngageTagBuilder blockTagBuilder = getBlockBuilder(blockTag); + for (Block blockProvider : blockProviders) { + itemTagBuilder.add(blockProvider.asItem()); + blockTagBuilder.add(blockProvider); + } + } + + protected void addToTag(TagKey tag, FluidRegistryObject... fluidRegistryObjects) { + IntrinsicEngageTagBuilder tagBuilder = getFluidBuilder(tag); + for (FluidRegistryObject fluidRO : fluidRegistryObjects) { + tagBuilder.add(fluidRO.getStillFluid(), fluidRO.getFlowingFluid()); + } + } +} \ No newline at end of file diff --git a/src/data/java/uk/gemwire/engage/data/tags/EngageTagBuilder.java b/src/data/java/uk/gemwire/engage/data/tags/EngageTagBuilder.java new file mode 100644 index 0000000..d3faae3 --- /dev/null +++ b/src/data/java/uk/gemwire/engage/data/tags/EngageTagBuilder.java @@ -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> { + + 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... tags) { + return apply(builder::addTag, TagKey::location, tags); + } + + public BUILDER add(TagEntry tag) { + builder.add(tag); + return getThis(); + } + + @SafeVarargs + public final BUILDER add(ResourceKey... keys) { + return add(ResourceKey::location, keys); + } + + @SafeVarargs + public final BUILDER add(Function 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 BUILDER addOptional(Function locationGetter, T... elements) { + return add(TagEntry::optionalElement, locationGetter, elements); + } + + @SafeVarargs + public final BUILDER addOptionalTag(TagKey... tags) { + return addOptionalTag(TagKey::location, tags); + } + + public BUILDER addOptionalTag(ResourceLocation... locations) { + return addOptionalTag(Function.identity(), locations); + } + + @SafeVarargs + public final BUILDER addOptionalTag(Function locationGetter, T... elements) { + return add(TagEntry::optionalTag, locationGetter, elements); + } + + @SafeVarargs + private BUILDER add(Function entryCreator, Function 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 BUILDER remove(Function locationGetter, T... elements) { + return apply(rl -> builder.removeElement(rl, modID), locationGetter, elements); + } + + @SafeVarargs + public final BUILDER remove(TagKey... tags) { + for (TagKey tag : tags) { + builder.removeTag(tag.location(), modID); + } + return getThis(); + } + + @SafeVarargs + protected final BUILDER apply(Consumer consumer, Function locationGetter, T... elements) { + for (T element : elements) { + consumer.accept(locationGetter.apply(element)); + } + return getThis(); + } +} \ No newline at end of file diff --git a/src/data/java/uk/gemwire/engage/data/tags/IntrinsicEngageTagBuilder.java b/src/data/java/uk/gemwire/engage/data/tags/IntrinsicEngageTagBuilder.java new file mode 100644 index 0000000..1286331 --- /dev/null +++ b/src/data/java/uk/gemwire/engage/data/tags/IntrinsicEngageTagBuilder.java @@ -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 extends EngageTagBuilder> { + + private final Function> keyExtractor; + + public IntrinsicEngageTagBuilder (Function> keyExtractor, TagBuilder builder, String modID) { + super(builder, modID); + this.keyExtractor = keyExtractor; + } + + @SafeVarargs + public final IntrinsicEngageTagBuilder add(Supplier... elements) { + return addTyped(Supplier::get, elements); + } + + public ResourceLocation getKey(TYPE element) { + return keyExtractor.apply(element).location(); + } + + @SafeVarargs + public final IntrinsicEngageTagBuilder add(TYPE... elements) { + return add(this::getKey, elements); + } + + @SafeVarargs + public final IntrinsicEngageTagBuilder addTyped(Function converter, T... elements) { + return add(converter.andThen(this::getKey), elements); + } + + @SafeVarargs + public final IntrinsicEngageTagBuilder addOptional(TYPE... elements) { + return addOptional(this::getKey, elements); + } + + @SafeVarargs + public final IntrinsicEngageTagBuilder remove(TYPE... elements) { + return remove(this::getKey, elements); + } +} \ No newline at end of file diff --git a/src/data/java/uk/gemwire/engage/data/tags/block/BlockTagProvider.java b/src/data/java/uk/gemwire/engage/data/tags/block/BlockTagProvider.java new file mode 100644 index 0000000..53d2ef5 --- /dev/null +++ b/src/data/java/uk/gemwire/engage/data/tags/block/BlockTagProvider.java @@ -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 lookupProvider, @Nullable ExistingFileHelper existingFileHelper) { + super(output, lookupProvider, "engage", existingFileHelper); + } + + @Override + protected List getAllBlocks() { + return Blocks.BLOCKS_REGISTRY.getEntries().stream().map(RegistryObject::get).toList(); + } + + @Override + protected void registerTags(HolderLookup.Provider registries) { + addOres(); + addHarvests(); + } + + private void addOres() { + List ores = List.of(Blocks.BERYLLITE_ORE_BLOCK.get()); + for (Block ore : ores) { + TagKey itemTag = ItemTags.create(new ResourceLocation("forge:ores/" + ForgeRegistries.ITEMS.getKey(ore.asItem()).getPath())); + TagKey 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); + } + +} \ No newline at end of file diff --git a/src/data/resources/.cache/25bd38b64d05cf6fc0314ea079b987c6b7e5e687 b/src/data/resources/.cache/25bd38b64d05cf6fc0314ea079b987c6b7e5e687 new file mode 100644 index 0000000..8391f12 --- /dev/null +++ b/src/data/resources/.cache/25bd38b64d05cf6fc0314ea079b987c6b7e5e687 @@ -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 diff --git a/src/data/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d b/src/data/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d new file mode 100644 index 0000000..4afdb83 --- /dev/null +++ b/src/data/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d @@ -0,0 +1,2 @@ +// 1.20.1 2023-06-30T03:04:16.2684959 Loot Tables +22933ac7663f965e6fe3c560231b4bcb76c43bfa data/engage/loot_tables/blocks/beryllite_ore.json diff --git a/src/data/resources/.cache/66a165d3767db9e7e553407f2f645b3cc5ca9de9 b/src/data/resources/.cache/66a165d3767db9e7e553407f2f645b3cc5ca9de9 new file mode 100644 index 0000000..0e934b3 --- /dev/null +++ b/src/data/resources/.cache/66a165d3767db9e7e553407f2f645b3cc5ca9de9 @@ -0,0 +1,2 @@ +// 1.20.1 2023-06-30T03:04:16.2664787 atlases generator for engage +11e6e1f83c37071af466a42d29a662f54c2253c8 assets/minecraft/atlases/blocks.json diff --git a/src/data/resources/.cache/7b0d0541763a0d94f474a7a474c958ce2416d969 b/src/data/resources/.cache/7b0d0541763a0d94f474a7a474c958ce2416d969 new file mode 100644 index 0000000..26b570d --- /dev/null +++ b/src/data/resources/.cache/7b0d0541763a0d94f474a7a474c958ce2416d969 @@ -0,0 +1 @@ +// 1.20.1 2023-06-30T03:19:18.0192671 Block model provider: engage diff --git a/src/data/resources/.cache/8a3dba5a712aa838300c907fbeebb5313f8fde21 b/src/data/resources/.cache/8a3dba5a712aa838300c907fbeebb5313f8fde21 new file mode 100644 index 0000000..39757de --- /dev/null +++ b/src/data/resources/.cache/8a3dba5a712aa838300c907fbeebb5313f8fde21 @@ -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 diff --git a/src/data/resources/.cache/94dbe45e11443c880589aa262160b67ceb23d4f4 b/src/data/resources/.cache/94dbe45e11443c880589aa262160b67ceb23d4f4 new file mode 100644 index 0000000..1bde796 --- /dev/null +++ b/src/data/resources/.cache/94dbe45e11443c880589aa262160b67ceb23d4f4 @@ -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 diff --git a/src/data/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 b/src/data/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 new file mode 100644 index 0000000..bdac8ec --- /dev/null +++ b/src/data/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 @@ -0,0 +1,2 @@ +// 1.20.1 2023-06-30T03:04:16.2694935 Languages: en_us +50b8d51f4adf81848b9ed702904feddb9c747a09 assets/engage/lang/en_us.json diff --git a/src/data/resources/assets/engage/blockstates/antideuterium.json b/src/data/resources/assets/engage/blockstates/antideuterium.json new file mode 100644 index 0000000..1425355 --- /dev/null +++ b/src/data/resources/assets/engage/blockstates/antideuterium.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "engage:block/antideuterium" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/engage/blockstates/beryllite_ore.json b/src/data/resources/assets/engage/blockstates/beryllite_ore.json similarity index 100% rename from src/main/resources/assets/engage/blockstates/beryllite_ore.json rename to src/data/resources/assets/engage/blockstates/beryllite_ore.json diff --git a/src/data/resources/assets/engage/blockstates/deuterium.json b/src/data/resources/assets/engage/blockstates/deuterium.json new file mode 100644 index 0000000..eceabb2 --- /dev/null +++ b/src/data/resources/assets/engage/blockstates/deuterium.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "engage:block/deuterium" + } + } +} \ No newline at end of file diff --git a/src/data/resources/assets/engage/blockstates/deuterium_slush.json b/src/data/resources/assets/engage/blockstates/deuterium_slush.json new file mode 100644 index 0000000..ce47ba7 --- /dev/null +++ b/src/data/resources/assets/engage/blockstates/deuterium_slush.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "engage:block/deuterium_slush" + } + } +} \ No newline at end of file diff --git a/src/data/resources/assets/engage/blockstates/heavy_water.json b/src/data/resources/assets/engage/blockstates/heavy_water.json new file mode 100644 index 0000000..1df3852 --- /dev/null +++ b/src/data/resources/assets/engage/blockstates/heavy_water.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "engage:block/heavy_water" + } + } +} \ No newline at end of file diff --git a/src/data/resources/assets/engage/blockstates/propane.json b/src/data/resources/assets/engage/blockstates/propane.json new file mode 100644 index 0000000..bea5238 --- /dev/null +++ b/src/data/resources/assets/engage/blockstates/propane.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "engage:block/propane" + } + } +} \ No newline at end of file diff --git a/src/data/resources/assets/engage/blockstates/warp_plasma.json b/src/data/resources/assets/engage/blockstates/warp_plasma.json new file mode 100644 index 0000000..de91332 --- /dev/null +++ b/src/data/resources/assets/engage/blockstates/warp_plasma.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "engage:block/warp_plasma" + } + } +} \ No newline at end of file diff --git a/src/data/resources/assets/engage/lang/en_us.json b/src/data/resources/assets/engage/lang/en_us.json new file mode 100644 index 0000000..8733702 --- /dev/null +++ b/src/data/resources/assets/engage/lang/en_us.json @@ -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" +} \ No newline at end of file diff --git a/src/data/resources/assets/engage/models/block/antideuterium.json b/src/data/resources/assets/engage/models/block/antideuterium.json new file mode 100644 index 0000000..b8b4e7e --- /dev/null +++ b/src/data/resources/assets/engage/models/block/antideuterium.json @@ -0,0 +1,5 @@ +{ + "textures": { + "particle": "engage:liquid/liquid" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/engage/models/block/beryllite_ore.json b/src/data/resources/assets/engage/models/block/beryllite_ore.json similarity index 100% rename from src/main/resources/assets/engage/models/block/beryllite_ore.json rename to src/data/resources/assets/engage/models/block/beryllite_ore.json diff --git a/src/data/resources/assets/engage/models/block/deuterium.json b/src/data/resources/assets/engage/models/block/deuterium.json new file mode 100644 index 0000000..b8b4e7e --- /dev/null +++ b/src/data/resources/assets/engage/models/block/deuterium.json @@ -0,0 +1,5 @@ +{ + "textures": { + "particle": "engage:liquid/liquid" + } +} \ No newline at end of file diff --git a/src/data/resources/assets/engage/models/block/deuterium_slush.json b/src/data/resources/assets/engage/models/block/deuterium_slush.json new file mode 100644 index 0000000..b8b4e7e --- /dev/null +++ b/src/data/resources/assets/engage/models/block/deuterium_slush.json @@ -0,0 +1,5 @@ +{ + "textures": { + "particle": "engage:liquid/liquid" + } +} \ No newline at end of file diff --git a/src/data/resources/assets/engage/models/block/heavy_water.json b/src/data/resources/assets/engage/models/block/heavy_water.json new file mode 100644 index 0000000..b8b4e7e --- /dev/null +++ b/src/data/resources/assets/engage/models/block/heavy_water.json @@ -0,0 +1,5 @@ +{ + "textures": { + "particle": "engage:liquid/liquid" + } +} \ No newline at end of file diff --git a/src/data/resources/assets/engage/models/block/propane.json b/src/data/resources/assets/engage/models/block/propane.json new file mode 100644 index 0000000..b8b4e7e --- /dev/null +++ b/src/data/resources/assets/engage/models/block/propane.json @@ -0,0 +1,5 @@ +{ + "textures": { + "particle": "engage:liquid/liquid" + } +} \ No newline at end of file diff --git a/src/data/resources/assets/engage/models/block/warp_plasma.json b/src/data/resources/assets/engage/models/block/warp_plasma.json new file mode 100644 index 0000000..b8b4e7e --- /dev/null +++ b/src/data/resources/assets/engage/models/block/warp_plasma.json @@ -0,0 +1,5 @@ +{ + "textures": { + "particle": "engage:liquid/liquid" + } +} \ No newline at end of file diff --git a/src/data/resources/assets/engage/models/item/antideuterium_bucket.json b/src/data/resources/assets/engage/models/item/antideuterium_bucket.json new file mode 100644 index 0000000..58951b5 --- /dev/null +++ b/src/data/resources/assets/engage/models/item/antideuterium_bucket.json @@ -0,0 +1,5 @@ +{ + "parent": "forge:item/bucket", + "fluid": "engage:antideuterium", + "loader": "forge:fluid_container" +} \ No newline at end of file diff --git a/src/main/resources/assets/engage/models/item/beryllite_ore.json b/src/data/resources/assets/engage/models/item/beryllite_ore.json similarity index 100% rename from src/main/resources/assets/engage/models/item/beryllite_ore.json rename to src/data/resources/assets/engage/models/item/beryllite_ore.json diff --git a/src/main/resources/assets/engage/models/item/beryllite_raw.json b/src/data/resources/assets/engage/models/item/beryllite_raw.json similarity index 100% rename from src/main/resources/assets/engage/models/item/beryllite_raw.json rename to src/data/resources/assets/engage/models/item/beryllite_raw.json diff --git a/src/data/resources/assets/engage/models/item/deuterium_bucket.json b/src/data/resources/assets/engage/models/item/deuterium_bucket.json new file mode 100644 index 0000000..85238a3 --- /dev/null +++ b/src/data/resources/assets/engage/models/item/deuterium_bucket.json @@ -0,0 +1,5 @@ +{ + "parent": "forge:item/bucket", + "fluid": "engage:deuterium", + "loader": "forge:fluid_container" +} \ No newline at end of file diff --git a/src/data/resources/assets/engage/models/item/deuterium_slush_bucket.json b/src/data/resources/assets/engage/models/item/deuterium_slush_bucket.json new file mode 100644 index 0000000..b93de8a --- /dev/null +++ b/src/data/resources/assets/engage/models/item/deuterium_slush_bucket.json @@ -0,0 +1,5 @@ +{ + "parent": "forge:item/bucket", + "fluid": "engage:deuterium_slush", + "loader": "forge:fluid_container" +} \ No newline at end of file diff --git a/src/data/resources/assets/engage/models/item/heavy_water_bucket.json b/src/data/resources/assets/engage/models/item/heavy_water_bucket.json new file mode 100644 index 0000000..d29c28a --- /dev/null +++ b/src/data/resources/assets/engage/models/item/heavy_water_bucket.json @@ -0,0 +1,5 @@ +{ + "parent": "forge:item/bucket", + "fluid": "engage:heavy_water", + "loader": "forge:fluid_container" +} \ No newline at end of file diff --git a/src/data/resources/assets/engage/models/item/propane_bucket.json b/src/data/resources/assets/engage/models/item/propane_bucket.json new file mode 100644 index 0000000..971c5f7 --- /dev/null +++ b/src/data/resources/assets/engage/models/item/propane_bucket.json @@ -0,0 +1,5 @@ +{ + "parent": "forge:item/bucket", + "fluid": "engage:propane", + "loader": "forge:fluid_container" +} \ No newline at end of file diff --git a/src/data/resources/assets/engage/models/item/warp_plasma_bucket.json b/src/data/resources/assets/engage/models/item/warp_plasma_bucket.json new file mode 100644 index 0000000..1f06259 --- /dev/null +++ b/src/data/resources/assets/engage/models/item/warp_plasma_bucket.json @@ -0,0 +1,5 @@ +{ + "parent": "forge:item/bucket", + "fluid": "engage:warp_plasma", + "loader": "forge:fluid_container" +} \ No newline at end of file diff --git a/src/data/resources/assets/minecraft/atlases/blocks.json b/src/data/resources/assets/minecraft/atlases/blocks.json new file mode 100644 index 0000000..5af9b48 --- /dev/null +++ b/src/data/resources/assets/minecraft/atlases/blocks.json @@ -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" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/engage/loot_tables/blocks/beryllite_ore.json b/src/data/resources/data/engage/loot_tables/blocks/beryllite_ore.json similarity index 100% rename from src/main/resources/data/engage/loot_tables/blocks/beryllite_ore.json rename to src/data/resources/data/engage/loot_tables/blocks/beryllite_ore.json diff --git a/src/main/resources/data/forge/tags/blocks/ore_rates/singular.json b/src/data/resources/data/forge/tags/blocks/ore_rates/singular.json similarity index 69% rename from src/main/resources/data/forge/tags/blocks/ore_rates/singular.json rename to src/data/resources/data/forge/tags/blocks/ore_rates/singular.json index aedd9b9..b4f9822 100644 --- a/src/main/resources/data/forge/tags/blocks/ore_rates/singular.json +++ b/src/data/resources/data/forge/tags/blocks/ore_rates/singular.json @@ -1,5 +1,4 @@ { - "replace": false, "values": [ "engage:beryllite_ore" ] diff --git a/src/data/resources/data/forge/tags/blocks/ores.json b/src/data/resources/data/forge/tags/blocks/ores.json new file mode 100644 index 0000000..27f153d --- /dev/null +++ b/src/data/resources/data/forge/tags/blocks/ores.json @@ -0,0 +1,5 @@ +{ + "values": [ + "#forge:ores/beryllite_ore" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/forge/tags/blocks/ores.json b/src/data/resources/data/forge/tags/blocks/ores/beryllite_ore.json similarity index 69% rename from src/main/resources/data/forge/tags/blocks/ores.json rename to src/data/resources/data/forge/tags/blocks/ores/beryllite_ore.json index aedd9b9..b4f9822 100644 --- a/src/main/resources/data/forge/tags/blocks/ores.json +++ b/src/data/resources/data/forge/tags/blocks/ores/beryllite_ore.json @@ -1,5 +1,4 @@ { - "replace": false, "values": [ "engage:beryllite_ore" ] diff --git a/src/main/resources/data/forge/tags/blocks/ores_in_ground/stone.json b/src/data/resources/data/forge/tags/blocks/ores_in_ground/stone.json similarity index 69% rename from src/main/resources/data/forge/tags/blocks/ores_in_ground/stone.json rename to src/data/resources/data/forge/tags/blocks/ores_in_ground/stone.json index aedd9b9..b4f9822 100644 --- a/src/main/resources/data/forge/tags/blocks/ores_in_ground/stone.json +++ b/src/data/resources/data/forge/tags/blocks/ores_in_ground/stone.json @@ -1,5 +1,4 @@ { - "replace": false, "values": [ "engage:beryllite_ore" ] diff --git a/src/data/resources/data/forge/tags/items/ore_rates/singular.json b/src/data/resources/data/forge/tags/items/ore_rates/singular.json new file mode 100644 index 0000000..b4f9822 --- /dev/null +++ b/src/data/resources/data/forge/tags/items/ore_rates/singular.json @@ -0,0 +1,5 @@ +{ + "values": [ + "engage:beryllite_ore" + ] +} \ No newline at end of file diff --git a/src/data/resources/data/forge/tags/items/ores.json b/src/data/resources/data/forge/tags/items/ores.json new file mode 100644 index 0000000..27f153d --- /dev/null +++ b/src/data/resources/data/forge/tags/items/ores.json @@ -0,0 +1,5 @@ +{ + "values": [ + "#forge:ores/beryllite_ore" + ] +} \ No newline at end of file diff --git a/src/data/resources/data/forge/tags/items/ores/beryllite_ore.json b/src/data/resources/data/forge/tags/items/ores/beryllite_ore.json new file mode 100644 index 0000000..b4f9822 --- /dev/null +++ b/src/data/resources/data/forge/tags/items/ores/beryllite_ore.json @@ -0,0 +1,5 @@ +{ + "values": [ + "engage:beryllite_ore" + ] +} \ No newline at end of file diff --git a/src/data/resources/data/forge/tags/items/ores_in_ground/stone.json b/src/data/resources/data/forge/tags/items/ores_in_ground/stone.json new file mode 100644 index 0000000..b4f9822 --- /dev/null +++ b/src/data/resources/data/forge/tags/items/ores_in_ground/stone.json @@ -0,0 +1,5 @@ +{ + "values": [ + "engage:beryllite_ore" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/minecraft/tags/blocks/mineable/pickaxe.json b/src/data/resources/data/minecraft/tags/blocks/mineable/pickaxe.json similarity index 69% rename from src/main/resources/data/minecraft/tags/blocks/mineable/pickaxe.json rename to src/data/resources/data/minecraft/tags/blocks/mineable/pickaxe.json index aedd9b9..b4f9822 100644 --- a/src/main/resources/data/minecraft/tags/blocks/mineable/pickaxe.json +++ b/src/data/resources/data/minecraft/tags/blocks/mineable/pickaxe.json @@ -1,5 +1,4 @@ { - "replace": false, "values": [ "engage:beryllite_ore" ] diff --git a/src/main/resources/data/minecraft/tags/blocks/needs_iron_tool.json b/src/data/resources/data/minecraft/tags/blocks/needs_iron_tool.json similarity index 69% rename from src/main/resources/data/minecraft/tags/blocks/needs_iron_tool.json rename to src/data/resources/data/minecraft/tags/blocks/needs_iron_tool.json index aedd9b9..b4f9822 100644 --- a/src/main/resources/data/minecraft/tags/blocks/needs_iron_tool.json +++ b/src/data/resources/data/minecraft/tags/blocks/needs_iron_tool.json @@ -1,5 +1,4 @@ { - "replace": false, "values": [ "engage:beryllite_ore" ] diff --git a/src/main/resources/data/minecraft/tags/blocks/overworld_carver_replaceables.json b/src/data/resources/data/minecraft/tags/blocks/overworld_carver_replaceables.json similarity index 69% rename from src/main/resources/data/minecraft/tags/blocks/overworld_carver_replaceables.json rename to src/data/resources/data/minecraft/tags/blocks/overworld_carver_replaceables.json index aedd9b9..b4f9822 100644 --- a/src/main/resources/data/minecraft/tags/blocks/overworld_carver_replaceables.json +++ b/src/data/resources/data/minecraft/tags/blocks/overworld_carver_replaceables.json @@ -1,5 +1,4 @@ { - "replace": false, "values": [ "engage:beryllite_ore" ] diff --git a/src/main/resources/data/minecraft/tags/blocks/snaps_goat_horn.json b/src/data/resources/data/minecraft/tags/blocks/snaps_goat_horn.json similarity index 69% rename from src/main/resources/data/minecraft/tags/blocks/snaps_goat_horn.json rename to src/data/resources/data/minecraft/tags/blocks/snaps_goat_horn.json index aedd9b9..b4f9822 100644 --- a/src/main/resources/data/minecraft/tags/blocks/snaps_goat_horn.json +++ b/src/data/resources/data/minecraft/tags/blocks/snaps_goat_horn.json @@ -1,5 +1,4 @@ { - "replace": false, "values": [ "engage:beryllite_ore" ] diff --git a/src/main/java/uk/gemwire/engage/Engage.java b/src/main/java/uk/gemwire/engage/Engage.java index 7228a00..37ea8f1 100644 --- a/src/main/java/uk/gemwire/engage/Engage.java +++ b/src/main/java/uk/gemwire/engage/Engage.java @@ -4,8 +4,44 @@ import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import uk.gemwire.engage.registries.Blocks; +import uk.gemwire.engage.registries.Fluids; 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") public class Engage { @@ -14,5 +50,8 @@ public class Engage { // registry classes Items.ITEMS_REGISTRY.register(bus); Blocks.BLOCKS_REGISTRY.register(bus); + Fluids.FLUIDS_REGISTRY.register(bus); + Worldgen.CARVER_REGISTRY.register(bus); + Worldgen.BIOME_MODIFIER_SERIALIZERS.register(bus); } } diff --git a/src/main/java/uk/gemwire/engage/registries/Fluids.java b/src/main/java/uk/gemwire/engage/registries/Fluids.java new file mode 100644 index 0000000..bff8014 --- /dev/null +++ b/src/main/java/uk/gemwire/engage/registries/Fluids.java @@ -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 HEAVY_WATER_FLUID = FLUIDS_REGISTRY.register("heavy_water", properties -> properties.tint(0xFFFF3232)); + + // Deuterium + public static final FluidRegistryObject DEUTERIUM_FLUID = FLUIDS_REGISTRY.register("deuterium", properties -> properties.tint(0xFFFF3232)); + + // Deuterium Slush + public static final FluidRegistryObject DEUTERIUM_SLUSH_FLUID = FLUIDS_REGISTRY.register("deuterium_slush", properties -> properties.tint(0xFFFF3232)); + + // Antideuterium + public static final FluidRegistryObject ANTIDEUTERIUM_FLUID = FLUIDS_REGISTRY.register("antideuterium", properties -> properties.tint(0xFFFF3232)); + + // Warp Plasma + public static final FluidRegistryObject WARP_PLASMA_FLUID = FLUIDS_REGISTRY.register("warp_plasma", properties -> properties.tint(0xFFFF3232)); + + // Propane (refrigerant) + public static final FluidRegistryObject PROPANE_FLUID = FLUIDS_REGISTRY.register("propane", properties -> properties.tint(0xFFFF3232)); + +} diff --git a/src/main/java/uk/gemwire/engage/registries/Worldgen.java b/src/main/java/uk/gemwire/engage/registries/Worldgen.java new file mode 100644 index 0000000..d33d4d4 --- /dev/null +++ b/src/main/java/uk/gemwire/engage/registries/Worldgen.java @@ -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> CARVER_REGISTRY = DeferredRegister.create(ForgeRegistries.WORLD_CARVERS, "engage"); + public static final DeferredRegister> BIOME_MODIFIER_SERIALIZERS = DeferredRegister.create(ForgeRegistries.Keys.BIOME_MODIFIER_SERIALIZERS, "engage"); + + public static final RegistryObject> PROPANE_CARVER = CARVER_REGISTRY.register("propane_cave", () -> new PropaneCaveCarver(PropaneCaveCarverConfiguration.CODEC)); + + public static final RegistryObject> 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)) + ); +} diff --git a/src/main/java/uk/gemwire/engage/registries/fluid/FluidDeferredRegister.java b/src/main/java/uk/gemwire/engage/registries/fluid/FluidDeferredRegister.java new file mode 100644 index 0000000..c9cb025 --- /dev/null +++ b/src/main/java/uk/gemwire/engage/registries/fluid/FluidDeferredRegister.java @@ -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> allFluids = new ArrayList<>(); + + private final DeferredRegister fluidTypeRegister; + private final DeferredRegister fluidRegister; + private final DeferredRegister blockRegister; + private final DeferredRegister 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 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 register(String name, UnaryOperator renderProperties) { + return register(name, UnaryOperator.identity(), renderProperties); + } + + public FluidRegistryObject register(String name, UnaryOperator properties, + UnaryOperator renderProperties) { + return register(name, BucketItem::new, properties, renderProperties); + } + + public FluidRegistryObject register(String name, BucketCreator bucketCreator, + UnaryOperator fluidProperties, UnaryOperator renderProperties) { + return register(name, fluidProperties.apply(getMekBaseBuilder()), renderProperties.apply(FluidTypeRenderProperties.builder()), bucketCreator, + MekanismFluidType::new); + } + + public FluidRegistryObject register(String name, + FluidType.Properties properties, FluidTypeRenderProperties renderProperties, BucketCreator bucketCreator, + BiFunction 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 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> getAllFluids() { + return Collections.unmodifiableList(allFluids); + } + + public void registerBucketDispenserBehavior() { + for (FluidRegistryObject fluidRO : getAllFluids()) { + DispenserBlock.registerBehavior(fluidRO.getBucket(), BUCKET_DISPENSE_BEHAVIOR); + } + } + + @FunctionalInterface + public interface BucketCreator { + + BUCKET create(Supplier 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 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; + } + }); + } + } +} \ No newline at end of file diff --git a/src/main/java/uk/gemwire/engage/registries/fluid/FluidRegistryObject.java b/src/main/java/uk/gemwire/engage/registries/fluid/FluidRegistryObject.java new file mode 100644 index 0000000..85b4634 --- /dev/null +++ b/src/main/java/uk/gemwire/engage/registries/fluid/FluidRegistryObject.java @@ -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 { + + private RegistryObject fluidTypeRO; + private RegistryObject stillRO; + private RegistryObject flowingRO; + private RegistryObject blockRO; + private RegistryObject 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 fluidTypeRO) { + this.fluidTypeRO = Objects.requireNonNull(fluidTypeRO); + } + + void updateStill(RegistryObject stillRO) { + this.stillRO = Objects.requireNonNull(stillRO); + } + + void updateFlowing(RegistryObject flowingRO) { + this.flowingRO = Objects.requireNonNull(flowingRO); + } + + void updateBlock(RegistryObject blockRO) { + this.blockRO = Objects.requireNonNull(blockRO); + } + + void updateBucket(RegistryObject bucketRO) { + this.bucketRO = Objects.requireNonNull(bucketRO); + } + + public STILL getFluid() { + //Default our fluid to being the still variant + return getStillFluid(); + } +} \ No newline at end of file diff --git a/src/main/java/uk/gemwire/engage/registries/fluid/IChemicalConstant.java b/src/main/java/uk/gemwire/engage/registries/fluid/IChemicalConstant.java new file mode 100644 index 0000000..e063e14 --- /dev/null +++ b/src/main/java/uk/gemwire/engage/registries/fluid/IChemicalConstant.java @@ -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(); +} \ No newline at end of file diff --git a/src/main/java/uk/gemwire/engage/worldgen/PropaneCaveCarver.java b/src/main/java/uk/gemwire/engage/worldgen/PropaneCaveCarver.java new file mode 100644 index 0000000..64e628e --- /dev/null +++ b/src/main/java/uk/gemwire/engage/worldgen/PropaneCaveCarver.java @@ -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 { + + + public PropaneCaveCarver(Codec 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> 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> 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> 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> 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; + } + } +} diff --git a/src/main/java/uk/gemwire/engage/worldgen/PropaneCaveCarverConfiguration.java b/src/main/java/uk/gemwire/engage/worldgen/PropaneCaveCarverConfiguration.java new file mode 100644 index 0000000..643a92f --- /dev/null +++ b/src/main/java/uk/gemwire/engage/worldgen/PropaneCaveCarverConfiguration.java @@ -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 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 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 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_); + } +} diff --git a/src/main/java/uk/gemwire/engage/worldgen/modifiers/AddCarverBiomeModifier.java b/src/main/java/uk/gemwire/engage/worldgen/modifiers/AddCarverBiomeModifier.java new file mode 100644 index 0000000..4ea269f --- /dev/null +++ b/src/main/java/uk/gemwire/engage/worldgen/modifiers/AddCarverBiomeModifier.java @@ -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 biomes, HolderSet> carvers, GenerationStep.Carving step) implements BiomeModifier { + + @Override + public void modify(Holder 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 codec() + { + return Worldgen.ADD_CARVERS_BIOME_MODIFIER_TYPE.get(); + } +} diff --git a/src/main/resources/assets/engage/textures/liquid/liquid.png b/src/main/resources/assets/engage/textures/liquid/liquid.png new file mode 100644 index 0000000000000000000000000000000000000000..ad196479cf5fe58b5a7eaf208e4a2a358db192fd GIT binary patch literal 5136 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/engage/textures/liquid/liquid.png.mcmeta b/src/main/resources/assets/engage/textures/liquid/liquid.png.mcmeta new file mode 100644 index 0000000..7e77c64 --- /dev/null +++ b/src/main/resources/assets/engage/textures/liquid/liquid.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation": { + "frametime": 2 + } +} \ No newline at end of file diff --git a/src/main/resources/assets/engage/textures/liquid/liquid_flow.png b/src/main/resources/assets/engage/textures/liquid/liquid_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..1a91a3fbb25bb37b656a55b12de9749057ab30ab GIT binary patch literal 4518 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 YmmOI*a(EI3|A;_Xo7