From cc66e0d5d92db5b09becb9a5f8eb34f234d36dd6 Mon Sep 17 00:00:00 2001 From: Jottyfan Date: Wed, 31 Dec 2025 20:43:19 +0100 Subject: [PATCH] basic block stacker, but still with bugs --- .../minecraft/block/BlockStacker.java | 84 +++++++++ .../minecraft/block/QuicklyBlocks.java | 6 +- .../blockentity/BlockStackerEntity.java | 168 ++++++++++++++++++ .../quickly/blockstates/blockstacker.json | 10 ++ .../{drilleast.json => blockstacker.json} | 2 +- .../assets/quickly/items/drillnorth.json | 6 - .../assets/quickly/items/drillsouth.json | 6 - .../assets/quickly/items/drillwest.json | 6 - .../resources/assets/quickly/lang/de_de.json | 1 + .../resources/assets/quickly/lang/en_us.json | 1 + .../models/block/blockstackerdown.json | 8 + .../models/block/blockstackereast.json | 11 ++ .../models/block/blockstackernorth.json | 11 ++ .../models/block/blockstackersouth.json | 11 ++ .../quickly/models/block/blockstackerup.json | 8 + .../models/block/blockstackerwest.json | 11 ++ .../quickly/models/item/blockstacker.json | 10 ++ .../textures/block/blockstackerdown.png | Bin 0 -> 6906 bytes .../quickly/textures/block/blockstackerin.png | Bin 0 -> 6700 bytes .../textures/block/blockstackerleft.png | Bin 0 -> 6916 bytes .../textures/block/blockstackerout.png | Bin 0 -> 6691 bytes .../textures/block/blockstackerright.png | Bin 0 -> 6929 bytes .../quickly/textures/block/blockstackerup.png | Bin 0 -> 6705 bytes .../quickly/recipe/shaped_blockstacker.json | 19 ++ 24 files changed, 359 insertions(+), 20 deletions(-) create mode 100644 src/main/java/de/jottyfan/minecraft/block/BlockStacker.java create mode 100644 src/main/java/de/jottyfan/minecraft/blockentity/BlockStackerEntity.java create mode 100644 src/main/resources/assets/quickly/blockstates/blockstacker.json rename src/main/resources/assets/quickly/items/{drilleast.json => blockstacker.json} (53%) delete mode 100644 src/main/resources/assets/quickly/items/drillnorth.json delete mode 100644 src/main/resources/assets/quickly/items/drillsouth.json delete mode 100644 src/main/resources/assets/quickly/items/drillwest.json create mode 100644 src/main/resources/assets/quickly/models/block/blockstackerdown.json create mode 100644 src/main/resources/assets/quickly/models/block/blockstackereast.json create mode 100644 src/main/resources/assets/quickly/models/block/blockstackernorth.json create mode 100644 src/main/resources/assets/quickly/models/block/blockstackersouth.json create mode 100644 src/main/resources/assets/quickly/models/block/blockstackerup.json create mode 100644 src/main/resources/assets/quickly/models/block/blockstackerwest.json create mode 100644 src/main/resources/assets/quickly/models/item/blockstacker.json create mode 100644 src/main/resources/assets/quickly/textures/block/blockstackerdown.png create mode 100644 src/main/resources/assets/quickly/textures/block/blockstackerin.png create mode 100644 src/main/resources/assets/quickly/textures/block/blockstackerleft.png create mode 100644 src/main/resources/assets/quickly/textures/block/blockstackerout.png create mode 100644 src/main/resources/assets/quickly/textures/block/blockstackerright.png create mode 100644 src/main/resources/assets/quickly/textures/block/blockstackerup.png create mode 100644 src/main/resources/data/quickly/recipe/shaped_blockstacker.json diff --git a/src/main/java/de/jottyfan/minecraft/block/BlockStacker.java b/src/main/java/de/jottyfan/minecraft/block/BlockStacker.java new file mode 100644 index 0000000..3ef6b40 --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/block/BlockStacker.java @@ -0,0 +1,84 @@ +package de.jottyfan.minecraft.block; + +import org.jspecify.annotations.Nullable; + +import com.mojang.serialization.MapCodec; + +import de.jottyfan.minecraft.blockentity.BlockStackerEntity; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition.Builder; +import net.minecraft.world.level.block.state.properties.EnumProperty; + +/** + * + * @author jotty + * + */ +public class BlockStacker extends Block implements EntityBlock { + public static final MapCodec CODEC = simpleCodec(BlockStacker::new); + + public static final EnumProperty SOURCE = EnumProperty.create("source", Direction.class, Direction.NORTH, + Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN); + public static final EnumProperty DEST = EnumProperty.create("dest", Direction.class, Direction.NORTH, + Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN); + + public BlockStacker(Properties properties) { + super(properties); + registerDefaultState(stateDefinition.any().setValue(SOURCE, Direction.UP).setValue(DEST, Direction.DOWN)); + } + + @Override + protected void createBlockStateDefinition(Builder builder) { + builder.add(SOURCE, DEST); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + return this.defaultBlockState().setValue(SOURCE, context.getNearestLookingDirection()).setValue(DEST, context.getNearestLookingDirection().getOpposite()); + } + + @Override + public @Nullable BlockEntityTicker getTicker(Level level, BlockState blockState, + BlockEntityType type) { + return (lambdaLevel, pos, state, blockEntity) -> BlockStackerEntity.tick(lambdaLevel, pos, state, blockEntity); + } + + @Override + public @Nullable BlockEntity newBlockEntity(BlockPos pos, BlockState blockState) { + return new BlockStackerEntity(pos, blockState); + } + + public static MapCodec getCodec() { + return CODEC; + } + + public Direction getSource(BlockState state) { + return state.getValue(SOURCE); + } + + public Direction getDest(BlockState state) { + return state.getValue(DEST); + } + + public BlockPos getOffset(BlockState state, EnumProperty sourceOrDest) { + BlockPos pos = new BlockPos(0, 0, 0); + return switch (state.getValue(sourceOrDest)) { + case Direction.UP -> pos.above(); + case Direction.DOWN -> pos.below(); + case Direction.NORTH -> pos.north(); + case Direction.EAST -> pos.east(); + case Direction.SOUTH -> pos.south(); + case Direction.WEST -> pos.west(); + default -> pos; + }; + } +} diff --git a/src/main/java/de/jottyfan/minecraft/block/QuicklyBlocks.java b/src/main/java/de/jottyfan/minecraft/block/QuicklyBlocks.java index da39415..041b862 100644 --- a/src/main/java/de/jottyfan/minecraft/block/QuicklyBlocks.java +++ b/src/main/java/de/jottyfan/minecraft/block/QuicklyBlocks.java @@ -4,6 +4,7 @@ import java.util.function.Function; import de.jottyfan.minecraft.Quickly; import de.jottyfan.minecraft.blockentity.BlockEntityRegister; +import de.jottyfan.minecraft.blockentity.BlockStackerEntity; import de.jottyfan.minecraft.blockentity.DrillBlockEntity; import de.jottyfan.minecraft.blockentity.ItemHoarderBlockEntity; import de.jottyfan.minecraft.item.QuicklyItems; @@ -55,8 +56,8 @@ public class QuicklyBlocks { properties -> new Monsterhoarder(properties)); public static final Block ITEMHOARDER = registerBlock("itemhoarder", properties -> new Itemhoarder(properties)); public static final Block DRILL = registerBlock("drill", properties -> new BlockDrill(properties)); + public static final Block STACKER = registerBlock("blockstacker", properties -> new BlockStacker(properties.strength(2.5f))); - // TODO: add blockstacker // TODO: add salpeter ore, sulfor ore // TODO: merge lavahoarder and emptylavahoarder into one block using a BooleanProperty for the lava fill state @@ -64,6 +65,8 @@ public class QuicklyBlocks { .registerBlockEntity("itemhoarderblockentity", ItemHoarderBlockEntity::new, ITEMHOARDER); public static final BlockEntityType BLOCKENTITY_DRILL = new BlockEntityRegister() .registerBlockEntity("drillblockentity", DrillBlockEntity::new, DRILL); + public static final BlockEntityType BLOCKSTACKER_BLOCKENTITY = new BlockEntityRegister() + .registerBlockEntity("blockstackerentity", BlockStackerEntity::new, STACKER); private static final Block registerBlock(String name, Properties properties) { return QuicklyBlocks.registerBlock(name, properties, p -> new Block(p)); @@ -95,6 +98,7 @@ public class QuicklyBlocks { block.accept(MONSTERHOARDER); block.accept(ITEMHOARDER); block.accept(DRILL); + block.accept(STACKER); }); } } diff --git a/src/main/java/de/jottyfan/minecraft/blockentity/BlockStackerEntity.java b/src/main/java/de/jottyfan/minecraft/blockentity/BlockStackerEntity.java new file mode 100644 index 0000000..dcc780a --- /dev/null +++ b/src/main/java/de/jottyfan/minecraft/blockentity/BlockStackerEntity.java @@ -0,0 +1,168 @@ +package de.jottyfan.minecraft.blockentity; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.jspecify.annotations.Nullable; + +import com.mojang.serialization.Codec; + +import de.jottyfan.minecraft.Quickly; +import de.jottyfan.minecraft.block.BlockStacker; +import de.jottyfan.minecraft.block.QuicklyBlocks; +import net.minecraft.core.BlockPos; +import net.minecraft.world.Container; +import net.minecraft.world.entity.SlotAccess; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BaseContainerBlockEntity; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; + +/** + * + * @author jotty + * + */ +public class BlockStackerEntity extends BlockEntity implements Container { + + public static final Codec> ITEM_STACK_MAP_CODEC = Codec.unboundedMap(Codec.STRING, + ItemStack.CODEC); + + private List inventory = new ArrayList<>(); + + public BlockStackerEntity(BlockPos pos, BlockState blockState) { + super(QuicklyBlocks.BLOCKSTACKER_BLOCKENTITY, pos, blockState); + } + + public static Object tick(Level level, BlockPos pos, BlockState state, T entity) { + pos.below(); + BlockStacker block = (BlockStacker) state.getBlock(); + BlockEntity source = level.getBlockEntity(pos.offset(block.getOffset(state, BlockStacker.SOURCE))); + BlockEntity dest = level.getBlockEntity(pos.offset(block.getOffset(state, BlockStacker.DEST))); + Boolean sourceIsLootable = source instanceof BaseContainerBlockEntity; + Boolean destIsLootable = dest instanceof BaseContainerBlockEntity; + if (sourceIsLootable && destIsLootable) { + BaseContainerBlockEntity lootableSource = (BaseContainerBlockEntity) source; + BaseContainerBlockEntity lootableDest = (BaseContainerBlockEntity) dest; + transferOneStack(lootableSource, lootableDest); + } + return null; + } + + public static final Boolean transferOneStack(BaseContainerBlockEntity source, BaseContainerBlockEntity dest) { + Boolean result = false; + Integer sourceSlot = findItemStackPos(source, false); + if (sourceSlot != null && !Items.AIR.equals(source.getSlot(sourceSlot).get().getItem())) { + ItemStack sourceStack = source.getSlot(sourceSlot).get(); + Integer destSlot = findItemStackPos(dest, sourceStack); + if (destSlot != null) { + ItemStack destStack = dest.getSlot(destSlot).get(); + Integer occupied = destStack.getCount(); + Integer free = destStack.getCount() - occupied; + Integer candidates = sourceStack.getCount(); + Integer travellers = candidates > free ? free : candidates; + if (travellers > 0) { + Quickly.LOGGER.debug("transfer {}/{} of {} from slot {} to slot {} on top of {} ones", travellers, candidates, + sourceStack.getItem().toString(), sourceSlot, destSlot, occupied); + sourceStack.shrink(travellers); + destStack.grow(travellers); + result = true; + } + } else { + Integer destFreeSlot = findItemStackPos(dest, true); + if (destFreeSlot != null) { + Quickly.LOGGER.debug("transfer all of {} from slot {} to slot {}", sourceStack.getItem().toString(), + sourceSlot, destSlot); + dest.setItem(destFreeSlot, new ItemStack(sourceStack.getItem(), sourceStack.getCount())); + sourceStack.shrink(sourceSlot); + result = true; + } + } + } + return result; + } + + private static final Integer findItemStackPos(BaseContainerBlockEntity blockEntity, ItemStack sourceStack) { + Integer counter = blockEntity.getContainerSize(); + while (counter > 0) { + counter--; + @Nullable + SlotAccess slotAccess = blockEntity.getSlot(counter); + if (slotAccess != null) { + ItemStack stack = slotAccess.get(); + if (sourceStack.getItem().equals(stack.getItem())) { + if (stack.getCount() < stack.getCount()) { + return counter; + } + } + } + } + return null; + } + + private static final Integer findItemStackPos(BaseContainerBlockEntity blockEntity, Boolean empty) { + Integer counter = blockEntity.getContainerSize(); + while (counter > 0) { + counter--; + @Nullable + SlotAccess slotAccess = blockEntity.getSlot(counter); + if (slotAccess != null) { + ItemStack stack = slotAccess.get(); + if (empty.equals(ItemStack.EMPTY.equals(stack))) { + return counter; + } + } + } + return null; + } + + @Override + public void clearContent() { + inventory.clear(); + } + + @Override + public int getContainerSize() { + return inventory.size(); + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public ItemStack getItem(int slot) { + return inventory.get(slot); + } + + @Override + public ItemStack removeItem(int slot, int count) { + ItemStack stack = inventory.get(slot); + stack.shrink(count); + setChanged(); + return stack; + } + + @Override + public ItemStack removeItemNoUpdate(int slot) { + ItemStack stack = inventory.get(slot); + stack.shrink(stack.getCount()); + return stack; + } + + @Override + public void setItem(int slot, ItemStack itemStack) { + inventory.set(slot, itemStack); + setChanged(); + } + + @Override + public boolean stillValid(Player player) { + return false; + } +} diff --git a/src/main/resources/assets/quickly/blockstates/blockstacker.json b/src/main/resources/assets/quickly/blockstates/blockstacker.json new file mode 100644 index 0000000..954ce9e --- /dev/null +++ b/src/main/resources/assets/quickly/blockstates/blockstacker.json @@ -0,0 +1,10 @@ +{ + "variants": { + "dest=up": { "model": "quickly:block/blockstackerup" }, + "dest=down": { "model": "quickly:block/blockstackerdown" }, + "dest=east": { "model": "quickly:block/blockstackereast" }, + "dest=south": { "model": "quickly:block/blockstackersouth" }, + "dest=west": { "model": "quickly:block/blockstackerwest" }, + "dest=north": { "model": "quickly:block/blockstackernorth" } + } +} diff --git a/src/main/resources/assets/quickly/items/drilleast.json b/src/main/resources/assets/quickly/items/blockstacker.json similarity index 53% rename from src/main/resources/assets/quickly/items/drilleast.json rename to src/main/resources/assets/quickly/items/blockstacker.json index f75faf3..c6679dd 100644 --- a/src/main/resources/assets/quickly/items/drilleast.json +++ b/src/main/resources/assets/quickly/items/blockstacker.json @@ -1,6 +1,6 @@ { "model": { "type": "minecraft:model", - "model": "quickly:block/drilleast" + "model": "quickly:block/blockstackerdown" } } \ No newline at end of file diff --git a/src/main/resources/assets/quickly/items/drillnorth.json b/src/main/resources/assets/quickly/items/drillnorth.json deleted file mode 100644 index 764cc6a..0000000 --- a/src/main/resources/assets/quickly/items/drillnorth.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "model": { - "type": "minecraft:model", - "model": "quickly:block/drillnorth" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/items/drillsouth.json b/src/main/resources/assets/quickly/items/drillsouth.json deleted file mode 100644 index b43952a..0000000 --- a/src/main/resources/assets/quickly/items/drillsouth.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "model": { - "type": "minecraft:model", - "model": "quickly:block/drillsouth" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/items/drillwest.json b/src/main/resources/assets/quickly/items/drillwest.json deleted file mode 100644 index c304011..0000000 --- a/src/main/resources/assets/quickly/items/drillwest.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "model": { - "type": "minecraft:model", - "model": "quickly:block/drillwest" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/lang/de_de.json b/src/main/resources/assets/quickly/lang/de_de.json index 2f77633..5a267ad 100644 --- a/src/main/resources/assets/quickly/lang/de_de.json +++ b/src/main/resources/assets/quickly/lang/de_de.json @@ -6,6 +6,7 @@ "item.quickly.blockcottonplant": "Baumwollpflanze", "item.quickly.blockquickiepowder": "Eilpulverblock", "item.quickly.blockspeedpowder": "Fluchtpulverblock", + "item.quickly.blockstacker": "Stapler", "item.quickly.blockturquoise": "Türkisblock", "item.quickly.canola": "Raps", "item.quickly.canolabottle": "Rapsöl", diff --git a/src/main/resources/assets/quickly/lang/en_us.json b/src/main/resources/assets/quickly/lang/en_us.json index 35972b8..98bf0d3 100644 --- a/src/main/resources/assets/quickly/lang/en_us.json +++ b/src/main/resources/assets/quickly/lang/en_us.json @@ -6,6 +6,7 @@ "item.quickly.blockcottonplant": "cotton plant", "item.quickly.blockquickiepowder": "quickie powder block", "item.quickly.blockspeedpowder": "speed powder block", + "item.quickly.blockstacker": "stacker", "item.quickly.blockturquoise": "block of turquoise", "item.quickly.canola": "canola", "item.quickly.canolabottle": "canola oil", diff --git a/src/main/resources/assets/quickly/models/block/blockstackerdown.json b/src/main/resources/assets/quickly/models/block/blockstackerdown.json new file mode 100644 index 0000000..5212c2e --- /dev/null +++ b/src/main/resources/assets/quickly/models/block/blockstackerdown.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "bottom": "quickly:block/blockstackerout", + "side": "quickly:block/blockstackerdown", + "top": "quickly:block/blockstackerin" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/models/block/blockstackereast.json b/src/main/resources/assets/quickly/models/block/blockstackereast.json new file mode 100644 index 0000000..1af2d4a --- /dev/null +++ b/src/main/resources/assets/quickly/models/block/blockstackereast.json @@ -0,0 +1,11 @@ +{ + "parent": "block/cube_directional", + "textures": { + "up": "quickly:block/blockstackerright", + "down": "quickly:block/blockstackerleft", + "north": "quickly:block/blockstackerleft", + "east": "quickly:block/blockstackerout", + "south": "quickly:block/blockstackerright", + "west": "quickly:block/blockstackerin" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/models/block/blockstackernorth.json b/src/main/resources/assets/quickly/models/block/blockstackernorth.json new file mode 100644 index 0000000..c7db1ac --- /dev/null +++ b/src/main/resources/assets/quickly/models/block/blockstackernorth.json @@ -0,0 +1,11 @@ +{ + "parent": "block/cube_directional", + "textures": { + "up": "quickly:block/blockstackerup", + "down": "quickly:block/blockstackerup", + "north": "quickly:block/blockstackerout", + "east": "quickly:block/blockstackerup", + "south": "quickly:block/blockstackerin", + "west": "quickly:block/blockstackerup" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/models/block/blockstackersouth.json b/src/main/resources/assets/quickly/models/block/blockstackersouth.json new file mode 100644 index 0000000..146a849 --- /dev/null +++ b/src/main/resources/assets/quickly/models/block/blockstackersouth.json @@ -0,0 +1,11 @@ +{ + "parent": "block/cube_directional", + "textures": { + "up": "quickly:block/blockstackerdown", + "down": "quickly:block/blockstackerdown", + "north": "quickly:block/blockstackerin", + "east": "quickly:block/blockstackerdown", + "south": "quickly:block/blockstackerout", + "west": "quickly:block/blockstackerdown" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/models/block/blockstackerup.json b/src/main/resources/assets/quickly/models/block/blockstackerup.json new file mode 100644 index 0000000..097f32d --- /dev/null +++ b/src/main/resources/assets/quickly/models/block/blockstackerup.json @@ -0,0 +1,8 @@ +{ + "parent": "block/cube_bottom_top", + "textures": { + "bottom": "quickly:block/blockstackerin", + "side": "quickly:block/blockstackerup", + "top": "quickly:block/blockstackerout" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/models/block/blockstackerwest.json b/src/main/resources/assets/quickly/models/block/blockstackerwest.json new file mode 100644 index 0000000..89541c5 --- /dev/null +++ b/src/main/resources/assets/quickly/models/block/blockstackerwest.json @@ -0,0 +1,11 @@ +{ + "parent": "block/cube_directional", + "textures": { + "up": "quickly:block/blockstackerleft", + "down": "quickly:block/blockstackerright", + "north": "quickly:block/blockstackerright", + "east": "quickly:block/blockstackerin", + "south": "quickly:block/blockstackerleft", + "west": "quickly:block/blockstackerout" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/models/item/blockstacker.json b/src/main/resources/assets/quickly/models/item/blockstacker.json new file mode 100644 index 0000000..909df1e --- /dev/null +++ b/src/main/resources/assets/quickly/models/item/blockstacker.json @@ -0,0 +1,10 @@ +{ + "parent": "quickly:block/blockstackerdown", + "display": { + "thirdperson": { + "rotation": [ 10, -45, 170 ], + "translation": [ 0, 1.5, -2.75 ], + "scale": [ 0.375, 0.375, 0.375 ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickly/textures/block/blockstackerdown.png b/src/main/resources/assets/quickly/textures/block/blockstackerdown.png new file mode 100644 index 0000000000000000000000000000000000000000..558ce819aaccdc4baba31deb1a906230e91eafd3 GIT binary patch literal 6906 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 EFG|}WF#rGn literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/quickly/textures/block/blockstackerleft.png b/src/main/resources/assets/quickly/textures/block/blockstackerleft.png new file mode 100644 index 0000000000000000000000000000000000000000..fb5e2806600cc2435d95015c1b96344d9886e5f4 GIT binary patch literal 6916 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/quickly/textures/block/blockstackerright.png b/src/main/resources/assets/quickly/textures/block/blockstackerright.png new file mode 100644 index 0000000000000000000000000000000000000000..639579084c5fe9b0947e248553f602700dd19baa GIT binary patch literal 6929 zcmeHMcTiK?)(^cGks{JUzycW3tArw<#7pRcfFjAs2}B7AN$3KCSg|0AST3R>hy|Vk zDv0HJDPAw4C?cqM!A4U-K&0z;0@itN=9@d;cW2%oX67XOti9H6t@Yb$oxRUwo42Q% zhU$D(7!0PtaHso1zuMAESq}PMjMVaj!IapE{wpQEtT?z(B;fKQLAWGA2*Sa59v23S ze_R+Cl5Jt7KGm(8ByTCd^~Jj#ZANbfNmlfP%O_L0t$G(RF1 zvLE{U4#hL}{H~`q(!C&?|2YlqME-W_7E*LeMMQ`fj@>s*@Pl0!gu*(iJI=(SJ# zcl7L3rlln)s+#7T|AB$Oi4z`U9~*m_CCoZPc#|4i7L>kWO84Zb!i6Zl->aL>YrGQz z-w$7#+_nFliAqQMuYV1gjhfWu`y?#;l*#o88Ej2fz7O2H)Z=htjdSY@+?C>N?LLm@ z>cAswHP0`s4j&8@=2wLJTo5lMq zfF~?7j-n;o-CXXlj`eRk+y2O3vfcPJhQ19`bfBPKXPqj;*Td>n1><~IR^6)ues_Yz zw^nT2?#ev0;z9&+m8?5%zrX07@A8tSAoHr{z1!t35TlMUGD{2hAHH~ht=oj8_x#Bt z)gSJ^?wq4I2AtTlWf!*Z#5Vs!*cTo+uRQSKCjXEd$e`%LoZQl~zRW{6CZ3Ea74JD# zujM-#mf}+rbth1sPu*sOgVlQ~Z|&BQ(K$rohB7ipA|u=y$5eCdjvYqjPDU8`;=N?s z%WV|VIT z5TWEX7CYRJj)XtxHdJ{>u$vTSzK=K~i*4vPKGrm`>gMBDE1b>TM*nQe+jU6w=#77c zXfsNS){9OpC{Nnu#c@pXtaSwIW6tt!StxxFHTRXbF#;RVb3$K}y%Y?_m+w@FnL^(;gM6iD5Ep8V3o0XN`p6iZQWt@mb%6Y zo3cq*Z}YzL}0w8I0B>zV{dH|m+$M~Aq(2}5u>I$C{t=CV#f zG9$JmVBhaM={f9`Tm!}7#@b!CM@YTsy@xTTB@e8P^lx(qm3F74mqcRd?be6t=T$L_ z*u8OTg=6RkXNOaWm+6!G=bagD4SBQ|d1(5xOJjS+8$IQlxCfufn`NCFu62s%-%m!CgvGnWIan-0f&|> z?T!+z&X$9Dt19(gMn-oVuMy}NMVcY1+{?~#cAnl_J+8X;`p6OM?U?y(Iay0{>u$@t zE~>(~{gQIjap_R++cTZMFLrEEtYdF_wnC70{(M-zp>puTTI}j2kt(>U<*12H8_kEO zM>5omn_AZ!7GJBz?{+B<%MQAP95wEXk(nO1C>VSjQa3dJw^Z5gGEiln(Uj*Db#vR^ z@r@HJ7Z&Yky5i%hD9la1l8FbBmcD=Tv1gY?4{H3rjp(|5L5d}(Oh1s=ds*xCUw`c! zOmUIZiD_~umknwdvf3MScXQ~V{G&AWrjACDg#SENPJW5+`f@#3dwbdOWgHP!@POC% z>>}%S!9wAu?$^Vf#N^{QuF;yivT3V2?r|05tBWf8?byu9(KU%oa0jPu$Y|TbOXuWV zeIFFo)w5)`=O?@=dUr*oCZ(+_<3fPfJ*DJow29Z#qEIF_szw>yzqBsWcbDrc(zKqQ zYk*35SW%h%hSaS5@%QP1=2QCu)ca}6k2~(ZDkv)7dFp`Xnd-OdZW`@vuz0Not z#Czttz0zpoPep{Z1f}=p*j`0>JgJ*jGgIAcseA5|0}Lj!k>~8}&2V=9vfDy??61jt zXzn$R#&v7_3SF#CZo})$ony)}mq(vnv3S`gZ<~s~F#8Dw=KO431GgI&Iy-N&TW-_^ z1u6wPX-~nTW1@W}dvreK>IT=w3)^?cjhe;{z)DvK;@80yA};g0u)Jg5tMr!rOW9)c z;_S`^b=WRCMy+EoW;ZNkKxawAr}lhcB{E1=TYIbDcGlxsquN`{Ct+8-ZriM2EU;g6 z1mBxpyW1m|mIADbJ_sDVa`0~B+~L|~g}Yzb2b?Z)wR1KOB;*ZMrQfuEfvgX{dP*{I zD|DV!uT6u;Ny=t*{qyp3WI1>rXA`1MMc;{)f80xXeA7%kji};?T8?G`G8z$Cs~pRDvY})+oGw99N!sM-cS1IYII=Q@@h--b2mqcQDtR6 zZ^%?wCAY)gFx#riH)~;_t=vHPd!|d+OZ|Dl!-=o^U%Z$3!!PiWQD>+2fnx6um+w~B zOkbT&DtgkPb?1_(!9J&TH4LWJ!-Eb#E14ctK)|fy8wHg@bUgSG9|$LI8YF!h*;1 zBcsIBcp72`mkN!gViW>Cqas;HL#$+a!<_{p5RSLS+oF*!@w`|p!d?|_C*p9azI4~m z5YQbB5h0NXsVG!jT%2tj&Q>4_M`0)w3JQ%yVX;U^11V03lCa{DQDO@z#4H9K6aylj zP{I>L!KIiiwjf4ALm;4e_?P(jLMHPoe3bYz3lJZuc$N@_u|=c!eAM?AVu?#E1oAnc z|7aohht7~FUr;QF5dok}EEpxR_#T1-e6<(Gh$3gw;Q%Nw668awV#q7z2bXRPruSD1 zDFxv?zHr70BKrqT36J}YtRG^N&dj9qeISteSKJ@8zvMon3~4c$RJs6&k%q^h(-2bs zRE_}Pai}vx0*8Rd;<$Ju5x`TBco2(6k~vraNx`tW0E@`QvoNghpcqkN2`dT!rBD#K zEf2yWgCu}L;NXyK3Y&z)lkotOjDyyd2w>4%5*Z+I@Zfh4ULqb;m8{6`qmn{#ASf)F z!{VSR1PFx)BJo5D7s&>(Xe5D5A`!Vb0)@<(h2j8ISAmGnf|irVXN7|(VO02x4=LeP zCvOG~fwe_{lXyq6BwWaVhVbA;#l(M`@aOSCKM709CWc7Cp@{?{mW08h@g&kWr2tSQ zhAL5ti9y@q@G~>gWuZdJK*X}7bqWE@$e~=Q&LWT{5s3T+f=C)d8WLP;`E{BJwG)RW zVbNI<5CTPGaa1&!iY5AE$W%0%iY3{gvC!a~zJSByCj4*O(&mBN%`Uk+PYn4_m=Vo( zlph#9dpCO<$(v~&%K#IZ!6Q#iyU#1&MYGhD$J&n%SH zkJ@n&AjI=$c2NI(J{T-ikt6~aNv3egNIZrEN=JAki%VeR2^0#EOr9-uAd?tB0Yng!yBcqE4ia*=p85y}jD zkRj1%EPv^&q5iE0XBEEN)S%Lxl|h>& zwD+REZoZ#u8jAOy{Cw{Hf6@gU{?p0d;`b+AKk52g4E!zSpVjq~uD`{=-%|crUH@-% zseXHX2cw`!QyP6Vl(4beWaM!jei@S{e>7Si7Jk990o%Qn}8oG|IAq zZ(AxhEfL#Rh|DiYtglKIUXdVcW2~+vTGb^XuO&OyuP0nf!`Eye)~8vOZ(VYAGpcS2 zu5P>CycfWapQsFEL;H9Gsu?aMAcjK@RHO zCm6-qr_pA=MWTj!jTyt&+{5uDncg`O*QlMgTs%HbU-DP%qWT=AKbm8W(i3<4_>Jc|6O$JJ!e)Xob9!Z3 z@+rZ{bWQfq+5QlP2bAMor($uBkgY-sQ3B~OWtnTeVbGMEcAEa`tAb_Qpp0P*7f*WW Ivat030cQemsQ>@~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/quickly/textures/block/blockstackerup.png b/src/main/resources/assets/quickly/textures/block/blockstackerup.png new file mode 100644 index 0000000000000000000000000000000000000000..3adebd0f174e50e33ed8d4c13aa6bc9b16ffb407 GIT binary patch literal 6705 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 Mj_%YGOV=j-4;)H1Y5)KL literal 0 HcmV?d00001 diff --git a/src/main/resources/data/quickly/recipe/shaped_blockstacker.json b/src/main/resources/data/quickly/recipe/shaped_blockstacker.json new file mode 100644 index 0000000..7f6ff4d --- /dev/null +++ b/src/main/resources/data/quickly/recipe/shaped_blockstacker.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "s s", + "scs", + " s " + ], + "key": { + "s": "quickky:speedingot", + "c": [ + "minecraft:chest", + "minecraft:barrel" + ] + }, + "result": { + "id": "quickly:blockstacker", + "count": 4 + } +} \ No newline at end of file