Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/main/java/io/github/pylonmc/pylon/base/BaseBlocks.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public static void initialize() {
PylonBlock.register(BaseKeys.HYDRAULIC_HAMMER_HEAD, Material.STONE_BRICKS, HydraulicHammerHead.class);
PylonBlock.register(BaseKeys.HYDRAULIC_PIPE_BENDER, Material.WAXED_CHISELED_COPPER, HydraulicPipeBender.class);
PylonBlock.register(BaseKeys.HYDRAULIC_TABLE_SAW, Material.WAXED_CUT_COPPER, HydraulicTableSaw.class);
PylonBlock.register(BaseKeys.SOLAR_LENS, Material.GLASS_PANE, PylonBlock.class);
PylonBlock.register(BaseKeys.SOLAR_LENS, Material.GLASS_PANE, SolarLens.class);
PylonBlock.register(BaseKeys.PURIFICATION_TOWER_GLASS, Material.LIGHT_GRAY_STAINED_GLASS, PylonBlock.class);
PylonBlock.register(BaseKeys.PURIFICATION_TOWER_CAP, Material.QUARTZ_SLAB, PylonBlock.class);
PylonBlock.register(BaseKeys.SOLAR_PURIFICATION_TOWER_1, Material.WAXED_COPPER_BLOCK, SolarPurificationTower.class);
Expand Down Expand Up @@ -151,5 +151,10 @@ public static void initialize() {
PylonBlock.register(BaseKeys.CARGO_MERGER, Material.STRUCTURE_VOID, CargoMerger.class);
PylonBlock.register(BaseKeys.CARGO_VALVE, Material.STRUCTURE_VOID, CargoValve.class);
PylonBlock.register(BaseKeys.CARGO_FILTER, Material.STRUCTURE_VOID, CargoFilter.class);
PylonBlock.register(BaseKeys.CARGO_MONITOR, Material.STRUCTURE_VOID, CargoMonitor.class);
PylonBlock.register(BaseKeys.CARGO_METER, Material.STRUCTURE_VOID, CargoMeter.class);
PylonBlock.register(BaseKeys.CARGO_GATE, Material.STRUCTURE_VOID, CargoGate.class);
PylonBlock.register(BaseKeys.CARGO_ACCUMULATOR, Material.STRUCTURE_VOID, CargoAccumulator.class);
PylonBlock.register(BaseKeys.CARGO_FLUID_ACCUMULATOR, Material.STRUCTURE_VOID, CargoFluidAccumulator.class);
}
}
50 changes: 45 additions & 5 deletions src/main/java/io/github/pylonmc/pylon/base/BaseItems.java
Original file line number Diff line number Diff line change
Expand Up @@ -1229,10 +1229,10 @@ private BaseItems() {
}

public static final ItemStack FLUID_METER = ItemStackBuilder.pylon(Material.STRUCTURE_VOID, BaseKeys.FLUID_METER)
.set(DataComponentTypes.ITEM_MODEL, Material.WHITE_CONCRETE.getKey())
.set(DataComponentTypes.ITEM_MODEL, Material.LIGHT_BLUE_STAINED_GLASS.getKey())
.build();
static {
PylonItem.register(FluidFilter.Item.class, FLUID_METER, BaseKeys.FLUID_METER);
PylonItem.register(FluidMeter.Item.class, FLUID_METER, BaseKeys.FLUID_METER);
BasePages.FLUID_MACHINES.addItem(FLUID_METER);
}

Expand Down Expand Up @@ -2013,15 +2013,15 @@ private BaseItems() {
}

public static final ItemStack CARGO_SPLITTER = ItemStackBuilder.pylon(Material.STRUCTURE_VOID, BaseKeys.CARGO_SPLITTER)
.set(DataComponentTypes.ITEM_MODEL, Material.STRIPPED_CRIMSON_HYPHAE.getKey())
.set(DataComponentTypes.ITEM_MODEL, Material.STRIPPED_CRIMSON_STEM.getKey())
.build();
static {
PylonItem.register(CargoSplitter.Item.class, CARGO_SPLITTER, BaseKeys.CARGO_SPLITTER);
BasePages.CARGO.addItem(CARGO_SPLITTER);
}

public static final ItemStack CARGO_MERGER = ItemStackBuilder.pylon(Material.STRUCTURE_VOID, BaseKeys.CARGO_MERGER)
.set(DataComponentTypes.ITEM_MODEL, Material.STRIPPED_WARPED_HYPHAE.getKey())
.set(DataComponentTypes.ITEM_MODEL, Material.STRIPPED_WARPED_STEM.getKey())
.build();
static {
PylonItem.register(CargoSplitter.Item.class, CARGO_MERGER, BaseKeys.CARGO_MERGER);
Expand All @@ -2037,13 +2037,53 @@ private BaseItems() {
}

public static final ItemStack CARGO_FILTER = ItemStackBuilder.pylon(Material.STRUCTURE_VOID, BaseKeys.CARGO_FILTER)
.set(DataComponentTypes.ITEM_MODEL, Material.PINK_TERRACOTTA.getKey())
.set(DataComponentTypes.ITEM_MODEL, Material.COMPARATOR.getKey())
.build();
static {
PylonItem.register(CargoValve.Item.class, CARGO_FILTER, BaseKeys.CARGO_FILTER);
BasePages.CARGO.addItem(CARGO_FILTER);
}

public static final ItemStack CARGO_MONITOR = ItemStackBuilder.pylon(Material.STRUCTURE_VOID, BaseKeys.CARGO_MONITOR)
.set(DataComponentTypes.ITEM_MODEL, Material.PINK_STAINED_GLASS.getKey())
.build();
static {
PylonItem.register(CargoMonitor.Item.class, CARGO_MONITOR, BaseKeys.CARGO_MONITOR);
BasePages.CARGO.addItem(CARGO_MONITOR);
}

public static final ItemStack CARGO_METER = ItemStackBuilder.pylon(Material.STRUCTURE_VOID, BaseKeys.CARGO_METER)
.set(DataComponentTypes.ITEM_MODEL, Material.LIGHT_BLUE_STAINED_GLASS.getKey())
.build();
static {
PylonItem.register(CargoMeter.Item.class, CARGO_METER, BaseKeys.CARGO_METER);
BasePages.CARGO.addItem(CARGO_METER);
}

public static final ItemStack CARGO_GATE = ItemStackBuilder.pylon(Material.STRUCTURE_VOID, BaseKeys.CARGO_GATE)
.set(DataComponentTypes.ITEM_MODEL, Material.REPEATER.getKey())
.build();
static {
PylonItem.register(CargoGate.Item.class, CARGO_GATE, BaseKeys.CARGO_GATE);
BasePages.CARGO.addItem(CARGO_GATE);
}

public static final ItemStack CARGO_ACCUMULATOR = ItemStackBuilder.pylon(Material.STRUCTURE_VOID, BaseKeys.CARGO_ACCUMULATOR)
.set(DataComponentTypes.ITEM_MODEL, Material.REDSTONE_LAMP.getKey())
.build();
static {
PylonItem.register(CargoAccumulator.Item.class, CARGO_ACCUMULATOR, BaseKeys.CARGO_ACCUMULATOR);
BasePages.CARGO.addItem(CARGO_ACCUMULATOR);
}

public static final ItemStack CARGO_FLUID_ACCUMULATOR = ItemStackBuilder.pylon(Material.STRUCTURE_VOID, BaseKeys.CARGO_FLUID_ACCUMULATOR)
.set(DataComponentTypes.ITEM_MODEL, Material.NOTE_BLOCK.getKey())
.build();
static {
PylonItem.register(CargoFluidAccumulator.Item.class, CARGO_FLUID_ACCUMULATOR, BaseKeys.CARGO_FLUID_ACCUMULATOR);
BasePages.CARGO.addItem(CARGO_FLUID_ACCUMULATOR);
}

// Calling this method forces all the static blocks to run, which initializes our items
public static void initialize() {
}
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/io/github/pylonmc/pylon/base/BaseKeys.java
Original file line number Diff line number Diff line change
Expand Up @@ -325,4 +325,9 @@ public class BaseKeys {
public static final NamespacedKey CARGO_MERGER = baseKey("cargo_merger");
public static final NamespacedKey CARGO_VALVE = baseKey("cargo_valve");
public static final NamespacedKey CARGO_FILTER = baseKey("cargo_filter");
public static final NamespacedKey CARGO_MONITOR = baseKey("cargo_monitor");
public static final NamespacedKey CARGO_METER = baseKey("cargo_meter");
public static final NamespacedKey CARGO_GATE = baseKey("cargo_gate");
public static final NamespacedKey CARGO_ACCUMULATOR = baseKey("cargo_accumulator");
public static final NamespacedKey CARGO_FLUID_ACCUMULATOR = baseKey("cargo_fluid_accumulator");
}
2 changes: 1 addition & 1 deletion src/main/java/io/github/pylonmc/pylon/base/BasePages.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class BasePages {
public static final SimpleStaticGuidePage SIMPLE_MACHINES = new SimpleStaticGuidePage(baseKey("simple_machines"), Material.SMOOTH_STONE_SLAB);
public static final SimpleStaticGuidePage SMELTING = new SimpleStaticGuidePage(baseKey("smelting"), Material.DEEPSLATE_TILES);
public static final SimpleStaticGuidePage FLUID_PIPES_AND_TANKS = new SimpleStaticGuidePage(baseKey("fluid_pipes_and_tanks"), Material.ORANGE_TERRACOTTA);
public static final SimpleStaticGuidePage FLUID_MACHINES = new SimpleStaticGuidePage(baseKey("fluid_machines"), Material.CAULDRON);
public static final SimpleStaticGuidePage FLUID_MACHINES = new SimpleStaticGuidePage(baseKey("fluid_machines"), Material.LIGHT_BLUE_STAINED_GLASS);
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);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
package io.github.pylonmc.pylon.base.content.machines.cargo;

import com.google.common.base.Preconditions;
import io.github.pylonmc.pylon.core.block.PylonBlock;
import io.github.pylonmc.pylon.core.block.base.PylonCargoBlock;
import io.github.pylonmc.pylon.core.block.base.PylonDirectionalBlock;
import io.github.pylonmc.pylon.core.block.base.PylonGuiBlock;
import io.github.pylonmc.pylon.core.block.context.BlockCreateContext;
import io.github.pylonmc.pylon.core.config.adapter.ConfigAdapter;
import io.github.pylonmc.pylon.core.datatypes.PylonSerializers;
import io.github.pylonmc.pylon.core.entity.display.BlockDisplayBuilder;
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.i18n.PylonArgument;
import io.github.pylonmc.pylon.core.item.PylonItem;
import io.github.pylonmc.pylon.core.item.builder.ItemStackBuilder;
import io.github.pylonmc.pylon.core.logistics.LogisticGroupType;
import io.github.pylonmc.pylon.core.util.MachineUpdateReason;
import io.github.pylonmc.pylon.core.util.gui.GuiItems;
import io.github.pylonmc.pylon.core.util.gui.unit.UnitFormat;
import io.github.pylonmc.pylon.core.waila.WailaDisplay;
import net.kyori.adventure.text.Component;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Block;
import org.bukkit.entity.BlockDisplay;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataContainer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.inventory.VirtualInventory;
import xyz.xenondevs.invui.item.ItemProvider;
import xyz.xenondevs.invui.item.impl.AbstractItem;

import java.util.Arrays;
import java.util.List;

import static io.github.pylonmc.pylon.base.util.BaseUtils.baseKey;


public class CargoAccumulator extends PylonBlock implements
PylonDirectionalBlock,
PylonGuiBlock,
PylonCargoBlock {

public static final NamespacedKey THRESHOLD_KEY = baseKey("threshold");

private final VirtualInventory inputInventory = new VirtualInventory(5);
private final VirtualInventory outputInventory = new VirtualInventory(5);

public final int transferRate = getSettings().getOrThrow("transfer-rate", ConfigAdapter.INT);

public int threshold;

public final ItemStackBuilder mainStack = ItemStackBuilder.of(Material.LIGHT_GRAY_CONCRETE)
.addCustomModelDataString(getKey() + ":main");
public final ItemStackBuilder inputStack = ItemStackBuilder.of(Material.LIME_TERRACOTTA)
.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.pylonbase.gui.threshold_button.lore"));

public static class Item extends PylonItem {

public final int transferRate = getSettings().getOrThrow("transfer-rate", ConfigAdapter.INT);

public Item(@NotNull ItemStack stack) {
super(stack);
}

@Override
public @NotNull List<PylonArgument> getPlaceholders() {
return List.of(
PylonArgument.of(
"transfer-rate",
UnitFormat.ITEMS_PER_SECOND.format(PylonCargoBlock.cargoItemsTransferredPerSecond(transferRate))
)
);
}
}

@SuppressWarnings("unused")
public CargoAccumulator(@NotNull Block block, @NotNull BlockCreateContext context) {
super(block, context);

setFacing(context.getFacing());

addCargoLogisticGroup(getFacing(), "input");
addCargoLogisticGroup(getFacing().getOppositeFace(), "output");
setCargoTransferRate(transferRate);

addEntity("main", new ItemDisplayBuilder()
.itemStack(mainStack)
.transformation(new TransformBuilder()
.lookAlong(getFacing())
.scale(0.6)
)
.build(block.getLocation().toCenterLocation())
);

addEntity("side1", new BlockDisplayBuilder()
.blockData(Material.REDSTONE_LAMP.createBlockData("[lit=false]"))
.transformation(new TransformBuilder()
.lookAlong(getFacing())
.rotate(Math.PI / 2, Math.PI / 2, 0)
.scale(0.45, 0.45, 0.65)
)
.build(block.getLocation().toCenterLocation())
);

addEntity("side2", new BlockDisplayBuilder()
.blockData(Material.REDSTONE_LAMP.createBlockData("[lit=false]"))
.transformation(new TransformBuilder()
.lookAlong(getFacing())
.rotate(Math.PI / 2, Math.PI / 2, 0)
.scale(0.65, 0.45, 0.45)
)
.build(block.getLocation().toCenterLocation())
);

addEntity("input", new ItemDisplayBuilder()
.itemStack(inputStack)
.transformation(new TransformBuilder()
.lookAlong(getFacing())
.translate(0, 0, 0.125)
.scale(0.4, 0.4, 0.4)
)
.build(block.getLocation().toCenterLocation())
);

addEntity("output", new ItemDisplayBuilder()
.itemStack(outputStack)
.transformation(new TransformBuilder()
.lookAlong(getFacing())
.translate(0, 0, -0.125)
.scale(0.4, 0.4, 0.4)
)
.build(block.getLocation().toCenterLocation())
);

threshold = 1;
}

@SuppressWarnings("unused")
public CargoAccumulator(@NotNull Block block, @NotNull PersistentDataContainer pdc) {
super(block, pdc);
threshold = pdc.get(THRESHOLD_KEY, PylonSerializers.INTEGER);
}

@Override
public void write(@NotNull PersistentDataContainer pdc) {
pdc.set(THRESHOLD_KEY, PylonSerializers.INTEGER, threshold);
}

@Override
public @NotNull Gui createGui() {
return Gui.normal()
.setStructure(
"# I i i i i i I #",
"# # # # # # # # #",
"# O o o o o o O #",
"# # # # # # # # #",
"# # # # t # # # #"
)
.addIngredient('#', GuiItems.background())
.addIngredient('i', inputInventory)
.addIngredient('I', GuiItems.input())
.addIngredient('o', outputInventory)
.addIngredient('O', GuiItems.output())
.addIngredient('t', new ThresholdButton())
.build();
}

@Override
public void postInitialise() {
createLogisticGroup("input", LogisticGroupType.INPUT, inputInventory);
createLogisticGroup("output", LogisticGroupType.OUTPUT, outputInventory);
inputInventory.setPostUpdateHandler(event -> {
if (!(event.getUpdateReason() instanceof MachineUpdateReason)) {
doTransfer();
}
});
outputInventory.setPostUpdateHandler(event -> {
if (!(event.getUpdateReason() instanceof MachineUpdateReason)) {
doTransfer();
}
});
}

@Override
public @Nullable WailaDisplay getWaila(@NotNull Player player) {
return new WailaDisplay(getDefaultWailaTranslationKey().arguments(
PylonArgument.of("threshold", threshold)
));
}

private void doTransfer() {
int inputTotal = 0;
for (ItemStack stack : inputInventory.getItems()) {
if (stack != null) {
inputTotal += stack.getAmount();
}
}

int outputTotal = 0;
for (ItemStack stack : outputInventory.getItems()) {
if (stack != null) {
outputTotal += stack.getAmount();
}
}

if (outputTotal == 0) {
getLogisticGroupOrThrow("input").setFilter(null);
getHeldEntityOrThrow(BlockDisplay.class, "side1")
.setBlock(Material.REDSTONE_LAMP.createBlockData("[lit=false]"));
getHeldEntityOrThrow(BlockDisplay.class, "side2")
.setBlock(Material.REDSTONE_LAMP.createBlockData("[lit=false]"));
}

if (inputTotal >= threshold) {
List<ItemStack> stacks = Arrays.stream(inputInventory.getItems()).toList();
Preconditions.checkState(outputInventory.canHold(stacks));
for (ItemStack stack : stacks) {
outputInventory.addItem(new MachineUpdateReason(), stack);
}
for (int slot = 0; slot < inputInventory.getItems().length; slot++) {
inputInventory.setItem(new MachineUpdateReason(), slot, null);
}
getLogisticGroupOrThrow("input").setFilter(stack -> false);
getHeldEntityOrThrow(BlockDisplay.class, "side1")
.setBlock(Material.REDSTONE_LAMP.createBlockData("[lit=true]"));
getHeldEntityOrThrow(BlockDisplay.class, "side2")
.setBlock(Material.REDSTONE_LAMP.createBlockData("[lit=true]"));
}
}

public class ThresholdButton extends AbstractItem {

@Override
public ItemProvider getItemProvider() {
return thresholdButtonStack
.name((Component.translatable("pylon.pylonbase.gui.threshold_button.name").arguments(
PylonArgument.of("threshold", threshold)
)));
}

@Override
public void handleClick(
@NotNull ClickType clickType,
@NotNull Player player,
@NotNull InventoryClickEvent event
) {
if (clickType.isLeftClick()) {
threshold += 1;
} else {
threshold = Math.max(1, threshold - 1);
}
notifyWindows();
doTransfer();
}
}
}
Loading
Loading