diff --git a/src/main/java/io/github/pylonmc/pylon/Pylon.java b/src/main/java/io/github/pylonmc/pylon/Pylon.java
index e74504208..71433f28f 100644
--- a/src/main/java/io/github/pylonmc/pylon/Pylon.java
+++ b/src/main/java/io/github/pylonmc/pylon/Pylon.java
@@ -12,6 +12,8 @@
import io.github.pylonmc.rebar.addon.RebarAddon;
import io.github.pylonmc.rebar.registry.RebarRegistry;
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents;
+import java.util.Locale;
+import java.util.Set;
import lombok.Getter;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
@@ -20,9 +22,6 @@
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
-import java.util.Locale;
-import java.util.Set;
-
import static io.github.pylonmc.pylon.util.PylonUtils.pylonKey;
public class Pylon extends JavaPlugin implements RebarAddon {
diff --git a/src/main/java/io/github/pylonmc/pylon/PylonBlocks.java b/src/main/java/io/github/pylonmc/pylon/PylonBlocks.java
index 06175390d..a95119bd4 100644
--- a/src/main/java/io/github/pylonmc/pylon/PylonBlocks.java
+++ b/src/main/java/io/github/pylonmc/pylon/PylonBlocks.java
@@ -7,6 +7,13 @@
import io.github.pylonmc.pylon.content.machines.diesel.machines.*;
import io.github.pylonmc.pylon.content.machines.diesel.production.Biorefinery;
import io.github.pylonmc.pylon.content.machines.diesel.production.Fermenter;
+import io.github.pylonmc.pylon.content.machines.electricity.Capacitor;
+import io.github.pylonmc.pylon.content.machines.electricity.ElectricityInputHatch;
+import io.github.pylonmc.pylon.content.machines.electricity.ElectricityOutputHatch;
+import io.github.pylonmc.pylon.content.machines.electricity.ElectricityPylon;
+import io.github.pylonmc.pylon.content.machines.electricity.generation.*;
+import io.github.pylonmc.pylon.content.machines.electricity.machines.ElectricBrickMolder;
+import io.github.pylonmc.pylon.content.machines.electricity.machines.ElectricGrindstone;
import io.github.pylonmc.pylon.content.machines.fluid.*;
import io.github.pylonmc.pylon.content.machines.hydraulics.*;
import io.github.pylonmc.pylon.content.machines.simple.*;
@@ -187,5 +194,18 @@ public static void initialize() {
RebarBlock.register(PylonKeys.PALLADIUM_SILO, Material.BLUE_TERRACOTTA, Silo.class);
RebarBlock.register(PylonKeys.SILO_CONVERTER, Material.STRIPPED_OAK_LOG, SiloConverter.class);
RebarBlock.register(PylonKeys.LISELETTE_COLLECTOR, Material.STRUCTURE_VOID, LiseletteCollector.class);
+ RebarBlock.register(PylonKeys.ELECTRICITY_PYLON, Material.SEA_LANTERN, ElectricityPylon.class);
+ RebarBlock.register(PylonKeys.CAPACITOR_1_KJ, Material.BLUE_GLAZED_TERRACOTTA, Capacitor.class);
+ RebarBlock.register(PylonKeys.CREATIVE_POWER_SOURCE, Material.PINK_STAINED_GLASS, CreativePowerSource.class);
+ RebarBlock.register(PylonKeys.ELECTRICITY_INPUT_HATCH, Material.GREEN_CONCRETE, ElectricityInputHatch.class);
+ RebarBlock.register(PylonKeys.ELECTRICITY_OUTPUT_HATCH, Material.ORANGE_CONCRETE, ElectricityOutputHatch.class);
+ RebarBlock.register(PylonKeys.BOILER_CASING, Material.NETHERITE_BLOCK, RebarBlock.class);
+ RebarBlock.register(PylonKeys.BOILER, Material.BLAST_FURNACE, Boiler.class);
+ RebarBlock.register(PylonKeys.STEAM_ENGINE, Material.IRON_BLOCK, SteamEngine.class);
+ RebarBlock.register(PylonKeys.GAS_TURBINE, Material.IRON_BLOCK, GasTurbine.class);
+ RebarBlock.register(PylonKeys.COMBUSTION_TOWER, Material.BRICKS, CombustionTower.class);
+ RebarBlock.register(PylonKeys.HEAT_EXCHANGER, Material.RED_NETHER_BRICK_WALL, HeatExchanger.class);
+ RebarBlock.register(PylonKeys.ELECTRIC_GRINDSTONE, Material.SMOOTH_STONE, ElectricGrindstone.class);
+ RebarBlock.register(PylonKeys.ELECTRIC_BRICK_MOLDER, Material.IRON_BLOCK, ElectricBrickMolder.class);
}
}
diff --git a/src/main/java/io/github/pylonmc/pylon/PylonFluids.java b/src/main/java/io/github/pylonmc/pylon/PylonFluids.java
index 551f0b83c..cb6d66c0a 100644
--- a/src/main/java/io/github/pylonmc/pylon/PylonFluids.java
+++ b/src/main/java/io/github/pylonmc/pylon/PylonFluids.java
@@ -11,6 +11,10 @@
import io.github.pylonmc.rebar.fluid.RebarFluid;
import io.github.pylonmc.rebar.fluid.tags.FluidTemperature;
import io.github.pylonmc.rebar.recipe.IngredientCalculator;
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+
+import static io.github.pylonmc.pylon.util.PylonUtils.pylonKey;
public final class PylonFluids {
@@ -18,6 +22,8 @@ private PylonFluids() {
throw new AssertionError("Utility class");
}
+ public static final double WATER_TO_STEAM_RATIO = 1.0 / 10.0;
+
public static final RebarFluid WATER = new RebarFluid(
pylonKey("water"),
Material.BLUE_CONCRETE
@@ -36,6 +42,14 @@ private PylonFluids() {
IngredientCalculator.addBaseIngredient(LAVA);
}
+ public static final RebarFluid STEAM = new RebarFluid(
+ pylonKey("steam"),
+ Material.WHITE_STAINED_GLASS
+ ).addTag(FluidTemperature.HOT);
+ static {
+ STEAM.register();
+ }
+
public static final RebarFluid PLANT_OIL = new RebarFluid(
pylonKey("plant_oil"),
Material.YELLOW_CONCRETE_POWDER
@@ -53,7 +67,6 @@ private PylonFluids() {
HYDRAULIC_FLUID.register();
}
-
public static final RebarFluid DIRTY_HYDRAULIC_FLUID = new RebarFluid(
pylonKey("dirty_hydraulic_fluid"),
Material.BROWN_CONCRETE_POWDER
@@ -248,6 +261,22 @@ private PylonFluids() {
SPONGE_IRON_SLURRY.register();
}
+ public static final RebarFluid VERY_HOT_EXHAUST = new RebarFluid(
+ pylonKey("very_hot_exhaust"),
+ Material.RED_STAINED_GLASS
+ ).addTag(FluidTemperature.HOT);
+ static {
+ VERY_HOT_EXHAUST.register();
+ }
+
+ public static final RebarFluid HOT_EXHAUST = new RebarFluid(
+ pylonKey("hot_exhaust"),
+ Material.ORANGE_STAINED_GLASS
+ ).addTag(FluidTemperature.HOT);
+ static {
+ HOT_EXHAUST.register();
+ }
+
/**
* Calling this function will run the static blocks
*/
diff --git a/src/main/java/io/github/pylonmc/pylon/PylonItems.java b/src/main/java/io/github/pylonmc/pylon/PylonItems.java
index 6a04aaba7..caf55ec24 100644
--- a/src/main/java/io/github/pylonmc/pylon/PylonItems.java
+++ b/src/main/java/io/github/pylonmc/pylon/PylonItems.java
@@ -16,6 +16,13 @@
import io.github.pylonmc.pylon.content.machines.diesel.machines.*;
import io.github.pylonmc.pylon.content.machines.diesel.production.Biorefinery;
import io.github.pylonmc.pylon.content.machines.diesel.production.Fermenter;
+import io.github.pylonmc.pylon.content.machines.electricity.Capacitor;
+import io.github.pylonmc.pylon.content.machines.electricity.Multimeter;
+import io.github.pylonmc.pylon.content.machines.electricity.generation.Boiler;
+import io.github.pylonmc.pylon.content.machines.electricity.generation.CombustionTower;
+import io.github.pylonmc.pylon.content.machines.electricity.generation.SteamEngine;
+import io.github.pylonmc.pylon.content.machines.electricity.machines.ElectricBrickMolder;
+import io.github.pylonmc.pylon.content.machines.electricity.machines.ElectricGrindstone;
import io.github.pylonmc.pylon.content.machines.fluid.*;
import io.github.pylonmc.pylon.content.machines.hydraulics.*;
import io.github.pylonmc.pylon.content.machines.simple.*;
@@ -48,7 +55,6 @@
import io.papermc.paper.datacomponent.item.consumable.ItemUseAnimation;
import io.papermc.paper.registry.keys.SoundEventKeys;
import io.papermc.paper.registry.keys.tags.DamageTypeTagKeys;
-import java.util.Objects;
import net.kyori.adventure.key.Key;
import org.bukkit.*;
import org.bukkit.attribute.Attribute;
@@ -3245,6 +3251,117 @@ private PylonItems() {
RecipeType.VANILLA_SHAPELESS.addRecipe(recipe);
}
+ //
+ public static final ItemStack ELECTRICITY_PYLON = ItemStackBuilder.rebar(Material.SEA_LANTERN, PylonKeys.ELECTRICITY_PYLON)
+ .build();
+ static {
+ RebarItem.register(RebarItem.class, ELECTRICITY_PYLON, PylonKeys.ELECTRICITY_PYLON);
+ PylonPages.ELECTRICITY.addItem(ELECTRICITY_PYLON);
+ }
+
+ public static final ItemStack CAPACITOR_1_KJ = ItemStackBuilder.rebar(Material.BLUE_GLAZED_TERRACOTTA, PylonKeys.CAPACITOR_1_KJ)
+ .build();
+ static {
+ RebarItem.register(Capacitor.Item.class, CAPACITOR_1_KJ, PylonKeys.CAPACITOR_1_KJ);
+ PylonPages.ELECTRICITY.addItem(CAPACITOR_1_KJ);
+ }
+
+ public static final ItemStack WIRE_1_GAUGE = ItemStackBuilder.rebar(Material.STRING, PylonKeys.WIRE_1_GAUGE)
+ .build();
+ static {
+ RebarItem.register(PylonWire.class, WIRE_1_GAUGE, PylonKeys.WIRE_1_GAUGE);
+ PylonPages.TOOLS.addItem(WIRE_1_GAUGE);
+ }
+
+ public static final ItemStack MULTIMETER = ItemStackBuilder.rebar(Material.CLOCK, PylonKeys.MULTIMETER)
+ .build();
+ static {
+ RebarItem.register(Multimeter.class, MULTIMETER, PylonKeys.MULTIMETER);
+ PylonPages.TOOLS.addItem(MULTIMETER);
+ }
+
+ public static final ItemStack CREATIVE_POWER_SOURCE = ItemStackBuilder.rebar(Material.PINK_STAINED_GLASS, PylonKeys.CREATIVE_POWER_SOURCE)
+ .build();
+ static {
+ RebarItem.register(RebarItem.class, CREATIVE_POWER_SOURCE, PylonKeys.CREATIVE_POWER_SOURCE);
+ PylonPages.CREATIVE_ITEMS.addItem(CREATIVE_POWER_SOURCE);
+ }
+
+ public static final ItemStack ELECTRICITY_INPUT_HATCH = ItemStackBuilder.rebar(Material.GREEN_CONCRETE, PylonKeys.ELECTRICITY_INPUT_HATCH)
+ .build();
+ static {
+ RebarItem.register(RebarItem.class, ELECTRICITY_INPUT_HATCH, PylonKeys.ELECTRICITY_INPUT_HATCH);
+ PylonPages.COMPONENTS.addItem(ELECTRICITY_INPUT_HATCH);
+ }
+
+ public static final ItemStack ELECTRICITY_OUTPUT_HATCH = ItemStackBuilder.rebar(Material.ORANGE_CONCRETE, PylonKeys.ELECTRICITY_OUTPUT_HATCH)
+ .build();
+ static {
+ RebarItem.register(RebarItem.class, ELECTRICITY_OUTPUT_HATCH, PylonKeys.ELECTRICITY_OUTPUT_HATCH);
+ PylonPages.COMPONENTS.addItem(ELECTRICITY_OUTPUT_HATCH);
+ }
+
+ public static final ItemStack BOILER_CASING = ItemStackBuilder.rebar(Material.NETHERITE_BLOCK, PylonKeys.BOILER_CASING)
+ .build();
+ static {
+ RebarItem.register(RebarItem.class, BOILER_CASING, PylonKeys.BOILER_CASING);
+ PylonPages.COMPONENTS.addItem(BOILER_CASING);
+ }
+
+ public static final ItemStack BOILER = ItemStackBuilder.rebar(Material.BLAST_FURNACE, PylonKeys.BOILER)
+ .build();
+ static {
+ RebarItem.register(Boiler.Item.class, BOILER, PylonKeys.BOILER);
+ PylonPages.ELECTRICITY.addItem(BOILER);
+ }
+
+ public static final ItemStack STEAM_ENGINE = ItemStackBuilder.rebar(Material.IRON_BLOCK, PylonKeys.STEAM_ENGINE)
+ .build();
+ static {
+ RebarItem.register(SteamEngine.Item.class, STEAM_ENGINE, PylonKeys.STEAM_ENGINE);
+ PylonPages.ELECTRICITY.addItem(STEAM_ENGINE);
+ }
+
+ public static final ItemStack GAS_TURBINE = ItemStackBuilder.rebar(Material.IRON_BLOCK, PylonKeys.GAS_TURBINE)
+ .build();
+ static {
+ RebarItem.register(RebarItem.class, GAS_TURBINE, PylonKeys.GAS_TURBINE);
+ PylonPages.ELECTRICITY.addItem(GAS_TURBINE);
+ RebarGuide.getOrCreateInfoPage(PylonKeys.GAS_TURBINE)
+ .addButton(new MachineRecipesButton(GAS_TURBINE, GasTurbineRecipe.RECIPE_TYPE));
+ }
+
+ public static final ItemStack COMBUSTION_TOWER = ItemStackBuilder.rebar(Material.BRICKS, PylonKeys.COMBUSTION_TOWER)
+ .build();
+ static {
+ RebarItem.register(CombustionTower.Item.class, COMBUSTION_TOWER, PylonKeys.COMBUSTION_TOWER);
+ PylonPages.ELECTRICITY.addItem(COMBUSTION_TOWER);
+ }
+
+ public static final ItemStack HEAT_EXCHANGER = ItemStackBuilder.rebar(Material.RED_NETHER_BRICK_WALL, PylonKeys.HEAT_EXCHANGER)
+ .build();
+ static {
+ RebarItem.register(RebarItem.class, HEAT_EXCHANGER, PylonKeys.HEAT_EXCHANGER);
+ PylonPages.ELECTRICITY.addItem(HEAT_EXCHANGER);
+ }
+
+ public static final ItemStack ELECTRIC_GRINDSTONE = ItemStackBuilder.rebar(Material.SMOOTH_STONE, PylonKeys.ELECTRIC_GRINDSTONE)
+ .build();
+ static {
+ RebarItem.register(ElectricGrindstone.Item.class, ELECTRIC_GRINDSTONE, PylonKeys.ELECTRIC_GRINDSTONE);
+ PylonPages.ELECTRICITY.addItem(ELECTRIC_GRINDSTONE);
+ RebarGuide.getOrCreateInfoPage(PylonKeys.ELECTRIC_GRINDSTONE)
+ .addButton(new MachineRecipesButton(ELECTRIC_GRINDSTONE, GrindstoneRecipe.RECIPE_TYPE));
+ }
+
+ public static final ItemStack ELECTRIC_BRICK_MOLDER = ItemStackBuilder.rebar(Material.IRON_BLOCK, PylonKeys.ELECTRIC_BRICK_MOLDER)
+ .build();
+ static {
+ RebarItem.register(ElectricBrickMolder.Item.class, ELECTRIC_BRICK_MOLDER, PylonKeys.ELECTRIC_BRICK_MOLDER);
+ PylonPages.ELECTRICITY.addItem(ELECTRIC_BRICK_MOLDER);
+ }
+ //
+
static {
PylonPages.initialise();
PylonHelpPages.initialise();
diff --git a/src/main/java/io/github/pylonmc/pylon/PylonKeys.java b/src/main/java/io/github/pylonmc/pylon/PylonKeys.java
index 6f16fc675..692229c0d 100644
--- a/src/main/java/io/github/pylonmc/pylon/PylonKeys.java
+++ b/src/main/java/io/github/pylonmc/pylon/PylonKeys.java
@@ -472,4 +472,20 @@ public class PylonKeys {
public static final NamespacedKey PALLADIUM_SILO = pylonKey("palladium_silo");
public static final NamespacedKey FINE_SEDIMENT = pylonKey("fine_sediment");
+
+ public static final NamespacedKey ELECTRICITY_PYLON = pylonKey("electricity_pylon");
+ public static final NamespacedKey CAPACITOR_1_KJ = pylonKey("capacitor_1_kj");
+ public static final NamespacedKey MULTIMETER = pylonKey("multimeter");
+ public static final NamespacedKey WIRE_1_GAUGE = pylonKey("wire_1_gauge");
+ public static final NamespacedKey CREATIVE_POWER_SOURCE = pylonKey("creative_power_source");
+ public static final NamespacedKey ELECTRICITY_INPUT_HATCH = pylonKey("electricity_input_hatch");
+ public static final NamespacedKey ELECTRICITY_OUTPUT_HATCH = pylonKey("electricity_output_hatch");
+ public static final NamespacedKey BOILER_CASING = pylonKey("boiler_casing");
+ public static final NamespacedKey BOILER = pylonKey("boiler");
+ public static final NamespacedKey STEAM_ENGINE = pylonKey("steam_engine");
+ public static final NamespacedKey GAS_TURBINE = pylonKey("gas_turbine");
+ public static final NamespacedKey COMBUSTION_TOWER = pylonKey("combustion_tower");
+ public static final NamespacedKey HEAT_EXCHANGER = pylonKey("heat_exchanger");
+ public static final NamespacedKey ELECTRIC_GRINDSTONE = pylonKey("electric_grindstone");
+ public static final NamespacedKey ELECTRIC_BRICK_MOLDER = pylonKey("electric_brick_molder");
}
\ No newline at end of file
diff --git a/src/main/java/io/github/pylonmc/pylon/PylonPages.java b/src/main/java/io/github/pylonmc/pylon/PylonPages.java
index 475ddb62d..4d4e51e37 100644
--- a/src/main/java/io/github/pylonmc/pylon/PylonPages.java
+++ b/src/main/java/io/github/pylonmc/pylon/PylonPages.java
@@ -35,6 +35,7 @@ public class PylonPages {
public static final SimpleStaticGuidePage CARGO = new SimpleStaticGuidePage(pylonKey("machines_cargo"));
public static final SimpleStaticGuidePage DIESEL_MACHINES = new SimpleStaticGuidePage(pylonKey("machines_diesel_machines"));
public static final SimpleStaticGuidePage DIESEL_PRODUCTION = new SimpleStaticGuidePage(pylonKey("machines_diesel_production"));
+ public static final SimpleStaticGuidePage ELECTRICITY = new SimpleStaticGuidePage(pylonKey("machines_electricity"));
public static final SimpleStaticGuidePage MACHINES = new SimpleStaticGuidePage(pylonKey("machines"));
public static final SimpleStaticGuidePage ASSEMBLING = new SimpleStaticGuidePage(pylonKey("assembling"));
@@ -72,6 +73,7 @@ public static void initialise() {
MACHINES.addPage(PylonItems.CARGO_BUFFER, CARGO);
MACHINES.addPage(PylonItems.DIESEL_PIPE_BENDER, DIESEL_MACHINES);
MACHINES.addPage(PylonItems.BIOREFINERY, DIESEL_PRODUCTION);
+ MACHINES.addPage(PylonItems.ELECTRICITY_PYLON, ELECTRICITY);
RebarGuide.getRootPage().addPage(PylonItems.MIXING_POT, MACHINES);
RebarGuide.getRootPage().addPage(PylonItems.ASSEMBLY_TABLE, ASSEMBLING);
diff --git a/src/main/java/io/github/pylonmc/pylon/PylonRecipes.java b/src/main/java/io/github/pylonmc/pylon/PylonRecipes.java
index d46adfd3f..537237bb2 100644
--- a/src/main/java/io/github/pylonmc/pylon/PylonRecipes.java
+++ b/src/main/java/io/github/pylonmc/pylon/PylonRecipes.java
@@ -5,6 +5,7 @@
import io.github.pylonmc.rebar.config.Config;
import io.github.pylonmc.rebar.config.Settings;
import io.github.pylonmc.rebar.config.adapter.ConfigAdapter;
+import io.github.pylonmc.rebar.fluid.FluidWithAmount;
import io.github.pylonmc.rebar.guide.button.FluidButton;
import io.github.pylonmc.rebar.guide.button.ItemButton;
import io.github.pylonmc.rebar.recipe.FluidOrItem;
@@ -45,12 +46,16 @@ public static void initialize() {
SiloConverterRecipe.RECIPE_TYPE.register();
HydraulicPurifier.RECIPE_TYPE.register();
FormingRecipe.RECIPE_TYPE.register();
+ GasTurbineRecipe.RECIPE_TYPE.register();
+ HeatExchangerRecipe.RECIPE_TYPE.register();
//hardcoded
initCollimator();
initPalladiumCondenser();
initBiorefinery();
initFermenter();
+ initBoiler();
+ initCombustionTower();
}
private static void initCollimator() {
@@ -77,6 +82,31 @@ private static void initCollimator() {
).register();
}
+ private static void initBoiler() {
+ NamespacedKey key = PylonKeys.BOILER;
+ double steamPerSecond = Settings.get(key).getOrThrow("steam-per-second", ConfigAdapter.DOUBLE);
+ RecipeInput.Fluid input = RecipeInput.of(PylonFluids.WATER, steamPerSecond * PylonFluids.WATER_TO_STEAM_RATIO);
+ FluidWithAmount output = new FluidWithAmount(PylonFluids.STEAM, steamPerSecond);
+ new SingleRecipe(
+ key,
+ input,
+ output.asFluidOrItem(),
+ () -> Gui.builder()
+ .setStructure(
+ "# # # # # # # # #",
+ "# # # # # # # # #",
+ "# i # # x # # o #",
+ "# # # # # # # # #",
+ "# # # # # # # # #"
+ )
+ .addIngredient('#', GuiItems.backgroundBlack())
+ .addIngredient('i', new FluidButton(input))
+ .addIngredient('x', ItemButton.from(PylonItems.BOILER))
+ .addIngredient('o', new FluidButton(output))
+ .build()
+ ).register();
+ }
+
private static void initPalladiumCondenser() {
NamespacedKey key = PylonKeys.PALLADIUM_CONDENSER;
Config setting = Settings.get(key);
@@ -182,4 +212,34 @@ private static void initFermenter() {
.build()
).register();
}
+
+ private static void initCombustionTower() {
+ NamespacedKey key = PylonKeys.COMBUSTION_TOWER;
+ Config setting = Settings.get(key);
+
+ double dieselUsage = setting.getOrThrow("diesel-usage", ConfigAdapter.DOUBLE);
+ double exhaustProduction = setting.getOrThrow("exhaust-production", ConfigAdapter.DOUBLE);
+
+ RecipeInput.Fluid input = RecipeInput.of(PylonFluids.BIODIESEL, dieselUsage);
+ FluidWithAmount output = new FluidWithAmount(PylonFluids.VERY_HOT_EXHAUST, exhaustProduction);
+
+ new SingleRecipe(
+ key,
+ input,
+ output.asFluidOrItem(),
+ () -> Gui.builder()
+ .setStructure(
+ "# # # # # # # # #",
+ "# # # # # # # # #",
+ "# d # # x # # e #",
+ "# # # # # # # # #",
+ "# # # # # # # # #"
+ )
+ .addIngredient('#', GuiItems.backgroundBlack())
+ .addIngredient('d', new FluidButton(input))
+ .addIngredient('x', ItemButton.from(PylonItems.COMBUSTION_TOWER))
+ .addIngredient('e', new FluidButton(output))
+ .build()
+ ).register();
+ }
}
diff --git a/src/main/java/io/github/pylonmc/pylon/content/components/FluidHatch.java b/src/main/java/io/github/pylonmc/pylon/content/components/FluidHatch.java
index 63440849e..d96f5d517 100644
--- a/src/main/java/io/github/pylonmc/pylon/content/components/FluidHatch.java
+++ b/src/main/java/io/github/pylonmc/pylon/content/components/FluidHatch.java
@@ -7,7 +7,7 @@
import io.github.pylonmc.rebar.block.BlockStorage;
import io.github.pylonmc.rebar.block.RebarBlock;
import io.github.pylonmc.rebar.block.base.RebarDirectionalBlock;
-import io.github.pylonmc.rebar.block.base.RebarFluidBufferBlock;
+import io.github.pylonmc.rebar.block.base.RebarFluidBlock;
import io.github.pylonmc.rebar.block.base.RebarSimpleMultiblock;
import io.github.pylonmc.rebar.block.context.BlockBreakContext;
import io.github.pylonmc.rebar.block.context.BlockCreateContext;
@@ -16,12 +16,14 @@
import io.github.pylonmc.rebar.entity.display.transform.TransformBuilder;
import io.github.pylonmc.rebar.fluid.RebarFluid;
import io.github.pylonmc.rebar.i18n.RebarArgument;
-import io.github.pylonmc.rebar.item.RebarItem;
import io.github.pylonmc.rebar.item.RebarItemSchema;
import io.github.pylonmc.rebar.registry.RebarRegistry;
import io.github.pylonmc.rebar.util.RebarUtils;
import io.github.pylonmc.rebar.waila.Waila;
import io.github.pylonmc.rebar.waila.WailaDisplay;
+import java.util.*;
+import kotlin.Pair;
+import lombok.Getter;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextColor;
import org.bukkit.Bukkit;
@@ -31,28 +33,36 @@
import org.bukkit.entity.ItemDisplay;
import org.bukkit.entity.Player;
import org.bukkit.persistence.PersistentDataContainer;
+import org.jetbrains.annotations.ApiStatus;
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 java.util.Objects;
-
import static io.github.pylonmc.pylon.util.PylonUtils.pylonKey;
public abstract class FluidHatch extends RebarBlock implements
- RebarFluidBufferBlock,
+ RebarFluidBlock,
RebarSimpleMultiblock,
RebarDirectionalBlock {
+ private static final NamespacedKey ALLOWED_FLUIDS_KEY = pylonKey("allowed_fluids");
private static final NamespacedKey FLUID_KEY = pylonKey("fluid");
+ private static final NamespacedKey FLUID_AMOUNT_KEY = pylonKey("fluid_amount");
+ private static final NamespacedKey CAPACITY_KEY = pylonKey("capacity");
private static MultiblockComponent component;
- public @Nullable RebarFluid fluid;
+ @Getter
+ private Set allowedFluids = new HashSet<>();
+
+ @Getter
+ private @Nullable RebarFluid fluid;
+
+ @Getter
+ private double fluidAmount = 0;
+
+ @Getter
+ private double capacity = 0;
static {
// run on first tick after all addons registered
@@ -77,14 +87,21 @@ public FluidHatch(@NotNull Block block, @NotNull BlockCreateContext context) {
);
}
+ @SuppressWarnings("DataFlowIssue")
public FluidHatch(@NotNull Block block, @NotNull PersistentDataContainer pdc) {
super(block, pdc);
+ allowedFluids = pdc.get(ALLOWED_FLUIDS_KEY, RebarSerializers.SET.setTypeFrom(RebarSerializers.REBAR_FLUID));
fluid = pdc.get(FLUID_KEY, RebarSerializers.REBAR_FLUID);
+ fluidAmount = pdc.get(FLUID_AMOUNT_KEY, RebarSerializers.DOUBLE);
+ capacity = pdc.get(CAPACITY_KEY, RebarSerializers.DOUBLE);
}
@Override
public void write(@NotNull PersistentDataContainer pdc) {
+ pdc.set(ALLOWED_FLUIDS_KEY, RebarSerializers.SET.setTypeFrom(RebarSerializers.REBAR_FLUID), allowedFluids);
RebarUtils.setNullable(pdc, FLUID_KEY, RebarSerializers.REBAR_FLUID, fluid);
+ pdc.set(FLUID_AMOUNT_KEY, RebarSerializers.DOUBLE, fluidAmount);
+ pdc.set(CAPACITY_KEY, RebarSerializers.DOUBLE, capacity);
}
@Override
@@ -100,10 +117,7 @@ public boolean 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);
- }
+ setCapacity(casing.capacity);
}
return formed;
}
@@ -113,7 +127,7 @@ public void onMultiblockUnformed(boolean partUnloaded) {
RebarSimpleMultiblock.super.onMultiblockUnformed(partUnloaded);
Waila.removeWailaOverride(getBlock().getRelative(BlockFace.UP));
if (fluid != null) {
- setFluidCapacity(fluid, 0);
+ setCapacity(0);
getFluidDisplay().setTransformationMatrix(new TransformBuilder()
.scale(0, 0, 0)
.buildForItemDisplay()
@@ -122,10 +136,59 @@ public void onMultiblockUnformed(boolean partUnloaded) {
}
@Override
- public boolean setFluid(@NotNull RebarFluid fluid, double amount) {
- boolean result = RebarFluidBufferBlock.super.setFluid(fluid, amount);
- float scale = (float) (0.9 * fluidAmount(fluid) / fluidCapacity(fluid));
+ public @NotNull List<@NotNull Pair> getSuppliedFluids() {
+ if (fluid == null || fluidAmount <= 1e-6) {
+ return List.of();
+ }
+ return List.of(new Pair<>(fluid, fluidAmount));
+ }
+
+ @Override
+ public double fluidAmountRequested(@NotNull RebarFluid fluid) {
+ if (Objects.equals(this.fluid, fluid)) {
+ return capacity - fluidAmount;
+ } else if (allowedFluids.contains(fluid)) {
+ return capacity;
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Implementation of {@link RebarFluidBlock}. Use {@link #addFluid} instead.
+ */
+ @ApiStatus.Internal
+ @Override
+ public void onFluidAdded(@NotNull RebarFluid fluid, double amount) {
+ setFluid(fluid, fluidAmount + amount);
+ }
+
+ /**
+ * Implementation of {@link RebarFluidBlock}. Use {@link #removeFluid} instead.
+ */
+ @ApiStatus.Internal
+ @Override
+ public void onFluidRemoved(@NotNull RebarFluid fluid, double amount) {
+ setFluid(fluid, fluidAmount - amount);
+ }
+
+ public void addFluid(@NotNull RebarFluid fluid, double amount) {
+ onFluidAdded(fluid, amount);
+ }
+
+ public void removeFluid(double amount) {
+ if (fluid != null) {
+ onFluidRemoved(fluid, amount);
+ }
+ }
+
+ public void setFluid(@NotNull RebarFluid fluid, double amount) {
+ this.fluid = fluid;
+ this.fluidAmount = Math.min(amount, capacity);
+ float scale = (float) (0.9 * fluidAmount / capacity);
if (scale < RebarUtils.FLUID_EPSILON) {
+ this.fluid = null;
+ this.fluidAmount = 0;
getFluidDisplay().setItemStack(null);
} else {
getFluidDisplay().setItemStack(fluid.getItem());
@@ -135,7 +198,14 @@ public boolean setFluid(@NotNull RebarFluid fluid, double amount) {
.scale(0.9, scale, 0.9)
.buildForItemDisplay()
);
- return result;
+ }
+
+ public double getFluidSpaceRemaining() {
+ if (fluid == null) {
+ return capacity;
+ } else {
+ return capacity - fluidAmount;
+ }
}
@Override
@@ -144,13 +214,13 @@ public boolean setFluid(@NotNull RebarFluid fluid, double amount) {
if (!isFormedAndFullyLoaded()) {
info = Component.translatable("pylon.message.fluid_hatch.no_casing");
} else if (fluid == null) {
- info = Component.translatable("pylon.message.fluid_hatch.no_multiblock");
+ info = Component.translatable("pylon.message.fluid_hatch.empty");
} else {
info = Component.translatable("pylon.message.fluid_hatch.working")
.arguments(
RebarArgument.of("bars", PylonUtils.createFluidAmountBar(
- fluidAmount(fluid),
- fluidCapacity(fluid),
+ fluidAmount,
+ capacity,
20,
TextColor.color(200, 255, 255)
)),
@@ -162,27 +232,32 @@ public boolean setFluid(@NotNull RebarFluid fluid, double amount) {
));
}
- public void setFluidType(@Nullable RebarFluid fluid) {
- if (Objects.equals(this.fluid, fluid)) {
- return;
- }
-
- if (this.fluid != null) {
- deleteFluidBuffer(this.fluid);
+ public void setAllowedFluids(@NotNull RebarFluid @NotNull ... fluids) {
+ setAllowedFluids(Set.of(fluids));
+ }
+
+ public void setAllowedFluids(@NotNull Set fluids) {
+ this.allowedFluids = fluids;
+
+ if (this.fluid != null && !fluids.contains(this.fluid)) {
+ fluid = null;
+ setCapacity(0);
getFluidDisplay().setTransformationMatrix(new TransformBuilder()
.scale(0, 0, 0)
.buildForItemDisplay()
);
+ this.fluid = null;
}
- 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);
- }
+ checkFormed();
+ }
+
+ public boolean canAcceptFluid(@NotNull RebarFluid fluid) {
+ return fluidAmount < capacity && ((this.fluid == null && allowedFluids.contains(fluid)) || Objects.equals(this.fluid, fluid));
+ }
+
+ private void setCapacity(double capacity) {
+ this.capacity = capacity;
+ this.fluidAmount = Math.min(this.fluidAmount, capacity);
}
public @NotNull ItemDisplay getFluidDisplay() {
@@ -191,7 +266,6 @@ public void setFluidType(@Nullable RebarFluid fluid) {
@Override
public void postBreak(@NotNull BlockBreakContext context) {
- RebarFluidBufferBlock.super.postBreak(context);
Waila.removeWailaOverride(getBlock().getRelative(BlockFace.UP));
}
}
diff --git a/src/main/java/io/github/pylonmc/pylon/content/components/LiseletteCollector.java b/src/main/java/io/github/pylonmc/pylon/content/components/LiseletteCollector.java
index d1e613c3d..d46a2ec57 100644
--- a/src/main/java/io/github/pylonmc/pylon/content/components/LiseletteCollector.java
+++ b/src/main/java/io/github/pylonmc/pylon/content/components/LiseletteCollector.java
@@ -41,7 +41,7 @@ public LiseletteCollector(@NotNull Block block, @NotNull PersistentDataContainer
}
@Override
- protected void postLoad() {
+ protected void postLoad(@NotNull PersistentDataContainer pdc) {
getHeldEntityOrThrow(ItemDisplay.class, "shell")
.setBrightness(new Display.Brightness(15, 15));
}
diff --git a/src/main/java/io/github/pylonmc/pylon/content/machines/cargo/CargoAccumulator.java b/src/main/java/io/github/pylonmc/pylon/content/machines/cargo/CargoAccumulator.java
index 5c7bac55a..7fb2a62e3 100644
--- a/src/main/java/io/github/pylonmc/pylon/content/machines/cargo/CargoAccumulator.java
+++ b/src/main/java/io/github/pylonmc/pylon/content/machines/cargo/CargoAccumulator.java
@@ -1,6 +1,7 @@
package io.github.pylonmc.pylon.content.machines.cargo;
import com.google.common.base.Preconditions;
+import io.github.pylonmc.pylon.util.NumberInputButton;
import io.github.pylonmc.rebar.block.RebarBlock;
import io.github.pylonmc.rebar.block.base.RebarCargoBlock;
import io.github.pylonmc.rebar.block.base.RebarDirectionalBlock;
@@ -26,17 +27,12 @@
import org.bukkit.block.Block;
import org.bukkit.entity.BlockDisplay;
import org.bukkit.entity.Player;
-import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataContainer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jspecify.annotations.NonNull;
-import xyz.xenondevs.invui.Click;
import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.inventory.VirtualInventory;
-import xyz.xenondevs.invui.item.AbstractItem;
-import xyz.xenondevs.invui.item.ItemProvider;
import java.util.Arrays;
import java.util.List;
@@ -66,8 +62,6 @@ public class CargoAccumulator extends RebarBlock implements
.addCustomModelDataString(getKey() + ":input");
public final ItemStackBuilder outputStack = ItemStackBuilder.of(Material.RED_TERRACOTTA)
.addCustomModelDataString(getKey() + ":output");
- public final ItemStackBuilder thresholdButtonStack = ItemStackBuilder.gui(Material.WHITE_CONCRETE, getKey() + "threshold_button")
- .lore(Component.translatable("pylon.gui.threshold_button.lore"));
public static class Item extends RebarItem {
@@ -176,7 +170,17 @@ public void write(@NotNull PersistentDataContainer pdc) {
.addIngredient('I', GuiItems.input())
.addIngredient('o', outputInventory)
.addIngredient('O', GuiItems.output())
- .addIngredient('t', new ThresholdButton())
+ .addIngredient('t', NumberInputButton.builder()
+ .material(Material.WHITE_CONCRETE)
+ .name(Component.translatable("pylon.gui.threshold"))
+ .increment(1)
+ .shiftIncrement(10)
+ .min(1)
+ .valueGetter(() -> threshold)
+ .valueSetter(value -> threshold = value)
+ .valueFormatter(UnitFormat.ITEMS::format)
+ .reopenWindow(this::openWindow)
+ .build())
.build();
}
@@ -249,26 +253,4 @@ private void doTransfer() {
.setBlock(Material.REDSTONE_LAMP.createBlockData("[lit=true]"));
}
}
-
- public class ThresholdButton extends AbstractItem {
-
- @Override
- public @NonNull ItemProvider getItemProvider(@NonNull Player viewer) {
- return thresholdButtonStack
- .name((Component.translatable("pylon.gui.threshold_button.name").arguments(
- RebarArgument.of("threshold", threshold)
- )));
- }
-
- @Override
- public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull Click click) {
- if (clickType.isLeftClick()) {
- threshold += 1;
- } else {
- threshold = Math.max(1, threshold - 1);
- }
- notifyWindows();
- doTransfer();
- }
- }
}
diff --git a/src/main/java/io/github/pylonmc/pylon/content/machines/cargo/CargoFluidAccumulator.java b/src/main/java/io/github/pylonmc/pylon/content/machines/cargo/CargoFluidAccumulator.java
index 4c6c64fff..d8c2d8780 100644
--- a/src/main/java/io/github/pylonmc/pylon/content/machines/cargo/CargoFluidAccumulator.java
+++ b/src/main/java/io/github/pylonmc/pylon/content/machines/cargo/CargoFluidAccumulator.java
@@ -1,6 +1,7 @@
package io.github.pylonmc.pylon.content.machines.cargo;
import com.google.common.base.Preconditions;
+import io.github.pylonmc.pylon.util.NumberInputButton;
import io.github.pylonmc.pylon.util.PylonUtils;
import io.github.pylonmc.rebar.block.RebarBlock;
import io.github.pylonmc.rebar.block.base.*;
@@ -29,17 +30,12 @@
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
-import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataContainer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jspecify.annotations.NonNull;
-import xyz.xenondevs.invui.Click;
import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.inventory.VirtualInventory;
-import xyz.xenondevs.invui.item.AbstractItem;
-import xyz.xenondevs.invui.item.ItemProvider;
import java.util.Arrays;
import java.util.List;
@@ -77,10 +73,6 @@ public class CargoFluidAccumulator extends RebarBlock implements
.addCustomModelDataString(getKey() + ":input");
public final ItemStackBuilder outputStack = ItemStackBuilder.of(Material.RED_TERRACOTTA)
.addCustomModelDataString(getKey() + ":output");
- public final ItemStackBuilder itemThresholdButtonStack = ItemStackBuilder.gui(Material.WHITE_CONCRETE, getKey() + "item_threshold_button")
- .lore(Component.translatable("pylon.gui.item_threshold_button.lore"));
- public final ItemStackBuilder fluidThresholdButtonStack = ItemStackBuilder.gui(Material.WHITE_CONCRETE, getKey() + "fluid_threshold_button")
- .lore(Component.translatable("pylon.gui.fluid_threshold_button.lore"));
public static class Item extends RebarItem {
@@ -163,7 +155,7 @@ public CargoFluidAccumulator(@NotNull Block block, @NotNull BlockCreateContext c
allowFluidInputs = true;
}
- @SuppressWarnings("unused")
+ @SuppressWarnings({"unused", "DataFlowIssue"})
public CargoFluidAccumulator(@NotNull Block block, @NotNull PersistentDataContainer pdc) {
super(block, pdc);
itemThreshold = pdc.get(ITEM_THRESHOLD_KEY, RebarSerializers.INTEGER);
@@ -232,8 +224,30 @@ public boolean isAllowedFluid(@NotNull RebarFluid fluid) {
.addIngredient('I', GuiItems.input())
.addIngredient('o', outputInventory)
.addIngredient('O', GuiItems.output())
- .addIngredient('t', new ItemThresholdButton())
- .addIngredient('T', new FluidThresholdButton())
+ .addIngredient('t', NumberInputButton.builder()
+ .material(Material.WHITE_CONCRETE)
+ .name(Component.translatable("pylon.gui.item-threshold"))
+ .increment(1)
+ .shiftIncrement(10)
+ .min(1)
+ .max(64)
+ .valueGetter(() -> itemThreshold)
+ .valueSetter(value -> itemThreshold = value)
+ .valueFormatter(UnitFormat.ITEMS::format)
+ .reopenWindow(this::openWindow)
+ .build())
+ .addIngredient('T', NumberInputButton.builder()
+ .material(Material.WHITE_CONCRETE)
+ .name(Component.translatable("pylon.gui.fluid-threshold"))
+ .increment(10)
+ .shiftIncrement(100)
+ .min(10)
+ .max(fluidBuffer)
+ .valueGetter(() -> fluidThreshold)
+ .valueSetter(value -> fluidThreshold = value)
+ .valueFormatter(UnitFormat.MILLIBUCKETS::format)
+ .reopenWindow(this::openWindow)
+ .build())
.build();
}
@@ -309,49 +323,4 @@ private void doTransfer() {
allowFluidInputs = false;
}
}
-
- public class ItemThresholdButton extends AbstractItem {
-
- @Override
- public @NonNull ItemProvider getItemProvider(@NotNull Player viewer) {
- return itemThresholdButtonStack
- .name((Component.translatable("pylon.gui.item_threshold_button.name").arguments(
- RebarArgument.of("threshold", itemThreshold)
- )));
- }
-
- @Override
- public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull Click click) {
- if (clickType.isLeftClick()) {
- itemThreshold += 1;
- } else {
- itemThreshold = Math.max(1, itemThreshold - 1);
- }
- notifyWindows();
- doTransfer();
- }
- }
-
- public class FluidThresholdButton extends AbstractItem {
-
- @Override
- public @NonNull ItemProvider getItemProvider(@NotNull Player viewer) {
- return fluidThresholdButtonStack
- .name((Component.translatable("pylon.gui.fluid_threshold_button.name").arguments(
- RebarArgument.of("threshold", fluidThreshold)
- )));
- }
-
- @Override
- public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull Click click) {
- int amount = clickType.isShiftClick() ? 100 : 10;
- if (clickType.isLeftClick()) {
- fluidThreshold = Math.min(fluidBuffer, fluidThreshold + amount);
- } else {
- fluidThreshold = Math.min(fluidBuffer, Math.max(10, fluidThreshold - amount));
- }
- notifyWindows();
- doTransfer();
- }
- }
}
diff --git a/src/main/java/io/github/pylonmc/pylon/content/machines/cargo/CargoGate.java b/src/main/java/io/github/pylonmc/pylon/content/machines/cargo/CargoGate.java
index f308e8644..7ebcbc161 100644
--- a/src/main/java/io/github/pylonmc/pylon/content/machines/cargo/CargoGate.java
+++ b/src/main/java/io/github/pylonmc/pylon/content/machines/cargo/CargoGate.java
@@ -1,5 +1,6 @@
package io.github.pylonmc.pylon.content.machines.cargo;
+import io.github.pylonmc.pylon.util.NumberInputButton;
import io.github.pylonmc.rebar.block.RebarBlock;
import io.github.pylonmc.rebar.block.base.RebarCargoBlock;
import io.github.pylonmc.rebar.block.base.RebarDirectionalBlock;
@@ -28,17 +29,12 @@
import org.bukkit.block.BlockFace;
import org.bukkit.entity.BlockDisplay;
import org.bukkit.entity.Player;
-import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataContainer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jspecify.annotations.NonNull;
-import xyz.xenondevs.invui.Click;
import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.inventory.VirtualInventory;
-import xyz.xenondevs.invui.item.AbstractItem;
-import xyz.xenondevs.invui.item.ItemProvider;
import java.util.List;
import java.util.Map;
@@ -77,30 +73,6 @@ public class CargoGate extends RebarBlock implements
.name(Component.translatable("pylon.gui.left"));
public final ItemStackBuilder rightStack = ItemStackBuilder.gui(Material.LIGHT_BLUE_STAINED_GLASS_PANE, getKey() + "right")
.name(Component.translatable("pylon.gui.right"));
- public final ItemStackBuilder thresholdButtonStack = ItemStackBuilder.gui(Material.WHITE_CONCRETE, getKey() + "threshold_button")
- .lore(Component.translatable("pylon.gui.threshold_button.lore"));
-
- public class ThresholdButton extends AbstractItem {
-
- @Override
- public @NonNull ItemProvider getItemProvider(@NotNull Player viewer) {
- return thresholdButtonStack
- .name((Component.translatable("pylon.gui.threshold_button.name").arguments(
- RebarArgument.of("threshold", threshold)
- )));
- }
-
- @Override
- public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull Click click) {
- if (clickType.isLeftClick()) {
- threshold += 1;
- } else {
- threshold = Math.max(1, threshold - 1);
- }
- itemsRemaining = threshold;
- notifyWindows();
- }
- }
public static class Item extends RebarItem {
@@ -213,7 +185,17 @@ public void write(@NotNull PersistentDataContainer pdc) {
.addIngredient('o', outputInventory)
.addIngredient('R', rightStack)
.addIngredient('r', rightInventory)
- .addIngredient('t', new ThresholdButton())
+ .addIngredient('t', NumberInputButton.builder()
+ .material(Material.WHITE_CONCRETE)
+ .name(Component.translatable("pylon.gui.threshold"))
+ .increment(1)
+ .shiftIncrement(10)
+ .min(1)
+ .valueGetter(() -> threshold)
+ .valueSetter(value -> threshold = value)
+ .valueFormatter(UnitFormat.ITEMS::format)
+ .reopenWindow(this::openWindow)
+ .build())
.build();
}
diff --git a/src/main/java/io/github/pylonmc/pylon/content/machines/cargo/CargoMeter.java b/src/main/java/io/github/pylonmc/pylon/content/machines/cargo/CargoMeter.java
index 0032d9e75..902db512b 100644
--- a/src/main/java/io/github/pylonmc/pylon/content/machines/cargo/CargoMeter.java
+++ b/src/main/java/io/github/pylonmc/pylon/content/machines/cargo/CargoMeter.java
@@ -1,5 +1,6 @@
package io.github.pylonmc.pylon.content.machines.cargo;
+import io.github.pylonmc.pylon.util.NumberInputButton;
import io.github.pylonmc.pylon.util.PylonUtils;
import io.github.pylonmc.rebar.block.RebarBlock;
import io.github.pylonmc.rebar.block.base.*;
@@ -27,18 +28,13 @@
import org.bukkit.entity.ItemDisplay;
import org.bukkit.entity.Player;
import org.bukkit.entity.TextDisplay;
-import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataContainer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.joml.Vector3d;
-import org.jspecify.annotations.NonNull;
-import xyz.xenondevs.invui.Click;
import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.inventory.VirtualInventory;
-import xyz.xenondevs.invui.item.AbstractItem;
-import xyz.xenondevs.invui.item.ItemProvider;
import java.time.Duration;
import java.util.ArrayList;
@@ -242,7 +238,18 @@ public void postInitialise() {
)
.addIngredient('#', GuiItems.background())
.addIngredient('x', inventory)
- .addIngredient('m', new MeasurementDurationItem())
+ .addIngredient('m', NumberInputButton.builder()
+ .material(Material.WHITE_CONCRETE)
+ .name(Component.translatable("pylon.gui.measurement-duration"))
+ .increment(1)
+ .shiftIncrement(10)
+ .min(minNumberOfMeasurements)
+ .max(maxNumberOfMeasurements)
+ .valueGetter(() -> numberOfMeasurements)
+ .valueSetter(value -> numberOfMeasurements = value)
+ .valueFormatter(value -> UnitFormat.formatDuration(getDuration(value), true, true))
+ .reopenWindow(this::openWindow)
+ .build())
.build();
}
@@ -278,30 +285,4 @@ public void tick() {
public static Duration getDuration(int numberOfMeasurements) {
return Duration.ofMillis((long) numberOfMeasurements * RebarConfig.CARGO_TICK_INTERVAL * 50);
}
-
- public class MeasurementDurationItem extends AbstractItem {
-
- @Override
- public @NonNull ItemProvider getItemProvider(@NotNull Player viewer) {
- return ItemStackBuilder.of(Material.WHITE_CONCRETE)
- .name(Component.translatable("pylon.gui.fluid_meter.name").arguments(
- RebarArgument.of("measurement-duration", UnitFormat.formatDuration(getDuration(numberOfMeasurements), true, true))
- ))
- .lore(Component.translatable("pylon.gui.fluid_meter.lore"));
- }
-
- @Override
- public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull Click click) {
- int newValue;
- if (clickType.isLeftClick()) {
- newValue = numberOfMeasurements + (clickType.isShiftClick() ? 10 : 1);
- } else if (clickType.isRightClick()) {
- newValue = numberOfMeasurements + (clickType.isShiftClick() ? -10 : -1);
- } else {
- newValue = numberOfMeasurements;
- }
- numberOfMeasurements = Math.clamp(newValue, minNumberOfMeasurements, maxNumberOfMeasurements);
- notifyWindows();
- }
- }
}
diff --git a/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/machines/DieselBrickMolder.java b/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/machines/DieselBrickMolder.java
index 1ec69244c..ac9785145 100644
--- a/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/machines/DieselBrickMolder.java
+++ b/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/machines/DieselBrickMolder.java
@@ -2,10 +2,10 @@
import com.destroystokyo.paper.ParticleBuilder;
import io.github.pylonmc.pylon.PylonFluids;
+import io.github.pylonmc.pylon.content.machines.generic.AbstractBrickMolder;
import io.github.pylonmc.pylon.recipes.MoldingRecipe;
import io.github.pylonmc.pylon.util.PylonUtils;
-import io.github.pylonmc.rebar.block.RebarBlock;
-import io.github.pylonmc.rebar.block.base.*;
+import io.github.pylonmc.rebar.block.base.RebarFluidBufferBlock;
import io.github.pylonmc.rebar.block.context.BlockBreakContext;
import io.github.pylonmc.rebar.block.context.BlockCreateContext;
import io.github.pylonmc.rebar.config.adapter.ConfigAdapter;
@@ -15,13 +15,10 @@
import io.github.pylonmc.rebar.i18n.RebarArgument;
import io.github.pylonmc.rebar.item.RebarItem;
import io.github.pylonmc.rebar.item.builder.ItemStackBuilder;
-import io.github.pylonmc.rebar.logistics.LogisticGroupType;
-import io.github.pylonmc.rebar.util.MachineUpdateReason;
import io.github.pylonmc.rebar.util.RebarUtils;
-import io.github.pylonmc.rebar.util.gui.GuiItems;
-import io.github.pylonmc.rebar.util.gui.ProgressItem;
import io.github.pylonmc.rebar.util.gui.unit.UnitFormat;
import io.github.pylonmc.rebar.waila.WailaDisplay;
+import java.util.List;
import net.kyori.adventure.text.format.TextColor;
import org.bukkit.Material;
import org.bukkit.Particle;
@@ -35,29 +32,12 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.joml.Vector3d;
-import xyz.xenondevs.invui.gui.Gui;
-import xyz.xenondevs.invui.inventory.VirtualInventory;
-
-import java.util.List;
-import java.util.Map;
-public class DieselBrickMolder extends RebarBlock implements
- RebarGuiBlock,
- RebarVirtualInventoryBlock,
- RebarFluidBufferBlock,
- RebarDirectionalBlock,
- RebarTickingBlock,
- RebarLogisticBlock,
- RebarRecipeProcessor {
+public class DieselBrickMolder extends AbstractBrickMolder implements RebarFluidBufferBlock {
public final double dieselBuffer = getSettings().getOrThrow("diesel-buffer", ConfigAdapter.DOUBLE);
public final double dieselPerSecond = getSettings().getOrThrow("diesel-per-second", ConfigAdapter.DOUBLE);
- public final int tickInterval = getSettings().getOrThrow("tick-interval", ConfigAdapter.INTEGER);
- public final int ticksPerMoldingCycle = getSettings().getOrThrow("ticks-per-molding-cycle", ConfigAdapter.INTEGER);
-
- private final VirtualInventory inputInventory = new VirtualInventory(1);
- private final VirtualInventory outputInventory = new VirtualInventory(1);
public static class Item extends RebarItem {
@@ -92,9 +72,7 @@ public Item(@NotNull ItemStack stack) {
@SuppressWarnings("unused")
public DieselBrickMolder(@NotNull Block block, @NotNull BlockCreateContext context) {
super(block, context);
- setTickInterval(tickInterval);
createFluidPoint(FluidPointType.INPUT, BlockFace.NORTH, context, false, 0.55F);
- setFacing(context.getFacing());
addEntity("chimney", new ItemDisplayBuilder()
.itemStack(chimneyStack)
.transformation(new TransformBuilder()
@@ -131,8 +109,6 @@ public DieselBrickMolder(@NotNull Block block, @NotNull BlockCreateContext conte
.build(block.getLocation().toCenterLocation().add(0, 0.5, 0))
);
createFluidBuffer(PylonFluids.BIODIESEL, dieselBuffer, true, false);
- setRecipeType(MoldingRecipe.RECIPE_TYPE);
- setRecipeProgressItem(new ProgressItem(GuiItems.background()));
}
@SuppressWarnings("unused")
@@ -140,19 +116,6 @@ public DieselBrickMolder(@NotNull Block block, @NotNull PersistentDataContainer
super(block, pdc);
}
- @Override
- public void postInitialise() {
- createLogisticGroup("input", LogisticGroupType.INPUT, inputInventory);
- createLogisticGroup("output", LogisticGroupType.OUTPUT, outputInventory);
- outputInventory.addPreUpdateHandler(RebarUtils.DISALLOW_PLAYERS_FROM_ADDING_ITEMS_HANDLER);
- outputInventory.addPostUpdateHandler(event -> tryStartRecipe());
- inputInventory.addPostUpdateHandler(event -> {
- if (!(event.getUpdateReason() instanceof MachineUpdateReason)) {
- tryStartRecipe();
- }
- });
- }
-
@Override
public void tick() {
if (!isProcessingRecipe() || fluidAmount(PylonFluids.BIODIESEL) < dieselPerSecond * tickInterval / 20) {
@@ -178,61 +141,13 @@ public void tick() {
.spawn();
}
- public void tryStartRecipe() {
- if (isProcessingRecipe()) {
- return;
- }
-
- ItemStack stack = inputInventory.getItem(0);
- if (stack == null || stack.isEmpty()) {
- return;
- }
-
- if (getLastRecipe() != null && tryStartRecipe(getLastRecipe(), stack)) {
- return;
- }
-
- for (MoldingRecipe recipe : MoldingRecipe.RECIPE_TYPE) {
- if (tryStartRecipe(recipe, stack)) {
- break;
- }
- }
- }
-
- private boolean tryStartRecipe(MoldingRecipe recipe, ItemStack stack) {
- if (!recipe.input().isSimilar(stack) || !outputInventory.canHold(recipe.result())) {
- return false;
- }
-
- startRecipe(recipe, recipe.moldingCycles() * tickInterval * ticksPerMoldingCycle);
- getRecipeProgressItem().setItem(ItemStackBuilder.of(stack.asOne()).clearLore());
- getHeldEntityOrThrow(ItemDisplay.class, "item").setItemStack(stack);
- inputInventory.setItem(new MachineUpdateReason(), 0, stack.subtract(recipe.input().getAmount()));
- return true;
- }
-
- @Override
- public void onRecipeFinished(@NotNull MoldingRecipe recipe) {
- getRecipeProgressItem().setItem(GuiItems.background());
- getHeldEntityOrThrow(ItemDisplay.class, "item").setItemStack(null);
- outputInventory.addItem(new MachineUpdateReason(), recipe.result().clone());
- }
-
@Override
- public @NotNull Gui createGui() {
- return Gui.builder()
- .setStructure(
- "# # I # # # O # #",
- "# # i # p # o # #",
- "# # I # # # O # #"
- )
- .addIngredient('#', GuiItems.background())
- .addIngredient('I', GuiItems.input())
- .addIngredient('i', inputInventory)
- .addIngredient('p', getRecipeProgressItem())
- .addIngredient('O', GuiItems.output())
- .addIngredient('o', outputInventory)
- .build();
+ protected boolean tryStartRecipe(MoldingRecipe recipe, ItemStack stack) {
+ boolean result = super.tryStartRecipe(recipe, stack);
+ if (result) {
+ getHeldEntityOrThrow(ItemDisplay.class, "item").setItemStack(stack);
+ }
+ return result;
}
@Override
@@ -249,15 +164,13 @@ public void onRecipeFinished(@NotNull MoldingRecipe recipe) {
@Override
public void onBreak(@NotNull List<@NotNull ItemStack> drops, @NotNull BlockBreakContext context) {
- RebarVirtualInventoryBlock.super.onBreak(drops, context);
+ super.onBreak(drops, context);
RebarFluidBufferBlock.super.onBreak(drops, context);
}
@Override
- public @NotNull Map getVirtualInventories() {
- return Map.of(
- "input", inputInventory,
- "output", outputInventory
- );
+ public void onRecipeFinished(@NotNull MoldingRecipe recipe) {
+ super.onRecipeFinished(recipe);
+ getHeldEntityOrThrow(ItemDisplay.class, "item").setItemStack(null);
}
}
diff --git a/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/machines/DieselCoreDrill.java b/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/machines/DieselCoreDrill.java
index 57d42404b..74d5744bb 100644
--- a/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/machines/DieselCoreDrill.java
+++ b/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/machines/DieselCoreDrill.java
@@ -11,6 +11,10 @@
import io.github.pylonmc.rebar.i18n.RebarArgument;
import io.github.pylonmc.rebar.util.MachineUpdateReason;
import io.github.pylonmc.rebar.util.gui.unit.UnitFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import org.bukkit.Particle;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
@@ -18,11 +22,6 @@
import org.jetbrains.annotations.NotNull;
import org.joml.Vector3i;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
public class DieselCoreDrill extends CoreDrill {
@@ -114,11 +113,11 @@ public void tick() {
FluidInputHatch fluidInputHatch = getMultiblockComponentOrThrow(FluidInputHatch.class, FLUID_INPUT_HATCH);
ItemOutputHatch itemOutputHatch = getMultiblockComponentOrThrow(ItemOutputHatch.class, ITEM_OUTPUT_HATCH);
- if (fluidInputHatch.fluidAmount(PylonFluids.BIODIESEL) < dieselPerRotation || !itemOutputHatch.inventory.canHold(output)) {
+ if (fluidInputHatch.getFluidAmount() < dieselPerRotation || !itemOutputHatch.inventory.canHold(output)) {
return;
}
- fluidInputHatch.removeFluid(PylonFluids.BIODIESEL, dieselPerRotation);
+ fluidInputHatch.removeFluid(dieselPerRotation);
new ParticleBuilder(Particle.CAMPFIRE_COSY_SMOKE)
.location(getMultiblockBlock(SMOKESTACK_CAP).getLocation().toCenterLocation())
@@ -145,6 +144,6 @@ public void onProcessFinished() {
public void onMultiblockFormed() {
super.onMultiblockFormed();
getMultiblockComponentOrThrow(FluidInputHatch.class, FLUID_INPUT_HATCH)
- .setFluidType(PylonFluids.BIODIESEL);
+ .setAllowedFluids(PylonFluids.BIODIESEL);
}
}
diff --git a/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/machines/DieselGrindstone.java b/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/machines/DieselGrindstone.java
index 5493efc0f..24f289532 100644
--- a/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/machines/DieselGrindstone.java
+++ b/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/machines/DieselGrindstone.java
@@ -2,11 +2,10 @@
import com.destroystokyo.paper.ParticleBuilder;
import io.github.pylonmc.pylon.PylonFluids;
-import io.github.pylonmc.pylon.content.machines.simple.Grindstone;
-import io.github.pylonmc.pylon.recipes.GrindstoneRecipe;
+import io.github.pylonmc.pylon.content.machines.generic.AbstractGrindstone;
import io.github.pylonmc.pylon.util.PylonUtils;
-import io.github.pylonmc.rebar.block.RebarBlock;
-import io.github.pylonmc.rebar.block.base.*;
+import io.github.pylonmc.rebar.block.base.RebarDirectionalBlock;
+import io.github.pylonmc.rebar.block.base.RebarFluidBufferBlock;
import io.github.pylonmc.rebar.block.context.BlockBreakContext;
import io.github.pylonmc.rebar.block.context.BlockCreateContext;
import io.github.pylonmc.rebar.config.adapter.ConfigAdapter;
@@ -17,13 +16,10 @@
import io.github.pylonmc.rebar.i18n.RebarArgument;
import io.github.pylonmc.rebar.item.RebarItem;
import io.github.pylonmc.rebar.item.builder.ItemStackBuilder;
-import io.github.pylonmc.rebar.logistics.LogisticGroupType;
-import io.github.pylonmc.rebar.util.MachineUpdateReason;
import io.github.pylonmc.rebar.util.RebarUtils;
-import io.github.pylonmc.rebar.util.gui.GuiItems;
-import io.github.pylonmc.rebar.util.gui.ProgressItem;
import io.github.pylonmc.rebar.util.gui.unit.UnitFormat;
import io.github.pylonmc.rebar.waila.WailaDisplay;
+import java.util.List;
import net.kyori.adventure.text.format.TextColor;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
@@ -38,32 +34,18 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.joml.Vector3d;
-import xyz.xenondevs.invui.gui.Gui;
-import xyz.xenondevs.invui.inventory.VirtualInventory;
-
-import java.util.List;
-import java.util.Map;
import static io.github.pylonmc.pylon.util.PylonUtils.pylonKey;
-public class DieselGrindstone extends RebarBlock implements
- RebarGuiBlock,
- RebarVirtualInventoryBlock,
+public class DieselGrindstone extends AbstractGrindstone implements
RebarFluidBufferBlock,
- RebarDirectionalBlock,
- RebarTickingBlock,
- RebarLogisticBlock,
- RebarRecipeProcessor {
+ RebarDirectionalBlock {
public static final NamespacedKey STONE_ROTATION_KEY = pylonKey("stone_rotation");
public final double dieselPerSecond = getSettings().getOrThrow("diesel-per-second", ConfigAdapter.DOUBLE);
public final double dieselBuffer = getSettings().getOrThrow("diesel-buffer", ConfigAdapter.DOUBLE);
- public final int tickInterval = getSettings().getOrThrow("tick-interval", ConfigAdapter.INTEGER);
-
- private final VirtualInventory inputInventory = new VirtualInventory(1);
- private final VirtualInventory outputInventory = new VirtualInventory(3);
private double stoneRotation;
public static class Item extends RebarItem {
@@ -96,7 +78,7 @@ public Item(@NotNull ItemStack stack) {
@SuppressWarnings("unused")
public DieselGrindstone(@NotNull Block block, @NotNull BlockCreateContext context) {
super(block, context);
- setTickInterval(tickInterval);
+
createFluidPoint(FluidPointType.INPUT, BlockFace.NORTH, context, false, 0.55F);
setFacing(context.getFacing());
addEntity("chimney", new ItemDisplayBuilder()
@@ -128,12 +110,10 @@ public DieselGrindstone(@NotNull Block block, @NotNull BlockCreateContext contex
.build(block.getLocation().toCenterLocation().add(0, 0.5, 0))
);
createFluidBuffer(PylonFluids.BIODIESEL, dieselBuffer, true, false);
- setRecipeType(GrindstoneRecipe.RECIPE_TYPE);
- setRecipeProgressItem(new ProgressItem(GuiItems.background()));
stoneRotation = 0;
}
- @SuppressWarnings("unused")
+ @SuppressWarnings({"unused", "DataFlowIssue"})
public DieselGrindstone(@NotNull Block block, @NotNull PersistentDataContainer pdc) {
super(block, pdc);
stoneRotation = pdc.get(STONE_ROTATION_KEY, RebarSerializers.DOUBLE);
@@ -144,19 +124,6 @@ public void write(@NotNull PersistentDataContainer pdc) {
pdc.set(STONE_ROTATION_KEY, RebarSerializers.DOUBLE, stoneRotation);
}
- @Override
- public void postInitialise() {
- createLogisticGroup("input", LogisticGroupType.INPUT, inputInventory);
- createLogisticGroup("output", LogisticGroupType.OUTPUT, outputInventory);
- outputInventory.addPreUpdateHandler(RebarUtils.DISALLOW_PLAYERS_FROM_ADDING_ITEMS_HANDLER);
- outputInventory.addPostUpdateHandler(event -> tryStartRecipe());
- inputInventory.addPostUpdateHandler(event -> {
- if (!(event.getUpdateReason() instanceof MachineUpdateReason)) {
- tryStartRecipe();
- }
- });
- }
-
@Override
public void tick() {
if (!isProcessingRecipe() || fluidAmount(PylonFluids.BIODIESEL) < dieselPerSecond * tickInterval / 20) {
@@ -186,65 +153,6 @@ public void tick() {
);
}
- public void tryStartRecipe() {
- if (isProcessingRecipe()) {
- return;
- }
-
- ItemStack stack = inputInventory.getItem(0);
- if (stack == null) {
- return;
- }
-
- if (getLastRecipe() != null && tryStartRecipe(getLastRecipe(), stack)) {
- return;
- }
-
- for (GrindstoneRecipe recipe : GrindstoneRecipe.RECIPE_TYPE) {
- if (tryStartRecipe(recipe, stack)) {
- return;
- }
- }
- }
-
- private boolean tryStartRecipe(GrindstoneRecipe recipe, ItemStack stack) {
- if (!recipe.input().matches(stack)) {
- return false;
- }
-
- if (!outputInventory.canHold(List.copyOf(recipe.results().getElements()))) {
- return true;
- }
-
- startRecipe(recipe, recipe.cycles() * Grindstone.CYCLE_DURATION_TICKS);
- getRecipeProgressItem().setItem(ItemStackBuilder.of(stack.asOne()).clearLore());
- inputInventory.setItem(new MachineUpdateReason(), 0, stack.subtract(recipe.input().getAmount()));
- return true;
- }
-
- @Override
- public void onRecipeFinished(@NotNull GrindstoneRecipe recipe) {
- getRecipeProgressItem().setItem(GuiItems.background());
- outputInventory.addItem(null, recipe.results().getRandom());
- }
-
- @Override
- public @NotNull Gui createGui() {
- return Gui.builder()
- .setStructure(
- "# I # # # O O O #",
- "# i # p # o o o #",
- "# I # # # O O O #"
- )
- .addIngredient('#', GuiItems.background())
- .addIngredient('I', GuiItems.input())
- .addIngredient('i', inputInventory)
- .addIngredient('O', GuiItems.output())
- .addIngredient('o', outputInventory)
- .addIngredient('p', getRecipeProgressItem())
- .build();
- }
-
@Override
public @Nullable WailaDisplay getWaila(@NotNull Player player) {
return new WailaDisplay(getDefaultWailaTranslationKey().arguments(
@@ -259,15 +167,7 @@ public void onRecipeFinished(@NotNull GrindstoneRecipe recipe) {
@Override
public void onBreak(@NotNull List<@NotNull ItemStack> drops, @NotNull BlockBreakContext context) {
- RebarVirtualInventoryBlock.super.onBreak(drops, context);
+ super.onBreak(drops, context);
RebarFluidBufferBlock.super.onBreak(drops, context);
}
-
- @Override
- public @NotNull Map getVirtualInventories() {
- return Map.of(
- "input", inputInventory,
- "output", outputInventory
- );
- }
}
diff --git a/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/machines/PalladiumCondenser.java b/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/machines/PalladiumCondenser.java
index 9a6f4b773..794e47797 100644
--- a/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/machines/PalladiumCondenser.java
+++ b/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/machines/PalladiumCondenser.java
@@ -21,6 +21,11 @@
import io.github.pylonmc.rebar.util.MachineUpdateReason;
import io.github.pylonmc.rebar.util.gui.unit.UnitFormat;
import io.github.pylonmc.rebar.waila.WailaDisplay;
+import java.time.Duration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Particle;
@@ -32,12 +37,6 @@
import org.jetbrains.annotations.Nullable;
import org.joml.Vector3i;
-import java.time.Duration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-
public class PalladiumCondenser extends RebarBlock implements
RebarSimpleMultiblock,
@@ -100,7 +99,6 @@ public Item(@NotNull ItemStack stack) {
public PalladiumCondenser(@NotNull Block block, @NotNull BlockCreateContext context) {
super(block, context);
setFacing(context.getFacing());
- setMultiblockDirection(getFacing());
setTickInterval(tickInterval);
}
@@ -180,16 +178,16 @@ public void tick() {
FluidOutputHatch dirtyHydraulicFluidOutputHatch = getMultiblockComponentOrThrow(FluidOutputHatch.class, DIRTY_HYDRAULIC_FLUID_OUTPUT_HATCH);
ItemOutputHatch palladiumDustOutputHatch = getMultiblockComponentOrThrow(ItemOutputHatch.class, PALLADIUM_DUST_OUTPUT_HATCH);
- if (biodieselInputHatch.fluidAmount(PylonFluids.BIODIESEL) < dieselPerSecond * getTickInterval() / 20
- || hydraulicFluidInputHatch.fluidAmount(PylonFluids.HYDRAULIC_FLUID) < hydraulicFluidPerSecond * getTickInterval() / 20
- || dirtyHydraulicFluidOutputHatch.fluidSpaceRemaining(PylonFluids.DIRTY_HYDRAULIC_FLUID) < hydraulicFluidPerSecond * getTickInterval() / 20
+ if (biodieselInputHatch.getFluidAmount() < dieselPerSecond * getTickInterval() / 20
+ || hydraulicFluidInputHatch.getFluidAmount() < hydraulicFluidPerSecond * getTickInterval() / 20
+ || dirtyHydraulicFluidOutputHatch.getFluidSpaceRemaining() < hydraulicFluidPerSecond * getTickInterval() / 20
|| !palladiumDustOutputHatch.inventory.canHold(PylonItems.PALLADIUM_DUST)
) {
return;
}
- biodieselInputHatch.removeFluid(PylonFluids.BIODIESEL, dieselPerSecond * getTickInterval() / 20);
- hydraulicFluidInputHatch.removeFluid(PylonFluids.HYDRAULIC_FLUID, hydraulicFluidPerSecond * getTickInterval() / 20);
+ biodieselInputHatch.removeFluid(dieselPerSecond * getTickInterval() / 20);
+ hydraulicFluidInputHatch.removeFluid(hydraulicFluidPerSecond * getTickInterval() / 20);
dirtyHydraulicFluidOutputHatch.addFluid(PylonFluids.DIRTY_HYDRAULIC_FLUID, hydraulicFluidPerSecond * getTickInterval() / 20);
progressProcess(getTickInterval());
@@ -243,11 +241,11 @@ public void onProcessFinished() {
public void onMultiblockFormed() {
RebarSimpleMultiblock.super.onMultiblockFormed();
getMultiblockComponentOrThrow(FluidInputHatch.class, BIODIESEL_INPUT_HATCH)
- .setFluidType(PylonFluids.BIODIESEL);
+ .setAllowedFluids(PylonFluids.BIODIESEL);
getMultiblockComponentOrThrow(FluidInputHatch.class, HYDRAULIC_FLUID_INPUT_HATCH)
- .setFluidType(PylonFluids.HYDRAULIC_FLUID);
+ .setAllowedFluids(PylonFluids.HYDRAULIC_FLUID);
getMultiblockComponentOrThrow(FluidOutputHatch.class, DIRTY_HYDRAULIC_FLUID_OUTPUT_HATCH)
- .setFluidType(PylonFluids.DIRTY_HYDRAULIC_FLUID);
+ .setAllowedFluids(PylonFluids.DIRTY_HYDRAULIC_FLUID);
}
@Override
diff --git a/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/production/Biorefinery.java b/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/production/Biorefinery.java
index be574a8f7..9263f5c93 100644
--- a/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/production/Biorefinery.java
+++ b/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/production/Biorefinery.java
@@ -21,11 +21,16 @@
import io.github.pylonmc.rebar.util.MachineUpdateReason;
import io.github.pylonmc.rebar.util.RebarUtils;
import io.github.pylonmc.rebar.util.gui.unit.UnitFormat;
-import io.github.pylonmc.rebar.waila.Waila;
import io.github.pylonmc.rebar.waila.WailaDisplay;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextColor;
-import org.bukkit.*;
+import org.bukkit.Keyed;
+import org.bukkit.Material;
+import org.bukkit.NamespacedKey;
+import org.bukkit.Particle;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@@ -36,10 +41,6 @@
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.util.PylonUtils.pylonKey;
public class Biorefinery extends RebarBlock implements
@@ -81,7 +82,6 @@ public Item(@NotNull ItemStack stack) {
public Biorefinery(@NotNull Block block, @NotNull BlockCreateContext context) {
super(block, context);
setFacing(context.getFacing());
- setMultiblockDirection(context.getFacing());
setTickInterval(tickInterval);
}
@@ -158,9 +158,9 @@ public Biorefinery(@NotNull Block block, @NotNull PersistentDataContainer pdc) {
@Override
public void onMultiblockFormed() {
RebarSimpleMultiblock.super.onMultiblockFormed();
- getMultiblockComponentOrThrow(FluidInputHatch.class, ETHANOL_INPUT_HATCH).setFluidType(PylonFluids.ETHANOL);
- getMultiblockComponentOrThrow(FluidInputHatch.class, PLANT_OIL_INPUT_HATCH).setFluidType(PylonFluids.PLANT_OIL);
- getMultiblockComponentOrThrow(FluidOutputHatch.class, BIODIESEL_OUTPUT_HATCH).setFluidType(PylonFluids.BIODIESEL);
+ getMultiblockComponentOrThrow(FluidInputHatch.class, ETHANOL_INPUT_HATCH).setAllowedFluids(PylonFluids.ETHANOL);
+ getMultiblockComponentOrThrow(FluidInputHatch.class, PLANT_OIL_INPUT_HATCH).setAllowedFluids(PylonFluids.PLANT_OIL);
+ getMultiblockComponentOrThrow(FluidOutputHatch.class, BIODIESEL_OUTPUT_HATCH).setAllowedFluids(PylonFluids.BIODIESEL);
}
@Override
@@ -177,19 +177,19 @@ public void tick() {
FluidOutputHatch biodieselOutputHatch = getMultiblockComponentOrThrow(FluidOutputHatch.class, BIODIESEL_OUTPUT_HATCH);
double biodieselToProduce = Math.min(
- biodieselOutputHatch.fluidSpaceRemaining(PylonFluids.BIODIESEL),
+ biodieselOutputHatch.getFluidSpaceRemaining(),
Math.min(
biodieselPerSecond * getTickInterval() / 20.0,
Math.min(
- ethanolInputHatch.fluidAmount(PylonFluids.ETHANOL) / ethanolPerMbOfBiodiesel,
- plantOilInputHatch.fluidAmount(PylonFluids.PLANT_OIL) / plantOilPerMbOfBiodiesel
+ ethanolInputHatch.getFluidAmount() / ethanolPerMbOfBiodiesel,
+ plantOilInputHatch.getFluidAmount() / plantOilPerMbOfBiodiesel
)
)
);
if (biodieselToProduce > RebarUtils.FLUID_EPSILON) {
- ethanolInputHatch.removeFluid(PylonFluids.ETHANOL, biodieselToProduce * ethanolPerMbOfBiodiesel);
- plantOilInputHatch.removeFluid(PylonFluids.PLANT_OIL, biodieselToProduce * plantOilPerMbOfBiodiesel);
+ ethanolInputHatch.removeFluid(biodieselToProduce * ethanolPerMbOfBiodiesel);
+ plantOilInputHatch.removeFluid(biodieselToProduce * plantOilPerMbOfBiodiesel);
biodieselOutputHatch.addFluid(PylonFluids.BIODIESEL, biodieselToProduce);
}
diff --git a/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/production/Fermenter.java b/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/production/Fermenter.java
index 47387a5dd..72cdc2fb5 100644
--- a/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/production/Fermenter.java
+++ b/src/main/java/io/github/pylonmc/pylon/content/machines/diesel/production/Fermenter.java
@@ -23,6 +23,9 @@
import io.github.pylonmc.rebar.util.RebarUtils;
import io.github.pylonmc.rebar.util.gui.unit.UnitFormat;
import io.github.pylonmc.rebar.waila.WailaDisplay;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import net.kyori.adventure.text.format.TextColor;
import org.bukkit.Material;
import org.bukkit.block.Block;
@@ -34,10 +37,6 @@
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 RebarBlock implements
RebarSimpleMultiblock,
RebarDirectionalBlock,
@@ -76,7 +75,6 @@ public Item(@NotNull ItemStack stack) {
public Fermenter(@NotNull Block block, @NotNull BlockCreateContext context) {
super(block, context);
setFacing(context.getFacing());
- setMultiblockDirection(context.getFacing());
setTickInterval(tickInterval);
createFluidBuffer(PylonFluids.SUGARCANE, ethanolPerSugarcane * sugarcaneCapacity, false, false);
addEntity("sugarcane", new ItemDisplayBuilder()
@@ -127,7 +125,6 @@ public Fermenter(@NotNull Block block, @NotNull PersistentDataContainer pdc) {
public void onMultiblockFormed() {
RebarSimpleMultiblock.super.onMultiblockFormed();
onMultiblockRefreshed();
- getMultiblockComponentOrThrow(FluidOutputHatch.class, OUTPUT_HATCH).setFluidType(PylonFluids.ETHANOL);
getHeldEntityOrThrow(ItemDisplay.class, "sugarcane").setItemStack(PylonFluids.SUGARCANE.getItem());
}
@@ -187,7 +184,7 @@ && fluidSpaceRemaining(PylonFluids.SUGARCANE) > ethanolPerSugarcane
}
double sugarcaneProportion = fluidAmount(PylonFluids.SUGARCANE) / fluidCapacity(PylonFluids.SUGARCANE);
- double outputSpaceRemaining = outputHatch.fluidSpaceRemaining(PylonFluids.ETHANOL);
+ double outputSpaceRemaining = outputHatch.getFluidSpaceRemaining();
double ethanolToOutput = Math.min(outputSpaceRemaining, sugarcaneProportion * maxEthanolOutputRate * getTickInterval() / 20);
if (ethanolToOutput > RebarUtils.FLUID_EPSILON) {
removeFluid(PylonFluids.SUGARCANE, ethanolToOutput);
diff --git a/src/main/java/io/github/pylonmc/pylon/content/machines/electricity/Capacitor.java b/src/main/java/io/github/pylonmc/pylon/content/machines/electricity/Capacitor.java
new file mode 100644
index 000000000..f129520f9
--- /dev/null
+++ b/src/main/java/io/github/pylonmc/pylon/content/machines/electricity/Capacitor.java
@@ -0,0 +1,113 @@
+package io.github.pylonmc.pylon.content.machines.electricity;
+
+import io.github.pylonmc.rebar.block.RebarBlock;
+import io.github.pylonmc.rebar.block.base.RebarDirectionalBlock;
+import io.github.pylonmc.rebar.block.base.RebarElectricBlock;
+import io.github.pylonmc.rebar.block.context.BlockCreateContext;
+import io.github.pylonmc.rebar.config.adapter.ConfigAdapter;
+import io.github.pylonmc.rebar.datatypes.RebarSerializers;
+import io.github.pylonmc.rebar.electricity.ElectricNode;
+import io.github.pylonmc.rebar.entity.display.TextDisplayBuilder;
+import io.github.pylonmc.rebar.entity.display.transform.TransformBuilder;
+import io.github.pylonmc.rebar.i18n.RebarArgument;
+import io.github.pylonmc.rebar.item.RebarItem;
+import io.github.pylonmc.rebar.util.gui.unit.UnitFormat;
+import io.github.pylonmc.rebar.util.position.BlockPosition;
+import java.util.List;
+import org.bukkit.NamespacedKey;
+import org.bukkit.block.Block;
+import org.bukkit.entity.TextDisplay;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.persistence.PersistentDataContainer;
+import org.jetbrains.annotations.NotNull;
+
+import static io.github.pylonmc.pylon.util.PylonUtils.pylonKey;
+
+public class Capacitor extends RebarBlock implements
+ RebarElectricBlock,
+ RebarDirectionalBlock {
+
+ public static final class Item extends RebarItem {
+
+ private final double capacity = getSettings().getOrThrow("capacity", ConfigAdapter.DOUBLE);
+
+ public Item(@NotNull ItemStack stack) {
+ super(stack);
+ }
+
+ @Override
+ public @NotNull List<@NotNull RebarArgument> getPlaceholders() {
+ return List.of(RebarArgument.of("capacity", UnitFormat.JOULES.format(capacity)));
+ }
+ }
+
+ private final double capacity = getSettings().getOrThrow("capacity", ConfigAdapter.DOUBLE);
+
+ private static final NamespacedKey STORED_ENERGY_KEY = pylonKey("stored_energy");
+ private double storedEnergy;
+
+ private ElectricNode.Producer output;
+
+ @SuppressWarnings("unused")
+ public Capacitor(@NotNull Block block, @NotNull BlockCreateContext context) {
+ super(block, context);
+
+ setFacing(context.getFacing());
+
+ addElectricPort(getFacing(), new ElectricNode.Acceptor("input", new BlockPosition(block)));
+ addElectricPort(getFacing().getOppositeFace(), new ElectricNode.Producer("output", new BlockPosition(block), 0));
+
+ addEntity("text_0", new TextDisplayBuilder()
+ .transformation(new TransformBuilder()
+ .lookAlong(getFacing())
+ .rotate(0, Math.PI / 2, 0))
+ .build(getBlock().getLocation().toCenterLocation().add(getFacing().getDirection().multiply(0.5001).rotateAroundY(Math.PI / 2)))
+ );
+
+ addEntity("text_1", new TextDisplayBuilder()
+ .transformation(new TransformBuilder()
+ .lookAlong(getFacing())
+ .rotate(0, -Math.PI / 2, 0))
+ .build(getBlock().getLocation().toCenterLocation().add(getFacing().getDirection().multiply(0.5001).rotateAroundY(-Math.PI / 2)))
+ );
+
+ storedEnergy = 0;
+ }
+
+ @SuppressWarnings({"unused", "DataFlowIssue"})
+ public Capacitor(@NotNull Block block, @NotNull PersistentDataContainer pdc) {
+ super(block, pdc);
+
+ storedEnergy = pdc.get(STORED_ENERGY_KEY, RebarSerializers.DOUBLE);
+ }
+
+ @Override
+ public void write(@NotNull PersistentDataContainer pdc) {
+ pdc.set(STORED_ENERGY_KEY, RebarSerializers.DOUBLE, storedEnergy);
+ }
+
+ @Override
+ public void postInitialise() {
+ ElectricNode.Acceptor input = (ElectricNode.Acceptor) getElectricNodeOrThrow("input");
+ input.onAccept(energy -> {
+ double accepted = Math.min(energy, capacity - storedEnergy);
+ setStoredEnergy(storedEnergy + accepted);
+ return accepted;
+ });
+
+ output = (ElectricNode.Producer) getElectricNodeOrThrow("output");
+ output.onPowerTake(energy -> {
+ double taken = Math.min(energy, storedEnergy);
+ setStoredEnergy(storedEnergy - taken);
+ });
+
+ setStoredEnergy(storedEnergy);
+ }
+
+ public void setStoredEnergy(double energy) {
+ storedEnergy = energy;
+ getHeldEntityOrThrow(TextDisplay.class, "text_0").text(UnitFormat.JOULES.format(storedEnergy).decimalPlaces(1).asComponent());
+ getHeldEntityOrThrow(TextDisplay.class, "text_1").text(UnitFormat.JOULES.format(storedEnergy).decimalPlaces(1).asComponent());
+ output.setPower(storedEnergy);
+ }
+}
diff --git a/src/main/java/io/github/pylonmc/pylon/content/machines/electricity/ElectricityInputHatch.java b/src/main/java/io/github/pylonmc/pylon/content/machines/electricity/ElectricityInputHatch.java
new file mode 100644
index 000000000..e07e9eedc
--- /dev/null
+++ b/src/main/java/io/github/pylonmc/pylon/content/machines/electricity/ElectricityInputHatch.java
@@ -0,0 +1,22 @@
+package io.github.pylonmc.pylon.content.machines.electricity;
+
+import io.github.pylonmc.rebar.block.RebarBlock;
+import io.github.pylonmc.rebar.block.base.RebarElectricConsumerBlock;
+import io.github.pylonmc.rebar.block.context.BlockCreateContext;
+import org.bukkit.block.Block;
+import org.bukkit.persistence.PersistentDataContainer;
+import org.jetbrains.annotations.NotNull;
+
+public class ElectricityInputHatch extends RebarBlock implements RebarElectricConsumerBlock {
+
+ @SuppressWarnings("unused")
+ public ElectricityInputHatch(@NotNull Block block, @NotNull BlockCreateContext context) {
+ super(block, context);
+ setFacing(context.getFacing());
+ }
+
+ @SuppressWarnings("unused")
+ public ElectricityInputHatch(@NotNull Block block, @NotNull PersistentDataContainer pdc) {
+ super(block, pdc);
+ }
+}
diff --git a/src/main/java/io/github/pylonmc/pylon/content/machines/electricity/ElectricityOutputHatch.java b/src/main/java/io/github/pylonmc/pylon/content/machines/electricity/ElectricityOutputHatch.java
new file mode 100644
index 000000000..dfdcf3e32
--- /dev/null
+++ b/src/main/java/io/github/pylonmc/pylon/content/machines/electricity/ElectricityOutputHatch.java
@@ -0,0 +1,22 @@
+package io.github.pylonmc.pylon.content.machines.electricity;
+
+import io.github.pylonmc.rebar.block.RebarBlock;
+import io.github.pylonmc.rebar.block.base.RebarElectricProducerBlock;
+import io.github.pylonmc.rebar.block.context.BlockCreateContext;
+import org.bukkit.block.Block;
+import org.bukkit.persistence.PersistentDataContainer;
+import org.jetbrains.annotations.NotNull;
+
+public class ElectricityOutputHatch extends RebarBlock implements RebarElectricProducerBlock {
+
+ @SuppressWarnings("unused")
+ public ElectricityOutputHatch(@NotNull Block block, @NotNull BlockCreateContext context) {
+ super(block, context);
+ setFacing(context.getFacing());
+ }
+
+ @SuppressWarnings("unused")
+ public ElectricityOutputHatch(@NotNull Block block, @NotNull PersistentDataContainer pdc) {
+ super(block, pdc);
+ }
+}
diff --git a/src/main/java/io/github/pylonmc/pylon/content/machines/electricity/ElectricityPylon.java b/src/main/java/io/github/pylonmc/pylon/content/machines/electricity/ElectricityPylon.java
new file mode 100644
index 000000000..515c3e1e6
--- /dev/null
+++ b/src/main/java/io/github/pylonmc/pylon/content/machines/electricity/ElectricityPylon.java
@@ -0,0 +1,50 @@
+package io.github.pylonmc.pylon.content.machines.electricity;
+
+import io.github.pylonmc.rebar.block.RebarBlock;
+import io.github.pylonmc.rebar.block.base.RebarElectricBlock;
+import io.github.pylonmc.rebar.block.base.RebarTickingBlock;
+import io.github.pylonmc.rebar.block.context.BlockCreateContext;
+import io.github.pylonmc.rebar.electricity.ElectricNetwork;
+import io.github.pylonmc.rebar.electricity.ElectricNode;
+import io.github.pylonmc.rebar.util.RebarUtils;
+import io.github.pylonmc.rebar.util.position.BlockPosition;
+import org.bukkit.Color;
+import org.bukkit.Particle;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
+import org.bukkit.persistence.PersistentDataContainer;
+import org.jetbrains.annotations.NotNull;
+
+public final class ElectricityPylon extends RebarBlock implements
+ RebarElectricBlock,
+ RebarTickingBlock {
+
+ @SuppressWarnings("unused")
+ public ElectricityPylon(@NotNull Block block, @NotNull BlockCreateContext context) {
+ super(block, context);
+
+ setTickInterval(10);
+ ElectricNode.Connector centralNode = addElectricNode(new ElectricNode.Connector("center", new BlockPosition(block)));
+ for (BlockFace face : RebarUtils.IMMEDIATE_FACES) {
+ ElectricNode.Connector port = addElectricPort(face, new ElectricNode.Connector(face.name(), new BlockPosition(block)));
+ centralNode.connect(port);
+ }
+ }
+
+ @SuppressWarnings("unused")
+ public ElectricityPylon(@NotNull Block block, @NotNull PersistentDataContainer pdc) {
+ super(block, pdc);
+ }
+
+ @Override
+ public void tick() {
+ ElectricNetwork network = getElectricNodes().getFirst().getNetwork();
+ for (ElectricNode node : network.getNodes()) {
+ Particle.DUST.builder()
+ .color(Color.fromARGB(network.hashCode()))
+ .location(node.getBlock().toLocation().toCenterLocation().add(0, 0.6, 0))
+ .receivers(32, true)
+ .spawn();
+ }
+ }
+}
diff --git a/src/main/java/io/github/pylonmc/pylon/content/machines/electricity/Multimeter.java b/src/main/java/io/github/pylonmc/pylon/content/machines/electricity/Multimeter.java
new file mode 100644
index 000000000..14d769bff
--- /dev/null
+++ b/src/main/java/io/github/pylonmc/pylon/content/machines/electricity/Multimeter.java
@@ -0,0 +1,28 @@
+package io.github.pylonmc.pylon.content.machines.electricity;
+
+import io.github.pylonmc.rebar.block.BlockStorage;
+import io.github.pylonmc.rebar.item.RebarItem;
+import io.github.pylonmc.rebar.item.base.RebarInteractor;
+import java.util.Comparator;
+import org.bukkit.Location;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.NotNull;
+
+public class Multimeter extends RebarItem implements RebarInteractor {
+ public Multimeter(@NotNull ItemStack stack) {
+ super(stack);
+ }
+
+ @Override
+ public void onUsedToClick(@NotNull PlayerInteractEvent event, @NotNull EventPriority priority) {
+ Location playerLocation = event.getPlayer().getLocation();
+ ElectricityPylon pylon = BlockStorage.getByType(ElectricityPylon.class).stream()
+ .min(Comparator.comparing(p -> p.getBlock().getLocation().toCenterLocation().distanceSquared(playerLocation)))
+ .filter(p -> p.getBlock().getLocation().toCenterLocation().distanceSquared(playerLocation) < 64 * 64)
+ .orElse(null);
+ if (pylon == null) return;
+ throw new UnsupportedOperationException("Multimeter interaction not implemented yet");
+ }
+}
diff --git a/src/main/java/io/github/pylonmc/pylon/content/machines/electricity/generation/Boiler.java b/src/main/java/io/github/pylonmc/pylon/content/machines/electricity/generation/Boiler.java
new file mode 100644
index 000000000..15739aad9
--- /dev/null
+++ b/src/main/java/io/github/pylonmc/pylon/content/machines/electricity/generation/Boiler.java
@@ -0,0 +1,239 @@
+package io.github.pylonmc.pylon.content.machines.electricity.generation;
+
+import io.github.pylonmc.pylon.PylonFluids;
+import io.github.pylonmc.pylon.PylonKeys;
+import io.github.pylonmc.pylon.content.components.FluidInputHatch;
+import io.github.pylonmc.pylon.content.components.FluidOutputHatch;
+import io.github.pylonmc.pylon.util.BurnerProgressItem;
+import io.github.pylonmc.rebar.block.RebarBlock;
+import io.github.pylonmc.rebar.block.base.*;
+import io.github.pylonmc.rebar.block.context.BlockCreateContext;
+import io.github.pylonmc.rebar.config.Settings;
+import io.github.pylonmc.rebar.config.adapter.ConfigAdapter;
+import io.github.pylonmc.rebar.i18n.RebarArgument;
+import io.github.pylonmc.rebar.item.ItemTypeWrapper;
+import io.github.pylonmc.rebar.item.RebarItem;
+import io.github.pylonmc.rebar.logistics.LogisticGroupType;
+import io.github.pylonmc.rebar.registry.RebarRegistry;
+import io.github.pylonmc.rebar.util.MachineUpdateReason;
+import io.github.pylonmc.rebar.util.RebarUtils;
+import io.github.pylonmc.rebar.util.gui.GuiItems;
+import io.github.pylonmc.rebar.util.gui.unit.UnitFormat;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import kotlin.Pair;
+import org.bukkit.Keyed;
+import org.bukkit.NamespacedKey;
+import org.bukkit.Particle;
+import org.bukkit.block.Block;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.persistence.PersistentDataContainer;
+import org.bukkit.util.Vector;
+import org.jetbrains.annotations.NotNull;
+import org.joml.Vector3i;
+import xyz.xenondevs.invui.gui.Gui;
+import xyz.xenondevs.invui.inventory.VirtualInventory;
+
+import static io.github.pylonmc.pylon.util.PylonUtils.pylonKey;
+
+public class Boiler extends RebarBlock implements
+ RebarSimpleMultiblock,
+ RebarDirectionalBlock,
+ RebarProcessor,
+ RebarTickingBlock,
+ RebarVirtualInventoryBlock,
+ RebarGuiBlock,
+ RebarLogisticBlock {
+
+ public static class Item extends RebarItem {
+
+ private final double steamPerSecond = getSettings().getOrThrow("steam-per-second", ConfigAdapter.DOUBLE);
+
+ public Item(@NotNull ItemStack stack) {
+ super(stack);
+ }
+
+ @Override
+ public @NotNull List<@NotNull RebarArgument> getPlaceholders() {
+ return List.of(
+ RebarArgument.of("water-usage", UnitFormat.MILLIBUCKETS_PER_SECOND.format(steamPerSecond * PylonFluids.WATER_TO_STEAM_RATIO)),
+ RebarArgument.of("steam-production", UnitFormat.MILLIBUCKETS_PER_SECOND.format(steamPerSecond))
+ );
+ }
+ }
+
+ private static final ConfigAdapter