From 31a25c46d747162d295d9082f603d0b2ca79f07e Mon Sep 17 00:00:00 2001 From: Burkino <24849979+Burkino@users.noreply.github.com> Date: Tue, 29 Oct 2024 08:46:00 -0400 Subject: [PATCH 1/4] Item Capability Proxy --- .../sfm/client/gui/screen/ProxyScreen.java | 40 +++++ .../sfm/client/registry/SFMMenuScreens.java | 2 + .../teamdman/sfm/common/block/ProxyBlock.java | 29 ++++ .../common/blockentity/ProxyBlockEntity.java | 149 ++++++++++++++++++ .../teamdman/sfm/common/compat/SFMCompat.java | 29 +++- .../containermenu/ProxyContainerMenu.java | 60 +++++++ .../common/registry/SFMBlockCapabilities.java | 26 ++- .../sfm/common/registry/SFMBlockEntities.java | 7 +- .../sfm/common/registry/SFMBlocks.java | 1 + .../sfm/common/registry/SFMItems.java | 3 + .../sfm/common/registry/SFMMenus.java | 48 +++++- .../sfm/textures/gui/container/proxy.png | Bin 0 -> 4573 bytes 12 files changed, 382 insertions(+), 12 deletions(-) create mode 100644 src/main/java/ca/teamdman/sfm/client/gui/screen/ProxyScreen.java create mode 100644 src/main/java/ca/teamdman/sfm/common/block/ProxyBlock.java create mode 100644 src/main/java/ca/teamdman/sfm/common/blockentity/ProxyBlockEntity.java create mode 100644 src/main/java/ca/teamdman/sfm/common/containermenu/ProxyContainerMenu.java create mode 100644 src/main/resources/assets/sfm/textures/gui/container/proxy.png diff --git a/src/main/java/ca/teamdman/sfm/client/gui/screen/ProxyScreen.java b/src/main/java/ca/teamdman/sfm/client/gui/screen/ProxyScreen.java new file mode 100644 index 000000000..2f3fd1548 --- /dev/null +++ b/src/main/java/ca/teamdman/sfm/client/gui/screen/ProxyScreen.java @@ -0,0 +1,40 @@ +package ca.teamdman.sfm.client.gui.screen; + +import ca.teamdman.sfm.SFM; +import ca.teamdman.sfm.common.containermenu.ProxyContainerMenu; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.PlayerRideable; +import net.minecraft.world.entity.player.Inventory; + +public class ProxyScreen extends AbstractContainerScreen { + private static final ResourceLocation PROXY_IMAGE = ResourceLocation.fromNamespaceAndPath( + SFM.MOD_ID, + "textures/gui/container/proxy.png" + ); + + public ProxyScreen( + ProxyContainerMenu menu, + Inventory inv, + Component title + ) { + super(menu, inv, title); + } + + @Override + protected void init() { + super.init(); + } + + @Override + protected void renderBg(GuiGraphics pGuiGraphics, float pPartialTick, int pMouseX, int pMouseY) { + + } + + @Override + public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { + super.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick); + } +} diff --git a/src/main/java/ca/teamdman/sfm/client/registry/SFMMenuScreens.java b/src/main/java/ca/teamdman/sfm/client/registry/SFMMenuScreens.java index 3fa2d9436..ce2f69c1a 100644 --- a/src/main/java/ca/teamdman/sfm/client/registry/SFMMenuScreens.java +++ b/src/main/java/ca/teamdman/sfm/client/registry/SFMMenuScreens.java @@ -2,6 +2,7 @@ import ca.teamdman.sfm.SFM; import ca.teamdman.sfm.client.gui.screen.ManagerScreen; +import ca.teamdman.sfm.client.gui.screen.ProxyScreen; import ca.teamdman.sfm.common.registry.SFMMenus; import net.minecraft.client.gui.screens.MenuScreens; import net.neoforged.bus.api.SubscribeEvent; @@ -13,5 +14,6 @@ public class SFMMenuScreens { @SubscribeEvent public static void register(RegisterMenuScreensEvent event) { event.register(SFMMenus.MANAGER_MENU.get(), ManagerScreen::new); + event.register(SFMMenus.PROXY_MENU.get(), ProxyScreen::new); } } diff --git a/src/main/java/ca/teamdman/sfm/common/block/ProxyBlock.java b/src/main/java/ca/teamdman/sfm/common/block/ProxyBlock.java new file mode 100644 index 000000000..43537cf85 --- /dev/null +++ b/src/main/java/ca/teamdman/sfm/common/block/ProxyBlock.java @@ -0,0 +1,29 @@ +package ca.teamdman.sfm.common.block; + +import ca.teamdman.sfm.common.blockentity.ProxyBlockEntity; +import com.mojang.serialization.MapCodec; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +public class ProxyBlock extends BaseEntityBlock implements EntityBlock { + public ProxyBlock() { + super(Properties.of() + .destroyTime(2) + .sound(SoundType.METAL)); + } + + @Override + protected MapCodec codec() { + return null; + } + + @Override + public @Nullable BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) { + return new ProxyBlockEntity(blockPos, blockState); + } +} diff --git a/src/main/java/ca/teamdman/sfm/common/blockentity/ProxyBlockEntity.java b/src/main/java/ca/teamdman/sfm/common/blockentity/ProxyBlockEntity.java new file mode 100644 index 000000000..8dd67bcb7 --- /dev/null +++ b/src/main/java/ca/teamdman/sfm/common/blockentity/ProxyBlockEntity.java @@ -0,0 +1,149 @@ +package ca.teamdman.sfm.common.blockentity; + +//import ca.teamdman.sfm.common.containermenu.ProxyContainerMenu; + +import ca.teamdman.sfm.common.containermenu.ProxyContainerMenu; +import ca.teamdman.sfm.common.registry.SFMBlockEntities; +import ca.teamdman.sfm.common.util.SFMContainerUtil; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.NonNullList; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.world.Container; +import net.minecraft.world.ContainerHelper; +import net.minecraft.world.MenuProvider; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.capabilities.BlockCapability; +import net.neoforged.neoforge.capabilities.Capabilities; +import net.neoforged.neoforge.capabilities.ItemCapability; +import net.neoforged.neoforge.items.wrapper.InvWrapper; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; + +/* + * https://github.com/CyclopsMC/CapabilityProxy/blob/master-1.21/loader-neoforge/src/main/java/org/cyclops/capabilityproxy/blockentity/BlockEntityItemCapabilityProxyNeoForge.java + */ +public class ProxyBlockEntity extends BlockEntity implements MenuProvider, Container { + private static final Component TITLE = Component.literal("Item Capability Proxy"); + + public static Map, ItemCapability> BLOCK_TO_ITEM_CAPABILITIES = Map.of(); + + private final NonNullList inventory = NonNullList.withSize(1, ItemStack.EMPTY); + + public ProxyBlockEntity(BlockPos pPos, BlockState pBlockState) { + super(SFMBlockEntities.PROXY_BLOCK_ENTITY.get(), pPos, pBlockState); + } + + @Nullable + public static ItemCapability blockCapabilityToItemCapability(BlockCapability capability) { + return (ItemCapability) BLOCK_TO_ITEM_CAPABILITIES.get(capability); + } + + @Override + public void setChanged() { + super.setChanged(); + invalidateCapabilities(); + } + + + @Override + public @Nullable AbstractContainerMenu createMenu(int windowId, Inventory inventory, Player player) { + return new ProxyContainerMenu(windowId, inventory, this); + } + + @Override + public int getMaxStackSize() { + return 1; + } + + @Override + public Component getDisplayName() { + return TITLE; + } + + @Override + public int getContainerSize() { + return inventory.size(); + } + + @Override + public boolean isEmpty() { + return inventory.isEmpty(); + } + + @Override + public ItemStack getItem(int slotId) { + if (slotId < 0 || slotId >= getContainerSize()) return ItemStack.EMPTY; + return inventory.get(slotId); + } + + @Override + public ItemStack removeItem(int slotId, int amount) { + ItemStack result = ContainerHelper.removeItem(inventory, slotId, amount); + setChanged(); + return result; + } + + @Override + public ItemStack removeItemNoUpdate(int slotId) { + ItemStack result = ContainerHelper.takeItem(inventory, slotId); + setChanged(); + return result; + } + + @Override + public void setItem(int slotId, ItemStack itemStack) { + if (slotId < 0 || slotId >= getContainerSize()) return; + inventory.set(slotId, itemStack); + setChanged(); + } + + @Override + public boolean stillValid(Player player) { + return SFMContainerUtil.stillValid(this, player); + } + + @Override + public void clearContent() { + inventory.clear(); + } + + @Override + protected void saveAdditional(CompoundTag pTag, HolderLookup.Provider pRegistries) { + super.saveAdditional(pTag, pRegistries); + ContainerHelper.saveAllItems(pTag, inventory, pRegistries); + } + + @Override + protected void loadAdditional(CompoundTag pTag, HolderLookup.Provider pRegistries) { + super.loadAdditional(pTag, pRegistries); + ContainerHelper.loadAllItems(pTag, inventory, pRegistries); + } + + @Nullable + public T getCapability(BlockCapability blockCapability, @Nullable C1 context) { + if (context == Direction.UP | context == Direction.DOWN) { + if (blockCapability == Capabilities.ItemHandler.BLOCK) { + return (T) new InvWrapper(this); + } + return null; + } + + ItemStack itemStack = getItem(0); + ItemCapability itemCapability = blockCapabilityToItemCapability(blockCapability); + if (itemCapability == null) { + return null; + } + T cap = itemStack.getCapability(itemCapability, null); + + return cap; + } +} \ No newline at end of file diff --git a/src/main/java/ca/teamdman/sfm/common/compat/SFMCompat.java b/src/main/java/ca/teamdman/sfm/common/compat/SFMCompat.java index 34c695799..dd0bb1230 100644 --- a/src/main/java/ca/teamdman/sfm/common/compat/SFMCompat.java +++ b/src/main/java/ca/teamdman/sfm/common/compat/SFMCompat.java @@ -1,12 +1,17 @@ package ca.teamdman.sfm.common.compat; +import ca.teamdman.sfm.common.resourcetype.ChemicalResourceType; +import com.google.common.collect.Maps; import net.minecraft.core.Direction; import net.neoforged.fml.ModList; import net.neoforged.neoforge.capabilities.BlockCapability; import net.neoforged.neoforge.capabilities.Capabilities; +import net.neoforged.neoforge.capabilities.ItemCapability; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.List; +import java.util.Map; public class SFMCompat { public static boolean isMekanismLoaded() { @@ -14,10 +19,30 @@ public static boolean isMekanismLoaded() { } public static List> getCapabilities() { - return List.of( + ArrayList> capabilities = new ArrayList<>(List.of( Capabilities.ItemHandler.BLOCK, Capabilities.FluidHandler.BLOCK, Capabilities.EnergyStorage.BLOCK - ); + )); + + if (isMekanismLoaded()) { + capabilities.add(ChemicalResourceType.CAP); + } + + return capabilities; } + + public static Map, ItemCapability> getCapabilityMap() { + Map, ItemCapability> capabilityMap = Maps.newIdentityHashMap(); + capabilityMap.put(Capabilities.ItemHandler.BLOCK, Capabilities.ItemHandler.ITEM); + capabilityMap.put(Capabilities.FluidHandler.BLOCK, Capabilities.FluidHandler.ITEM); + capabilityMap.put(Capabilities.EnergyStorage.BLOCK, Capabilities.EnergyStorage.ITEM); + + if (isMekanismLoaded()) { + capabilityMap.put(ChemicalResourceType.CAP, mekanism.common.capabilities.Capabilities.CHEMICAL.item()); + } + + return capabilityMap; + } + } diff --git a/src/main/java/ca/teamdman/sfm/common/containermenu/ProxyContainerMenu.java b/src/main/java/ca/teamdman/sfm/common/containermenu/ProxyContainerMenu.java new file mode 100644 index 000000000..5bd215aed --- /dev/null +++ b/src/main/java/ca/teamdman/sfm/common/containermenu/ProxyContainerMenu.java @@ -0,0 +1,60 @@ +package ca.teamdman.sfm.common.containermenu; + +import ca.teamdman.sfm.common.blockentity.ProxyBlockEntity; +import ca.teamdman.sfm.common.registry.SFMMenus; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.world.Container; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; + +public class ProxyContainerMenu extends AbstractContainerMenu { + private final ProxyBlockEntity PROXY_BLOCK_ENTITY; + private final Inventory PLAYER_INVENTORY; + + public ProxyContainerMenu(int windowId, Inventory inventory, FriendlyByteBuf buf) { + this(windowId, inventory, (ProxyBlockEntity) inventory.player.level().getBlockEntity(buf.readBlockPos())); + } + + public ProxyContainerMenu(int windowId, Inventory inventory, ProxyBlockEntity proxyBlockEntity) { + super(SFMMenus.PROXY_MENU.get(), windowId); + + PROXY_BLOCK_ENTITY = proxyBlockEntity; + PLAYER_INVENTORY = inventory; + + addContainerSlot(proxyBlockEntity); + } + + @Override + public ItemStack quickMoveStack(Player pPlayer, int pIndex) { + return null; + } + + @Override + public boolean stillValid(Player pPlayer) { + return PROXY_BLOCK_ENTITY.stillValid(pPlayer); + } + + private void addContainerSlot(Container container) { + addSlot(new Slot( + container, + 0, + 81, + 5 + )); + } + + private void addPlayerInventory(Inventory inventory) { + } + + private void addPlayerHotbar(Inventory inventory) { + } + + private void addInternalItemSlots() { + } + + private void addInternalTanks() { + } +} diff --git a/src/main/java/ca/teamdman/sfm/common/registry/SFMBlockCapabilities.java b/src/main/java/ca/teamdman/sfm/common/registry/SFMBlockCapabilities.java index ad2f219d6..7c3a16732 100644 --- a/src/main/java/ca/teamdman/sfm/common/registry/SFMBlockCapabilities.java +++ b/src/main/java/ca/teamdman/sfm/common/registry/SFMBlockCapabilities.java @@ -2,6 +2,9 @@ import ca.teamdman.sfm.SFM; import ca.teamdman.sfm.common.blockcapabilityprovider.CauldronBlockCapabilityProvider; +import ca.teamdman.sfm.common.blockentity.ProxyBlockEntity; +import ca.teamdman.sfm.common.compat.SFMCompat; +import com.google.common.collect.Maps; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.level.Level; @@ -11,13 +14,13 @@ import net.minecraft.world.level.block.state.BlockState; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.neoforge.capabilities.Capabilities; -import net.neoforged.neoforge.capabilities.IBlockCapabilityProvider; -import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent; +import net.neoforged.neoforge.capabilities.*; import net.neoforged.neoforge.items.IItemHandler; import net.neoforged.neoforge.items.wrapper.InvWrapper; import org.jetbrains.annotations.Nullable; +import java.util.Map; + @EventBusSubscriber(modid = SFM.MOD_ID, bus = EventBusSubscriber.Bus.MOD) public class SFMBlockCapabilities { @@ -64,5 +67,22 @@ private static void registerCapabilities(RegisterCapabilitiesEvent event) { Blocks.LAVA_CAULDRON, Blocks.WATER_CAULDRON ); + + handleCapabilityProxyRegistration(event); + } + + /* + * https://github.com/CyclopsMC/CapabilityProxy/blob/master-1.21/loader-neoforge/src/main/java/org/cyclops/capabilityproxy/blockentity/BlockEntityItemCapabilityProxyNeoForgeConfig.java + */ + private static void handleCapabilityProxyRegistration(RegisterCapabilitiesEvent event) { + ProxyBlockEntity.BLOCK_TO_ITEM_CAPABILITIES = SFMCompat.getCapabilityMap(); + + for (BlockCapability blockCapability : SFMCompat.getCapabilities()) { + event.registerBlockEntity( + (BlockCapability) blockCapability, + SFMBlockEntities.PROXY_BLOCK_ENTITY.get(), + (object, context) -> object.getCapability((BlockCapability) blockCapability, context) + ); + } } } diff --git a/src/main/java/ca/teamdman/sfm/common/registry/SFMBlockEntities.java b/src/main/java/ca/teamdman/sfm/common/registry/SFMBlockEntities.java index 7f2876a4d..d87c023bd 100644 --- a/src/main/java/ca/teamdman/sfm/common/registry/SFMBlockEntities.java +++ b/src/main/java/ca/teamdman/sfm/common/registry/SFMBlockEntities.java @@ -64,5 +64,10 @@ public static void register(IEventBus bus) { .build(null) ); - + public static final Supplier> PROXY_BLOCK_ENTITY = BLOCK_ENTITY_TYPES.register( + "proxy", + () -> BlockEntityType.Builder + .of(ProxyBlockEntity::new, SFMBlocks.PROXY_BLOCK.get()) + .build(null) + ); } diff --git a/src/main/java/ca/teamdman/sfm/common/registry/SFMBlocks.java b/src/main/java/ca/teamdman/sfm/common/registry/SFMBlocks.java index 44a0c8c29..1fd8f6a57 100644 --- a/src/main/java/ca/teamdman/sfm/common/registry/SFMBlocks.java +++ b/src/main/java/ca/teamdman/sfm/common/registry/SFMBlocks.java @@ -21,6 +21,7 @@ public class SFMBlocks { public static final Supplier CABLE_BLOCK = BLOCKS.register("cable", CableBlock::new); public static final Supplier BATTERY_BLOCK = BLOCKS.register("battery", BatteryBlock::new); public static final Supplier TEST_BARREL_BLOCK = BLOCKS.register("test_barrel", TestBarrelBlock::new); + public static final Supplier PROXY_BLOCK = BLOCKS.register("proxy", ProxyBlock::new); public static void register(IEventBus bus) { BLOCKS.register(bus); diff --git a/src/main/java/ca/teamdman/sfm/common/registry/SFMItems.java b/src/main/java/ca/teamdman/sfm/common/registry/SFMItems.java index fc5587f15..8c1e3fa41 100644 --- a/src/main/java/ca/teamdman/sfm/common/registry/SFMItems.java +++ b/src/main/java/ca/teamdman/sfm/common/registry/SFMItems.java @@ -20,6 +20,7 @@ public class SFMItems { public static final Supplier CABLE_ITEM = register("cable", SFMBlocks.CABLE_BLOCK); // public static final Supplier BATTERY_ITEM = register("battery", SFMBlocks.BATTERY_BLOCK); public static final Supplier WATER_TANK_ITEM = register("water_tank", SFMBlocks.WATER_TANK_BLOCK); + public static final Supplier PROXY_ITEM = register("proxy", SFMBlocks.PROXY_BLOCK); public static final Supplier DISK_ITEM = ITEMS.register("disk", DiskItem::new); public static final Supplier LABEL_GUN_ITEM = ITEMS.register( "labelgun", @@ -36,6 +37,8 @@ public class SFMItems { public static final Supplier EXPERIENCE_SHARD_ITEM = ITEMS.register("xp_shard", ExperienceShard::new); public static final Supplier EXPERIENCE_GOOP_ITEM = ITEMS.register("xp_goop", ExperienceGoop::new); + + public static void register(IEventBus bus) { ITEMS.register(bus); } diff --git a/src/main/java/ca/teamdman/sfm/common/registry/SFMMenus.java b/src/main/java/ca/teamdman/sfm/common/registry/SFMMenus.java index e0ea6b2dc..693087588 100644 --- a/src/main/java/ca/teamdman/sfm/common/registry/SFMMenus.java +++ b/src/main/java/ca/teamdman/sfm/common/registry/SFMMenus.java @@ -4,9 +4,10 @@ import ca.teamdman.sfm.SFM; import ca.teamdman.sfm.client.ClientStuff; import ca.teamdman.sfm.common.blockentity.ManagerBlockEntity; +import ca.teamdman.sfm.common.blockentity.ProxyBlockEntity; import ca.teamdman.sfm.common.containermenu.ManagerContainerMenu; +import ca.teamdman.sfm.common.containermenu.ProxyContainerMenu; import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.MenuType; @@ -24,11 +25,6 @@ public class SFMMenus { BuiltInRegistries.MENU, SFM.MOD_ID ); - - public static void register(IEventBus bus) { - MENU_TYPES.register(bus); - } - public static final Supplier> MANAGER_MENU = MENU_TYPES.register( "manager", () -> IMenuTypeExtension.create( @@ -66,6 +62,46 @@ public ManagerContainerMenu create( } }) ); + public static final Supplier> PROXY_MENU = MENU_TYPES.register( + "proxy", + () -> IMenuTypeExtension.create( + new IContainerFactory<>() { + @Override + public ProxyContainerMenu create( + int windowId, + Inventory inv, + RegistryFriendlyByteBuf data + ) { + return new ProxyContainerMenu( + windowId, + inv, + data + ); + } + + @Override + public ProxyContainerMenu create( + int windowId, + Inventory inv + ) { + if (FMLEnvironment.dist.isClient()) { + BlockEntity be = ClientStuff.getLookBlockEntity(); + if (!(be instanceof ProxyBlockEntity pbe)) { + return IContainerFactory.super.create(windowId, inv); + } + return new ProxyContainerMenu(windowId, inv, pbe); + } else { + return IContainerFactory.super.create( + windowId, + inv + ); + } + } + }) + ); + public static void register(IEventBus bus) { + MENU_TYPES.register(bus); + } } diff --git a/src/main/resources/assets/sfm/textures/gui/container/proxy.png b/src/main/resources/assets/sfm/textures/gui/container/proxy.png new file mode 100644 index 0000000000000000000000000000000000000000..08276c01f4eb95c1493c0558c80c9644c1f7a348 GIT binary patch literal 4573 zcmeHLe^3)w9^W8TNC!tNDpRSqM(Ne+W`86h$sU1363tqI6asSAqMO}K*g}4oY)HhZ z#`fBtKj!qjwkH-(P7!}}N_9p$*E_7G$`4QMAg#UHt4gtOg=^2Tw&I-5ac?&vz+7iK z%v}Ftlil}y-}n7~-g}?-ec$Bm_QHadsq#nV5Co-CR&x;q$$%(>5~qQpX4EMpdWgSF-f60!c(4Emu;uLYPqEm{O$!{urSqaf~E%Fs>rS zF9ED&^(Wl71&=Tq7+cVB8>t?lm{T2^;0<*3Y@pZ@_HeBu1={NEe4Fzfua zOl?c;rLNg`&M!Z{vtL>I*Txmuwv1xUfp6cf>v-}e(!RF2>GZ7&<>^blT6!`6sD4M< z+*66O64;NQHqFWEJ3Z7;*4e$Krz7|4e_Q+)zC2-E*pcvDH~j9Flezb@eeVyN4Vj`s)%mTCYJ8_*AW1nir999qN$yg@(1S*kgYuxLC4%f$VC zL4TDr9hO14D$Wf|1E5!YLYLx(i+hL^xOlfu@&aT}uoQUb7+Dj>Cbme^89xx<9><+v zJvw*E7+BeCq}j^^#o^M{92DgV2(*XcL?{5R$Dig(TLjV)FWzEtwZ#B96UHouVFEjPUUb&P%J~P@cP{}SWeze zyExS6aY+p#;iRdMGAIaTbl{Svu!x%=RLvjn5mt2bHxHJvWaU|7_QP}VJcjw z(W>-gMx~rT03uPulv1bEA}$LFCIg72#W)23k{-;3%=2@!;PucRqEiUa)f_906JSM~m9>gLO_s4|ttIi1u?P7vK?a1;SJMfr6iq7HY{v>re$Jt^yzo!7+r;#Rwx* zF~ZQ;gi$ePjLtY4{U1)UC4+HE2KYsFAbEjYh{ls)j59Iq{DfC*Eq=lt0Q6KRlj3)Z zt|_`E#lWPDr=n|$u1PU4DdVZ=`oGa7A3IKQ9`G+H1P)7UdQw`!K`Xs5-)@nPT;fBk z)s~c$?A*Dty}f;8WaP@pihV#U6N(CoA>+WOPO;*6YNZ+ab<$(vc|65u{bc}x9-b}U zGH8EYI#5m*D4S*aSMrQmsq<`^w-bTSYRYV~hd=w~nrYQJV_M{kC2h|qwZ7PuA~!_f zy9uR#+o3C8zl3_{z_#p0=IqwjEGa*$UAADb!8Vw4=-CsVJF_plJ{vfG^x;UyOygDe z`oDU2oW2KG^%Id|&SU<{p!*;;PM+B6&2)PPS0PXL?NdEZMpa>+6X4)&h!b?=(QY z_<>BZlI~J`duCze_`MrBjc-0^z789|_skO;pvbY~e@dE3?3D=*WemyQxRcd;<<030 qugo-F+-m*RgYA~Ri>c9X>PKkn Date: Wed, 30 Oct 2024 12:22:49 -0400 Subject: [PATCH 2/4] More items and blocks to test capabilities --- build.gradle | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/build.gradle b/build.gradle index 7a1952036..d4bdbba01 100644 --- a/build.gradle +++ b/build.gradle @@ -218,6 +218,13 @@ dependencies { implementation "mekanism:Mekanism:1.21.1-10.7.4.60:api" implementation "curse.maven:spark-361579:5759671" // spark-1.10.109-neoforge.jar + + implementation "curse.maven:cloth-config-348521:5729127" // cloth-config-15.0.140-neoforge.jar + implementation "curse.maven:powah-rearchitected-633483:5735677" // Powah-6.1.2.jar + + implementation "curse.maven:sophisticated-core-618298:5810072" // sophisticatedcore-1.21-0.6.45.722.jar + implementation "curse.maven:sophisticated-backpacks-422301:5787622" // sophisticatedbackpacks-1.21-3.20.17.1113.jar + implementation "curse.maven:sophisticated-storage-619320:5801696" // sophisticatedstorage-1.21-0.10.45.910.jar } // This block of code expands all declared replace properties in the specified resource targets. From 55a834c9790d0c80549d74e7c20dc6e3b5a65192 Mon Sep 17 00:00:00 2001 From: Burkino <24849979+Burkino@users.noreply.github.com> Date: Wed, 30 Oct 2024 12:24:25 -0400 Subject: [PATCH 3/4] Finish up proxy block --- .../sfm/client/gui/screen/ProxyScreen.java | 14 +-- .../teamdman/sfm/common/block/ProxyBlock.java | 49 ++++++++++- .../common/blockentity/ProxyBlockEntity.java | 41 ++++++--- .../containermenu/ProxyContainerMenu.java | 82 +++++++++++++----- .../sfm/textures/gui/container/proxy.png | Bin 4573 -> 4672 bytes 5 files changed, 146 insertions(+), 40 deletions(-) diff --git a/src/main/java/ca/teamdman/sfm/client/gui/screen/ProxyScreen.java b/src/main/java/ca/teamdman/sfm/client/gui/screen/ProxyScreen.java index 2f3fd1548..4bc237554 100644 --- a/src/main/java/ca/teamdman/sfm/client/gui/screen/ProxyScreen.java +++ b/src/main/java/ca/teamdman/sfm/client/gui/screen/ProxyScreen.java @@ -6,11 +6,10 @@ import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.PlayerRideable; import net.minecraft.world.entity.player.Inventory; public class ProxyScreen extends AbstractContainerScreen { - private static final ResourceLocation PROXY_IMAGE = ResourceLocation.fromNamespaceAndPath( + private static final ResourceLocation TEXTURE = ResourceLocation.fromNamespaceAndPath( SFM.MOD_ID, "textures/gui/container/proxy.png" ); @@ -26,15 +25,20 @@ public ProxyScreen( @Override protected void init() { super.init(); + this.imageWidth = 176; + this.imageHeight = 209; + this.topPos /= 2; + this.inventoryLabelY = 80; } @Override protected void renderBg(GuiGraphics pGuiGraphics, float pPartialTick, int pMouseX, int pMouseY) { - + pGuiGraphics.blit(TEXTURE, this.leftPos, this.topPos, 0, 0, this.imageWidth, this.imageHeight); } @Override - public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { - super.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick); + public void render(GuiGraphics graphics, int mx, int my, float partialTicks) { + super.render(graphics, mx, my, partialTicks); + this.renderTooltip(graphics, mx, my); } } diff --git a/src/main/java/ca/teamdman/sfm/common/block/ProxyBlock.java b/src/main/java/ca/teamdman/sfm/common/block/ProxyBlock.java index 43537cf85..f1065aa40 100644 --- a/src/main/java/ca/teamdman/sfm/common/block/ProxyBlock.java +++ b/src/main/java/ca/teamdman/sfm/common/block/ProxyBlock.java @@ -1,13 +1,24 @@ package ca.teamdman.sfm.common.block; import ca.teamdman.sfm.common.blockentity.ProxyBlockEntity; +import ca.teamdman.sfm.common.containermenu.ProxyContainerMenu; +import ca.teamdman.sfm.common.registry.SFMBlockEntities; import com.mojang.serialization.MapCodec; import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.Container; +import net.minecraft.world.Containers; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; import net.minecraft.world.level.block.BaseEntityBlock; import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.SoundType; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import org.apache.commons.lang3.NotImplementedException; import org.jetbrains.annotations.Nullable; public class ProxyBlock extends BaseEntityBlock implements EntityBlock { @@ -19,11 +30,43 @@ public ProxyBlock() { @Override protected MapCodec codec() { - return null; + throw new NotImplementedException("This isn't used until 1.20.5 apparently"); + } + + public RenderShape getRenderShape(BlockState state) { + return RenderShape.MODEL; + } + + @Override + public @Nullable BlockEntity newBlockEntity(BlockPos pPos, BlockState pState) { + return SFMBlockEntities.PROXY_BLOCK_ENTITY.get() + .create(pPos, pState); + } + + @Override + protected InteractionResult useWithoutItem( + BlockState pState, + Level level, + BlockPos pos, + Player player, + BlockHitResult pHitResult + ) { + if (level.getBlockEntity(pos) instanceof ProxyBlockEntity pbe && player instanceof ServerPlayer sp) { + sp.openMenu(pbe, buf -> ProxyContainerMenu.encode(pbe, buf)); + return InteractionResult.CONSUME; + } + return InteractionResult.SUCCESS; } @Override - public @Nullable BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) { - return new ProxyBlockEntity(blockPos, blockState); + @SuppressWarnings("deprecation") + public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) { + if (!state.is(newState.getBlock())) { + if (level.getBlockEntity(pos) instanceof Container container) { + Containers.dropContents(level, pos, container); + level.updateNeighbourForOutputSignal(pos, this); + } + super.onRemove(state, level, pos, newState, isMoving); + } } } diff --git a/src/main/java/ca/teamdman/sfm/common/blockentity/ProxyBlockEntity.java b/src/main/java/ca/teamdman/sfm/common/blockentity/ProxyBlockEntity.java index 8dd67bcb7..7abeb92a0 100644 --- a/src/main/java/ca/teamdman/sfm/common/blockentity/ProxyBlockEntity.java +++ b/src/main/java/ca/teamdman/sfm/common/blockentity/ProxyBlockEntity.java @@ -1,7 +1,5 @@ package ca.teamdman.sfm.common.blockentity; -//import ca.teamdman.sfm.common.containermenu.ProxyContainerMenu; - import ca.teamdman.sfm.common.containermenu.ProxyContainerMenu; import ca.teamdman.sfm.common.registry.SFMBlockEntities; import ca.teamdman.sfm.common.util.SFMContainerUtil; @@ -11,14 +9,12 @@ import net.minecraft.core.NonNullList; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; -import net.minecraft.world.Container; import net.minecraft.world.ContainerHelper; -import net.minecraft.world.MenuProvider; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BaseContainerBlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.neoforged.neoforge.capabilities.BlockCapability; import net.neoforged.neoforge.capabilities.Capabilities; @@ -31,12 +27,12 @@ /* * https://github.com/CyclopsMC/CapabilityProxy/blob/master-1.21/loader-neoforge/src/main/java/org/cyclops/capabilityproxy/blockentity/BlockEntityItemCapabilityProxyNeoForge.java */ -public class ProxyBlockEntity extends BlockEntity implements MenuProvider, Container { +public class ProxyBlockEntity extends BaseContainerBlockEntity { private static final Component TITLE = Component.literal("Item Capability Proxy"); public static Map, ItemCapability> BLOCK_TO_ITEM_CAPABILITIES = Map.of(); - private final NonNullList inventory = NonNullList.withSize(1, ItemStack.EMPTY); + private NonNullList inventory = NonNullList.withSize(4, ItemStack.EMPTY); public ProxyBlockEntity(BlockPos pPos, BlockState pBlockState) { super(SFMBlockEntities.PROXY_BLOCK_ENTITY.get(), pPos, pBlockState); @@ -53,9 +49,8 @@ public void setChanged() { invalidateCapabilities(); } - @Override - public @Nullable AbstractContainerMenu createMenu(int windowId, Inventory inventory, Player player) { + protected AbstractContainerMenu createMenu(int windowId, Inventory inventory) { return new ProxyContainerMenu(windowId, inventory, this); } @@ -65,10 +60,20 @@ public int getMaxStackSize() { } @Override - public Component getDisplayName() { + protected Component getDefaultName() { return TITLE; } + @Override + protected NonNullList getItems() { + return inventory; + } + + @Override + protected void setItems(NonNullList nonNullList) { + inventory = nonNullList; + } + @Override public int getContainerSize() { return inventory.size(); @@ -130,14 +135,26 @@ protected void loadAdditional(CompoundTag pTag, HolderLookup.Provider pRegistrie @Nullable public T getCapability(BlockCapability blockCapability, @Nullable C1 context) { - if (context == Direction.UP | context == Direction.DOWN) { + if (!(context instanceof Direction ctx)) { + return null; + } + + if (ctx == Direction.UP | ctx == Direction.DOWN) { if (blockCapability == Capabilities.ItemHandler.BLOCK) { return (T) new InvWrapper(this); } return null; } - ItemStack itemStack = getItem(0); + int slot = switch (ctx) { + case DOWN, UP -> throw new IllegalStateException("Trying to read UP or DOWN direction of capabilities"); + case NORTH -> 0; + case EAST -> 1; + case SOUTH -> 2; + case WEST -> 3; + }; + + ItemStack itemStack = getItem(slot); ItemCapability itemCapability = blockCapabilityToItemCapability(blockCapability); if (itemCapability == null) { return null; diff --git a/src/main/java/ca/teamdman/sfm/common/containermenu/ProxyContainerMenu.java b/src/main/java/ca/teamdman/sfm/common/containermenu/ProxyContainerMenu.java index 5bd215aed..1311b9bf9 100644 --- a/src/main/java/ca/teamdman/sfm/common/containermenu/ProxyContainerMenu.java +++ b/src/main/java/ca/teamdman/sfm/common/containermenu/ProxyContainerMenu.java @@ -3,6 +3,7 @@ import ca.teamdman.sfm.common.blockentity.ProxyBlockEntity; import ca.teamdman.sfm.common.registry.SFMMenus; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.util.Tuple; import net.minecraft.world.Container; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; @@ -10,9 +11,19 @@ import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; +import java.util.List; + public class ProxyContainerMenu extends AbstractContainerMenu { + public static final List> CONTAINER_SLOT_POSITIONS = List.of( + new Tuple<>(80, 17), + new Tuple<>(100, 37), + new Tuple<>(80, 57), + new Tuple<>(60, 37) + ); + + public static Tuple PLAYER_INV_START_POS = new Tuple<>(8, 90); + private final ProxyBlockEntity PROXY_BLOCK_ENTITY; - private final Inventory PLAYER_INVENTORY; public ProxyContainerMenu(int windowId, Inventory inventory, FriendlyByteBuf buf) { this(windowId, inventory, (ProxyBlockEntity) inventory.player.level().getBlockEntity(buf.readBlockPos())); @@ -22,14 +33,40 @@ public ProxyContainerMenu(int windowId, Inventory inventory, ProxyBlockEntity pr super(SFMMenus.PROXY_MENU.get(), windowId); PROXY_BLOCK_ENTITY = proxyBlockEntity; - PLAYER_INVENTORY = inventory; - addContainerSlot(proxyBlockEntity); + createContainerSlot(PROXY_BLOCK_ENTITY); + createPlayerInventory(inventory); + } + + public static void encode(ProxyBlockEntity pbe, FriendlyByteBuf buf) { + buf.writeBlockPos(pbe.getBlockPos()); } @Override public ItemStack quickMoveStack(Player pPlayer, int pIndex) { - return null; + var slot = this.slots.get(pIndex); + if (!slot.hasItem()) return ItemStack.EMPTY; + + var containerEnd = PROXY_BLOCK_ENTITY.getContainerSize(); + var inventoryEnd = this.slots.size(); + + var contents = slot.getItem(); + var result = contents.copy(); + + if (pIndex < containerEnd) { + // clicked slot in container + if (!this.moveItemStackTo(contents, containerEnd, inventoryEnd, true)) return ItemStack.EMPTY; + } else { + // clicked slot in inventory + if (!this.moveItemStackTo(contents, 0, containerEnd, false)) return ItemStack.EMPTY; + } + + if (contents.isEmpty()) { + slot.set(ItemStack.EMPTY); + } else { + slot.setChanged(); + } + return result; } @Override @@ -37,24 +74,29 @@ public boolean stillValid(Player pPlayer) { return PROXY_BLOCK_ENTITY.stillValid(pPlayer); } - private void addContainerSlot(Container container) { - addSlot(new Slot( - container, - 0, - 81, - 5 - )); - } - - private void addPlayerInventory(Inventory inventory) { + private void createContainerSlot(Container container) { + for (int slot = 0; slot < CONTAINER_SLOT_POSITIONS.size(); slot++) { + Tuple pos = CONTAINER_SLOT_POSITIONS.get(slot); + addSlot( + new Slot(container, slot, pos.getA(), pos.getB()) + ); + } } - private void addPlayerHotbar(Inventory inventory) { - } - - private void addInternalItemSlots() { - } + private void createPlayerInventory(Inventory playerInv) { + int xPos = PLAYER_INV_START_POS.getA(); + int yPos = PLAYER_INV_START_POS.getB(); + for (int row = 0; row < 3; row++) { + for (int column = 0; column < 9; column++) { + addSlot(new Slot(playerInv, + 9 + column + (row * 9), + xPos + (column * 18), + yPos + (row * 18))); + } + } - private void addInternalTanks() { + for (int column = 0; column < 9; column++) { + this.addSlot(new Slot(playerInv, column, xPos + column * 18, yPos + (18 * 3) + 4)); + } } } diff --git a/src/main/resources/assets/sfm/textures/gui/container/proxy.png b/src/main/resources/assets/sfm/textures/gui/container/proxy.png index 08276c01f4eb95c1493c0558c80c9644c1f7a348..21ac6c68421dfd18acfd3ab875bda4a6f8dda693 100644 GIT binary patch delta 754 zcmcbsd_ZNwZ6#v^1w%tCLjx;ALk30$#s$nkk^zi?6hpv_W4|{3y~V7Ol4g{YnrLXM zYiep?rfZUBoTi&(m}sP%m~3KUmS}EiV3C$O`8SKailKp-L7Ih$fo_VWrKPS(YMPm@ zrJ+Hxu9=BtTB@m;ak8F z;xXCq;vO(0HhH=@hE&{odnYi9$xy=e;SOeI-dK-tg&mCnkJz$mr(Y`heU`;KLB@c2 za*S2+xyv?J`)3^6ubI)4d+}b#_TQNox5|CE#Uk+Cm|;5GT>h^O9H4MzU#=B1~oV*k;_Q3cX$E+K?#VlYT+=!1LKV{2CrI?3>T@DaYhY zx>LjJA7VaCO;Q)iS@&o&+T}OqH57@w<@H$qY)O7&=~0y%)xx)mgx>6BS~rKqTHd99 zazg#{#TBpTw*^m5xLR_;=Y;J;tM{Dq(`;KZ!n2c`|Q8wG+gP31=HVetKBDu>Eq(f%{uNZ@u8m0+C?&V}79G=ZC!) zoKuvTph5 gk4hHRJC;)b<ktANoY#u7G}SB$ein?1O?nte&TfWzr}kCs23u9H+e cVTkv#{=th^C+rXL^aAPhboFyt=akR{03HO@0RR91 From e8bb4060a1f6df68eda5dbee069391f80115c22a Mon Sep 17 00:00:00 2001 From: Burkino <24849979+Burkino@users.noreply.github.com> Date: Thu, 31 Oct 2024 12:40:50 -0400 Subject: [PATCH 4/4] Try and optimize reusing the same label multiple times --- .../common/program/CapabilityConsumer.java | 3 +- .../sfm/common/resourcetype/ResourceType.java | 8 ++-- .../ca/teamdman/sfml/ast/InputStatement.java | 23 ++++++----- .../ca/teamdman/sfml/ast/OutputStatement.java | 40 ++++++++++--------- .../teamdman/sfml/ast/ResourceComparer.java | 2 +- .../java/ca/teamdman/sfml/ast/RoundRobin.java | 15 ++++--- 6 files changed, 51 insertions(+), 40 deletions(-) diff --git a/src/main/java/ca/teamdman/sfm/common/program/CapabilityConsumer.java b/src/main/java/ca/teamdman/sfm/common/program/CapabilityConsumer.java index d34272c3c..40c3ee84c 100644 --- a/src/main/java/ca/teamdman/sfm/common/program/CapabilityConsumer.java +++ b/src/main/java/ca/teamdman/sfm/common/program/CapabilityConsumer.java @@ -10,6 +10,7 @@ void accept( Label label, BlockPos pos, Direction direction, - T cap + T cap, + int count ); } diff --git a/src/main/java/ca/teamdman/sfm/common/resourcetype/ResourceType.java b/src/main/java/ca/teamdman/sfm/common/resourcetype/ResourceType.java index ba3e52bcb..30f6c0c23 100644 --- a/src/main/java/ca/teamdman/sfm/common/resourcetype/ResourceType.java +++ b/src/main/java/ca/teamdman/sfm/common/resourcetype/ResourceType.java @@ -16,7 +16,7 @@ import net.neoforged.neoforge.capabilities.BlockCapability; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; +import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.stream.Stream; @@ -120,12 +120,12 @@ public void forEachCapability( CableNetwork network = programContext.getNetwork(); RoundRobin roundRobin = labelAccess.roundRobin(); LabelPositionHolder labelPositionHolder = programContext.getLabelPositionHolder(); - ArrayList> positions = roundRobin.getPositionsForLabels( + HashMap, Integer> positions = roundRobin.getPositionsForLabels( labelAccess, labelPositionHolder ); - for (var pair : positions) { + for (var pair : positions.keySet()) { Label label = pair.getFirst(); BlockPos pos = pair.getSecond(); // Expand pos to (pos, direction) pairs @@ -143,7 +143,7 @@ public void forEachCapability( pos, dir ))); - consumer.accept(label, pos, dir, cap); + consumer.accept(label, pos, dir, cap, positions.get(pair)); continue; } } diff --git a/src/main/java/ca/teamdman/sfml/ast/InputStatement.java b/src/main/java/ca/teamdman/sfml/ast/InputStatement.java index 1c2f742f7..aedaff04d 100644 --- a/src/main/java/ca/teamdman/sfml/ast/InputStatement.java +++ b/src/main/java/ca/teamdman/sfml/ast/InputStatement.java @@ -96,10 +96,10 @@ public void gatherSlots( // gather slots for each capability found for positions tagged by a provided label Consumer> finalSlotConsumer = slotConsumer; // TODO: fix #166 forEachCapability advances the round robin when it should be shared between resource types - resourceType.forEachCapability(context, labelAccess, (label, pos, direction, cap) -> gatherSlotsForCap( + resourceType.forEachCapability(context, labelAccess, (label, pos, direction, cap, count) -> gatherSlotsForCap( context, (ResourceType) resourceType, - label, pos, direction, cap, + label, pos, direction, cap, count, inputTrackers, finalSlotConsumer )); @@ -119,12 +119,12 @@ public void gatherSlots( // gather slots for each capability found for positions tagged by a provided label Consumer> finalSlotConsumer = slotConsumer; - resourceType.forEachCapability(context, labelAccess, (label, pos, direction, cap) -> { + resourceType.forEachCapability(context, labelAccess, (label, pos, direction, cap, count) -> { List inputTrackers = resourceLimits.createInputTrackers(); gatherSlotsForCap( context, (ResourceType) resourceType, - label, pos, direction, cap, + label, pos, direction, cap, count, inputTrackers, finalSlotConsumer ); @@ -237,6 +237,7 @@ private void gatherSlotsForCap( BlockPos pos, Direction direction, CAP capability, + int count, List trackers, Consumer> acceptor ) { @@ -258,12 +259,14 @@ private void gatherSlotsForCap( stack, tracker.toString() ))); - acceptor.accept(LimitedInputSlotObjectPool.acquire( - label, pos, direction, slot, capability, - tracker, - stack, - type - )); + for (int i = 0; i < count; i++) { + acceptor.accept(LimitedInputSlotObjectPool.acquire( + label, pos, direction, slot, capability, + tracker, + stack, + type + )); + } } } } else { diff --git a/src/main/java/ca/teamdman/sfml/ast/OutputStatement.java b/src/main/java/ca/teamdman/sfml/ast/OutputStatement.java index 63607ba35..ff290e638 100644 --- a/src/main/java/ca/teamdman/sfml/ast/OutputStatement.java +++ b/src/main/java/ca/teamdman/sfml/ast/OutputStatement.java @@ -5,11 +5,8 @@ import ca.teamdman.sfm.common.program.*; import ca.teamdman.sfm.common.registry.SFMResourceTypes; import ca.teamdman.sfm.common.resourcetype.ResourceType; -import com.mojang.math.Constants; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.core.component.DataComponents; -import net.minecraft.world.item.ItemStack; import java.util.ArrayDeque; import java.util.List; @@ -357,13 +354,14 @@ public void gatherSlots( resourceType.displayAsCapabilityClass() ))); resourceType.forEachCapability(context, labelAccess, ( - (label, pos, direction, cap) -> gatherSlotsForCap( + (label, pos, direction, cap, count) -> gatherSlotsForCap( context, (ResourceType) resourceType, label, pos, direction, cap, + count, outputTracker, slotConsumer ) @@ -378,7 +376,7 @@ public void gatherSlots( resourceType.displayAsCapabilityClass(), resourceType.displayAsCapabilityClass() ))); - resourceType.forEachCapability(context, labelAccess, (label, pos, direction, cap) -> { + resourceType.forEachCapability(context, labelAccess, (label, pos, direction, cap, count) -> { // create a new list of trackers for each limited slot List outputTracker = resourceLimits.createOutputTrackers(); gatherSlotsForCap( @@ -388,6 +386,7 @@ public void gatherSlots( pos, direction, cap, + count, outputTracker, slotConsumer ); @@ -461,6 +460,7 @@ private void gatherSlotsForCap( BlockPos pos, Direction direction, CAP capability, + int count, List trackers, Consumer> acceptor ) { @@ -485,26 +485,28 @@ private void gatherSlotsForCap( stack, tracker.toString() ))); - acceptor.accept(LimitedOutputSlotObjectPool.acquire( - label, - pos, - direction, - slot, - capability, - tracker, - stack, - type - )); + for (int i = 0; i < count; i++) { + acceptor.accept(LimitedOutputSlotObjectPool.acquire( + label, + pos, + direction, + slot, + capability, + tracker, + stack, + type + )); + } } else { context .getLogger() .debug(x -> x.accept(LocalizationKeys.LOG_PROGRAM_TICK_IO_STATEMENT_GATHER_SLOTS_SLOT_SHOULD_NOT_CREATE.get( finalSlot, type.getAmount(stack) - + " of " - + Math.min(type.getMaxStackSize(stack), type.getMaxStackSizeForSlot(capability, finalSlot)) - + " " - + type.getItem(stack) + + " of " + + Math.min(type.getMaxStackSize(stack), type.getMaxStackSizeForSlot(capability, finalSlot)) + + " " + + type.getItem(stack) ))); } } diff --git a/src/main/java/ca/teamdman/sfml/ast/ResourceComparer.java b/src/main/java/ca/teamdman/sfml/ast/ResourceComparer.java index 69c20b520..a94c3b02a 100644 --- a/src/main/java/ca/teamdman/sfml/ast/ResourceComparer.java +++ b/src/main/java/ca/teamdman/sfml/ast/ResourceComparer.java @@ -21,7 +21,7 @@ public BoolExpr toBooleanExpression(SetOperator setOp, LabelAccess labelAccess, AtomicLong overallCount = new AtomicLong(0); // track how many inventories satisfied the condition List satisfiedSet = new ArrayList<>(); - type.forEachCapability(context, labelAccess, (label, pos, direction, cap) -> { + type.forEachCapability(context, labelAccess, (label, pos, direction, cap, count) -> { long inThisInv = 0; for (var stack : (Iterable) type.getStacksInSlots(cap, labelAccess.slots())::iterator) { if (this.res.matchesStack(stack)) { diff --git a/src/main/java/ca/teamdman/sfml/ast/RoundRobin.java b/src/main/java/ca/teamdman/sfml/ast/RoundRobin.java index cdd1083ae..73e2b4726 100644 --- a/src/main/java/ca/teamdman/sfml/ast/RoundRobin.java +++ b/src/main/java/ca/teamdman/sfml/ast/RoundRobin.java @@ -7,6 +7,7 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; public class RoundRobin implements ASTNode { @@ -43,17 +44,19 @@ public boolean isEnabled() { return behaviour != Behaviour.UNMODIFIED; } - public @NotNull ArrayList> getPositionsForLabels( + public @NotNull HashMap, Integer> getPositionsForLabels( LabelAccess labelAccess, LabelPositionHolder labelPositionHolder ) { - ArrayList> positions = new ArrayList<>(); + HashMap, Integer> positions = new HashMap<>(); + switch (getBehaviour()) { case BY_LABEL -> { int index = next(labelAccess.labels().size()); Label label = labelAccess.labels().get(index); for (BlockPos pos : labelPositionHolder.getPositions(label.name())) { - positions.add(Pair.of(label, pos)); + Pair pair = Pair.of(label, pos); + positions.put(pair, positions.getOrDefault(pair, 0) + 1); } } case BY_BLOCK -> { @@ -66,13 +69,15 @@ public boolean isEnabled() { } } if (!candidates.isEmpty()) { - positions.add(candidates.get(next(candidates.size()))); + Pair pair = candidates.get(next(candidates.size())); + positions.put(pair, positions.getOrDefault(pair, 0) + 1); } } case UNMODIFIED -> { for (Label label : labelAccess.labels()) { for (BlockPos pos : labelPositionHolder.getPositions(label.name())) { - positions.add(Pair.of(label, pos)); + Pair pair = Pair.of(label, pos); + positions.put(pair, positions.getOrDefault(pair, 0) + 1); } } }