Last active
December 20, 2022 22:36
-
-
Save X-Niter/83ce88193e803249ebdec0e8e7c0b47e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class FluidRegistry { | |
private static final ResourceLocation OVERLAY = new ResourceLocation("block/water_overlay"); | |
private static final ResourceLocation RENDER_OVERLAY = new ResourceLocation("textures/misc/underwater.png"); | |
private static final ResourceLocation LIQUID = new ResourceLocation("block/water_still"); | |
private static final ResourceLocation LIQUID_FLOW = new ResourceLocation("block/water_flow"); | |
private final DeferredRegister<Fluid> FLUIDS; | |
private final DeferredRegister<FluidType> FLUID_TYPES; | |
private final DeferredRegister<Block> LIQUID_BLOCKS; | |
private final DeferredRegister<Item> BUCKETS; | |
private static final List<FluidProviderRegistryObject<? extends ChemlibFluidTypes, ?, ?, ?, ?>> allFluids = new ArrayList<>(); | |
private final String modid; | |
public FluidRegistry(String modid) { | |
this.modid = modid; | |
FLUIDS = DeferredRegister.create(ForgeRegistries.FLUIDS, modid); | |
FLUID_TYPES = DeferredRegister.create(ForgeRegistries.Keys.FLUID_TYPES, modid); | |
LIQUID_BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, modid); | |
BUCKETS = DeferredRegister.create(ForgeRegistries.ITEMS, modid); | |
} | |
public DeferredRegister<FluidType> getFluidTypes() { | |
return this.FLUID_TYPES; | |
} | |
public FluidProviderRegistryObject<ChemlibFluidTypes, Source, Flowing, LiquidBlock, BucketItem> registerLiquidChemical(String name, int pColor) { | |
int density = Math.round(100); | |
return register(name, properties -> properties | |
.temperature(0) | |
.density(density) | |
.viscosity(density) | |
.lightLevel(0), renderProperties -> renderProperties | |
.tint(pColor) | |
); | |
} | |
public static FluidType.Properties getFluidTypeProperties() { | |
return FluidType.Properties.create() | |
.sound(SoundActions.BUCKET_FILL, SoundEvents.BUCKET_FILL) | |
.sound(SoundActions.BUCKET_EMPTY, SoundEvents.BUCKET_EMPTY); | |
} | |
public void registerElementalFluids() { | |
for (JsonElement jsonElement : ELEMENTS_JSON.getAsJsonArray("elements")) { | |
JsonObject object = jsonElement.getAsJsonObject(); | |
String elementName = object.get("name").getAsString(); | |
MatterState matterState = MatterState.valueOf(object.get("matter_state").getAsString().toUpperCase()); | |
boolean artificial = object.has("artificial") && object.get("artificial").getAsBoolean(); | |
String color = object.get("color").getAsString(); | |
if (!artificial) { | |
switch (matterState) { | |
case LIQUID, GAS -> { | |
boolean hasFluid = object.has("has_fluid") && object.get("has_fluid").getAsBoolean(); | |
if (!hasFluid) { | |
JsonObject properties = object.get("fluid_properties").getAsJsonObject(); | |
int slopeFindDistance = properties.has("slope_find_distance") ? properties.get("slope_find_distance").getAsInt() : 4; | |
int decreasePerBlock = properties.has("decrease_per_block") ? properties.get("decrease_per_block").getAsInt() : 1; | |
register( | |
elementName, | |
fluidTypePropertiesFactory(properties, elementName), | |
renderProperties -> renderProperties | |
.tint((int) Long.parseLong(color, 16)) | |
); | |
} | |
} | |
} | |
} | |
} | |
} | |
public void registerCompoundFluids() {// TODO ADD IN THE JSON COMPOUND DYNAMIC FLUID REGISTRATION SIMILAR TO THE ABOVE METHOD | |
} | |
public FluidProviderRegistryObject<ChemlibFluidTypes, Source, Flowing, LiquidBlock, BucketItem> register(String name, UnaryOperator<FluidTypeRenderProperties> renderProperties) { | |
return register(name, UnaryOperator.identity(), renderProperties); | |
} | |
public FluidProviderRegistryObject<ChemlibFluidTypes, Source, Flowing, LiquidBlock, BucketItem> register( | |
String name, UnaryOperator<FluidType.Properties> properties, UnaryOperator<FluidTypeRenderProperties> renderProperties) { | |
return register(name, BucketItem::new, properties, renderProperties); | |
} | |
public FluidProviderRegistryObject<ChemlibFluidTypes, Source, Flowing, LiquidBlock, BucketItem> register( | |
String name, FluidType.Properties properties, UnaryOperator<FluidTypeRenderProperties> renderProperties) { | |
return register(name, BucketItem::new, properties, renderProperties); | |
} | |
public <BUCKET extends BucketItem> FluidProviderRegistryObject<ChemlibFluidTypes, Source, Flowing, LiquidBlock, BUCKET> register( | |
String name, BucketCreator<BUCKET> bucketCreator, FluidType.Properties fluidProperties, UnaryOperator<FluidTypeRenderProperties> renderProperties) { | |
return register(name, fluidProperties, renderProperties.apply(FluidTypeRenderProperties.builder()), bucketCreator, | |
ChemlibFluidTypes::new); | |
} | |
public <BUCKET extends BucketItem> FluidProviderRegistryObject<ChemlibFluidTypes, Source, Flowing, LiquidBlock, BUCKET> register( | |
String name, BucketCreator<BUCKET> bucketCreator, UnaryOperator<FluidType.Properties> fluidProperties, UnaryOperator<FluidTypeRenderProperties> renderProperties) { | |
return register(name, fluidProperties.apply(getFluidTypeProperties()), renderProperties.apply(FluidTypeRenderProperties.builder()), bucketCreator, | |
ChemlibFluidTypes::new); | |
} | |
public <TYPE extends ChemlibFluidTypes, BUCKET extends BucketItem> FluidProviderRegistryObject<TYPE, Source, Flowing, LiquidBlock, BUCKET> register( | |
String pName, FluidType.Properties properties, FluidTypeRenderProperties renderProperties, BucketCreator<BUCKET> bucketCreator, BiFunction<FluidType.Properties, FluidTypeRenderProperties, TYPE> fluidTypeCreator) { | |
String fluidSource = pName + "_fluid"; | |
String fluidFlowing = pName + "_flowing"; | |
String bucket = pName + "_bucket"; | |
//Set the translation string to the same as the block | |
//properties.descriptionId(Util.makeDescriptionId("block", new ResourceLocation(modid, pName))); | |
//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 | |
FluidProviderRegistryObject<TYPE, Source, Flowing, LiquidBlock, BUCKET> fluidRegistryObject = new FluidProviderRegistryObject<>(); | |
//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(FLUID_TYPES.register(pName, () -> | |
fluidTypeCreator.apply(properties, renderProperties))); | |
fluidRegistryObject.updateStill(FLUIDS.register(fluidSource, () -> | |
new Source(fluidProperties))); | |
fluidRegistryObject.updateFlowing(FLUIDS.register(fluidFlowing, () -> | |
new Flowing(fluidProperties))); | |
//Note: The block properties used here is a copy of the ones for water | |
fluidRegistryObject.updateBlock(LIQUID_BLOCKS.register(pName, () -> | |
new LiquidBlock(fluidRegistryObject::getStillFluid, BlockBehaviour.Properties.of(Material.WATER)))); | |
fluidRegistryObject.updateBucket(BUCKETS.register(bucket, () -> | |
bucketCreator.create(fluidRegistryObject::getStillFluid, new Item.Properties().tab(ItemRegistry.MISC_TAB).stacksTo(1)))); | |
allFluids.add(fluidRegistryObject); | |
return fluidRegistryObject; | |
} | |
public void register(IEventBus bus) { | |
// Fires the JSON OBJECT Elements to get registered as fluids first | |
registerElementalFluids(); | |
// Register fluids as normal | |
FLUID_TYPES.register(bus); | |
FLUIDS.register(bus); | |
LIQUID_BLOCKS.register(bus); | |
BUCKETS.register(bus); | |
} | |
public List<FluidProviderRegistryObject<? extends ChemlibFluidTypes, ?, ?, ?, ?>> getAllFluids() { | |
return Collections.unmodifiableList(allFluids); | |
} | |
@FunctionalInterface | |
public interface BucketCreator<BUCKET extends BucketItem> { | |
BUCKET create(Supplier<? extends Fluid> supplier, Item.Properties builder); | |
} | |
public static class FluidTypeRenderProperties { | |
private ResourceLocation stillTexture = LIQUID; | |
private ResourceLocation flowingTexture = LIQUID_FLOW; | |
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 ChemlibFluidTypes extends FluidType { | |
private final ResourceLocation stillTexture; | |
private final ResourceLocation flowingTexture; | |
private final ResourceLocation overlayTexture; | |
private final ResourceLocation renderOverlayTexture; | |
private final int color; | |
public ChemlibFluidTypes(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; | |
} | |
//For use in datagen | |
// TODO: Could this be the solution to solve JEI and Mek rendering our fluids invisible??? | |
public ResourceLocation getStillTexture() { | |
return stillTexture; | |
} | |
@Override | |
public boolean isVaporizedOnPlacement(Level level, BlockPos pos, FluidStack stack) { | |
//TODO - I wonder if we can allow json object definition for if this fluid vaporizes? That would be cool | |
return false; | |
} | |
@Override | |
public void initializeClient(Consumer<IClientFluidTypeExtensions> consumer) { | |
consumer.accept(new IClientFluidTypeExtensions() { | |
@Override | |
public ResourceLocation getStillTexture() { | |
return stillTexture; | |
} | |
@Override | |
public ResourceLocation getFlowingTexture() { | |
return flowingTexture; | |
} | |
@Override | |
public ResourceLocation getOverlayTexture() { | |
return overlayTexture; | |
} | |
@Nullable | |
@Override | |
public ResourceLocation getRenderOverlayTexture(Minecraft mc) { | |
return renderOverlayTexture; | |
} | |
@Override | |
public int getTintColor() { | |
return color; | |
} | |
}); | |
} | |
} | |
/* | |
This section defines helper methods for accessing fluids and fluid types from the registry. | |
The first set of helper methods provide streams of fluid objects. | |
*/ | |
public Stream<Fluid> getFluidsAsStream() { | |
return FLUIDS.getEntries().stream().map(RegistryObject::get); | |
} | |
public Stream<FluidType> getFluidTypesAsStream() { | |
return getFluidsAsStream().map(Fluid::getFluidType); | |
} | |
public Stream<ForgeFlowingFluid.Source> getSourceFluidsAsStream() { | |
return getFluidsAsStream().filter(fluid -> fluid instanceof ForgeFlowingFluid.Source).map(fluid -> (ForgeFlowingFluid.Source) fluid); | |
} | |
public Stream<ForgeFlowingFluid.Source> getLiquidSourceFluidsAsStream() { | |
return getSourceFluidsAsStream().filter(source -> !source.getFluidType().isLighterThanAir()); | |
} | |
public Stream<ForgeFlowingFluid.Source> getGasSourceFluidsAsStream() { | |
return getSourceFluidsAsStream().filter(source -> source.getFluidType().isLighterThanAir()); | |
} | |
/* | |
This set of helper methods provide lists of fluid objects. | |
*/ | |
public List<Fluid> getFluids() { | |
return getFluidsAsStream().collect(Collectors.toList()); | |
} | |
public List<Fluid> getSourceFluids() { | |
return getSourceFluidsAsStream().collect(Collectors.toList()); | |
} | |
public List<Fluid> getLiquidSourceFluids() { | |
return getLiquidSourceFluidsAsStream().collect(Collectors.toList()); | |
} | |
public List<Fluid> getGasSourceFluids() { | |
return getGasSourceFluidsAsStream().collect(Collectors.toList()); | |
} | |
/* | |
Get a single object by filtering a registry stream. | |
*/ | |
public Optional<FluidType> getFluidTypeByName(String pName) { | |
return getFluidTypesAsStream().filter(fluidType -> Objects.requireNonNull(ForgeRegistries.FLUID_TYPES.get().getKey(fluidType)).getPath().equals(pName)).findFirst(); | |
} | |
public Optional<ForgeFlowingFluid.Source> getSourceFluidByName(String pName) { | |
return getSourceFluidsAsStream().filter(source -> Objects.requireNonNull(ForgeRegistries.FLUID_TYPES.get().getKey(source.getFluidType())).getPath().equals(pName)).findFirst(); | |
} | |
public Optional<ForgeFlowingFluid.Source> getLiquidSourceFluidByName(String pName) { | |
return getLiquidSourceFluidsAsStream().filter(source -> Objects.requireNonNull(ForgeRegistries.FLUID_TYPES.get().getKey(source.getFluidType())).getPath().equals(pName)).findFirst(); | |
} | |
public Optional<ForgeFlowingFluid.Source> getGasSourceFluidByName(String pName) { | |
return getGasSourceFluidsAsStream().filter(source -> Objects.requireNonNull(ForgeRegistries.FLUID_TYPES.get().getKey(source.getFluidType())).getPath().equals(pName)).findFirst(); | |
} | |
/* | |
This set of helpers define methods to get blocks and items from the fluid registry. | |
*/ | |
public Stream<LiquidBlock> getLiquidBlocks() { | |
return LIQUID_BLOCKS.getEntries().stream().map(RegistryObject::get).map(block -> (LiquidBlock) block); | |
} | |
public Stream<BucketItem> getBuckets() { | |
return BUCKETS.getEntries().stream().map(RegistryObject::get).map(item -> (BucketItem) item); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment