From 83267ea506622abe0cdc63257efc9e21ab65aa62 Mon Sep 17 00:00:00 2001 From: Jottyfan Date: Sat, 30 Nov 2024 18:44:28 +0100 Subject: [PATCH] blockstacker without menu --- gradle.properties | 2 +- .../jottyfan/quickiemod/block/BlockDrill.java | 9 +- .../quickiemod/block/BlockStacker.java | 117 ++++++++ .../jottyfan/quickiemod/block/ModBlocks.java | 30 +- .../blockentity/BlockStackerEntity.java | 261 ++++++++++++++++++ .../blockentity/DrillBlockEntity.java | 13 +- .../blockentity/EnumDrillDirection.java | 36 --- .../blockentity/ModBlockentity.java | 5 + .../container/BlockStackerInventory.java | 30 ++ .../container/BlockStackerScreen.java | 44 +++ .../container/BlockStackerScreenHandler.java | 97 +++++++ .../container/ImplementedInventory.java | 133 +++++++++ .../container/ScreenHandlerTypes.java | 14 + .../quickiemod/identifier/ModIdentifiers.java | 7 + .../blockstates/blockstackerdown.json | 7 + .../blockstates/blockstackereast.json | 7 + .../blockstates/blockstackernorth.json | 7 + .../blockstates/blockstackersouth.json | 7 + .../blockstates/blockstackerup.json | 7 + .../blockstates/blockstackerwest.json | 7 + .../models/block/blockstackerdown.json | 8 + .../models/block/blockstackereast.json | 11 + .../models/block/blockstackernorth.json | 11 + .../models/block/blockstackersouth.json | 11 + .../models/block/blockstackerup.json | 8 + .../models/block/blockstackerwest.json | 11 + .../models/item/blockstackerdown.json | 10 + .../models/item/blockstackereast.json | 10 + .../models/item/blockstackernorth.json | 10 + .../models/item/blockstackersouth.json | 10 + .../models/item/blockstackerup.json | 10 + .../models/item/blockstackerwest.json | 10 + .../quickiemod/textures/gui/backpack.png | Bin 0 -> 35433 bytes .../quickiemod/textures/gui/blockstacker.png | Bin 0 -> 21668 bytes .../assets/quickiemod/textures/gui/slot.png | Bin 0 -> 436 bytes .../recipe/shaped_blockstacker.json | 19 ++ .../recipe/shapeless_blockstackerdown_up.json | 10 + .../shapeless_blockstackereast_down.json | 10 + .../shapeless_blockstackernorth_west.json | 10 + .../shapeless_blockstackersouth_east.json | 10 + .../shapeless_blockstackerup_north.json | 10 + .../shapeless_blockstackerwest_south.json | 10 + 42 files changed, 986 insertions(+), 53 deletions(-) create mode 100644 src/main/java/de/jottyfan/quickiemod/block/BlockStacker.java create mode 100644 src/main/java/de/jottyfan/quickiemod/blockentity/BlockStackerEntity.java delete mode 100644 src/main/java/de/jottyfan/quickiemod/blockentity/EnumDrillDirection.java create mode 100644 src/main/java/de/jottyfan/quickiemod/container/BlockStackerInventory.java create mode 100644 src/main/java/de/jottyfan/quickiemod/container/BlockStackerScreen.java create mode 100644 src/main/java/de/jottyfan/quickiemod/container/BlockStackerScreenHandler.java create mode 100644 src/main/java/de/jottyfan/quickiemod/container/ImplementedInventory.java create mode 100644 src/main/java/de/jottyfan/quickiemod/container/ScreenHandlerTypes.java create mode 100644 src/main/resources/assets/quickiemod/blockstates/blockstackerdown.json create mode 100644 src/main/resources/assets/quickiemod/blockstates/blockstackereast.json create mode 100644 src/main/resources/assets/quickiemod/blockstates/blockstackernorth.json create mode 100644 src/main/resources/assets/quickiemod/blockstates/blockstackersouth.json create mode 100644 src/main/resources/assets/quickiemod/blockstates/blockstackerup.json create mode 100644 src/main/resources/assets/quickiemod/blockstates/blockstackerwest.json create mode 100644 src/main/resources/assets/quickiemod/models/block/blockstackerdown.json create mode 100644 src/main/resources/assets/quickiemod/models/block/blockstackereast.json create mode 100644 src/main/resources/assets/quickiemod/models/block/blockstackernorth.json create mode 100644 src/main/resources/assets/quickiemod/models/block/blockstackersouth.json create mode 100644 src/main/resources/assets/quickiemod/models/block/blockstackerup.json create mode 100644 src/main/resources/assets/quickiemod/models/block/blockstackerwest.json create mode 100644 src/main/resources/assets/quickiemod/models/item/blockstackerdown.json create mode 100644 src/main/resources/assets/quickiemod/models/item/blockstackereast.json create mode 100644 src/main/resources/assets/quickiemod/models/item/blockstackernorth.json create mode 100644 src/main/resources/assets/quickiemod/models/item/blockstackersouth.json create mode 100644 src/main/resources/assets/quickiemod/models/item/blockstackerup.json create mode 100644 src/main/resources/assets/quickiemod/models/item/blockstackerwest.json create mode 100644 src/main/resources/assets/quickiemod/textures/gui/backpack.png create mode 100644 src/main/resources/assets/quickiemod/textures/gui/blockstacker.png create mode 100644 src/main/resources/assets/quickiemod/textures/gui/slot.png create mode 100644 src/main/resources/data/quickiemod/recipe/shaped_blockstacker.json create mode 100644 src/main/resources/data/quickiemod/recipe/shapeless_blockstackerdown_up.json create mode 100644 src/main/resources/data/quickiemod/recipe/shapeless_blockstackereast_down.json create mode 100644 src/main/resources/data/quickiemod/recipe/shapeless_blockstackernorth_west.json create mode 100644 src/main/resources/data/quickiemod/recipe/shapeless_blockstackersouth_east.json create mode 100644 src/main/resources/data/quickiemod/recipe/shapeless_blockstackerup_north.json create mode 100644 src/main/resources/data/quickiemod/recipe/shapeless_blockstackerwest_south.json diff --git a/gradle.properties b/gradle.properties index f696655..9c3a176 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ yarn_mappings=1.21.3+build.2 loader_version=0.16.9 # Mod Properties -mod_version=1.21.3.0 +mod_version=1.21.3.1 maven_group=de.jottyfan.quickiemod archives_base_name=quickiemod diff --git a/src/main/java/de/jottyfan/quickiemod/block/BlockDrill.java b/src/main/java/de/jottyfan/quickiemod/block/BlockDrill.java index acd0d33..14335bd 100644 --- a/src/main/java/de/jottyfan/quickiemod/block/BlockDrill.java +++ b/src/main/java/de/jottyfan/quickiemod/block/BlockDrill.java @@ -6,7 +6,6 @@ import java.util.Map; import com.mojang.serialization.MapCodec; import de.jottyfan.quickiemod.blockentity.DrillBlockEntity; -import de.jottyfan.quickiemod.blockentity.EnumDrillDirection; import de.jottyfan.quickiemod.item.ModItems; import net.minecraft.block.AbstractBlock; import net.minecraft.block.Block; @@ -24,12 +23,14 @@ import net.minecraft.item.Items; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKeys; import net.minecraft.state.StateManager.Builder; +import net.minecraft.state.property.EnumProperty; import net.minecraft.state.property.IntProperty; import net.minecraft.text.Text; import net.minecraft.util.ActionResult; import net.minecraft.util.Identifier; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; import net.minecraft.world.World; /** @@ -40,11 +41,11 @@ import net.minecraft.world.World; public class BlockDrill extends FallingBlock implements BlockEntityProvider { private static final Integer MAX_FUEL = 255; public static final IntProperty FUEL = IntProperty.of("fuel", 0, MAX_FUEL); - public static final IntProperty DIRECTION = IntProperty.of("direction", 0, 4); + public static final EnumProperty DIRECTION = EnumProperty.of("direction", Direction.class, Direction.values()); - public BlockDrill(Identifier identifier, EnumDrillDirection direction) { + public BlockDrill(Identifier identifier, Direction direction) { super(AbstractBlock.Settings.create().hardness(2.5f).registryKey(RegistryKey.of(RegistryKeys.BLOCK, identifier))); - setDefaultState(getDefaultState().with(FUEL, 0).with(DIRECTION, direction.get())); + setDefaultState(getDefaultState().with(FUEL, 0).with(DIRECTION, direction)); } @Override diff --git a/src/main/java/de/jottyfan/quickiemod/block/BlockStacker.java b/src/main/java/de/jottyfan/quickiemod/block/BlockStacker.java new file mode 100644 index 0000000..a17dfc6 --- /dev/null +++ b/src/main/java/de/jottyfan/quickiemod/block/BlockStacker.java @@ -0,0 +1,117 @@ +package de.jottyfan.quickiemod.block; + +import com.mojang.serialization.MapCodec; + +import de.jottyfan.quickiemod.blockentity.BlockStackerEntity; +import de.jottyfan.quickiemod.blockentity.ModBlockentity; +import net.minecraft.block.AbstractBlock; +import net.minecraft.block.BlockEntityProvider; +import net.minecraft.block.BlockRenderType; +import net.minecraft.block.BlockState; +import net.minecraft.block.BlockWithEntity; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityTicker; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.screen.ScreenHandler; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Identifier; +import net.minecraft.util.ItemScatterer; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.World; + +/** + * + * @author jotty + * + */ +public class BlockStacker extends BlockWithEntity implements BlockEntityProvider { + + private final Direction source; + private final Direction dest; + + public BlockStacker(Identifier identifier, Direction source, Direction dest) { + super(AbstractBlock.Settings.create().hardness(2.5f).registryKey(RegistryKey.of(RegistryKeys.BLOCK, identifier))); + this.source = source; + this.dest = dest; + } + + @Override + public BlockRenderType getRenderType(BlockState state) { + return BlockRenderType.MODEL; + } + + /** + * define the source offset + * + * @return the direction of the source offset (1 block beside) + */ + public Direction getSourceOffset() { + return source; + } + + /** + * define the dest offset + * + * @return the direction of the dest offset (1 block beside) + */ + public Direction getDestOffset() { + return dest; + } + + @Override + public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + return new BlockStackerEntity(pos, state); + } + + @Override + protected MapCodec getCodec() { + // TODO Auto-generated method stub + return null; + } + + @Override + public BlockEntityTicker getTicker(World world, BlockState state, + BlockEntityType type) { + return validateTicker(type, ModBlockentity.BLOCKSTACKER_BLOCKENTITY, + (world1, pos, state1, be) -> BlockStackerEntity.tick(world1, pos, state1, be)); + } + + @Override + protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) { +// if (!world.isClient) { +// NamedScreenHandlerFactory screenHandlerFactory = state.createScreenHandlerFactory(world, pos); +// if (screenHandlerFactory != null) { +// player.openHandledScreen(screenHandlerFactory); +// } +// } + return ActionResult.SUCCESS; + } + + @Override + public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { + if (state.getBlock() != newState.getBlock()) { + BlockEntity blockEntity = world.getBlockEntity(pos); + if (blockEntity instanceof BlockStackerEntity) { + ItemScatterer.spawn(world, pos, (BlockStackerEntity) blockEntity); + // update comparators + world.updateComparators(pos, this); + } + super.onStateReplaced(state, world, pos, newState, moved); + } + } + + @Override + public boolean hasComparatorOutput(BlockState state) { + return true; + } + + @Override + public int getComparatorOutput(BlockState state, World world, BlockPos pos) { + return ScreenHandler.calculateComparatorOutput(world.getBlockEntity(pos)); + } +} diff --git a/src/main/java/de/jottyfan/quickiemod/block/ModBlocks.java b/src/main/java/de/jottyfan/quickiemod/block/ModBlocks.java index 3b2216d..dd00aa1 100644 --- a/src/main/java/de/jottyfan/quickiemod/block/ModBlocks.java +++ b/src/main/java/de/jottyfan/quickiemod/block/ModBlocks.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.List; import de.jottyfan.quickiemod.Quickiemod; -import de.jottyfan.quickiemod.blockentity.EnumDrillDirection; import de.jottyfan.quickiemod.identifier.ModIdentifiers; import de.jottyfan.quickiemod.item.ModItems; import net.minecraft.block.Block; @@ -17,6 +16,7 @@ import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKeys; import net.minecraft.sound.BlockSoundGroup; import net.minecraft.util.Identifier; +import net.minecraft.util.math.Direction; /** * @@ -62,15 +62,27 @@ public class ModBlocks { public static final Block BLOCK_CANOLAPLANT = registerBlock(ModIdentifiers.BLOCK_CANOLAPLANT, new BlockPlant(ModIdentifiers.BLOCK_CANOLAPLANT, ModItems.ITEM_CANOLASEED, ModItems.ITEM_CANOLA), false); public static final Block BLOCK_DRILL_DOWN = registerBlock(ModIdentifiers.BLOCK_DRILLDOWN, - new BlockDrill(ModIdentifiers.BLOCK_DRILLDOWN, EnumDrillDirection.DOWN)); + new BlockDrill(ModIdentifiers.BLOCK_DRILLDOWN, Direction.DOWN)); public static final Block BLOCK_DRILL_EAST = registerBlock(ModIdentifiers.BLOCK_DRILLEAST, - new BlockDrill(ModIdentifiers.BLOCK_DRILLEAST, EnumDrillDirection.EAST)); + new BlockDrill(ModIdentifiers.BLOCK_DRILLEAST, Direction.EAST)); public static final Block BLOCK_DRILL_SOUTH = registerBlock(ModIdentifiers.BLOCK_DRILLSOUTH, - new BlockDrill(ModIdentifiers.BLOCK_DRILLSOUTH, EnumDrillDirection.SOUTH)); + new BlockDrill(ModIdentifiers.BLOCK_DRILLSOUTH, Direction.SOUTH)); public static final Block BLOCK_DRILL_WEST = registerBlock(ModIdentifiers.BLOCK_DRILLWEST, - new BlockDrill(ModIdentifiers.BLOCK_DRILLWEST, EnumDrillDirection.WEST)); + new BlockDrill(ModIdentifiers.BLOCK_DRILLWEST, Direction.WEST)); public static final Block BLOCK_DRILL_NORTH = registerBlock(ModIdentifiers.BLOCK_DRILLNORTH, - new BlockDrill(ModIdentifiers.BLOCK_DRILLNORTH, EnumDrillDirection.NORTH)); + new BlockDrill(ModIdentifiers.BLOCK_DRILLNORTH, Direction.NORTH)); + public static final Block BLOCK_STACKER_DOWN = registerBlock(ModIdentifiers.BLOCK_STACKERDOWN, + new BlockStacker(ModIdentifiers.BLOCK_STACKERDOWN, Direction.UP, Direction.DOWN)); + public static final Block BLOCK_STACKER_EAST = registerBlock(ModIdentifiers.BLOCK_STACKEREAST, + new BlockStacker(ModIdentifiers.BLOCK_STACKEREAST, Direction.WEST, Direction.EAST)); + public static final Block BLOCK_STACKER_SOUTH = registerBlock(ModIdentifiers.BLOCK_STACKERSOUTH, + new BlockStacker(ModIdentifiers.BLOCK_STACKERSOUTH, Direction.NORTH, Direction.SOUTH)); + public static final Block BLOCK_STACKER_WEST = registerBlock(ModIdentifiers.BLOCK_STACKERWEST, + new BlockStacker(ModIdentifiers.BLOCK_STACKERWEST, Direction.EAST, Direction.WEST)); + public static final Block BLOCK_STACKER_NORTH = registerBlock(ModIdentifiers.BLOCK_STACKERNORTH, + new BlockStacker(ModIdentifiers.BLOCK_STACKERNORTH, Direction.SOUTH, Direction.NORTH)); + public static final Block BLOCK_STACKER_UP = registerBlock(ModIdentifiers.BLOCK_STACKERUP, + new BlockStacker(ModIdentifiers.BLOCK_STACKERUP, Direction.DOWN, Direction.UP)); private static final Block registerBlock(Identifier identifier, Block block) { return registerBlock(identifier, block, true); @@ -109,6 +121,12 @@ public class ModBlocks { blocks.add(BLOCK_DRILL_SOUTH); blocks.add(BLOCK_DRILL_WEST); blocks.add(BLOCK_DRILL_NORTH); + blocks.add(BLOCK_STACKER_DOWN); + blocks.add(BLOCK_STACKER_EAST); + blocks.add(BLOCK_STACKER_SOUTH); + blocks.add(BLOCK_STACKER_WEST); + blocks.add(BLOCK_STACKER_NORTH); + blocks.add(BLOCK_STACKER_UP); return blocks; } } diff --git a/src/main/java/de/jottyfan/quickiemod/blockentity/BlockStackerEntity.java b/src/main/java/de/jottyfan/quickiemod/blockentity/BlockStackerEntity.java new file mode 100644 index 0000000..e08f396 --- /dev/null +++ b/src/main/java/de/jottyfan/quickiemod/blockentity/BlockStackerEntity.java @@ -0,0 +1,261 @@ +package de.jottyfan.quickiemod.blockentity; + +import java.util.ArrayList; +import java.util.List; + +import de.jottyfan.quickiemod.Quickiemod; +import de.jottyfan.quickiemod.block.BlockStacker; +import de.jottyfan.quickiemod.container.BlockStackerScreenHandler; +import de.jottyfan.quickiemod.container.ImplementedInventory; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.LootableContainerBlockEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.Inventories; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.RegistryWrapper.WrapperLookup; +import net.minecraft.screen.NamedScreenHandlerFactory; +import net.minecraft.screen.ScreenHandler; +import net.minecraft.text.Text; +import net.minecraft.util.collection.DefaultedList; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +/** + * + * @author jotty + * + */ +public class BlockStackerEntity extends BlockEntity implements NamedScreenHandlerFactory, ImplementedInventory { + + private final DefaultedList inventory = DefaultedList.ofSize(BlockStackerScreenHandler.SLOTSIZE, ItemStack.EMPTY); + + public BlockStackerEntity(BlockPos blockPos, BlockState blockState) { + super(ModBlockentity.BLOCKSTACKER_BLOCKENTITY, blockPos, blockState); + } + + @Override + public DefaultedList getItems() { + return inventory; + } + + public List getWhiteList() { + int counter = 0; + List list = new ArrayList<>(); + for (ItemStack stack : inventory) { + counter++; + if (counter < 10) { // first 9 items are whitelist items + list.add(stack); + } + } + return list; + } + + public List getBlackList() { + int counter = 0; + List list = new ArrayList<>(); + for (ItemStack stack : inventory) { + counter++; + if (counter > 9) { // second 9 items are blacklist items + list.add(stack); + } + } + return list; + } + + @Override + public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, PlayerEntity player) { + return new BlockStackerScreenHandler(syncId, playerInventory, this); + } + + @Override + public Text getDisplayName() { + return Text.translatable(getCachedState().getBlock().getTranslationKey()); + } + + @Override + protected void readNbt(NbtCompound nbt, WrapperLookup registryLookup) { + super.readNbt(nbt, registryLookup); + Inventories.readNbt(nbt, inventory, registryLookup); + } + + @Override + protected void writeNbt(NbtCompound nbt, WrapperLookup registryLookup) { + Inventories.writeNbt(nbt, inventory, registryLookup); + super.writeNbt(nbt, registryLookup); + } + + /** + * if whitelist, return true if current == pattern; return false otherwise + * + * @param current the current item stack + * @param pattern the item stack to compare with + * @param whitelist if true, filter only current == pattern, if false, filter + * all but that + * @return true or false + */ + public static final Boolean filter(ItemStack current, ItemStack pattern, Boolean whitelist) { + Boolean matches = pattern.getItem().equals(current.getItem()); + return whitelist ? matches : !matches; + } + + public static void tick(World world, BlockPos pos, BlockState state, BlockStackerEntity entity) { + if (!world.isClient) { + pos.down(); + BlockStacker block = (BlockStacker) state.getBlock(); + BlockEntity source = world.getBlockEntity(pos.offset(block.getSourceOffset())); + BlockEntity dest = world.getBlockEntity(pos.offset(block.getDestOffset())); + Boolean sourceIsLootable = source instanceof LootableContainerBlockEntity; + Boolean destIsLootable = dest instanceof LootableContainerBlockEntity; + if (sourceIsLootable && destIsLootable) { + LootableContainerBlockEntity lootableSource = (LootableContainerBlockEntity) source; + LootableContainerBlockEntity lootableDest = (LootableContainerBlockEntity) dest; + transferOneStack(lootableSource, lootableDest, entity.getWhiteList(), entity.getBlackList()); + } + } + } + + private static final Boolean transferOneStack(LootableContainerBlockEntity source, LootableContainerBlockEntity dest, List whiteList, List blackList) { + + // whitelist behaviour + List checked = new ArrayList<>(); + + // this way, we block whitelist items that are in the blacklist + for (ItemStack stack : blackList) { + if (stack != null && !stack.isEmpty()) { + checked.add(stack.getItem()); + } + } + Boolean found = false; + + if (hasItems(whiteList)) { + Item matchItem = findNextItem(whiteList, checked); + while(!found && matchItem != null) { + checked.add(matchItem); + List matchItems = new ArrayList<>(); + matchItems.add(matchItem); + found = transferOneStack(source, dest, matchItems, true); + matchItem = findNextItem(whiteList, checked); + } + } else { + // transport all but the items of the blacklist + found = transferOneStack(source, dest, checked, false); + } + return found; + } + + private static final Boolean transferOneStack(LootableContainerBlockEntity source, LootableContainerBlockEntity dest, + List ignoreItems, Boolean whitelist) { + Boolean result = false; + Integer sourceSlot = findItemStackPos(source, ignoreItems, whitelist); + if (sourceSlot != null && !Items.AIR.equals(source.getStack(sourceSlot).getItem())) { + ItemStack sourceStack = source.getStack(sourceSlot); + Integer destSlot = findItemStackPos(dest, sourceStack); + if (destSlot != null) { + Integer occupied = dest.getStack(destSlot).getCount(); + Integer free = dest.getStack(destSlot).getMaxCount() - occupied; + Integer candidates = source.getStack(sourceSlot).getCount(); + Integer travellers = candidates > free ? free : candidates; + if (travellers > 0) { + Quickiemod.LOGGER.debug("transfer {}/{} of {} from slot {} to slot {} on top of {} ones", travellers, candidates, + source.getStack(sourceSlot).getItem().toString(), sourceSlot, destSlot, occupied); + source.getStack(sourceSlot).decrement(travellers); + if (source.getStack(sourceSlot).getCount() < 1) { + source.removeStack(sourceSlot); // make empty slots really empty + } + dest.getStack(destSlot).increment(travellers); + result = true; + } + } else { + Integer destFreeSlot = findItemStackPos(dest, true); + if (destFreeSlot != null) { + Quickiemod.LOGGER.debug("transfer all of {} from slot {} to slot {}", source.getStack(sourceSlot).getItem().toString(), + sourceSlot, destSlot); + dest.setStack(destFreeSlot, source.removeStack(sourceSlot)); + result = true; + } + } + } + return result; + } + + private static final Boolean hasItems(List list) { + Boolean result = false; + for (ItemStack stack : list) { + result = result || (stack != null && !stack.isEmpty() && stack.getCount() > 0); + } + return result; + } + + private static final Item findNextItem(List inventory, List exclude) { + for (ItemStack stack : inventory) { + if (!stack.isEmpty()) { + Item item = stack.getItem(); + if (!exclude.contains(item)) { + return item; + } + } + } + return null; + } + + private static final Integer findItemStackPos(LootableContainerBlockEntity lcbe, ItemStack sourceStack) { + Integer counter = lcbe.size(); + while (counter > 0) { + counter--; + ItemStack stack = lcbe.getStack(counter); + if (sourceStack.getItem().equals(stack.getItem())) { + if (stack.getCount() < stack.getMaxCount()) { + return counter; + } + } + } + return null; + } + + private static final Integer findItemStackPos(LootableContainerBlockEntity lcbe, Boolean empty) { + Integer counter = lcbe.size(); + while (counter > 0) { + counter--; + ItemStack stack = lcbe.getStack(counter); + if (empty.equals(ItemStack.EMPTY.equals(stack))) { + return counter; + } + } + return null; + } + + private static final Integer findItemStackPos(LootableContainerBlockEntity lcbe, List filterItems, Boolean whitelist) { + if (whitelist == null) { + whitelist = true; + Quickiemod.LOGGER.error("whitelist is null"); + } + if (filterItems == null || filterItems.size() < 1) { + if (whitelist) { + return null; + } else { + return findItemStackPos(lcbe, false); + } + } else { + Integer counter = lcbe.size(); + while (counter > 0) { + counter--; + ItemStack stack = lcbe.getStack(counter); + Boolean found = whitelist ? filterItems.contains(stack.getItem()) : !filterItems.contains(stack.getItem()); + if (found) { + return counter; + } + } + return null; + } + } + + @Override + public int size() { + return inventory.size(); + } +} diff --git a/src/main/java/de/jottyfan/quickiemod/blockentity/DrillBlockEntity.java b/src/main/java/de/jottyfan/quickiemod/blockentity/DrillBlockEntity.java index fc4ffd6..29e5563 100644 --- a/src/main/java/de/jottyfan/quickiemod/blockentity/DrillBlockEntity.java +++ b/src/main/java/de/jottyfan/quickiemod/blockentity/DrillBlockEntity.java @@ -8,6 +8,7 @@ import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.entity.BlockEntity; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; import net.minecraft.world.World; /** @@ -29,17 +30,17 @@ public class DrillBlockEntity extends BlockEntity { public static void tick(World world, BlockPos pos, BlockState state, BlockEntity be) { if (be instanceof DrillBlockEntity dbe) { - Integer dir = state.get(BlockDrill.DIRECTION); + Direction dir = state.get(BlockDrill.DIRECTION); List list = new ArrayList<>(); - if (EnumDrillDirection.DOWN.get().equals(dir)) { + if (Direction.DOWN.equals(dir)) { list = downFrom(pos); - } else if (EnumDrillDirection.EAST.get().equals(dir)) { + } else if (Direction.EAST.equals(dir)) { list = directedFrom(pos.east()); - } else if (EnumDrillDirection.SOUTH.get().equals(dir)) { + } else if (Direction.SOUTH.equals(dir)) { list = directedFrom(pos.south()); - } else if (EnumDrillDirection.WEST.get().equals(dir)) { + } else if (Direction.WEST.equals(dir)) { list = directedFrom(pos.west()); - } else if (EnumDrillDirection.NORTH.get().equals(dir)) { + } else if (Direction.NORTH.equals(dir)) { list = directedFrom(pos.north()); } DrillBlockEntity.tick(world, pos, state, dbe, MAXDRILLSTEP, list); diff --git a/src/main/java/de/jottyfan/quickiemod/blockentity/EnumDrillDirection.java b/src/main/java/de/jottyfan/quickiemod/blockentity/EnumDrillDirection.java deleted file mode 100644 index 0f07cb7..0000000 --- a/src/main/java/de/jottyfan/quickiemod/blockentity/EnumDrillDirection.java +++ /dev/null @@ -1,36 +0,0 @@ -package de.jottyfan.quickiemod.blockentity; - -/** - * - * @author jotty - * - */ -public enum EnumDrillDirection { - DOWN(0), EAST(1), SOUTH(2), WEST(3), NORTH(4); - - private final Integer value; - - private EnumDrillDirection(Integer value) { - this.value = value; - } - - @Override - public String toString() { - return String.format("%s: %d", EnumDrillDirection.lookupValue(value), value); - } - - public static final String lookupValue(Integer value) { - return switch (value) { - case 0 -> "down"; - case 1 -> "east"; - case 2 -> "south"; - case 3 -> "west"; - case 4 -> "north"; - default -> "not supported"; - }; - } - - public Integer get() { - return value; - } -} diff --git a/src/main/java/de/jottyfan/quickiemod/blockentity/ModBlockentity.java b/src/main/java/de/jottyfan/quickiemod/blockentity/ModBlockentity.java index 1f011a2..7617111 100644 --- a/src/main/java/de/jottyfan/quickiemod/blockentity/ModBlockentity.java +++ b/src/main/java/de/jottyfan/quickiemod/blockentity/ModBlockentity.java @@ -20,6 +20,11 @@ public class ModBlockentity { Registries.BLOCK_ENTITY_TYPE, ModIdentifiers.BLOCKENTITY_DRILL, FabricBlockEntityTypeBuilder.create(DrillBlockEntity::new, ModBlocks.BLOCK_DRILL_DOWN, ModBlocks.BLOCK_DRILL_EAST, ModBlocks.BLOCK_DRILL_SOUTH, ModBlocks.BLOCK_DRILL_WEST, ModBlocks.BLOCK_DRILL_NORTH).build()); + public static final BlockEntityType BLOCKSTACKER_BLOCKENTITY = Registry.register( + Registries.BLOCK_ENTITY_TYPE, ModIdentifiers.BLOCKENTITY_BLOCKSTACKER, + FabricBlockEntityTypeBuilder.create(BlockStackerEntity::new, ModBlocks.BLOCK_STACKER_DOWN, + ModBlocks.BLOCK_STACKER_EAST, ModBlocks.BLOCK_STACKER_SOUTH, ModBlocks.BLOCK_STACKER_WEST, + ModBlocks.BLOCK_STACKER_NORTH, ModBlocks.BLOCK_STACKER_UP).build()); public static final void registerModBlockentities() { }; diff --git a/src/main/java/de/jottyfan/quickiemod/container/BlockStackerInventory.java b/src/main/java/de/jottyfan/quickiemod/container/BlockStackerInventory.java new file mode 100644 index 0000000..9238be4 --- /dev/null +++ b/src/main/java/de/jottyfan/quickiemod/container/BlockStackerInventory.java @@ -0,0 +1,30 @@ +package de.jottyfan.quickiemod.container; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.inventory.SimpleInventory; +import net.minecraft.sound.SoundEvents; + +/** + * + * @author jotty + * + */ +public class BlockStackerInventory extends SimpleInventory { + + public BlockStackerInventory(Integer slotsize) { + super(slotsize); + } + + @Override + public void onOpen(PlayerEntity player) { + super.onOpen(player); + player.playSound(SoundEvents.BLOCK_CHEST_OPEN, 1f, 1f); + } + + @Override + public void onClose(PlayerEntity player) { + super.onClose(player); + player.playSound(SoundEvents.BLOCK_CHEST_CLOSE, 1f, 1f); + } + +} diff --git a/src/main/java/de/jottyfan/quickiemod/container/BlockStackerScreen.java b/src/main/java/de/jottyfan/quickiemod/container/BlockStackerScreen.java new file mode 100644 index 0000000..98a9f35 --- /dev/null +++ b/src/main/java/de/jottyfan/quickiemod/container/BlockStackerScreen.java @@ -0,0 +1,44 @@ +package de.jottyfan.quickiemod.container; + +import de.jottyfan.quickiemod.Quickiemod; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.client.gui.screen.ingame.ScreenHandlerProvider; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +/** + * + * @author jotty + * + */ +@Environment(EnvType.CLIENT) +public class BlockStackerScreen extends HandledScreen + implements ScreenHandlerProvider { + private final static Identifier TEXTURE = Identifier.of(Quickiemod.MOD_ID, "textures/gui/blockstacker.png"); + private final Integer containerHeight = 222; + private final Integer containerWidth = 176; + + public BlockStackerScreen(BlockStackerScreenHandler handler, PlayerInventory inventory, Text title) { + super(handler, inventory, title); + } + + @Override + public void render(DrawContext drawContext, int mouseX, int mouseY, float partialTicks) { + this.renderInGameBackground(drawContext); + super.render(drawContext, mouseX, mouseY, partialTicks); + this.drawMouseoverTooltip(drawContext, mouseX, mouseY); + } + + @Override + protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) { +// context.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + int guiX = (this.width - this.containerWidth) / 2; + int guiY = (this.height - this.containerHeight) / 2; + super.renderInGameBackground(context); +// context.drawTexture(TEXTURE, guiX, guiY, 0f, 0f, containerWidth, containerHeight, 0, 0); + } +} diff --git a/src/main/java/de/jottyfan/quickiemod/container/BlockStackerScreenHandler.java b/src/main/java/de/jottyfan/quickiemod/container/BlockStackerScreenHandler.java new file mode 100644 index 0000000..9d4da6f --- /dev/null +++ b/src/main/java/de/jottyfan/quickiemod/container/BlockStackerScreenHandler.java @@ -0,0 +1,97 @@ +package de.jottyfan.quickiemod.container; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.Inventory; +import net.minecraft.item.ItemStack; +import net.minecraft.screen.NamedScreenHandlerFactory; +import net.minecraft.screen.ScreenHandler; +import net.minecraft.screen.slot.Slot; + +/** + * + * @author jotty + * + */ +public class BlockStackerScreenHandler extends ScreenHandler { + + public static final Integer SLOTSIZE = 18; + + private final Inventory inventory; + + /** + * client constructor + * + * @param syncId + * @param playerInventory + */ + public BlockStackerScreenHandler(int syncId, PlayerInventory playerInventory) { + this(syncId, playerInventory, new BlockStackerInventory(SLOTSIZE)); + } + + /** + * server constructor + * + * @param syncId + * @param playerInventory + * @param inventory + */ + public BlockStackerScreenHandler(int syncId, PlayerInventory playerInventory, Inventory inventory) { + super(ScreenHandlerTypes.BLOCKSTACKER_SCREEN_HANDLER, syncId); + checkSize(inventory, SLOTSIZE); + this.inventory = inventory; + inventory.onOpen(playerInventory.player); + int m; + int l; + // whitelist + for (m = 0; m < 3; ++m) { + for (l = 0; l < 3; ++l) { + this.addSlot(new Slot(inventory, l + m * 3, 8 + l * 18, 17 + m * 18)); + } + } + + // blacklist + for (m = 0; m < 3; ++m) { + for (l = 0; l < 3; ++l) { + this.addSlot(new Slot(inventory, l + m * 3 + 9, 116 + l * 18, 17 + m * 18)); + } + } + + for (m = 0; m < 3; ++m) { + for (l = 0; l < 9; ++l) { + this.addSlot(new Slot(playerInventory, l + m * 9 + 9, 8 + l * 18, 84 + m * 18)); + } + } + for (m = 0; m < 9; ++m) { + this.addSlot(new Slot(playerInventory, m, 8 + m * 18, 142)); + } + } + + @Override + public boolean canUse(PlayerEntity player) { + return this.inventory.canPlayerUse(player); + } + + @Override + public ItemStack quickMove(PlayerEntity player, int invSlot) { + ItemStack newStack = ItemStack.EMPTY; + Slot slot = this.slots.get(invSlot); + if (slot != null && slot.hasStack()) { + ItemStack originalStack = slot.getStack(); + newStack = originalStack.copy(); + if (invSlot < this.inventory.size()) { + if (!this.insertItem(originalStack, this.inventory.size(), this.slots.size(), true)) { + return ItemStack.EMPTY; + } + } else if (!this.insertItem(originalStack, 0, this.inventory.size(), false)) { + return ItemStack.EMPTY; + } + if (originalStack.isEmpty()) { + slot.setStack(ItemStack.EMPTY); + } else { + slot.markDirty(); + } + } + return newStack; + } +} diff --git a/src/main/java/de/jottyfan/quickiemod/container/ImplementedInventory.java b/src/main/java/de/jottyfan/quickiemod/container/ImplementedInventory.java new file mode 100644 index 0000000..add90a5 --- /dev/null +++ b/src/main/java/de/jottyfan/quickiemod/container/ImplementedInventory.java @@ -0,0 +1,133 @@ +package de.jottyfan.quickiemod.container; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.inventory.Inventories; +import net.minecraft.inventory.Inventory; +import net.minecraft.item.ItemStack; +import net.minecraft.util.collection.DefaultedList; + +/** + * + * @author jotty + * + * @see https://fabricmc.net/wiki/tutorial:inventory + * + */ +public interface ImplementedInventory extends Inventory { + + /** + * Retrieves the item list of this inventory. + * Must return the same instance every time it's called. + */ + DefaultedList getItems(); + + /** + * Creates an inventory from the item list. + */ + static ImplementedInventory of(DefaultedList items) { + return () -> items; + } + + /** + * Creates a new inventory with the specified size. + */ + static ImplementedInventory ofSize(int size) { + return of(DefaultedList.ofSize(size, ItemStack.EMPTY)); + } + + /** + * Returns the inventory size. + */ + @Override + default int size() { + return getItems().size(); + } + + /** + * Checks if the inventory is empty. + * @return true if this inventory has only empty stacks, false otherwise. + */ + @Override + default boolean isEmpty() { + for (int i = 0; i < size(); i++) { + ItemStack stack = getStack(i); + if (!stack.isEmpty()) { + return false; + } + } + return true; + } + + /** + * Retrieves the item in the slot. + */ + @Override + default ItemStack getStack(int slot) { + return getItems().get(slot); + } + + /** + * Removes items from an inventory slot. + * @param slot The slot to remove from. + * @param count How many items to remove. If there are less items in the slot than what are requested, + * takes all items in that slot. + */ + @Override + default ItemStack removeStack(int slot, int count) { + ItemStack result = Inventories.splitStack(getItems(), slot, count); + if (!result.isEmpty()) { + markDirty(); + } + return result; + } + + /** + * Removes all items from an inventory slot. + * @param slot The slot to remove from. + */ + @Override + default ItemStack removeStack(int slot) { + return Inventories.removeStack(getItems(), slot); + } + + /** + * Replaces the current stack in an inventory slot with the provided stack. + * @param slot The inventory slot of which to replace the itemstack. + * @param stack The replacing itemstack. If the stack is too big for + * this inventory ({@link Inventory#getMaxCountPerStack()}), + * it gets resized to this inventory's maximum amount. + */ + @Override + default void setStack(int slot, ItemStack stack) { + getItems().set(slot, stack); + if (stack.getCount() > stack.getMaxCount()) { + stack.setCount(stack.getMaxCount()); + } + } + + /** + * Clears the inventory. + */ + @Override + default void clear() { + getItems().clear(); + } + + /** + * Marks the state as dirty. + * Must be called after changes in the inventory, so that the game can properly save + * the inventory contents and notify neighboring blocks of inventory changes. + */ + @Override + default void markDirty() { + // Override if you want behavior. + } + + /** + * @return true if the player can use the inventory, false otherwise. + */ + @Override + default boolean canPlayerUse(PlayerEntity player) { + return true; + } +} \ No newline at end of file diff --git a/src/main/java/de/jottyfan/quickiemod/container/ScreenHandlerTypes.java b/src/main/java/de/jottyfan/quickiemod/container/ScreenHandlerTypes.java new file mode 100644 index 0000000..e82a510 --- /dev/null +++ b/src/main/java/de/jottyfan/quickiemod/container/ScreenHandlerTypes.java @@ -0,0 +1,14 @@ +package de.jottyfan.quickiemod.container; + +import net.minecraft.resource.featuretoggle.FeatureFlags; +import net.minecraft.screen.ScreenHandlerType; + +/** + * + * @author jotty + * + */ +public class ScreenHandlerTypes { + public static final ScreenHandlerType BLOCKSTACKER_SCREEN_HANDLER = new ScreenHandlerType<>(BlockStackerScreenHandler::new, + FeatureFlags.VANILLA_FEATURES); +} diff --git a/src/main/java/de/jottyfan/quickiemod/identifier/ModIdentifiers.java b/src/main/java/de/jottyfan/quickiemod/identifier/ModIdentifiers.java index 79c82dc..6efffe8 100644 --- a/src/main/java/de/jottyfan/quickiemod/identifier/ModIdentifiers.java +++ b/src/main/java/de/jottyfan/quickiemod/identifier/ModIdentifiers.java @@ -63,8 +63,15 @@ public class ModIdentifiers { public static final Identifier BLOCK_DRILLSOUTH = Identifier.of(Quickiemod.MOD_ID, "drillsouth"); public static final Identifier BLOCK_DRILLWEST = Identifier.of(Quickiemod.MOD_ID, "drillwest"); public static final Identifier BLOCK_DRILLNORTH = Identifier.of(Quickiemod.MOD_ID, "drillnorth"); + public static final Identifier BLOCK_STACKERDOWN = Identifier.of(Quickiemod.MOD_ID, "blockstackerdown"); + public static final Identifier BLOCK_STACKEREAST = Identifier.of(Quickiemod.MOD_ID, "blockstackereast"); + public static final Identifier BLOCK_STACKERSOUTH = Identifier.of(Quickiemod.MOD_ID, "blockstackersouth"); + public static final Identifier BLOCK_STACKERWEST = Identifier.of(Quickiemod.MOD_ID, "blockstackerwest"); + public static final Identifier BLOCK_STACKERNORTH = Identifier.of(Quickiemod.MOD_ID, "blockstackernorth"); + public static final Identifier BLOCK_STACKERUP = Identifier.of(Quickiemod.MOD_ID, "blockstackerup"); public static final Identifier BLOCKENTITY_ITEMHOARDER = Identifier.of(Quickiemod.MOD_ID, "itemhoarderblockentity"); public static final Identifier BLOCKENTITY_BLOCKSTACKER = Identifier.of(Quickiemod.MOD_ID, "blockstackerblockentity"); public static final Identifier BLOCKENTITY_DRILL = Identifier.of(Quickiemod.MOD_ID, "drillblockentity"); + public static final Identifier BLOCKSTACKERUP = Identifier.of(Quickiemod.MOD_ID, "blockstackerblockentity"); } diff --git a/src/main/resources/assets/quickiemod/blockstates/blockstackerdown.json b/src/main/resources/assets/quickiemod/blockstates/blockstackerdown.json new file mode 100644 index 0000000..6bb43c7 --- /dev/null +++ b/src/main/resources/assets/quickiemod/blockstates/blockstackerdown.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "quickiemod:block/blockstackerdown" + } + } +} diff --git a/src/main/resources/assets/quickiemod/blockstates/blockstackereast.json b/src/main/resources/assets/quickiemod/blockstates/blockstackereast.json new file mode 100644 index 0000000..7b1fd09 --- /dev/null +++ b/src/main/resources/assets/quickiemod/blockstates/blockstackereast.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "quickiemod:block/blockstackereast" + } + } +} diff --git a/src/main/resources/assets/quickiemod/blockstates/blockstackernorth.json b/src/main/resources/assets/quickiemod/blockstates/blockstackernorth.json new file mode 100644 index 0000000..d20bddd --- /dev/null +++ b/src/main/resources/assets/quickiemod/blockstates/blockstackernorth.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "quickiemod:block/blockstackernorth" + } + } +} diff --git a/src/main/resources/assets/quickiemod/blockstates/blockstackersouth.json b/src/main/resources/assets/quickiemod/blockstates/blockstackersouth.json new file mode 100644 index 0000000..d18af44 --- /dev/null +++ b/src/main/resources/assets/quickiemod/blockstates/blockstackersouth.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "quickiemod:block/blockstackersouth" + } + } +} diff --git a/src/main/resources/assets/quickiemod/blockstates/blockstackerup.json b/src/main/resources/assets/quickiemod/blockstates/blockstackerup.json new file mode 100644 index 0000000..dc4b60c --- /dev/null +++ b/src/main/resources/assets/quickiemod/blockstates/blockstackerup.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "quickiemod:block/blockstackerup" + } + } +} diff --git a/src/main/resources/assets/quickiemod/blockstates/blockstackerwest.json b/src/main/resources/assets/quickiemod/blockstates/blockstackerwest.json new file mode 100644 index 0000000..18629ae --- /dev/null +++ b/src/main/resources/assets/quickiemod/blockstates/blockstackerwest.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "quickiemod:block/blockstackerwest" + } + } +} diff --git a/src/main/resources/assets/quickiemod/models/block/blockstackerdown.json b/src/main/resources/assets/quickiemod/models/block/blockstackerdown.json new file mode 100644 index 0000000..d42110b --- /dev/null +++ b/src/main/resources/assets/quickiemod/models/block/blockstackerdown.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "bottom": "quickiemod:block/blockstackerout", + "side": "quickiemod:block/blockstackerdown", + "top": "quickiemod:block/blockstackerin" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickiemod/models/block/blockstackereast.json b/src/main/resources/assets/quickiemod/models/block/blockstackereast.json new file mode 100644 index 0000000..7e907bc --- /dev/null +++ b/src/main/resources/assets/quickiemod/models/block/blockstackereast.json @@ -0,0 +1,11 @@ +{ + "parent": "block/cube_directional", + "textures": { + "up": "quickiemod:block/blockstackerright", + "down": "quickiemod:block/blockstackerleft", + "north": "quickiemod:block/blockstackerleft", + "east": "quickiemod:block/blockstackerout", + "south": "quickiemod:block/blockstackerright", + "west": "quickiemod:block/blockstackerin" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickiemod/models/block/blockstackernorth.json b/src/main/resources/assets/quickiemod/models/block/blockstackernorth.json new file mode 100644 index 0000000..721b498 --- /dev/null +++ b/src/main/resources/assets/quickiemod/models/block/blockstackernorth.json @@ -0,0 +1,11 @@ +{ + "parent": "block/cube_directional", + "textures": { + "up": "quickiemod:block/blockstackerup", + "down": "quickiemod:block/blockstackerup", + "north": "quickiemod:block/blockstackerout", + "east": "quickiemod:block/blockstackerup", + "south": "quickiemod:block/blockstackerin", + "west": "quickiemod:block/blockstackerup" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickiemod/models/block/blockstackersouth.json b/src/main/resources/assets/quickiemod/models/block/blockstackersouth.json new file mode 100644 index 0000000..5b9efea --- /dev/null +++ b/src/main/resources/assets/quickiemod/models/block/blockstackersouth.json @@ -0,0 +1,11 @@ +{ + "parent": "block/cube_directional", + "textures": { + "up": "quickiemod:block/blockstackerdown", + "down": "quickiemod:block/blockstackerdown", + "north": "quickiemod:block/blockstackerin", + "east": "quickiemod:block/blockstackerdown", + "south": "quickiemod:block/blockstackerout", + "west": "quickiemod:block/blockstackerdown" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickiemod/models/block/blockstackerup.json b/src/main/resources/assets/quickiemod/models/block/blockstackerup.json new file mode 100644 index 0000000..bea5c62 --- /dev/null +++ b/src/main/resources/assets/quickiemod/models/block/blockstackerup.json @@ -0,0 +1,8 @@ +{ + "parent": "block/cube_bottom_top", + "textures": { + "bottom": "quickiemod:block/blockstackerin", + "side": "quickiemod:block/blockstackerup", + "top": "quickiemod:block/blockstackerout" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickiemod/models/block/blockstackerwest.json b/src/main/resources/assets/quickiemod/models/block/blockstackerwest.json new file mode 100644 index 0000000..76b588e --- /dev/null +++ b/src/main/resources/assets/quickiemod/models/block/blockstackerwest.json @@ -0,0 +1,11 @@ +{ + "parent": "block/cube_directional", + "textures": { + "up": "quickiemod:block/blockstackerleft", + "down": "quickiemod:block/blockstackerright", + "north": "quickiemod:block/blockstackerright", + "east": "quickiemod:block/blockstackerin", + "south": "quickiemod:block/blockstackerleft", + "west": "quickiemod:block/blockstackerout" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickiemod/models/item/blockstackerdown.json b/src/main/resources/assets/quickiemod/models/item/blockstackerdown.json new file mode 100644 index 0000000..62e0d3f --- /dev/null +++ b/src/main/resources/assets/quickiemod/models/item/blockstackerdown.json @@ -0,0 +1,10 @@ +{ + "parent": "quickiemod: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/quickiemod/models/item/blockstackereast.json b/src/main/resources/assets/quickiemod/models/item/blockstackereast.json new file mode 100644 index 0000000..3626d53 --- /dev/null +++ b/src/main/resources/assets/quickiemod/models/item/blockstackereast.json @@ -0,0 +1,10 @@ +{ + "parent": "quickiemod:block/blockstackerwest", + "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/quickiemod/models/item/blockstackernorth.json b/src/main/resources/assets/quickiemod/models/item/blockstackernorth.json new file mode 100644 index 0000000..29de363 --- /dev/null +++ b/src/main/resources/assets/quickiemod/models/item/blockstackernorth.json @@ -0,0 +1,10 @@ +{ + "parent": "quickiemod:block/blockstackernorth", + "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/quickiemod/models/item/blockstackersouth.json b/src/main/resources/assets/quickiemod/models/item/blockstackersouth.json new file mode 100644 index 0000000..2fdb3f4 --- /dev/null +++ b/src/main/resources/assets/quickiemod/models/item/blockstackersouth.json @@ -0,0 +1,10 @@ +{ + "parent": "quickiemod:block/blockstackersouth", + "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/quickiemod/models/item/blockstackerup.json b/src/main/resources/assets/quickiemod/models/item/blockstackerup.json new file mode 100644 index 0000000..db2bd6a --- /dev/null +++ b/src/main/resources/assets/quickiemod/models/item/blockstackerup.json @@ -0,0 +1,10 @@ +{ + "parent": "quickiemod:block/blockstackerup", + "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/quickiemod/models/item/blockstackerwest.json b/src/main/resources/assets/quickiemod/models/item/blockstackerwest.json new file mode 100644 index 0000000..18f7e4f --- /dev/null +++ b/src/main/resources/assets/quickiemod/models/item/blockstackerwest.json @@ -0,0 +1,10 @@ +{ + "parent": "quickiemod:block/blockstackereast", + "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/quickiemod/textures/gui/backpack.png b/src/main/resources/assets/quickiemod/textures/gui/backpack.png new file mode 100644 index 0000000000000000000000000000000000000000..f24c05bcd7b53283fe20f3d7656a37ab8394d035 GIT binary patch literal 35433 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 Hv9vz{XT4J& literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/quickiemod/textures/gui/slot.png b/src/main/resources/assets/quickiemod/textures/gui/slot.png new file mode 100644 index 0000000000000000000000000000000000000000..32b0bfa5f270f58c4d0c546f6715f43e148dfa7c GIT binary patch literal 436 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G$6%U;1OBOz@VoL!i*J5?aP3I z>?NMQuI!IlWrex4>z1641!@ZRba4!+xb^mmq2K`n9u`Nvl z$H#TYQe^fmUSb?%n-v$0R1sWMY_J8Nxv(7=F$@gX{U?O#@ZCZN?L b2F$5ol)dCvJ5f2{Gsw@Lu6{1-oD!M