diff --git a/README.md b/README.md index 1228ff3e..b9a0ce0e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Pylon is an upcoming Minecraft Java plugin that will hugely expand vanilla gamep Pylon uses an addon system, meaning anyone can add content to Pylon by writing an addon for it! It also comes with a number of really useful features, such as: - First-class translation support, meaning each player can select their own language. -- Extensive configuration options, including per-machine configuration. +- Extensive configuration options, including per-machine configuration - An intuitive and user-friendly guide to help players figure out the plugin. ## Find out more diff --git a/src/main/java/io/github/pylonmc/pylon/base/BaseBlocks.java b/src/main/java/io/github/pylonmc/pylon/base/BaseBlocks.java index 6fd7661e..fb33a835 100644 --- a/src/main/java/io/github/pylonmc/pylon/base/BaseBlocks.java +++ b/src/main/java/io/github/pylonmc/pylon/base/BaseBlocks.java @@ -4,11 +4,13 @@ import io.github.pylonmc.pylon.base.content.building.ExplosiveTarget; import io.github.pylonmc.pylon.base.content.building.Immobilizer; import io.github.pylonmc.pylon.base.content.building.Pedestal; -import io.github.pylonmc.pylon.base.content.components.EnrichedSoulSoil; +import io.github.pylonmc.pylon.base.content.components.*; import io.github.pylonmc.pylon.base.content.machines.cargo.CargoExtractor; import io.github.pylonmc.pylon.base.content.machines.cargo.CargoInserter; -import io.github.pylonmc.pylon.base.content.machines.diesel.*; import io.github.pylonmc.pylon.base.content.machines.cargo.CargoBuffer; +import io.github.pylonmc.pylon.base.content.machines.diesel.machines.*; +import io.github.pylonmc.pylon.base.content.machines.diesel.production.Biorefinery; +import io.github.pylonmc.pylon.base.content.machines.diesel.production.Fermenter; import io.github.pylonmc.pylon.base.content.machines.fluid.*; import io.github.pylonmc.pylon.base.content.machines.hydraulics.*; import io.github.pylonmc.pylon.base.content.machines.hydraulics.CoalFiredPurificationTower; @@ -58,6 +60,10 @@ public static void initialize() { PylonBlock.register(BaseKeys.FLUID_TANK_CASING_BRONZE, Material.ORANGE_STAINED_GLASS, FluidTankCasing.class); PylonBlock.register(BaseKeys.FLUID_TANK_CASING_IGNEOUS_COMPOSITE, Material.BLACK_STAINED_GLASS, FluidTankCasing.class); PylonBlock.register(BaseKeys.FLUID_TANK_CASING_STEEL, Material.GRAY_STAINED_GLASS, FluidTankCasing.class); + PylonBlock.register(BaseKeys.FLUID_INPUT_HATCH, Material.LIGHT_BLUE_TERRACOTTA, FluidInputHatch.class); + PylonBlock.register(BaseKeys.FLUID_OUTPUT_HATCH, Material.ORANGE_TERRACOTTA, FluidOutputHatch.class); + PylonBlock.register(BaseKeys.ITEM_INPUT_HATCH, Material.GREEN_TERRACOTTA, ItemInputHatch.class); + PylonBlock.register(BaseKeys.ITEM_OUTPUT_HATCH, Material.RED_TERRACOTTA, ItemOutputHatch.class); PylonBlock.register(BaseKeys.FLUID_VALVE, Material.STRUCTURE_VOID, FluidValve.class); PylonBlock.register(BaseKeys.WATER_PUMP, Material.BLUE_TERRACOTTA, WaterPump.class); PylonBlock.register(BaseKeys.FLUID_FILTER, Material.STRUCTURE_VOID, FluidFilter.class); @@ -112,8 +118,6 @@ public static void initialize() { PylonBlock.register(BaseKeys.MANUAL_CORE_DRILL, Material.CHISELED_STONE_BRICKS, ManualCoreDrill.class); PylonBlock.register(BaseKeys.IMPROVED_MANUAL_CORE_DRILL, Material.WAXED_OXIDIZED_COPPER, ImprovedManualCoreDrill.class); PylonBlock.register(BaseKeys.HYDRAULIC_CORE_DRILL, Material.WAXED_COPPER_BULB, HydraulicCoreDrill.class); - PylonBlock.register(BaseKeys.HYDRAULIC_CORE_DRILL_INPUT_HATCH, Material.LIGHT_BLUE_TERRACOTTA, HydraulicCoreDrillInputHatch.class); - PylonBlock.register(BaseKeys.HYDRAULIC_CORE_DRILL_OUTPUT_HATCH, Material.ORANGE_TERRACOTTA, HydraulicCoreDrillOutputHatch.class); PylonBlock.register(BaseKeys.VACUUM_HOPPER_1, Material.HOPPER, VacuumHopper.class); PylonBlock.register(BaseKeys.VACUUM_HOPPER_2, Material.HOPPER, VacuumHopper.class); PylonBlock.register(BaseKeys.VACUUM_HOPPER_3, Material.HOPPER, VacuumHopper.class); @@ -132,6 +136,15 @@ public static void initialize() { PylonBlock.register(BaseKeys.DIESEL_FURNACE, Material.FURNACE, DieselFurnace.class); PylonBlock.register(BaseKeys.DIESEL_BREAKER, Material.DROPPER, DieselBreaker.class); PylonBlock.register(BaseKeys.DIESEL_MINER, Material.IRON_BLOCK, DieselMiner.class); + PylonBlock.register(BaseKeys.FERMENTER, Material.PINK_TERRACOTTA, Fermenter.class); + PylonBlock.register(BaseKeys.FERMENTER_CORE, Material.GRAY_STAINED_GLASS, PylonBlock.class); + PylonBlock.register(BaseKeys.FERMENTER_CASING, Material.GRAY_STAINED_GLASS_PANE, PylonBlock.class); + PylonBlock.register(BaseKeys.BIOREFINERY, Material.PURPLE_TERRACOTTA, Biorefinery.class); + PylonBlock.register(BaseKeys.BIOREFINERY_FOUNDATION, Material.LIGHT_GRAY_CONCRETE, PylonBlock.class); + PylonBlock.register(BaseKeys.BIOREFINERY_PLATING, Material.GRAY_STAINED_GLASS_PANE, PylonBlock.class); + PylonBlock.register(BaseKeys.BIOREFINERY_TOWER_RING, Material.IRON_BLOCK, PylonBlock.class); + PylonBlock.register(BaseKeys.BIOREFINERY_SMOKESTACK_RING, Material.POLISHED_DEEPSLATE_WALL, PylonBlock.class); + PylonBlock.register(BaseKeys.BIOREFINERY_SMOKESTACK_CAP, Material.FLOWER_POT, PylonBlock.class); PylonBlock.register(BaseKeys.CARGO_DUCT, Material.STRUCTURE_VOID, CargoDuct.class); PylonBlock.register(BaseKeys.CARGO_BUFFER, Material.STRUCTURE_VOID, CargoBuffer.class); PylonBlock.register(BaseKeys.CARGO_EXTRACTOR, Material.STRUCTURE_VOID, CargoExtractor.class); diff --git a/src/main/java/io/github/pylonmc/pylon/base/BaseFluids.java b/src/main/java/io/github/pylonmc/pylon/base/BaseFluids.java index 39c24276..c8ffc188 100644 --- a/src/main/java/io/github/pylonmc/pylon/base/BaseFluids.java +++ b/src/main/java/io/github/pylonmc/pylon/base/BaseFluids.java @@ -3,6 +3,7 @@ import io.github.pylonmc.pylon.base.content.machines.smelting.Slurry; import io.github.pylonmc.pylon.base.recipes.CastingRecipe; import io.github.pylonmc.pylon.base.recipes.MeltingRecipe; +import io.github.pylonmc.pylon.core.content.guide.PylonGuide; import io.github.pylonmc.pylon.core.fluid.PylonFluid; import io.github.pylonmc.pylon.core.fluid.tags.FluidTemperature; import io.github.pylonmc.pylon.core.recipe.RecipeInput; @@ -150,6 +151,16 @@ private BaseFluids() { Material.WHITE_CONCRETE_POWDER ).addTag(FluidTemperature.NORMAL); + public static final PylonFluid SUGARCANE = new PylonFluid( + baseKey("sugarcane"), + Material.LIME_CONCRETE + ).addTag(FluidTemperature.NORMAL); + + public static final PylonFluid ETHANOL = new PylonFluid( + baseKey("ethanol"), + Material.LIGHT_GRAY_CONCRETE_POWDER + ).addTag(FluidTemperature.NORMAL); + public static final PylonFluid BIODIESEL = new PylonFluid( baseKey("biodiesel"), Material.YELLOW_CONCRETE @@ -273,6 +284,12 @@ public static void initialize() { REFLECTOR_FLUID.register(); + SUGARCANE.register(); + + PylonGuide.hideFluid(SUGARCANE.getKey()); + + ETHANOL.register(); + BIODIESEL.register(); } diff --git a/src/main/java/io/github/pylonmc/pylon/base/BaseItems.java b/src/main/java/io/github/pylonmc/pylon/base/BaseItems.java index f54a3c6b..f1695da4 100644 --- a/src/main/java/io/github/pylonmc/pylon/base/BaseItems.java +++ b/src/main/java/io/github/pylonmc/pylon/base/BaseItems.java @@ -11,7 +11,9 @@ import io.github.pylonmc.pylon.base.content.machines.cargo.CargoBuffer; import io.github.pylonmc.pylon.base.content.machines.cargo.CargoExtractor; import io.github.pylonmc.pylon.base.content.machines.cargo.CargoInserter; -import io.github.pylonmc.pylon.base.content.machines.diesel.*; +import io.github.pylonmc.pylon.base.content.machines.diesel.machines.*; +import io.github.pylonmc.pylon.base.content.machines.diesel.production.Biorefinery; +import io.github.pylonmc.pylon.base.content.machines.diesel.production.Fermenter; import io.github.pylonmc.pylon.base.content.machines.fluid.*; import io.github.pylonmc.pylon.base.content.machines.hydraulics.*; import io.github.pylonmc.pylon.base.content.machines.hydraulics.CoalFiredPurificationTower; @@ -1093,6 +1095,34 @@ private BaseItems() { BasePages.FLUID_PIPES_AND_TANKS.addItem(FLUID_TANK_CASING_STEEL); } + public static final ItemStack FLUID_INPUT_HATCH = ItemStackBuilder.pylon(Material.LIGHT_BLUE_TERRACOTTA, BaseKeys.FLUID_INPUT_HATCH) + .build(); + static { + PylonItem.register(PylonItem.class, FLUID_INPUT_HATCH, BaseKeys.FLUID_INPUT_HATCH); + BasePages.COMPONENTS.addItem(FLUID_INPUT_HATCH); + } + + public static final ItemStack FLUID_OUTPUT_HATCH = ItemStackBuilder.pylon(Material.ORANGE_TERRACOTTA, BaseKeys.FLUID_OUTPUT_HATCH) + .build(); + static { + PylonItem.register(PylonItem.class, FLUID_OUTPUT_HATCH, BaseKeys.FLUID_OUTPUT_HATCH); + BasePages.COMPONENTS.addItem(FLUID_OUTPUT_HATCH); + } + + public static final ItemStack ITEM_INPUT_HATCH = ItemStackBuilder.pylon(Material.GREEN_TERRACOTTA, BaseKeys.ITEM_INPUT_HATCH) + .build(); + static { + PylonItem.register(PylonItem.class, ITEM_INPUT_HATCH, BaseKeys.ITEM_INPUT_HATCH); + BasePages.COMPONENTS.addItem(ITEM_INPUT_HATCH); + } + + public static final ItemStack ITEM_OUTPUT_HATCH = ItemStackBuilder.pylon(Material.RED_TERRACOTTA, BaseKeys.ITEM_OUTPUT_HATCH) + .build(); + static { + PylonItem.register(PylonItem.class, ITEM_OUTPUT_HATCH, BaseKeys.ITEM_OUTPUT_HATCH); + BasePages.COMPONENTS.addItem(ITEM_OUTPUT_HATCH); + } + public static final ItemStack ROTOR = ItemStackBuilder.pylon(Material.IRON_TRAPDOOR, BaseKeys.ROTOR) .build(); static { @@ -1663,20 +1693,6 @@ private BaseItems() { BasePages.HYDRAULICS.addItem(HYDRAULIC_CORE_DRILL); } - public static final ItemStack HYDRAULIC_CORE_DRILL_INPUT_HATCH = ItemStackBuilder.pylon(Material.LIGHT_BLUE_TERRACOTTA, BaseKeys.HYDRAULIC_CORE_DRILL_INPUT_HATCH) - .build(); - static { - PylonItem.register(PylonItem.class, HYDRAULIC_CORE_DRILL_INPUT_HATCH, BaseKeys.HYDRAULIC_CORE_DRILL_INPUT_HATCH); - BasePages.HYDRAULICS.addItem(HYDRAULIC_CORE_DRILL_INPUT_HATCH); - } - - public static final ItemStack HYDRAULIC_CORE_DRILL_OUTPUT_HATCH = ItemStackBuilder.pylon(Material.ORANGE_TERRACOTTA, BaseKeys.HYDRAULIC_CORE_DRILL_OUTPUT_HATCH) - .build(); - static { - PylonItem.register(PylonItem.class, HYDRAULIC_CORE_DRILL_OUTPUT_HATCH, BaseKeys.HYDRAULIC_CORE_DRILL_OUTPUT_HATCH); - BasePages.HYDRAULICS.addItem(HYDRAULIC_CORE_DRILL_OUTPUT_HATCH); - } - public static final ItemStack REACTIVATED_WITHER_SKULL = ItemStackBuilder.pylon(Material.WITHER_SKELETON_SKULL, BaseKeys.REACTIVATED_WITHER_SKULL) .durability(Settings.get(BaseKeys.REACTIVATED_WITHER_SKULL).getOrThrow("durability", ConfigAdapter.INT)) .useCooldown(Settings.get(BaseKeys.REACTIVATED_WITHER_SKULL).getOrThrow("cooldown-ticks", ConfigAdapter.INT), BaseKeys.REACTIVATED_WITHER_SKULL) @@ -1903,6 +1919,69 @@ private BaseItems() { BasePages.DIESEL_MACHINES.addItem(DIESEL_MINER); } + public static final ItemStack FERMENTER = ItemStackBuilder.pylon(Material.PINK_TERRACOTTA, BaseKeys.FERMENTER) + .build(); + static { + PylonItem.register(Fermenter.Item.class, FERMENTER, BaseKeys.FERMENTER); + BasePages.DIESEL_PRODUCTION.addItem(FERMENTER); + } + + public static final ItemStack FERMENTER_CORE = ItemStackBuilder.pylon(Material.GRAY_STAINED_GLASS, BaseKeys.FERMENTER_CORE) + .build(); + static { + PylonItem.register(PylonItem.class, FERMENTER_CORE, BaseKeys.FERMENTER_CORE); + BasePages.DIESEL_PRODUCTION.addItem(FERMENTER_CORE); + } + + public static final ItemStack FERMENTER_CASING = ItemStackBuilder.pylon(Material.GRAY_STAINED_GLASS_PANE, BaseKeys.FERMENTER_CASING) + .build(); + static { + PylonItem.register(PylonItem.class, FERMENTER_CASING, BaseKeys.FERMENTER_CASING); + BasePages.DIESEL_PRODUCTION.addItem(FERMENTER_CASING); + } + + public static final ItemStack BIOREFINERY = ItemStackBuilder.pylon(Material.PURPLE_TERRACOTTA, BaseKeys.BIOREFINERY) + .build(); + static { + PylonItem.register(Biorefinery.Item.class, BIOREFINERY, BaseKeys.BIOREFINERY); + BasePages.DIESEL_PRODUCTION.addItem(BIOREFINERY); + } + + public static final ItemStack BIOREFINERY_FOUNDATION = ItemStackBuilder.pylon(Material.LIGHT_GRAY_CONCRETE, BaseKeys.BIOREFINERY_FOUNDATION) + .build(); + static { + PylonItem.register(PylonItem.class, BIOREFINERY_FOUNDATION, BaseKeys.BIOREFINERY_FOUNDATION); + BasePages.DIESEL_PRODUCTION.addItem(BIOREFINERY_FOUNDATION); + } + + public static final ItemStack BIOREFINERY_PLATING = ItemStackBuilder.pylon(Material.GRAY_STAINED_GLASS_PANE, BaseKeys.BIOREFINERY_PLATING) + .build(); + static { + PylonItem.register(PylonItem.class, BIOREFINERY_PLATING, BaseKeys.BIOREFINERY_PLATING); + BasePages.DIESEL_PRODUCTION.addItem(BIOREFINERY_PLATING); + } + + public static final ItemStack BIOREFINERY_TOWER_RING = ItemStackBuilder.pylon(Material.IRON_BLOCK, BaseKeys.BIOREFINERY_TOWER_RING) + .build(); + static { + PylonItem.register(PylonItem.class, BIOREFINERY_TOWER_RING, BaseKeys.BIOREFINERY_TOWER_RING); + BasePages.DIESEL_PRODUCTION.addItem(BIOREFINERY_TOWER_RING); + } + + public static final ItemStack BIOREFINERY_SMOKESTACK_RING = ItemStackBuilder.pylon(Material.POLISHED_DEEPSLATE_WALL, BaseKeys.BIOREFINERY_SMOKESTACK_RING) + .build(); + static { + PylonItem.register(PylonItem.class, BIOREFINERY_SMOKESTACK_RING, BaseKeys.BIOREFINERY_SMOKESTACK_RING); + BasePages.DIESEL_PRODUCTION.addItem(BIOREFINERY_SMOKESTACK_RING); + } + + public static final ItemStack BIOREFINERY_SMOKESTACK_CAP = ItemStackBuilder.pylon(Material.FLOWER_POT, BaseKeys.BIOREFINERY_SMOKESTACK_CAP) + .build(); + static { + PylonItem.register(PylonItem.class, BIOREFINERY_SMOKESTACK_CAP, BaseKeys.BIOREFINERY_SMOKESTACK_CAP); + BasePages.DIESEL_PRODUCTION.addItem(BIOREFINERY_SMOKESTACK_CAP); + } + public static final ItemStack CARGO_DUCT = ItemStackBuilder.pylon(Material.STRUCTURE_VOID, BaseKeys.CARGO_DUCT) .set(DataComponentTypes.ITEM_MODEL, Material.GRAY_CONCRETE.getKey()) .build(); diff --git a/src/main/java/io/github/pylonmc/pylon/base/BaseKeys.java b/src/main/java/io/github/pylonmc/pylon/base/BaseKeys.java index 15904253..021f8a68 100644 --- a/src/main/java/io/github/pylonmc/pylon/base/BaseKeys.java +++ b/src/main/java/io/github/pylonmc/pylon/base/BaseKeys.java @@ -185,6 +185,11 @@ public class BaseKeys { public static final NamespacedKey FLUID_TANK_CASING_IGNEOUS_COMPOSITE = baseKey("fluid_tank_casing_igneous_composite"); public static final NamespacedKey FLUID_TANK_CASING_STEEL = baseKey("fluid_tank_casing_steel"); + public static final NamespacedKey FLUID_INPUT_HATCH = baseKey("fluid_input_hatch"); + public static final NamespacedKey FLUID_OUTPUT_HATCH = baseKey("fluid_output_hatch"); + public static final NamespacedKey ITEM_INPUT_HATCH = baseKey("item_input_hatch"); + public static final NamespacedKey ITEM_OUTPUT_HATCH = baseKey("item_output_hatch"); + public static final NamespacedKey WATER_PUMP = baseKey("water_pump"); public static final NamespacedKey FLUID_VALVE = baseKey("fluid_valve"); @@ -259,8 +264,6 @@ public class BaseKeys { public static final NamespacedKey IMPROVED_MANUAL_CORE_DRILL = baseKey("improved_manual_core_drill"); public static final NamespacedKey HYDRAULIC_CORE_DRILL = baseKey("hydraulic_core_drill"); - public static final NamespacedKey HYDRAULIC_CORE_DRILL_INPUT_HATCH = baseKey("hydraulic_core_drill_input_hatch"); - public static final NamespacedKey HYDRAULIC_CORE_DRILL_OUTPUT_HATCH = baseKey("hydraulic_core_drill_output_hatch"); public static final NamespacedKey SHALLOW_CORE_CHUNK = baseKey("shallow_core_chunk"); public static final NamespacedKey SUBSURFACE_CORE_CHUNK = baseKey("subsurface_core_chunk"); @@ -303,6 +306,17 @@ public class BaseKeys { public static final NamespacedKey DIESEL_BREAKER = baseKey("diesel_breaker"); public static final NamespacedKey DIESEL_MINER = baseKey("diesel_miner"); + public static final NamespacedKey FERMENTER = baseKey("fermenter"); + public static final NamespacedKey FERMENTER_CORE = baseKey("fermenter_core"); + public static final NamespacedKey FERMENTER_CASING = baseKey("fermenter_casing"); + + public static final NamespacedKey BIOREFINERY = baseKey("biorefinery"); + public static final NamespacedKey BIOREFINERY_FOUNDATION = baseKey("biorefinery_foundation"); + public static final NamespacedKey BIOREFINERY_PLATING = baseKey("biorefinery_plating"); + public static final NamespacedKey BIOREFINERY_TOWER_RING = baseKey("biorefinery_tower_ring"); + public static final NamespacedKey BIOREFINERY_SMOKESTACK_RING = baseKey("biorefinery_smokestack_ring"); + public static final NamespacedKey BIOREFINERY_SMOKESTACK_CAP = baseKey("biorefinery_smokestack_cap"); + public static final NamespacedKey CARGO_BUFFER = baseKey("cargo_buffer"); public static final NamespacedKey CARGO_DUCT = baseKey("cargo_duct"); public static final NamespacedKey CARGO_EXTRACTOR = baseKey("cargo_extractor"); diff --git a/src/main/java/io/github/pylonmc/pylon/base/BasePages.java b/src/main/java/io/github/pylonmc/pylon/base/BasePages.java index 3948a701..bd2832ce 100644 --- a/src/main/java/io/github/pylonmc/pylon/base/BasePages.java +++ b/src/main/java/io/github/pylonmc/pylon/base/BasePages.java @@ -25,6 +25,7 @@ public class BasePages { public static final SimpleStaticGuidePage HYDRAULICS = new SimpleStaticGuidePage(baseKey("hydraulics"), Material.BLUE_CONCRETE_POWDER); public static final SimpleStaticGuidePage CARGO = new SimpleStaticGuidePage(baseKey("cargo"), Material.HOPPER); public static final SimpleStaticGuidePage DIESEL_MACHINES = new SimpleStaticGuidePage(baseKey("diesel_machines"), Material.YELLOW_CONCRETE); + public static final SimpleStaticGuidePage DIESEL_PRODUCTION = new SimpleStaticGuidePage(baseKey("diesel_production"), Material.YELLOW_CONCRETE_POWDER); private static final SimpleStaticGuidePage MACHINES = new SimpleStaticGuidePage(baseKey("machines"), Material.BLAST_FURNACE); public static final SimpleStaticGuidePage BUILDING = new SimpleStaticGuidePage(baseKey("building"), Material.STONE_BRICK_WALL); @@ -52,6 +53,7 @@ public boolean shouldDisplay(@NotNull Player player) { MACHINES.addPage(HYDRAULICS); MACHINES.addPage(CARGO); MACHINES.addPage(DIESEL_MACHINES); + MACHINES.addPage(DIESEL_PRODUCTION); PylonGuide.getRootPage().addPage(MACHINES); PylonGuide.getRootPage().addPage(BUILDING); diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/components/FluidHatch.java b/src/main/java/io/github/pylonmc/pylon/base/content/components/FluidHatch.java new file mode 100644 index 00000000..019ef606 --- /dev/null +++ b/src/main/java/io/github/pylonmc/pylon/base/content/components/FluidHatch.java @@ -0,0 +1,191 @@ +package io.github.pylonmc.pylon.base.content.components; + +import com.google.common.base.Preconditions; +import io.github.pylonmc.pylon.base.PylonBase; +import io.github.pylonmc.pylon.base.content.machines.fluid.FluidTankCasing; +import io.github.pylonmc.pylon.base.util.BaseUtils; +import io.github.pylonmc.pylon.core.block.BlockStorage; +import io.github.pylonmc.pylon.core.block.PylonBlock; +import io.github.pylonmc.pylon.core.block.base.PylonDirectionalBlock; +import io.github.pylonmc.pylon.core.block.base.PylonFluidBufferBlock; +import io.github.pylonmc.pylon.core.block.base.PylonSimpleMultiblock; +import io.github.pylonmc.pylon.core.block.context.BlockBreakContext; +import io.github.pylonmc.pylon.core.block.context.BlockCreateContext; +import io.github.pylonmc.pylon.core.datatypes.PylonSerializers; +import io.github.pylonmc.pylon.core.entity.display.ItemDisplayBuilder; +import io.github.pylonmc.pylon.core.entity.display.transform.TransformBuilder; +import io.github.pylonmc.pylon.core.fluid.PylonFluid; +import io.github.pylonmc.pylon.core.i18n.PylonArgument; +import io.github.pylonmc.pylon.core.item.PylonItem; +import io.github.pylonmc.pylon.core.item.PylonItemSchema; +import io.github.pylonmc.pylon.core.registry.PylonRegistry; +import io.github.pylonmc.pylon.core.util.PylonUtils; +import io.github.pylonmc.pylon.core.waila.Waila; +import io.github.pylonmc.pylon.core.waila.WailaDisplay; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.TextColor; +import org.bukkit.Bukkit; +import org.bukkit.NamespacedKey; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.ItemDisplay; +import org.bukkit.entity.Player; +import org.bukkit.persistence.PersistentDataContainer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.joml.Vector3i; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static io.github.pylonmc.pylon.base.util.BaseUtils.baseKey; + +public abstract class FluidHatch extends PylonBlock implements + PylonFluidBufferBlock, + PylonSimpleMultiblock, + PylonDirectionalBlock { + + private static final NamespacedKey FLUID_KEY = baseKey("fluid"); + + private static MixedMultiblockComponent component = null; + + public @Nullable PylonFluid fluid; + + static { + // run on first tick after all addons registered + Bukkit.getScheduler().runTaskLater(PylonBase.getInstance(), () -> { + List components = new ArrayList<>(); + for (PylonItemSchema schema : PylonRegistry.ITEMS) { + if (PylonItem.fromStack(schema.getItemStack()) instanceof FluidTankCasing.Item) { + components.add(new PylonMultiblockComponent(schema.getKey())); + } + } + component = new MixedMultiblockComponent(components); + }, 0); + } + + public FluidHatch(@NotNull Block block, @NotNull BlockCreateContext context) { + super(block, context); + fluid = null; + setFacing(context.getFacing()); + addEntity("fluid", new ItemDisplayBuilder() + .transformation(new TransformBuilder().scale(0)) + .build(getBlock().getLocation().toCenterLocation().add(0, 1, 0)) + ); + } + + public FluidHatch(@NotNull Block block, @NotNull PersistentDataContainer pdc) { + super(block, pdc); + fluid = pdc.get(FLUID_KEY, PylonSerializers.PYLON_FLUID); + } + + @Override + public void write(@NotNull PersistentDataContainer pdc) { + PylonUtils.setNullable(pdc, FLUID_KEY, PylonSerializers.PYLON_FLUID, fluid); + } + + @Override + public @NotNull Map getComponents() { + Map components = new HashMap<>(); + components.put(new Vector3i(0, 1, 0), component); + return components; + } + + @Override + public boolean checkFormed() { + boolean formed = PylonSimpleMultiblock.super.checkFormed(); + if (formed) { + FluidTankCasing casing = BlockStorage.getAs(FluidTankCasing.class, getBlock().getRelative(BlockFace.UP)); + Preconditions.checkState(casing != null); + Waila.addWailaOverride(casing.getBlock(), this::getWaila); + if (fluid != null) { + setFluidCapacity(fluid, casing.capacity); + } + } + return formed; + } + + @Override + public void onMultiblockUnformed(boolean partUnloaded) { + PylonSimpleMultiblock.super.onMultiblockUnformed(partUnloaded); + Waila.removeWailaOverride(getBlock().getRelative(BlockFace.UP)); + if (fluid != null) { + setFluidCapacity(fluid, 0); + getFluidDisplay().setTransformationMatrix(new TransformBuilder() + .scale(0, 0, 0) + .buildForItemDisplay() + ); + } + } + + @Override + public boolean setFluid(@NotNull PylonFluid fluid, double amount) { + boolean result = PylonFluidBufferBlock.super.setFluid(fluid, amount); + float scale = (float) (0.9 * fluidAmount(fluid) / fluidCapacity(fluid)); + if (scale < 1.0e-9) { + scale = 0.0F; + } + getFluidDisplay().setItemStack(fluid.getItem()); + getFluidDisplay().setTransformationMatrix(new TransformBuilder() + .translate(0.0, -0.45 + scale / 2, 0.0) + .scale(0.9, scale, 0.9) + .buildForItemDisplay() + ); + return result; + } + + @Override + public @Nullable WailaDisplay getWaila(@NotNull Player player) { + Component info; + if (!isFormedAndFullyLoaded()) { + info = Component.translatable("pylon.pylonbase.message.fluid_hatch.no_casing"); + } else if (fluid == null) { + info = Component.translatable("pylon.pylonbase.message.fluid_hatch.no_multiblock"); + } else { + info = Component.translatable("pylon.pylonbase.message.fluid_hatch.working") + .arguments( + PylonArgument.of("bars", BaseUtils.createFluidAmountBar( + fluidAmount(fluid), + fluidCapacity(fluid), + 20, + TextColor.color(200, 255, 255) + )), + PylonArgument.of("fluid", fluid.getName()) + ); + } + return new WailaDisplay(getDefaultWailaTranslationKey().arguments( + PylonArgument.of("info", info) + )); + } + + public void setFluidType(PylonFluid fluid) { + if (this.fluid != null) { + deleteFluidBuffer(this.fluid); + getFluidDisplay().setTransformationMatrix(new TransformBuilder() + .scale(0, 0, 0) + .buildForItemDisplay() + ); + } + this.fluid = fluid; + if (fluid != null) { + createFluidBuffer(fluid, 0, true, true); + } + if (isFormedAndFullyLoaded() && fluid != null) { + FluidTankCasing casing = BlockStorage.getAs(FluidTankCasing.class, getBlock().getRelative(BlockFace.UP)); + Preconditions.checkState(casing != null); + setFluidCapacity(fluid, casing.capacity); + } + } + + public @NotNull ItemDisplay getFluidDisplay() { + return getHeldEntityOrThrow(ItemDisplay.class, "fluid"); + } + + @Override + public void postBreak(@NotNull BlockBreakContext context) { + PylonFluidBufferBlock.super.postBreak(context); + Waila.removeWailaOverride(getBlock().getRelative(BlockFace.UP)); + } +} diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/components/FluidInputHatch.java b/src/main/java/io/github/pylonmc/pylon/base/content/components/FluidInputHatch.java new file mode 100644 index 00000000..3178503f --- /dev/null +++ b/src/main/java/io/github/pylonmc/pylon/base/content/components/FluidInputHatch.java @@ -0,0 +1,19 @@ +package io.github.pylonmc.pylon.base.content.components; + +import io.github.pylonmc.pylon.core.block.context.BlockCreateContext; +import io.github.pylonmc.pylon.core.fluid.FluidPointType; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.persistence.PersistentDataContainer; +import org.jetbrains.annotations.NotNull; + +public class FluidInputHatch extends FluidHatch { + public FluidInputHatch(@NotNull Block block, @NotNull BlockCreateContext context) { + super(block, context); + createFluidPoint(FluidPointType.INPUT, BlockFace.NORTH, context, true); + } + + public FluidInputHatch(@NotNull Block block, @NotNull PersistentDataContainer pdc) { + super(block, pdc); + } +} diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/components/FluidOutputHatch.java b/src/main/java/io/github/pylonmc/pylon/base/content/components/FluidOutputHatch.java new file mode 100644 index 00000000..7a5f67fb --- /dev/null +++ b/src/main/java/io/github/pylonmc/pylon/base/content/components/FluidOutputHatch.java @@ -0,0 +1,19 @@ +package io.github.pylonmc.pylon.base.content.components; + +import io.github.pylonmc.pylon.core.block.context.BlockCreateContext; +import io.github.pylonmc.pylon.core.fluid.FluidPointType; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.persistence.PersistentDataContainer; +import org.jetbrains.annotations.NotNull; + +public class FluidOutputHatch extends FluidHatch { + public FluidOutputHatch(@NotNull Block block, @NotNull BlockCreateContext context) { + super(block, context); + createFluidPoint(FluidPointType.OUTPUT, BlockFace.NORTH, context, true); + } + + public FluidOutputHatch(@NotNull Block block, @NotNull PersistentDataContainer pdc) { + super(block, pdc); + } +} diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/components/ItemInputHatch.java b/src/main/java/io/github/pylonmc/pylon/base/content/components/ItemInputHatch.java new file mode 100644 index 00000000..aa9c31c2 --- /dev/null +++ b/src/main/java/io/github/pylonmc/pylon/base/content/components/ItemInputHatch.java @@ -0,0 +1,40 @@ +package io.github.pylonmc.pylon.base.content.components; + +import io.github.pylonmc.pylon.core.block.PylonBlock; +import io.github.pylonmc.pylon.core.block.base.PylonGuiBlock; +import io.github.pylonmc.pylon.core.block.base.PylonLogisticBlock; +import io.github.pylonmc.pylon.core.block.context.BlockCreateContext; +import io.github.pylonmc.pylon.core.logistics.LogisticSlotType; +import io.github.pylonmc.pylon.core.util.gui.GuiItems; +import org.bukkit.block.Block; +import org.bukkit.persistence.PersistentDataContainer; +import org.jetbrains.annotations.NotNull; +import xyz.xenondevs.invui.gui.Gui; +import xyz.xenondevs.invui.inventory.VirtualInventory; + +public class ItemInputHatch extends PylonBlock implements PylonGuiBlock, PylonLogisticBlock { + + public final VirtualInventory inventory = new VirtualInventory(1); + + public ItemInputHatch(@NotNull Block block, @NotNull BlockCreateContext context) { + super(block, context); + } + + public ItemInputHatch(@NotNull Block block, @NotNull PersistentDataContainer pdc) { + super(block, pdc); + } + + @Override + public void postInitialise() { + createLogisticGroup("input", LogisticSlotType.INPUT, inventory); + } + + @Override + public @NotNull Gui createGui() { + return Gui.normal() + .setStructure("# # # # x # # # #") + .addIngredient('#', GuiItems.background()) + .addIngredient('x', inventory) + .build(); + } +} diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/components/ItemOutputHatch.java b/src/main/java/io/github/pylonmc/pylon/base/content/components/ItemOutputHatch.java new file mode 100644 index 00000000..e63688af --- /dev/null +++ b/src/main/java/io/github/pylonmc/pylon/base/content/components/ItemOutputHatch.java @@ -0,0 +1,40 @@ +package io.github.pylonmc.pylon.base.content.components; + +import io.github.pylonmc.pylon.core.block.PylonBlock; +import io.github.pylonmc.pylon.core.block.base.PylonGuiBlock; +import io.github.pylonmc.pylon.core.block.base.PylonLogisticBlock; +import io.github.pylonmc.pylon.core.block.context.BlockCreateContext; +import io.github.pylonmc.pylon.core.logistics.LogisticSlotType; +import io.github.pylonmc.pylon.core.util.gui.GuiItems; +import org.bukkit.block.Block; +import org.bukkit.persistence.PersistentDataContainer; +import org.jetbrains.annotations.NotNull; +import xyz.xenondevs.invui.gui.Gui; +import xyz.xenondevs.invui.inventory.VirtualInventory; + +public class ItemOutputHatch extends PylonBlock implements PylonGuiBlock, PylonLogisticBlock { + + public final VirtualInventory inventory = new VirtualInventory(1); + + public ItemOutputHatch(@NotNull Block block, @NotNull BlockCreateContext context) { + super(block, context); + } + + public ItemOutputHatch(@NotNull Block block, @NotNull PersistentDataContainer pdc) { + super(block, pdc); + } + + @Override + public void postInitialise() { + createLogisticGroup("output", LogisticSlotType.OUTPUT, inventory); + } + + @Override + public @NotNull Gui createGui() { + return Gui.normal() + .setStructure("# # # # x # # # #") + .addIngredient('#', GuiItems.background()) + .addIngredient('x', inventory) + .build(); + } +} diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselBreaker.java b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselBreaker.java similarity index 99% rename from src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselBreaker.java rename to src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselBreaker.java index 97859779..a7ed3cc9 100644 --- a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselBreaker.java +++ b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselBreaker.java @@ -1,4 +1,4 @@ -package io.github.pylonmc.pylon.base.content.machines.diesel; +package io.github.pylonmc.pylon.base.content.machines.diesel.machines; import com.destroystokyo.paper.ParticleBuilder; import io.github.pylonmc.pylon.base.BaseFluids; diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselBrickMolder.java b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselBrickMolder.java similarity index 99% rename from src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselBrickMolder.java rename to src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselBrickMolder.java index 97e88966..2fdc8df1 100644 --- a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselBrickMolder.java +++ b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselBrickMolder.java @@ -1,4 +1,4 @@ -package io.github.pylonmc.pylon.base.content.machines.diesel; +package io.github.pylonmc.pylon.base.content.machines.diesel.machines; import com.destroystokyo.paper.ParticleBuilder; import io.github.pylonmc.pylon.base.BaseFluids; diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselFurnace.java b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselFurnace.java similarity index 99% rename from src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselFurnace.java rename to src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselFurnace.java index 3b1afd31..2b4af912 100644 --- a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselFurnace.java +++ b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselFurnace.java @@ -1,4 +1,4 @@ -package io.github.pylonmc.pylon.base.content.machines.diesel; +package io.github.pylonmc.pylon.base.content.machines.diesel.machines; import com.destroystokyo.paper.ParticleBuilder; import io.github.pylonmc.pylon.base.BaseFluids; diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselGrindstone.java b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselGrindstone.java similarity index 99% rename from src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselGrindstone.java rename to src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselGrindstone.java index 0518fdcb..03ceed1b 100644 --- a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselGrindstone.java +++ b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselGrindstone.java @@ -1,4 +1,4 @@ -package io.github.pylonmc.pylon.base.content.machines.diesel; +package io.github.pylonmc.pylon.base.content.machines.diesel.machines; import com.destroystokyo.paper.ParticleBuilder; import io.github.pylonmc.pylon.base.BaseFluids; diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselHammerHead.java b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselHammerHead.java similarity index 99% rename from src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselHammerHead.java rename to src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselHammerHead.java index 54f32a1e..52716206 100644 --- a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselHammerHead.java +++ b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselHammerHead.java @@ -1,4 +1,4 @@ -package io.github.pylonmc.pylon.base.content.machines.diesel; +package io.github.pylonmc.pylon.base.content.machines.diesel.machines; import com.destroystokyo.paper.ParticleBuilder; import io.github.pylonmc.pylon.base.BaseFluids; diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselMiner.java b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselMiner.java similarity index 99% rename from src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselMiner.java rename to src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselMiner.java index 02abdcce..431c29bb 100644 --- a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselMiner.java +++ b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselMiner.java @@ -1,4 +1,4 @@ -package io.github.pylonmc.pylon.base.content.machines.diesel; +package io.github.pylonmc.pylon.base.content.machines.diesel.machines; import com.destroystokyo.paper.ParticleBuilder; import io.github.pylonmc.pylon.base.BaseFluids; diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselMixingAttachment.java b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselMixingAttachment.java similarity index 99% rename from src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselMixingAttachment.java rename to src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselMixingAttachment.java index d7fc4b03..1ac77fc9 100644 --- a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselMixingAttachment.java +++ b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselMixingAttachment.java @@ -1,4 +1,4 @@ -package io.github.pylonmc.pylon.base.content.machines.diesel; +package io.github.pylonmc.pylon.base.content.machines.diesel.machines; import com.destroystokyo.paper.ParticleBuilder; import io.github.pylonmc.pylon.base.BaseFluids; diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselPipeBender.java b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselPipeBender.java similarity index 99% rename from src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselPipeBender.java rename to src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselPipeBender.java index 38d18a8d..e792c42c 100644 --- a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselPipeBender.java +++ b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselPipeBender.java @@ -1,4 +1,4 @@ -package io.github.pylonmc.pylon.base.content.machines.diesel; +package io.github.pylonmc.pylon.base.content.machines.diesel.machines; import com.destroystokyo.paper.ParticleBuilder; import io.github.pylonmc.pylon.base.BaseFluids; diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselPress.java b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselPress.java similarity index 99% rename from src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselPress.java rename to src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselPress.java index 4c4e5a92..6cd9f322 100644 --- a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselPress.java +++ b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselPress.java @@ -1,4 +1,4 @@ -package io.github.pylonmc.pylon.base.content.machines.diesel; +package io.github.pylonmc.pylon.base.content.machines.diesel.machines; import com.destroystokyo.paper.ParticleBuilder; import io.github.pylonmc.pylon.base.BaseFluids; diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselTableSaw.java b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselTableSaw.java similarity index 99% rename from src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselTableSaw.java rename to src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselTableSaw.java index 08431835..6539b9d8 100644 --- a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/DieselTableSaw.java +++ b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/machines/DieselTableSaw.java @@ -1,4 +1,4 @@ -package io.github.pylonmc.pylon.base.content.machines.diesel; +package io.github.pylonmc.pylon.base.content.machines.diesel.machines; import com.destroystokyo.paper.ParticleBuilder; import io.github.pylonmc.pylon.base.BaseFluids; diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/production/Biorefinery.java b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/production/Biorefinery.java new file mode 100644 index 00000000..473ae424 --- /dev/null +++ b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/production/Biorefinery.java @@ -0,0 +1,349 @@ +package io.github.pylonmc.pylon.base.content.machines.diesel.production; + +import com.destroystokyo.paper.ParticleBuilder; +import com.google.common.base.Preconditions; +import io.github.pylonmc.pylon.base.BaseFluids; +import io.github.pylonmc.pylon.base.BaseItems; +import io.github.pylonmc.pylon.base.BaseKeys; +import io.github.pylonmc.pylon.base.content.components.FluidInputHatch; +import io.github.pylonmc.pylon.base.content.components.FluidOutputHatch; +import io.github.pylonmc.pylon.base.content.components.ItemInputHatch; +import io.github.pylonmc.pylon.base.util.BaseUtils; +import io.github.pylonmc.pylon.core.block.BlockStorage; +import io.github.pylonmc.pylon.core.block.PylonBlock; +import io.github.pylonmc.pylon.core.block.base.PylonDirectionalBlock; +import io.github.pylonmc.pylon.core.block.base.PylonProcessor; +import io.github.pylonmc.pylon.core.block.base.PylonSimpleMultiblock; +import io.github.pylonmc.pylon.core.block.base.PylonTickingBlock; +import io.github.pylonmc.pylon.core.block.context.BlockCreateContext; +import io.github.pylonmc.pylon.core.config.adapter.ConfigAdapter; +import io.github.pylonmc.pylon.core.i18n.PylonArgument; +import io.github.pylonmc.pylon.core.item.PylonItem; +import io.github.pylonmc.pylon.core.registry.PylonRegistry; +import io.github.pylonmc.pylon.core.util.MachineUpdateReason; +import io.github.pylonmc.pylon.core.util.PylonUtils; +import io.github.pylonmc.pylon.core.util.gui.unit.UnitFormat; +import io.github.pylonmc.pylon.core.waila.Waila; +import io.github.pylonmc.pylon.core.waila.WailaDisplay; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.TextColor; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.joml.Vector3d; +import org.joml.Vector3i; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static io.github.pylonmc.pylon.base.util.BaseUtils.baseKey; + +public class Biorefinery extends PylonBlock implements + PylonDirectionalBlock, + PylonSimpleMultiblock, + PylonProcessor, + PylonTickingBlock { + + public final int tickInterval = getSettings().getOrThrow("tick-interval", ConfigAdapter.INT); + public final double biodieselPerSecond = getSettings().getOrThrow("biodiesel-per-second", ConfigAdapter.DOUBLE); + public final double ethanolPerMbOfBiodiesel = getSettings().getOrThrow("ethanol-per-mb-of-biodiesel", ConfigAdapter.DOUBLE); + public final double plantOilPerMbOfBiodiesel = getSettings().getOrThrow("plant-oil-per-mb-of-biodiesel", ConfigAdapter.DOUBLE); + + public static class Item extends PylonItem { + + public final double biodieselPerSecond = getSettings().getOrThrow("biodiesel-per-second", ConfigAdapter.DOUBLE); + public final double ethanolPerMbOfBiodiesel = getSettings().getOrThrow("ethanol-per-mb-of-biodiesel", ConfigAdapter.DOUBLE); + public final double plantOilPerMbOfBiodiesel = getSettings().getOrThrow("plant-oil-per-mb-of-biodiesel", ConfigAdapter.DOUBLE); + + public Item(@NotNull ItemStack stack) { + super(stack); + } + + @Override + public @NotNull List<@NotNull PylonArgument> getPlaceholders() { + return List.of( + PylonArgument.of("biodiesel-per-second", UnitFormat.MILLIBUCKETS_PER_SECOND.format(biodieselPerSecond)), + PylonArgument.of("ethanol-per-mb-of-biodiesel", UnitFormat.MILLIBUCKETS.format(ethanolPerMbOfBiodiesel)), + PylonArgument.of("plant-oil-per-mb-of-biodiesel", UnitFormat.MILLIBUCKETS.format(plantOilPerMbOfBiodiesel)) + ); + } + } + + public Biorefinery(@NotNull Block block, @NotNull BlockCreateContext context) { + super(block, context); + setFacing(context.getFacing()); + setMultiblockDirection(context.getFacing()); + setTickInterval(tickInterval); + } + + public Biorefinery(@NotNull Block block, @NotNull PersistentDataContainer pdc) { + super(block, pdc); + } + + @Override + public @NotNull Map<@NotNull Vector3i, @NotNull MultiblockComponent> getComponents() { + Map components = new HashMap<>(); + + // foundation + components.put(new Vector3i(0, 0, -1), new PylonMultiblockComponent(BaseKeys.FLUID_OUTPUT_HATCH)); + components.put(new Vector3i(-1, 0, 0), new PylonMultiblockComponent(BaseKeys.FLUID_INPUT_HATCH)); + components.put(new Vector3i(1, 0, 0), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_FOUNDATION)); + components.put(new Vector3i(2, 0, 0), new PylonMultiblockComponent(BaseKeys.FLUID_INPUT_HATCH)); + components.put(new Vector3i(0, 0, 1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_FOUNDATION)); + components.put(new Vector3i(0, 0, 2), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_FOUNDATION)); + components.put(new Vector3i(0, 0, 3), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_FOUNDATION)); + components.put(new Vector3i(-1, 0, 3), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_FOUNDATION)); + components.put(new Vector3i(1, 0, 3), new PylonMultiblockComponent(BaseKeys.ITEM_INPUT_HATCH)); + components.put(new Vector3i(0, 0, 4), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_FOUNDATION)); + + // tower + components.put(new Vector3i(0, 1, 0), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_TOWER_RING)); + components.put(new Vector3i(0, 2, 0), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_TOWER_RING)); + components.put(new Vector3i(0, 3, 0), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_TOWER_RING)); + components.put(new Vector3i(0, 4, 0), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_TOWER_RING)); + components.put(new Vector3i(1, 1, 0), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_SMOKESTACK_RING)); + components.put(new Vector3i(1, 2, 0), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_SMOKESTACK_RING)); + components.put(new Vector3i(1, 3, 0), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_SMOKESTACK_RING)); + components.put(new Vector3i(1, 4, 0), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_SMOKESTACK_RING)); + components.put(new Vector3i(1, 5, 0), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_SMOKESTACK_CAP)); + + // burner smokestack + components.put(new Vector3i(0, 1, 3), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_SMOKESTACK_RING)); + components.put(new Vector3i(0, 2, 3), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_SMOKESTACK_RING)); + components.put(new Vector3i(0, 3, 3), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_SMOKESTACK_RING)); + components.put(new Vector3i(0, 4, 3), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_SMOKESTACK_CAP)); + + // casing + components.put(new Vector3i(-1, 0, 1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + components.put(new Vector3i(-1, 1, 1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + components.put(new Vector3i(-1, 0, -1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + components.put(new Vector3i(-1, 1, -1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + + components.put(new Vector3i(1, 0, 1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + components.put(new Vector3i(1, 1, 1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + components.put(new Vector3i(1, 0, -1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + components.put(new Vector3i(1, 1, -1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + + components.put(new Vector3i(2, 0, 1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + components.put(new Vector3i(2, 1, 1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + components.put(new Vector3i(2, 0, -1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + components.put(new Vector3i(2, 1, -1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + + components.put(new Vector3i(0, 1, 1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + components.put(new Vector3i(0, 1, 2), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + components.put(new Vector3i(1, 1, 3), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + components.put(new Vector3i(-1, 1, 3), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + components.put(new Vector3i(0, 1, 4), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + + components.put(new Vector3i(-1, 3, -1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + components.put(new Vector3i(-1, 3, 0), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + components.put(new Vector3i(-1, 3, 1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + components.put(new Vector3i(0, 3, 1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + components.put(new Vector3i(1, 3, 1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + components.put(new Vector3i(1, 3, -1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + components.put(new Vector3i(0, 3, -1), new PylonMultiblockComponent(BaseKeys.BIOREFINERY_PLATING)); + + return components; + } + + @Override + public boolean checkFormed() { + boolean formed = PylonSimpleMultiblock.super.checkFormed(); + if (formed) { + getEthanolInputHatch().setFluidType(BaseFluids.ETHANOL); + getPlantOilInputHatch().setFluidType(BaseFluids.PLANT_OIL); + getBiodieselOutputHatch().setFluidType(BaseFluids.BIODIESEL); + for (Vector3i position : getComponents().keySet()) { + Vector relative = Vector.fromJOML(PylonUtils.rotateVectorToFace(position, getFacing())); + Location location = getBlock().getLocation().add(relative); + Waila.addWailaOverride(location.getBlock(), this::getWaila); + } + } + return formed; + } + + @Override + public void onMultiblockUnformed(boolean partUnloaded) { + PylonSimpleMultiblock.super.onMultiblockUnformed(partUnloaded); + FluidInputHatch ethanolInputHatch = getEthanolInputHatch(); + if (ethanolInputHatch != null) { + ethanolInputHatch.setFluidType(null); + } + FluidInputHatch plantOilInputHatch = getPlantOilInputHatch(); + if (plantOilInputHatch != null) { + plantOilInputHatch.setFluidType(null); + } + FluidOutputHatch biodieselOutputHatch = getBiodieselOutputHatch(); + if (biodieselOutputHatch != null) { + biodieselOutputHatch.setFluidType(null); + } + for (Vector3i position : getComponents().keySet()) { + Vector relative = Vector.fromJOML(PylonUtils.rotateVectorToFace(position, getFacing())); + Location location = getBlock().getLocation().add(relative); + Waila.removeWailaOverride(location.getBlock()); + } + } + + @Override + public void tick() { + if (!isFormedAndFullyLoaded()) { + return; + } + + // Tick production + if (isProcessing()) { + progressProcess(getTickInterval()); + FluidInputHatch ethanolInputHatch = getEthanolInputHatch(); + FluidInputHatch plantOilInputHatch = getPlantOilInputHatch(); + FluidOutputHatch biodieselOutputHatch = getBiodieselOutputHatch(); + Preconditions.checkState(ethanolInputHatch != null + && plantOilInputHatch != null + && biodieselOutputHatch != null + ); + + double biodieselToProduce = Math.min( + biodieselOutputHatch.fluidSpaceRemaining(BaseFluids.BIODIESEL), + Math.min( + biodieselPerSecond * getTickInterval() / 20.0, + Math.min( + ethanolInputHatch.fluidAmount(BaseFluids.ETHANOL) / ethanolPerMbOfBiodiesel, + plantOilInputHatch.fluidAmount(BaseFluids.PLANT_OIL) / plantOilPerMbOfBiodiesel + ) + ) + ); + + if (biodieselToProduce > 1.0e-3) { + ethanolInputHatch.removeFluid(BaseFluids.ETHANOL, biodieselToProduce * ethanolPerMbOfBiodiesel); + plantOilInputHatch.removeFluid(BaseFluids.PLANT_OIL, biodieselToProduce * plantOilPerMbOfBiodiesel); + biodieselOutputHatch.addFluid(BaseFluids.BIODIESEL, biodieselToProduce); + } + + Vector smokePosition1 = Vector.fromJOML(PylonUtils.rotateVectorToFace( + new Vector3d(1, 5, 0), + getFacing() + )); + new ParticleBuilder(Particle.CAMPFIRE_COSY_SMOKE) + .location(getBlock().getLocation().toCenterLocation().add(smokePosition1)) + .offset(0, 1, 0) + .count(0) + .extra(0.05) + .spawn(); + + Vector smokePosition2 = Vector.fromJOML(PylonUtils.rotateVectorToFace( + new Vector3d(0, 4, 3), + getFacing() + )); + new ParticleBuilder(Particle.CAMPFIRE_COSY_SMOKE) + .location(getBlock().getLocation().toCenterLocation().add(smokePosition2)) + .offset(0, 1, 0) + .count(0) + .extra(0.05) + .spawn(); + } + + // Consume fuel + if (!isProcessing()) { + ItemInputHatch fuelInputHatch = getFuelInputHatch(); + Preconditions.checkState(fuelInputHatch != null); + ItemStack input = fuelInputHatch.inventory.getItem(0); + if (input != null) { + for (Fuel fuel : FUELS) { + if (fuel.stack.isSimilar(input)) { + fuelInputHatch.inventory.setItem(new MachineUpdateReason(), 0, input.subtract()); + startProcess(fuel.burnTimeSeconds * 20); + break; + } + } + } + } + } + + @Override + public @Nullable WailaDisplay getWaila(@NotNull Player player) { + if (isProcessing()) { + double percent = (double) getProcessTicksRemaining() / getProcessTimeTicks(); + return new WailaDisplay(getDefaultWailaTranslationKey().arguments( + PylonArgument.of("info", Component.translatable("pylon.pylonbase.message.biorefinery.has_fuel").arguments( + PylonArgument.of("fuel-bar", BaseUtils.createBar( + percent, + 20, + TextColor.color(255, 200, 50) + )), + PylonArgument.of("remaining-time", UnitFormat.SECONDS.format(getProcessTicksRemaining() / 20)) + )) + )); + } else { + return new WailaDisplay(getDefaultWailaTranslationKey().arguments( + PylonArgument.of("info", Component.translatable("pylon.pylonbase.message.biorefinery.no_fuel")) + )); + } + } + + public @Nullable ItemInputHatch getFuelInputHatch() { + Vector relative = Vector.fromJOML(PylonUtils.rotateVectorToFace(new Vector3i(1, 0, 3), getFacing())); + Location location = getBlock().getLocation().add(relative); + return BlockStorage.getAs(ItemInputHatch.class, location); + } + + public @Nullable FluidOutputHatch getBiodieselOutputHatch() { + Vector relative = Vector.fromJOML(PylonUtils.rotateVectorToFace(new Vector3i(0, 0, -1), getFacing())); + Location location = getBlock().getLocation().add(relative); + return BlockStorage.getAs(FluidOutputHatch.class, location); + } + + public @Nullable FluidInputHatch getEthanolInputHatch() { + Vector relative = Vector.fromJOML(PylonUtils.rotateVectorToFace(new Vector3i(-1, 0, 0), getFacing())); + Location location = getBlock().getLocation().add(relative); + return BlockStorage.getAs(FluidInputHatch.class, location); + } + + public @Nullable FluidInputHatch getPlantOilInputHatch() { + Vector relative = Vector.fromJOML(PylonUtils.rotateVectorToFace(new Vector3i(2, 0, 0), getFacing())); + Location location = getBlock().getLocation().add(relative); + return BlockStorage.getAs(FluidInputHatch.class, location); + } + + public record Fuel( + @NotNull NamespacedKey key, + @NotNull ItemStack stack, + int burnTimeSeconds + ) implements Keyed { + @Override + public @NotNull NamespacedKey getKey() { + return key; + } + } + + public static final NamespacedKey FUELS_KEY = baseKey("biorefinery_fuels"); + public static final PylonRegistry FUELS = new PylonRegistry<>(FUELS_KEY); + + static { + PylonRegistry.addRegistry(FUELS); + FUELS.register(new Fuel( + baseKey("coal"), + new ItemStack(Material.COAL), + 15 + )); + FUELS.register(new Fuel( + baseKey("coal_block"), + new ItemStack(Material.COAL_BLOCK), + 135 + )); + FUELS.register(new Fuel( + baseKey("charcoal"), + new ItemStack(Material.CHARCOAL), + 10 + )); + FUELS.register(new Fuel( + baseKey("charcoal_block"), + BaseItems.CHARCOAL_BLOCK, + 90 + )); + } +} diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/production/Fermenter.java b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/production/Fermenter.java new file mode 100644 index 00000000..b8e55cd9 --- /dev/null +++ b/src/main/java/io/github/pylonmc/pylon/base/content/machines/diesel/production/Fermenter.java @@ -0,0 +1,226 @@ +package io.github.pylonmc.pylon.base.content.machines.diesel.production; + +import com.google.common.base.Preconditions; +import io.github.pylonmc.pylon.base.BaseFluids; +import io.github.pylonmc.pylon.base.BaseKeys; +import io.github.pylonmc.pylon.base.content.components.FluidOutputHatch; +import io.github.pylonmc.pylon.base.content.components.ItemInputHatch; +import io.github.pylonmc.pylon.base.util.BaseUtils; +import io.github.pylonmc.pylon.core.block.BlockStorage; +import io.github.pylonmc.pylon.core.block.PylonBlock; +import io.github.pylonmc.pylon.core.block.base.PylonDirectionalBlock; +import io.github.pylonmc.pylon.core.block.base.PylonFluidBufferBlock; +import io.github.pylonmc.pylon.core.block.base.PylonSimpleMultiblock; +import io.github.pylonmc.pylon.core.block.base.PylonTickingBlock; +import io.github.pylonmc.pylon.core.block.context.BlockCreateContext; +import io.github.pylonmc.pylon.core.config.adapter.ConfigAdapter; +import io.github.pylonmc.pylon.core.entity.display.ItemDisplayBuilder; +import io.github.pylonmc.pylon.core.entity.display.transform.TransformBuilder; +import io.github.pylonmc.pylon.core.fluid.PylonFluid; +import io.github.pylonmc.pylon.core.i18n.PylonArgument; +import io.github.pylonmc.pylon.core.item.PylonItem; +import io.github.pylonmc.pylon.core.util.MachineUpdateReason; +import io.github.pylonmc.pylon.core.util.PylonUtils; +import io.github.pylonmc.pylon.core.util.gui.unit.UnitFormat; +import io.github.pylonmc.pylon.core.waila.Waila; +import io.github.pylonmc.pylon.core.waila.WailaDisplay; +import net.kyori.adventure.text.format.TextColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.ItemDisplay; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.joml.Vector3i; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Fermenter extends PylonBlock implements + PylonSimpleMultiblock, + PylonDirectionalBlock, + PylonTickingBlock, + PylonFluidBufferBlock { + + public final int tickInterval = getSettings().getOrThrow("tick-interval", ConfigAdapter.INT); + public final double ethanolPerSugarcane = getSettings().getOrThrow("ethanol-per-sugarcane", ConfigAdapter.DOUBLE); + public final int sugarcaneCapacity = getSettings().getOrThrow("sugarcane-capacity", ConfigAdapter.INT); + public final double maxEthanolOutputRate = getSettings().getOrThrow("max-ethanol-output-rate", ConfigAdapter.DOUBLE); + + public static class Item extends PylonItem { + + public final double ethanolPerSugarcane = getSettings().getOrThrow("ethanol-per-sugarcane", ConfigAdapter.DOUBLE); + public final int sugarcaneCapacity = getSettings().getOrThrow("sugarcane-capacity", ConfigAdapter.INT); + public final double maxEthanolOutputRate = getSettings().getOrThrow("max-ethanol-output-rate", ConfigAdapter.DOUBLE); + + public Item(@NotNull ItemStack stack) { + super(stack); + } + + @Override + public @NotNull List<@NotNull PylonArgument> getPlaceholders() { + return List.of( + PylonArgument.of("ethanol-per-sugarcane", UnitFormat.MILLIBUCKETS.format(ethanolPerSugarcane)), + PylonArgument.of("sugarcane-capacity", UnitFormat.ITEMS.format(sugarcaneCapacity)), + PylonArgument.of("max-ethanol-output-rate", UnitFormat.MILLIBUCKETS_PER_SECOND.format(maxEthanolOutputRate)) + ); + } + } + + @SuppressWarnings("unused") + public Fermenter(@NotNull Block block, @NotNull BlockCreateContext context) { + super(block, context); + setFacing(context.getFacing()); + setMultiblockDirection(context.getFacing()); + setTickInterval(tickInterval); + createFluidBuffer(BaseFluids.SUGARCANE, ethanolPerSugarcane * sugarcaneCapacity, false, false); + addEntity("sugarcane", new ItemDisplayBuilder() + .itemStack(BaseFluids.SUGARCANE.getItem()) + .transformation(new TransformBuilder() + .scale(0, 0, 0)) + .build(getBlock().getLocation().toCenterLocation().add(0, 0.5, 0)) + ); + } + + @SuppressWarnings("unused") + public Fermenter(@NotNull Block block, @NotNull PersistentDataContainer pdc) { + super(block, pdc); + } + + @Override + public @NotNull Map<@NotNull Vector3i, @NotNull MultiblockComponent> getComponents() { + Map components = new HashMap<>(); + + components.put(new Vector3i(-1, 0, 0), new VanillaMultiblockComponent(Material.IRON_BLOCK)); + components.put(new Vector3i(1, 0, 0), new VanillaMultiblockComponent(Material.IRON_BLOCK)); + components.put(new Vector3i(0, 0, -1), new PylonMultiblockComponent(BaseKeys.ITEM_INPUT_HATCH)); + components.put(new Vector3i(0, 0, 1), new PylonMultiblockComponent(BaseKeys.FLUID_OUTPUT_HATCH)); + components.put(new Vector3i(-1, 0, -1), new VanillaMultiblockComponent(Material.POLISHED_DEEPSLATE_WALL)); + components.put(new Vector3i(-1, 0, 1), new VanillaMultiblockComponent(Material.POLISHED_DEEPSLATE_WALL)); + components.put(new Vector3i(1, 0, -1), new VanillaMultiblockComponent(Material.POLISHED_DEEPSLATE_WALL)); + components.put(new Vector3i(1, 0, 1), new VanillaMultiblockComponent(Material.POLISHED_DEEPSLATE_WALL)); + + for (int x = -1; x <= 1; x++) { + for (int y = 1 ; y <= 4; y++) { + for (int z = -1; z <= 1; z++) { + Vector3i position = new Vector3i(x, y, z); + if (x == 0 && z == 0) { + components.put(position, new PylonMultiblockComponent(BaseKeys.FERMENTER_CORE)); + } else { + components.put(position, new PylonMultiblockComponent(BaseKeys.FERMENTER_CASING)); + } + } + } + } + + components.remove(new Vector3i(0, 1, 1)); + + return components; + } + + @Override + public boolean checkFormed() { + boolean formed = PylonSimpleMultiblock.super.checkFormed(); + if (formed) { + getOutputHatch().setFluidType(BaseFluids.ETHANOL); + for (Vector3i position : getComponents().keySet()) { + Vector relative = Vector.fromJOML(PylonUtils.rotateVectorToFace(position, getFacing())); + Location location = getBlock().getLocation().add(relative); + Waila.addWailaOverride(location.getBlock(), this::getWaila); + } + } + return formed; + } + + @Override + public void onMultiblockUnformed(boolean partUnloaded) { + PylonSimpleMultiblock.super.onMultiblockUnformed(partUnloaded); + FluidOutputHatch outputHatch = getOutputHatch(); + if (outputHatch != null) { + outputHatch.setFluidType(null); + } + for (Vector3i position : getComponents().keySet()) { + Vector relative = Vector.fromJOML(PylonUtils.rotateVectorToFace(position, getFacing())); + Location location = getBlock().getLocation().add(relative); + Waila.removeWailaOverride(location.getBlock()); + } + } + + @Override + public void tick() { + if (!isFormedAndFullyLoaded()) { + return; + } + + ItemInputHatch inputHatch = getInputHatch(); + FluidOutputHatch outputHatch = getOutputHatch(); + Preconditions.checkState(inputHatch != null && outputHatch != null); + + ItemStack sugarcane = inputHatch.inventory.getItem(0); + if (sugarcane != null + && PylonItem.fromStack(sugarcane) == null + && sugarcane.getType().equals(Material.SUGAR_CANE) + && fluidSpaceRemaining(BaseFluids.SUGARCANE) > ethanolPerSugarcane + ) { + int max = (int) (fluidSpaceRemaining(BaseFluids.SUGARCANE) / ethanolPerSugarcane); + int sugarcaneToConsume = Math.min(max, sugarcane.getAmount()); + addFluid(BaseFluids.SUGARCANE, sugarcaneToConsume * ethanolPerSugarcane); + inputHatch.inventory.setItem(new MachineUpdateReason(), 0, sugarcane.subtract(sugarcaneToConsume)); + } + + double sugarcaneProportion = fluidAmount(BaseFluids.SUGARCANE) / fluidCapacity(BaseFluids.SUGARCANE); + double outputSpaceRemaining = outputHatch.fluidSpaceRemaining(BaseFluids.ETHANOL); + double ethanolToOutput = Math.min(outputSpaceRemaining, sugarcaneProportion * maxEthanolOutputRate * getTickInterval() / 20); + if (ethanolToOutput > 1.0e-6) { + removeFluid(BaseFluids.SUGARCANE, ethanolToOutput); + outputHatch.addFluid(BaseFluids.ETHANOL, ethanolToOutput); + } + } + + @Override + public boolean setFluid(@NotNull PylonFluid fluid, double amount) { + boolean wasSet = PylonFluidBufferBlock.super.setFluid(fluid, amount); + if (wasSet) { + double sugarcaneProportion = fluidAmount(BaseFluids.SUGARCANE) / fluidCapacity(BaseFluids.SUGARCANE); + getHeldEntityOrThrow(ItemDisplay.class, "sugarcane").setTransformationMatrix( + new TransformBuilder() + .scale(0.7, 4 * sugarcaneProportion, 0.7) + .translate(0, 0.5, 0) + .buildForItemDisplay() + ); + } + return wasSet; + } + + @Override + public @Nullable WailaDisplay getWaila(@NotNull Player player) { + double sugarcaneProportion = fluidAmount(BaseFluids.SUGARCANE) / fluidCapacity(BaseFluids.SUGARCANE); + int sugarcaneAmount = sugarcaneProportion < 1.0e-3 + ? 0 + : (int) (sugarcaneProportion * sugarcaneCapacity) + 1; + return new WailaDisplay(getDefaultWailaTranslationKey().arguments( + PylonArgument.of("sugarcane-bar", BaseUtils.createBar( + sugarcaneProportion, + 20, TextColor.color(163, 237, 45) + )), + PylonArgument.of("sugarcane-amount", sugarcaneAmount) + )); + } + + public @Nullable ItemInputHatch getInputHatch() { + Vector relative = Vector.fromJOML(PylonUtils.rotateVectorToFace(new Vector3i(0, 0, -1), getFacing())); + Location location = getBlock().getLocation().add(relative); + return BlockStorage.getAs(ItemInputHatch.class, location); + } + + public @Nullable FluidOutputHatch getOutputHatch() { + Vector relative = Vector.fromJOML(PylonUtils.rotateVectorToFace(new Vector3i(0, 0, 1), getFacing())); + Location location = getBlock().getLocation().add(relative); + return BlockStorage.getAs(FluidOutputHatch.class, location); + } +} \ No newline at end of file diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/machines/fluid/FluidInputHatch.java b/src/main/java/io/github/pylonmc/pylon/base/content/machines/fluid/FluidInputHatch.java deleted file mode 100644 index 8a2b19d3..00000000 --- a/src/main/java/io/github/pylonmc/pylon/base/content/machines/fluid/FluidInputHatch.java +++ /dev/null @@ -1,27 +0,0 @@ -package io.github.pylonmc.pylon.base.content.machines.fluid; - -import io.github.pylonmc.pylon.core.block.PylonBlock; -import io.github.pylonmc.pylon.core.block.base.PylonSimpleMultiblock; -import io.github.pylonmc.pylon.core.block.context.BlockCreateContext; -import org.bukkit.block.Block; -import org.bukkit.persistence.PersistentDataContainer; -import org.jetbrains.annotations.NotNull; -import org.joml.Vector3i; - -import java.util.Map; - -public class FluidInputHatch extends PylonBlock implements PylonSimpleMultiblock { - - public FluidInputHatch(@NotNull Block block, @NotNull BlockCreateContext context) { - super(block, context); - } - - public FluidInputHatch(@NotNull Block block, @NotNull PersistentDataContainer pdc) { - super(block, pdc); - } - - @Override - public @NotNull Map<@NotNull Vector3i, @NotNull MultiblockComponent> getComponents() { - return Map.of(); - } -} diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/CoalFiredPurificationTower.java b/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/CoalFiredPurificationTower.java index b0aafbd2..8b6ce607 100644 --- a/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/CoalFiredPurificationTower.java +++ b/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/CoalFiredPurificationTower.java @@ -1,7 +1,9 @@ package io.github.pylonmc.pylon.base.content.machines.hydraulics; import io.github.pylonmc.pylon.base.BaseFluids; +import io.github.pylonmc.pylon.base.BaseItems; import io.github.pylonmc.pylon.base.BaseKeys; +import io.github.pylonmc.pylon.base.content.machines.diesel.production.Biorefinery; import io.github.pylonmc.pylon.base.util.BaseUtils; import io.github.pylonmc.pylon.core.block.PylonBlock; import io.github.pylonmc.pylon.core.block.base.*; @@ -54,7 +56,7 @@ public class CoalFiredPurificationTower extends PylonBlock implements public final double buffer = getSettings().getOrThrow("buffer", ConfigAdapter.INT); public final int tickInterval = getSettings().getOrThrow("tick-interval", ConfigAdapter.INT); - public static final NamespacedKey FUELS_KEY = baseKey("smeltery_burner_fuels"); + public static final NamespacedKey FUELS_KEY = baseKey("coal_fired_purification_tower_fuels"); public static final PylonRegistry FUELS = new PylonRegistry<>(FUELS_KEY); // TODO display fuels @@ -86,6 +88,11 @@ public record Fuel( new ItemStack(Material.CHARCOAL), 10 )); + FUELS.register(new Fuel( + baseKey("charcoal_block"), + BaseItems.CHARCOAL_BLOCK, + 90 + )); } private final ItemStackBuilder idleProgressItem = ItemStackBuilder.of(Material.BLAZE_POWDER) diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/HydraulicCoreDrill.java b/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/HydraulicCoreDrill.java index 5c5145d9..89ed15db 100644 --- a/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/HydraulicCoreDrill.java +++ b/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/HydraulicCoreDrill.java @@ -3,8 +3,9 @@ import com.google.common.base.Preconditions; import io.github.pylonmc.pylon.base.BaseFluids; import io.github.pylonmc.pylon.base.BaseKeys; +import io.github.pylonmc.pylon.base.content.components.FluidInputHatch; +import io.github.pylonmc.pylon.base.content.components.FluidOutputHatch; import io.github.pylonmc.pylon.base.content.machines.simple.CoreDrill; -import io.github.pylonmc.pylon.base.util.BaseUtils; import io.github.pylonmc.pylon.core.block.BlockStorage; import io.github.pylonmc.pylon.core.block.base.PylonTickingBlock; import io.github.pylonmc.pylon.core.block.context.BlockCreateContext; @@ -12,14 +13,11 @@ import io.github.pylonmc.pylon.core.i18n.PylonArgument; import io.github.pylonmc.pylon.core.util.PylonUtils; import io.github.pylonmc.pylon.core.util.gui.unit.UnitFormat; -import io.github.pylonmc.pylon.core.waila.WailaDisplay; -import net.kyori.adventure.text.format.TextColor; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.Chest; -import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.util.Vector; @@ -93,10 +91,8 @@ public HydraulicCoreDrill(@NotNull Block block, @NotNull PersistentDataContainer components.put(new Vector3i(1, -2, 2), new VanillaMultiblockComponent(Material.IRON_BARS)); components.put(new Vector3i(0, -2, 3), new VanillaMultiblockComponent(Material.CAULDRON)); - components.put(new Vector3i(1, -2, 3), new PylonMultiblockComponent(BaseKeys.HYDRAULIC_CORE_DRILL_INPUT_HATCH)); - components.put(new Vector3i(1, -1, 3), new PylonMultiblockComponent(BaseKeys.FLUID_TANK_CASING_COPPER)); - components.put(new Vector3i(-1, -2, 3), new PylonMultiblockComponent(BaseKeys.HYDRAULIC_CORE_DRILL_OUTPUT_HATCH)); - components.put(new Vector3i(-1, -1, 3), new PylonMultiblockComponent(BaseKeys.FLUID_TANK_CASING_COPPER)); + components.put(new Vector3i(1, -2, 3), new PylonMultiblockComponent(BaseKeys.FLUID_INPUT_HATCH)); + components.put(new Vector3i(-1, -2, 3), new PylonMultiblockComponent(BaseKeys.FLUID_OUTPUT_HATCH)); components.put(new Vector3i(0, -2, 4), new VanillaMultiblockComponent(Material.CHEST)); @@ -109,12 +105,8 @@ public void tick() { return; } - Location inputHatchLocation = getBlock().getLocation().add(Vector.fromJOML(PylonUtils.rotateVectorToFace(new Vector3i(1, -2, 3), getFacing()))); - HydraulicCoreDrillHatch inputHatch = BlockStorage.getAs(HydraulicCoreDrillInputHatch.class, inputHatchLocation); - - Location outputHatchLocation = getBlock().getLocation().add(Vector.fromJOML(PylonUtils.rotateVectorToFace(new Vector3i(-1, -2, 3), getFacing()))); - HydraulicCoreDrillHatch outputHatch = BlockStorage.getAs(HydraulicCoreDrillOutputHatch.class, outputHatchLocation); - + FluidInputHatch inputHatch = getInputHatch(); + FluidOutputHatch outputHatch = getOutputHatch(); Preconditions.checkState(inputHatch != null && outputHatch != null); if (inputHatch.fluidAmount(BaseFluids.HYDRAULIC_FLUID) < hydraulicFluidPerCycle @@ -144,4 +136,39 @@ public void onProcessFinished() { output ); } + + @Override + public void onMultiblockFormed() { + super.onMultiblockFormed(); + FluidInputHatch inputHatch = getInputHatch(); + FluidOutputHatch outputHatch = getOutputHatch(); + Preconditions.checkState(inputHatch != null && outputHatch != null); + inputHatch.setFluidType(BaseFluids.HYDRAULIC_FLUID); + outputHatch.setFluidType(BaseFluids.DIRTY_HYDRAULIC_FLUID); + } + + @Override + public void onMultiblockUnformed(boolean partUnloaded) { + super.onMultiblockUnformed(partUnloaded); + FluidInputHatch inputHatch = getInputHatch(); + if (inputHatch != null) { + inputHatch.setFluidType(null); + } + FluidOutputHatch outputHatch = getOutputHatch(); + if (outputHatch != null) { + outputHatch.setFluidType(null); + } + } + + public @Nullable FluidInputHatch getInputHatch() { + Vector relativeLocation = Vector.fromJOML(PylonUtils.rotateVectorToFace(new Vector3i(1, -2, 3), getFacing())); + Location inputHatchLocation = getBlock().getLocation().add(relativeLocation); + return BlockStorage.getAs(FluidInputHatch.class, inputHatchLocation); + } + + public @Nullable FluidOutputHatch getOutputHatch() { + Vector relativeLocation = Vector.fromJOML(PylonUtils.rotateVectorToFace(new Vector3i(-1, -2, 3), getFacing())); + Location inputHatchLocation = getBlock().getLocation().add(relativeLocation); + return BlockStorage.getAs(FluidOutputHatch.class, inputHatchLocation); + } } diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/HydraulicCoreDrillHatch.java b/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/HydraulicCoreDrillHatch.java deleted file mode 100644 index 4aa8d699..00000000 --- a/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/HydraulicCoreDrillHatch.java +++ /dev/null @@ -1,76 +0,0 @@ -package io.github.pylonmc.pylon.base.content.machines.hydraulics; - -import io.github.pylonmc.pylon.base.BaseKeys; -import io.github.pylonmc.pylon.core.block.BlockStorage; -import io.github.pylonmc.pylon.core.block.PylonBlock; -import io.github.pylonmc.pylon.core.block.base.PylonEntityHolderBlock; -import io.github.pylonmc.pylon.core.block.base.PylonFluidBufferBlock; -import io.github.pylonmc.pylon.core.block.base.PylonMultiblock; -import io.github.pylonmc.pylon.core.block.context.BlockCreateContext; -import io.github.pylonmc.pylon.core.entity.display.transform.TransformBuilder; -import io.github.pylonmc.pylon.core.fluid.PylonFluid; -import io.github.pylonmc.pylon.core.util.position.BlockPosition; -import io.github.pylonmc.pylon.core.util.position.ChunkPosition; -import io.github.pylonmc.pylon.core.waila.Waila; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.entity.ItemDisplay; -import org.bukkit.persistence.PersistentDataContainer; -import org.jetbrains.annotations.NotNull; - -import java.util.Set; - -public abstract class HydraulicCoreDrillHatch extends PylonBlock - implements PylonFluidBufferBlock, PylonMultiblock, PylonEntityHolderBlock { - - @SuppressWarnings("unused") - public HydraulicCoreDrillHatch(@NotNull Block block, @NotNull BlockCreateContext context) { - super(block, context); - } - - @SuppressWarnings("unused") - public HydraulicCoreDrillHatch(@NotNull Block block, @NotNull PersistentDataContainer pdc) { - super(block, pdc); - } - - @Override - public @NotNull Set getChunksOccupied() { - return Set.of(new ChunkPosition(getBlock())); - } - - @Override - public boolean checkFormed() { - PylonBlock aboveBlock = BlockStorage.get(getBlock().getRelative(BlockFace.UP)); - return aboveBlock != null && aboveBlock.getKey().equals(BaseKeys.FLUID_TANK_CASING_COPPER); - } - - @Override - public boolean isPartOfMultiblock(@NotNull Block otherBlock) { - return getBlock().getRelative(BlockFace.UP) == otherBlock; - } - - @Override - public void onMultiblockRefreshed() { - Waila.addWailaOverride(new BlockPosition(getBlock().getRelative(BlockFace.UP)), this::getWaila); - } - - - @Override - public boolean setFluid(@NotNull PylonFluid fluid, double amount) { - boolean result = PylonFluidBufferBlock.super.setFluid(fluid, amount); - float scale = (float) (0.9 * fluidAmount(fluid) / fluidCapacity(fluid)); - if (scale < 1.0e-9) { - scale = 0.0F; - } - getFluidDisplay().setTransformationMatrix(new TransformBuilder() - .translate(0.0, -0.45 + scale / 2, 0.0) - .scale(0.9, scale, 0.9) - .buildForItemDisplay() - ); - return result; - } - - public @NotNull ItemDisplay getFluidDisplay() { - return getHeldEntityOrThrow(ItemDisplay.class, "fluid"); - } -} diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/HydraulicCoreDrillInputHatch.java b/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/HydraulicCoreDrillInputHatch.java deleted file mode 100644 index 564c4d15..00000000 --- a/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/HydraulicCoreDrillInputHatch.java +++ /dev/null @@ -1,73 +0,0 @@ -package io.github.pylonmc.pylon.base.content.machines.hydraulics; - -import io.github.pylonmc.pylon.base.BaseFluids; -import io.github.pylonmc.pylon.base.BaseKeys; -import io.github.pylonmc.pylon.base.util.BaseUtils; -import io.github.pylonmc.pylon.core.block.context.BlockCreateContext; -import io.github.pylonmc.pylon.core.config.Settings; -import io.github.pylonmc.pylon.core.config.adapter.ConfigAdapter; -import io.github.pylonmc.pylon.core.entity.display.ItemDisplayBuilder; -import io.github.pylonmc.pylon.core.entity.display.transform.TransformBuilder; -import io.github.pylonmc.pylon.core.fluid.FluidPointType; -import io.github.pylonmc.pylon.core.i18n.PylonArgument; -import io.github.pylonmc.pylon.core.waila.WailaDisplay; -import net.kyori.adventure.text.format.TextColor; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.entity.Player; -import org.bukkit.persistence.PersistentDataContainer; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public class HydraulicCoreDrillInputHatch extends HydraulicCoreDrillHatch { - - private final double buffer = Settings.get(BaseKeys.FLUID_TANK_CASING_COPPER) - .getOrThrow("capacity", ConfigAdapter.DOUBLE); - - @SuppressWarnings("unused") - public HydraulicCoreDrillInputHatch(@NotNull Block block, @NotNull BlockCreateContext context) { - super(block, context); - createFluidBuffer( - BaseFluids.HYDRAULIC_FLUID, - buffer, - true, - false - ); - addEntity("fluid", new ItemDisplayBuilder() - .itemStack(BaseFluids.HYDRAULIC_FLUID.getItem()) - .transformation(new TransformBuilder().scale(0)) - .build(getBlock().getLocation().toCenterLocation().add(0, 1, 0)) - ); - createFluidPoint(FluidPointType.INPUT, BlockFace.NORTH, context, true); - } - - @SuppressWarnings("unused") - public HydraulicCoreDrillInputHatch(@NotNull Block block, @NotNull PersistentDataContainer pdc) { - super(block, pdc); - } - - @Override - public void onMultiblockFormed() { - setFluidCapacity(BaseFluids.HYDRAULIC_FLUID, buffer); - } - - @Override - public void onMultiblockUnformed(boolean partUnloaded) { - if (!partUnloaded) { - setFluidCapacity(BaseFluids.HYDRAULIC_FLUID, 0); - setFluid(BaseFluids.HYDRAULIC_FLUID, 0); - } - } - - @Override - public @Nullable WailaDisplay getWaila(@NotNull Player player) { - return new WailaDisplay(getDefaultWailaTranslationKey().arguments( - PylonArgument.of("bars", BaseUtils.createFluidAmountBar( - fluidAmount(BaseFluids.HYDRAULIC_FLUID), - fluidCapacity(BaseFluids.HYDRAULIC_FLUID), - 20, - TextColor.fromHexString("#212d99") - )) - )); - } -} diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/HydraulicCoreDrillOutputHatch.java b/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/HydraulicCoreDrillOutputHatch.java deleted file mode 100644 index d9147c81..00000000 --- a/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/HydraulicCoreDrillOutputHatch.java +++ /dev/null @@ -1,73 +0,0 @@ -package io.github.pylonmc.pylon.base.content.machines.hydraulics; - -import io.github.pylonmc.pylon.base.BaseFluids; -import io.github.pylonmc.pylon.base.BaseKeys; -import io.github.pylonmc.pylon.base.util.BaseUtils; -import io.github.pylonmc.pylon.core.block.context.BlockCreateContext; -import io.github.pylonmc.pylon.core.config.Settings; -import io.github.pylonmc.pylon.core.config.adapter.ConfigAdapter; -import io.github.pylonmc.pylon.core.entity.display.ItemDisplayBuilder; -import io.github.pylonmc.pylon.core.entity.display.transform.TransformBuilder; -import io.github.pylonmc.pylon.core.fluid.FluidPointType; -import io.github.pylonmc.pylon.core.i18n.PylonArgument; -import io.github.pylonmc.pylon.core.waila.WailaDisplay; -import net.kyori.adventure.text.format.TextColor; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.entity.Player; -import org.bukkit.persistence.PersistentDataContainer; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public class HydraulicCoreDrillOutputHatch extends HydraulicCoreDrillHatch { - - private final double buffer = Settings.get(BaseKeys.FLUID_TANK_CASING_COPPER) - .getOrThrow("capacity", ConfigAdapter.DOUBLE); - - @SuppressWarnings("unused") - public HydraulicCoreDrillOutputHatch(@NotNull Block block, @NotNull BlockCreateContext context) { - super(block, context); - createFluidBuffer( - BaseFluids.DIRTY_HYDRAULIC_FLUID, - buffer, - false, - true - ); - addEntity("fluid", new ItemDisplayBuilder() - .itemStack(BaseFluids.DIRTY_HYDRAULIC_FLUID.getItem()) - .transformation(new TransformBuilder().scale(0)) - .build(getBlock().getLocation().toCenterLocation().add(0, 1, 0)) - ); - createFluidPoint(FluidPointType.OUTPUT, BlockFace.NORTH, context, true); - } - - @SuppressWarnings("unused") - public HydraulicCoreDrillOutputHatch(@NotNull Block block, @NotNull PersistentDataContainer pdc) { - super(block, pdc); - } - - @Override - public void onMultiblockFormed() { - setFluidCapacity(BaseFluids.DIRTY_HYDRAULIC_FLUID, buffer); - } - - @Override - public void onMultiblockUnformed(boolean partUnloaded) { - if (!partUnloaded) { - setFluidCapacity(BaseFluids.DIRTY_HYDRAULIC_FLUID, 0); - setFluid(BaseFluids.DIRTY_HYDRAULIC_FLUID, 0); - } - } - - @Override - public @Nullable WailaDisplay getWaila(@NotNull Player player) { - return new WailaDisplay(getDefaultWailaTranslationKey().arguments( - PylonArgument.of("bars", BaseUtils.createFluidAmountBar( - fluidAmount(BaseFluids.DIRTY_HYDRAULIC_FLUID), - fluidCapacity(BaseFluids.DIRTY_HYDRAULIC_FLUID), - 20, - TextColor.fromHexString("#48459b") - )) - )); - } -} diff --git a/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/HydraulicFarmer.java b/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/HydraulicFarmer.java index b18af19a..77c7d026 100644 --- a/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/HydraulicFarmer.java +++ b/src/main/java/io/github/pylonmc/pylon/base/content/machines/hydraulics/HydraulicFarmer.java @@ -46,26 +46,27 @@ public class HydraulicFarmer extends PylonBlock implements PylonDirectionalBlock { private static final Set CROPS_TO_BREAK = EnumSet.of( - Material.PUMPKIN, - Material.MELON, - Material.CARROTS, - Material.POTATOES, - Material.WHEAT, - Material.BEETROOTS, - Material.NETHER_WART + Material.PUMPKIN, + Material.MELON, + Material.CARROTS, + Material.POTATOES, + Material.WHEAT, + Material.BEETROOTS, + Material.NETHER_WART, + Material.SUGAR_CANE ); // farmland -> crop item -> block private static final Map> CROP_TO_PLANT = Map.of( - Material.FARMLAND, Map.of( - Material.CARROT, Material.CARROTS, - Material.POTATO, Material.POTATOES, - Material.WHEAT_SEEDS, Material.WHEAT, - Material.BEETROOT_SEEDS, Material.BEETROOTS, - Material.PUMPKIN_SEEDS, Material.PUMPKIN_STEM, - Material.MELON_SEEDS, Material.MELON_STEM - ), - Material.SOUL_SAND, Map.of(Material.NETHER_WART, Material.NETHER_WART) + Material.FARMLAND, Map.of( + Material.CARROT, Material.CARROTS, + Material.POTATO, Material.POTATOES, + Material.WHEAT_SEEDS, Material.WHEAT, + Material.BEETROOT_SEEDS, Material.BEETROOTS, + Material.PUMPKIN_SEEDS, Material.PUMPKIN_STEM, + Material.MELON_SEEDS, Material.MELON_STEM + ), + Material.SOUL_SAND, Map.of(Material.NETHER_WART, Material.NETHER_WART) ); public final int radius = getSettings().getOrThrow("radius", ConfigAdapter.INT); diff --git a/src/main/java/io/github/pylonmc/pylon/base/util/BaseUtils.java b/src/main/java/io/github/pylonmc/pylon/base/util/BaseUtils.java index 2383e8a8..6d0e0fb1 100644 --- a/src/main/java/io/github/pylonmc/pylon/base/util/BaseUtils.java +++ b/src/main/java/io/github/pylonmc/pylon/base/util/BaseUtils.java @@ -95,6 +95,12 @@ private int clampAndRound(double value) { return getDisplacement(source, target).normalize(); } + public @NotNull Component createBar(double proportion, int bars, TextColor color) { + int filledBars = (int) Math.round(bars * proportion); + return Component.text("|".repeat(filledBars)).color(color) + .append(Component.text("|".repeat(bars - filledBars)).color(NamedTextColor.GRAY)); + } + public @NotNull Component createProgressBar(double progress, int bars, TextColor color) { int filledBars = (int) Math.round(bars * progress); return Component.translatable("pylon.pylonbase.gui.progress_bar.text").arguments( diff --git a/src/main/resources/lang/en.yml b/src/main/resources/lang/en.yml index 0d5c9a0f..064cf66b 100644 --- a/src/main/resources/lang/en.yml +++ b/src/main/resources/lang/en.yml @@ -1205,23 +1205,40 @@ item: 1x 1x Cauldron 1x Chest - 1x - 1x - 2x + 1x + 1x 6x Iron Bars 12x Polished Deepslate Wall - hydraulic_core_drill_input_hatch: - name: "Hydraulic Core Drill Input Hatch" + fluid_input_hatch: + name: "Fluid Input Hatch" lore: |- - Hydraulic Core Drill multiblock component - waila: "Hydraulic Core Drill Input Hatch | %bars%" + Multiblock component + Acts as a fluid input for multiblock machines + Requires a fluid casing above + waila: "Fluid Input Hatch | %info%" + + fluid_output_hatch: + name: "Fluid Output Hatch" + lore: |- + Multiblock component + Acts as a fluid output for multiblock machines + Requires a fluid casing above + waila: "Fluid Output Hatch | %info%" - hydraulic_core_drill_output_hatch: - name: "Hydraulic Core Drill Output Hatch" + item_input_hatch: + name: "Item Input Hatch" lore: |- - Hydraulic Core Drill multiblock component - waila: "Hydraulic Core Drill Output Hatch | %bars%" + Multiblock component + Acts as an item input for multiblock machines + waila: "Item Input Hatch" + + item_output_hatch: + name: "Item Output Hatch" + lore: |- + Multiblock component + Acts as an item output for multiblock machines + waila: "Item Output Hatch" shallow_core_chunk: name: "Shallow Core Chunk" @@ -1469,6 +1486,83 @@ item: Diesel buffer: %diesel-buffer% waila: "Diesel Miner | %bar%" + fermenter: + name: "Fermenter" + lore: |- + Multiblock + Ferments sugarcane into ethanol + Fermentation speed is proportional to the amount of sugarcane inside + Ethanol per sugarcane: %ethanol-per-sugarcane% + Sugarcane capacity: %sugarcane-capacity% + Maximum ethanol output rate: %max-ethanol-output-rate% + + Components + 1x + 1x + 1x + 2x Block of Iron + 4x Polished Deepslate Wall + 4x + 31x + waila: "Fermenter | %sugarcane-bar% %sugarcane-amount% sugarcane" + + fermenter_core: + name: "Fermenter Core" + lore: |- + Fermenter multiblock component + + fermenter_casing: + name: "Fermenter Casing" + lore: |- + Fermenter multiblock component + + biorefinery: + name: "Biorefinery" + lore: |- + Multiblock + Refines plant oil and ethanol into biodiesel + Requires fuel to run + Constantly consumes fuel even if not producing biodiesel + Biodiesel production rate: %biodiesel-per-second% + Ethanol per mb of biodiesel: %ethanol-per-mb-of-biodiesel% + Plant oil per mb of biodiesel: %plant-oil-per-mb-of-biodiesel% + + Components + 1x + 1x + 2x + 6x + 4x + 9x + 2x + 24x + waila: "Biorefinery | %info%" + + biorefinery_foundation: + name: "Biorefinery Foundation" + lore: |- + Biorefinery multiblock component + + biorefinery_plating: + name: "Biorefinery Plating" + lore: |- + Biorefinery multiblock component + + biorefinery_tower_ring: + name: "Biorefinery Tower Ring" + lore: |- + Biorefinery multiblock component + + biorefinery_smokestack_ring: + name: "Biorefinery Smokestack Ring" + lore: |- + Biorefinery multiblock component + + biorefinery_smokestack_cap: + name: "Biorefinery Smokestack Cap" + lore: |- + Biorefinery multiblock component + cargo_duct: name: "Cargo Duct" lore: |- @@ -1524,6 +1618,8 @@ fluid: dirty_hydraulic_fluid: "<#48459b>Dirty Hydraulic Fluid" obscyra: "<#5c4a66>Obscyra" reflector_fluid: "<#d1c9ab>Reflector Fluid" + sugarcane: "<#a3ed2d>Sugarcane" + ethanol: "<#d8d8d8>Ethanol" biodiesel: "<#eaa627>Biodiesel" waila: @@ -1603,6 +1699,7 @@ guide: hydraulics: "Hydraulic Machines" cargo: "Cargo" diesel_machines: "Diesel Machines" + diesel_production: "Diesel Production" smelting: "Smelting" machines: "Machines" building: "Building" @@ -1623,6 +1720,13 @@ message: fluid_selector: current_fluid: "Current fluid: %fluid%" clear: "Clear" + fluid_hatch: + no_casing: "No casing" + no_multiblock: "No multiblock" + working: "%bars% (%fluid%)" + biorefinery: + no_fuel: "No fuel" + has_fuel: "%fuel-bar% %remaining-time%" hammer_cant_use: "You cannot use this hammer on this block" sprinkler_too_close: "You cannot place sprinklers within %radius% blocks of each other" gained_research_points: "+%points% research points (%total% points total)" diff --git a/src/main/resources/recipes/minecraft/crafting_shaped.yml b/src/main/resources/recipes/minecraft/crafting_shaped.yml index 36f96c5c..0c3f582e 100644 --- a/src/main/resources/recipes/minecraft/crafting_shaped.yml +++ b/src/main/resources/recipes/minecraft/crafting_shaped.yml @@ -1355,30 +1355,6 @@ pylonbase:hydraulic_core_drill: result: pylonbase:hydraulic_core_drill category: building -pylonbase:hydraulic_core_drill_input_hatch: - pattern: - - "T T" - - "PO " - - "T T" - key: - T: minecraft:terracotta - P: pylonbase:fluid_pipe_bronze - O: pylonbase:backflow_valve - result: pylonbase:hydraulic_core_drill_input_hatch - category: building - -pylonbase:hydraulic_core_drill_output_hatch: - pattern: - - "T T" - - " OP" - - "T T" - key: - T: minecraft:terracotta - P: pylonbase:fluid_pipe_bronze - O: pylonbase:backflow_valve - result: pylonbase:hydraulic_core_drill_output_hatch - category: building - pylonbase:climbing_pick: pattern: - "H H" diff --git a/src/main/resources/researches.yml b/src/main/resources/researches.yml index 4b1709f1..c8465c72 100644 --- a/src/main/resources/researches.yml +++ b/src/main/resources/researches.yml @@ -164,8 +164,6 @@ hydraulic_drilling: cost: 40 unlocks: - pylonbase:hydraulic_core_drill - - pylonbase:hydraulic_core_drill_input_hatch - - pylonbase:hydraulic_core_drill_output_hatch - pylonbase:intermediate_core_chunk igneous_magic: material: obsidian diff --git a/src/main/resources/settings/biorefinery.yml b/src/main/resources/settings/biorefinery.yml new file mode 100644 index 00000000..08b54f15 --- /dev/null +++ b/src/main/resources/settings/biorefinery.yml @@ -0,0 +1,4 @@ +tick-interval: 10 +biodiesel-per-second: 150 +ethanol-per-mb-of-biodiesel: 0.8 +plant-oil-per-mb-of-biodiesel: 0.2 \ No newline at end of file diff --git a/src/main/resources/settings/fermenter.yml b/src/main/resources/settings/fermenter.yml new file mode 100644 index 00000000..2e3eca20 --- /dev/null +++ b/src/main/resources/settings/fermenter.yml @@ -0,0 +1,4 @@ +tick-interval: 10 +ethanol-per-sugarcane: 200 +sugarcane-capacity: 256 +max-ethanol-output-rate: 65 \ No newline at end of file