/
Many things have been changed in this update, so be safe and create a backup of your world before updating!
Big Features:
BlockFluidFinite fluidlogging (blocks like Biomes O' Plenty honey)!Small Features:
blacklist, fluidTags, and whitelist can now be supplied as a list or object, making the configs much easier to use overall. For example, fluids: [{fluidId: "lava"}, {fluidId: ["oil", "crude_oil"]}, {materialId: "water"}] and fluids: {fluidId: "lava"} are both valid. When something is supplied as a list, anything matching even just one entry will be accepted.general.cfg in-game will now cause the world to re-render (like changing between fast and fancy graphics).boxes: {min: 0, max: 16} tells Fluidlogged API that this entry occupies a [X by 16 by Z] pixel-wide area, and boxes: [{min: 0, max: 5}, {min: 7, max: 16}] tells Fluidlogged API that there's a vertical gap of 2 pixels starting 5 pixels off the ground. Many modded blocks do not have collision boxes that accurately reflect their block model. Fluidlogged API tries to dynamically calculate fluidloggability based on collision boxes for non-source fluidlogging, so this setting allows that calculation to be accurate!canFluidFlow: true, canFluidFlow: "up", and canFluidFlow: ["north", "south", "east", "west"] are all valid.{fluidId: "water"} returns the vanilla water fluid.{materialId: lava} finds the vanilla lava fluid, then returns all fluids that have that same block material."water") will still work.fluidTags.cfg entry improvements:
IFluidloggable blocks that have overrideApplyDefaultsSetting() return true.fluidlogged_api/blacklist.cfg, fluidlogged_api/fluidTags.cfg, fluidlogged_api/general.cfg, fluidlogged_api/whitelist.cfg] files, instead of all settings being in one fluidlogged_api.cfg file.fluidlogged_api.cfg config is automatically converted to the new format at runtime, with existing settings preserved. The old file in renamed fluidlogged_api.cfg_old and a fluidlogged_api.cfg_README.txt file is created to inform players of the config system change.getOptimalFlowDirections())]. ["removeVerticalFluidloggedFluidSpread" was removed due to rewriting fluid flow logic, the addition of non-source fluidlogging superseding it, and it being a workaround for the limited fluidlogging functionality at the time].fluidlogged and fluidlogged_api tree commands:
help subcommand: functions the same as the /forge help subcommand.print subcommand: outputs all fluidlogging information to a file, making it easy for modpack devs to identify all fluidloggable blocks.reload subcommand: functions the same as the reloadFluidloggedAPI command.setfluid subcommand: functions the same as the /setfluid command, and now accepts an optional fluid level argument.test subcommand: tests the fluidloggability of whatever block is at the provided position./fluidlogged and /fluidloggedAPI tree commands. The existing /reloadFluidloggedAPI and /setfluid commands will remain.Bug Fixes:
Block.getExplosionResistance() calls, to fix compatibility issues for blocks that override Block.getExplosionResistance().World.isMaterialInBB() collision bug.useNeighborBrightness = true.FluidState.of() now accounts for IExtendedBlockState instances, preventing possible duplicate FluidStates at runtime.FillBucketEvent, instead handled by class transformations.FluidState.getExtendedState code:
Compatibility Bug Fixes:
EntityBoat) should now work properly (issue#194).BlockWall fixes to all improperly coded modded wall blocks.IFluidBlock.getFilledPercentage(). It caused some inconsistencies with certain mods, like some modded fluids having a higher light level while Fluidlogged API was installedFluidBucketWrapper now accounts for modded ItemBucket instances.FillBucketEvent event subscriber.IFluidHandler when placing/taking fluids.PluginCBMultipart).BlockGrating fluidloggable, and removing all of its built-in "pseudo-fluidlogging" logic. This also fixes many other miscellaneous bugs and compatibility issues with the block in general.getExtendedState code (fixes rendering bugs).IFluidHandler when placing/taking fluids.IFluidHandler when placing/taking fluids.IFluidHandler.IFluidHandler when placing/taking fluids.IFluidHandler when placing/taking fluids.API Changes:
api.world package rewrite, aimed at "un-hardcoding" FluidState world access.PluginBlockLiquid, PluginBlockFluidBase, PluginBlockFluidClassic, etc. into their own handler classes.api.asm.impl package.api.asm.IASMPlugin:
addMethod() method that accepts a method signature.findLocal() method that allows local variable whose indexes change to still be used.getAccessorClass() method that returns the class name of a nested accessor interface.overrideMethod() method that takes in a MethodNode directly, instead of a search condition.h condition.transform() method that takes in a ClassNode.transformNode() method, splits some functionality off byte[] transform().withAccessorClass() method that returns a formatted method descriptor string, with the accessor class added.api.block.BlockWaterloggedPlant:
api.block.IFluidloggable:
api.block.IFluidloggable are exempt from the world generation changes.isFluidloggable() method that accepts a FluidState, to allow for non-source fluidlogging.overrideApplyDefaultsSetting() method that allows blocks to keep their fluidlogging functionality while "applyDefaults" is turned off.isFluidloggable() and isFluidValid() methods are now only called by the new isFluidloggable() method.api.block.IFluidloggableFluid:
api.fluid.IFluidloggableFluid.api.fluid.IFluidloggableFluid now has all control over fluidlogging.api.capability.IFluidStateCapability:
get() for chunks, now O(1) instead of O(2n).getContainer() methods and replace them with one getContainer() method that accepts a y position.api.capability.IFluidStateContainer:
getFluidState() method that accepts the block position as (x, y, z) integers.getSerializedPositions() method that exposes all non-empty FluidState positions as an unmodifiable char set.setFluidState() method that accepts the block position as (x, y, z) integers.forEach() method that does not box the serialized positions.api.capability.IPosSerializer:
api.capability.IFluidStateContainer.api.datafix:
api.event.FluidloggableEvent:
IBlockAccess and FluidState fields.api.event.FluidloggedAPIConfigsEvent:
JsonObject config data on read/reload, or to outright block them.api.fluid.ICompatibleFluid:
getFluidCompatibility() method, allows fluids to specify fluid incompatibility.isCompatibleFluid() method is now only called by getFluidCompatibility().api.fluid.IFlowCostFluid:
api.network.FluidloggedAPINetworkHandler:
mod.FluidloggedAPI.api.network.IClientMessageHandler:
getWorldFromContext() utility method that returns the world from the message context, prevents a very rare NPE crash.handleMessage() method that accepts the message context.handleMessage() method is now deprecated.api.util.FluidState:
addLevel(int) method that returns this FluidState with the provided fluid level added.createFluidStack() method returns a new FluidStack containing this FluidState's fluid.get(access, x, y, z) method. Functions like get(access, pos), but takes [x, y, z] directly.getActualHeight(access, pos) method that returns the in-world height of this FluidState in pixels, 1 if this FluidState is submerged.getDensity() method that returns this FluidState's fluid density.getDensityDir() method that returns the densityDir of this FluidState's block if it's a BlockFluidBase, otherwise returns -1.getDisplacements() method that returns the displacements of this FluidState's block if it's a BlockFluidBase, otherwise returns empty.getDownDensityFace() method that returns the direction that this FluidState thinks is "down", using FluidState.getDensityDir().getFlowCost(world) method that returns the flow cost of this fluid.getFluidBlockHandler() method that returns this FluidState as an IFluidloggableFluid.getFluidBox(access, pos) method that returns the in-world box that this fluid occupies.getFromProvider(provider, x, y, z) method. Functions like getFromProvider(provider, pos), but takes [x, y, z] directly.getHeight() method that returns the approximate in-world height of this FluidState in pixels, using only this FluidState's level.getMetadata() method that returns the metadata value of this FluidState's IBlockState.getQuantaFraction() method that returns the quantaFraction of this FluidState's block if it's a BlockFluidBase, otherwise returns 8/9.getQuantaPerBlock() method that returns the quantaPerBlock of this FluidState's block if it's a BlockFluidBase, otherwise returns 8.getQuantaPerBlockFloat() method that returns the quantaPerBlockFloat of this FluidState's block if it's a BlockFluidBase, otherwise returns 8.getQuantaValue() method that returns the quanta value of this FluidState, using only this FluidState level.getQuantaValue(access, pos) method that returns the quanta value of the FluidState (or wrapped fluid IBlockState) at the position, but only if it's compatible with this FluidState. Otherwise, returns -1, or 0 if the block is air.getQuantaValueAbove(access, pos, int) that returns the quanta value of the FluidState (or wrapped fluid IBlockState) at the position, but only if it's compatible with this FluidState and the quanta value is higher than the "aboveThis" int parameter. Otherwise, returns -1.getQuantaValueBelow(access, pos, int) that returns the quanta value of the FluidState (or wrapped fluid IBlockState) at the position, but only if it's compatible with this FluidState and the quanta value is below the "belowThis" int parameter. Otherwise, returns -1.getTemperature() method that returns this FluidState's fluid temperature.getUpDensityFace() method that returns the direction that this FluidState thinks is "up", using FluidState.getDensityDir().getWrappedLevel(world) method that returns the flow cost if this FluidState is a BlockLiquid waterfall, otherwise returns the fluid level.isFluidloggable() method that returns true if this FluidState can be used for fluidlogging.isSource() method that returns true if this FluidState is a source block.toFlowing() method that returns this FluidState as a BlockDynamicLiquid if it's a BlockStaticLiquid, otherwise returns itself.toSource() method that returns this FluidState as a source block.toStatic() method that returns this FluidState as a BlockStaticLiquid if it's a BlockDynamicLiquid, otherwise returns itself.withLevel(int) method that returns this FluidState with the provided fluid level.Supplier<IBlockState> state field, instead uses a IBlockState state field.api.util.FluidloggedUtils:
canCreateSource(state, world, pos) method that returns true if the fluid IBlockState can create source blocks.canFluidOccupy(state, access, pos, fluidState) method that returns true if the FluidState physically fits outside the provided actual state.getFluidOrReal(chunk, pos) method. Functions like getFluidOrReal(access, pos), but uses a Chunk instead.getFluidOrReal(chunk, pos, state) method. Functions like getFluidOrReal(access, pos, state), but uses a Chunk instead.getFluidState(chunk, pos) method. Functions like getFluidState(access, pos), but uses a Chunk instead.getFluidState(chunk, pos, state) method. Functions like getFluidState(access, pos, state), but uses a Chunk instead.isCompatibleFluid(fluidState, fluidState) method. Functions like isCompatibleFluid(fluid. fluid), but uses FluidState instead.isStateFluidloggable(state, access, pos, fluidState) method that returns true if the provided state is fluidloggable with the provided FluidState.playVaporizeEffects(world, pos, fluidStack) utility method that runs Fluid.vaporize() from the server, while still allowing clients to see any particles.relightFluidBlock(world, pos, chunk. fluidState) method. Functions like relightFluidBlock(world, pos, fluidState), but allows the Chunk to be passed in.setFluidToAir(world, pos, state, int) method that sets a FluidState or fluid IBlockState to air, and returns true if it was successful.getFluidOrReal and getFluidState methods by calling their alternative Chunk-based method when possible.
A library mod that adds highly customizable fluidlogging to 1.12.2!