This commit is contained in:
		| @@ -9,7 +9,7 @@ yarn_mappings=1.21.3+build.2 | |||||||
| loader_version=0.16.9 | loader_version=0.16.9 | ||||||
|  |  | ||||||
| # Mod Properties | # Mod Properties | ||||||
| mod_version=1.21.3.0 | mod_version=1.21.3.1 | ||||||
| maven_group=de.jottyfan.quickiemod | maven_group=de.jottyfan.quickiemod | ||||||
| archives_base_name=quickiemod | archives_base_name=quickiemod | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ import java.util.Map; | |||||||
| import com.mojang.serialization.MapCodec; | import com.mojang.serialization.MapCodec; | ||||||
|  |  | ||||||
| import de.jottyfan.quickiemod.blockentity.DrillBlockEntity; | import de.jottyfan.quickiemod.blockentity.DrillBlockEntity; | ||||||
| import de.jottyfan.quickiemod.blockentity.EnumDrillDirection; |  | ||||||
| import de.jottyfan.quickiemod.item.ModItems; | import de.jottyfan.quickiemod.item.ModItems; | ||||||
| import net.minecraft.block.AbstractBlock; | import net.minecraft.block.AbstractBlock; | ||||||
| import net.minecraft.block.Block; | import net.minecraft.block.Block; | ||||||
| @@ -24,12 +23,14 @@ import net.minecraft.item.Items; | |||||||
| import net.minecraft.registry.RegistryKey; | import net.minecraft.registry.RegistryKey; | ||||||
| import net.minecraft.registry.RegistryKeys; | import net.minecraft.registry.RegistryKeys; | ||||||
| import net.minecraft.state.StateManager.Builder; | import net.minecraft.state.StateManager.Builder; | ||||||
|  | import net.minecraft.state.property.EnumProperty; | ||||||
| import net.minecraft.state.property.IntProperty; | import net.minecraft.state.property.IntProperty; | ||||||
| import net.minecraft.text.Text; | import net.minecraft.text.Text; | ||||||
| import net.minecraft.util.ActionResult; | import net.minecraft.util.ActionResult; | ||||||
| import net.minecraft.util.Identifier; | import net.minecraft.util.Identifier; | ||||||
| import net.minecraft.util.hit.BlockHitResult; | import net.minecraft.util.hit.BlockHitResult; | ||||||
| import net.minecraft.util.math.BlockPos; | import net.minecraft.util.math.BlockPos; | ||||||
|  | import net.minecraft.util.math.Direction; | ||||||
| import net.minecraft.world.World; | import net.minecraft.world.World; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -40,11 +41,11 @@ import net.minecraft.world.World; | |||||||
| public class BlockDrill extends FallingBlock implements BlockEntityProvider { | public class BlockDrill extends FallingBlock implements BlockEntityProvider { | ||||||
| 	private static final Integer MAX_FUEL = 255; | 	private static final Integer MAX_FUEL = 255; | ||||||
| 	public static final IntProperty FUEL = IntProperty.of("fuel", 0, MAX_FUEL); | 	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> 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))); | 		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 | 	@Override | ||||||
|   | |||||||
							
								
								
									
										117
									
								
								src/main/java/de/jottyfan/quickiemod/block/BlockStacker.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								src/main/java/de/jottyfan/quickiemod/block/BlockStacker.java
									
									
									
									
									
										Normal file
									
								
							| @@ -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<? extends BlockWithEntity> getCodec() { | ||||||
|  | 		// TODO Auto-generated method stub | ||||||
|  | 		return null; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, | ||||||
|  | 			BlockEntityType<T> 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)); | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -4,7 +4,6 @@ import java.util.ArrayList; | |||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
| import de.jottyfan.quickiemod.Quickiemod; | import de.jottyfan.quickiemod.Quickiemod; | ||||||
| import de.jottyfan.quickiemod.blockentity.EnumDrillDirection; |  | ||||||
| import de.jottyfan.quickiemod.identifier.ModIdentifiers; | import de.jottyfan.quickiemod.identifier.ModIdentifiers; | ||||||
| import de.jottyfan.quickiemod.item.ModItems; | import de.jottyfan.quickiemod.item.ModItems; | ||||||
| import net.minecraft.block.Block; | import net.minecraft.block.Block; | ||||||
| @@ -17,6 +16,7 @@ import net.minecraft.registry.RegistryKey; | |||||||
| import net.minecraft.registry.RegistryKeys; | import net.minecraft.registry.RegistryKeys; | ||||||
| import net.minecraft.sound.BlockSoundGroup; | import net.minecraft.sound.BlockSoundGroup; | ||||||
| import net.minecraft.util.Identifier; | 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, | 	public static final Block BLOCK_CANOLAPLANT = registerBlock(ModIdentifiers.BLOCK_CANOLAPLANT, | ||||||
| 			new BlockPlant(ModIdentifiers.BLOCK_CANOLAPLANT, ModItems.ITEM_CANOLASEED, ModItems.ITEM_CANOLA), false); | 			new BlockPlant(ModIdentifiers.BLOCK_CANOLAPLANT, ModItems.ITEM_CANOLASEED, ModItems.ITEM_CANOLA), false); | ||||||
| 	public static final Block BLOCK_DRILL_DOWN = registerBlock(ModIdentifiers.BLOCK_DRILLDOWN, | 	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, | 	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, | 	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, | 	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, | 	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) { | 	private static final Block registerBlock(Identifier identifier, Block block) { | ||||||
| 		return registerBlock(identifier, block, true); | 		return registerBlock(identifier, block, true); | ||||||
| @@ -109,6 +121,12 @@ public class ModBlocks { | |||||||
| 		blocks.add(BLOCK_DRILL_SOUTH); | 		blocks.add(BLOCK_DRILL_SOUTH); | ||||||
| 		blocks.add(BLOCK_DRILL_WEST); | 		blocks.add(BLOCK_DRILL_WEST); | ||||||
| 		blocks.add(BLOCK_DRILL_NORTH); | 		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; | 		return blocks; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -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<ItemStack> inventory = DefaultedList.ofSize(BlockStackerScreenHandler.SLOTSIZE, ItemStack.EMPTY); | ||||||
|  |  | ||||||
|  | 	public BlockStackerEntity(BlockPos blockPos, BlockState blockState) { | ||||||
|  | 		super(ModBlockentity.BLOCKSTACKER_BLOCKENTITY, blockPos, blockState); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public DefaultedList<ItemStack> getItems() { | ||||||
|  | 		return inventory; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public List<ItemStack> getWhiteList() { | ||||||
|  | 		int counter = 0; | ||||||
|  | 		List<ItemStack> list = new ArrayList<>(); | ||||||
|  | 		for (ItemStack stack : inventory) { | ||||||
|  | 			counter++; | ||||||
|  | 			if (counter < 10) { // first 9 items are whitelist items | ||||||
|  | 				list.add(stack); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		return list; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public List<ItemStack> getBlackList() { | ||||||
|  | 		int counter = 0; | ||||||
|  | 		List<ItemStack> 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<ItemStack> whiteList, List<ItemStack> blackList) { | ||||||
|  |  | ||||||
|  | 		// whitelist behaviour | ||||||
|  | 		List<Item> 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<Item> 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<Item> 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<ItemStack> 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<ItemStack> inventory, List<Item> 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<Item> 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(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -8,6 +8,7 @@ import net.minecraft.block.BlockState; | |||||||
| import net.minecraft.block.Blocks; | import net.minecraft.block.Blocks; | ||||||
| import net.minecraft.block.entity.BlockEntity; | import net.minecraft.block.entity.BlockEntity; | ||||||
| import net.minecraft.util.math.BlockPos; | import net.minecraft.util.math.BlockPos; | ||||||
|  | import net.minecraft.util.math.Direction; | ||||||
| import net.minecraft.world.World; | 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) { | 	public static void tick(World world, BlockPos pos, BlockState state, BlockEntity be) { | ||||||
| 		if (be instanceof DrillBlockEntity dbe) { | 		if (be instanceof DrillBlockEntity dbe) { | ||||||
| 			Integer dir = state.get(BlockDrill.DIRECTION); | 			Direction dir = state.get(BlockDrill.DIRECTION); | ||||||
| 			List<BlockPos> list = new ArrayList<>(); | 			List<BlockPos> list = new ArrayList<>(); | ||||||
| 			if (EnumDrillDirection.DOWN.get().equals(dir)) { | 			if (Direction.DOWN.equals(dir)) { | ||||||
| 				list = downFrom(pos); | 				list = downFrom(pos); | ||||||
| 		  } else if (EnumDrillDirection.EAST.get().equals(dir)) { | 		  } else if (Direction.EAST.equals(dir)) { | ||||||
| 				list = directedFrom(pos.east()); | 				list = directedFrom(pos.east()); | ||||||
| 			}	else if (EnumDrillDirection.SOUTH.get().equals(dir)) { | 			}	else if (Direction.SOUTH.equals(dir)) { | ||||||
| 				list = directedFrom(pos.south()); | 				list = directedFrom(pos.south()); | ||||||
| 			}	else if (EnumDrillDirection.WEST.get().equals(dir)) { | 			}	else if (Direction.WEST.equals(dir)) { | ||||||
| 				list = directedFrom(pos.west()); | 				list = directedFrom(pos.west()); | ||||||
| 			}	else if (EnumDrillDirection.NORTH.get().equals(dir)) { | 			}	else if (Direction.NORTH.equals(dir)) { | ||||||
| 				list = directedFrom(pos.north()); | 				list = directedFrom(pos.north()); | ||||||
| 			} | 			} | ||||||
| 			DrillBlockEntity.tick(world, pos, state, dbe, MAXDRILLSTEP, list); | 			DrillBlockEntity.tick(world, pos, state, dbe, MAXDRILLSTEP, list); | ||||||
|   | |||||||
| @@ -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; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @@ -20,6 +20,11 @@ public class ModBlockentity { | |||||||
| 			Registries.BLOCK_ENTITY_TYPE, ModIdentifiers.BLOCKENTITY_DRILL, | 			Registries.BLOCK_ENTITY_TYPE, ModIdentifiers.BLOCKENTITY_DRILL, | ||||||
| 			FabricBlockEntityTypeBuilder.create(DrillBlockEntity::new, ModBlocks.BLOCK_DRILL_DOWN, ModBlocks.BLOCK_DRILL_EAST, | 			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()); | 					ModBlocks.BLOCK_DRILL_SOUTH, ModBlocks.BLOCK_DRILL_WEST, ModBlocks.BLOCK_DRILL_NORTH).build()); | ||||||
|  | 	public static final BlockEntityType<BlockStackerEntity> 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() { | 	public static final void registerModBlockentities() { | ||||||
| 	}; | 	}; | ||||||
|   | |||||||
| @@ -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); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -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<BlockStackerScreenHandler> | ||||||
|  | 		implements ScreenHandlerProvider<BlockStackerScreenHandler> { | ||||||
|  | 	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); | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -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; | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -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<ItemStack> getItems(); | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * Creates an inventory from the item list. | ||||||
|  |    */ | ||||||
|  |   static ImplementedInventory of(DefaultedList<ItemStack> 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; | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -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<BlockStackerScreenHandler> BLOCKSTACKER_SCREEN_HANDLER = new ScreenHandlerType<>(BlockStackerScreenHandler::new, | ||||||
|  | 			FeatureFlags.VANILLA_FEATURES); | ||||||
|  | } | ||||||
| @@ -63,8 +63,15 @@ public class ModIdentifiers { | |||||||
| 	public static final Identifier BLOCK_DRILLSOUTH = Identifier.of(Quickiemod.MOD_ID, "drillsouth"); | 	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_DRILLWEST = Identifier.of(Quickiemod.MOD_ID, "drillwest"); | ||||||
| 	public static final Identifier BLOCK_DRILLNORTH = Identifier.of(Quickiemod.MOD_ID, "drillnorth"); | 	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_ITEMHOARDER = Identifier.of(Quickiemod.MOD_ID, "itemhoarderblockentity"); | ||||||
| 	public static final Identifier BLOCKENTITY_BLOCKSTACKER = Identifier.of(Quickiemod.MOD_ID, "blockstackerblockentity"); | 	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 BLOCKENTITY_DRILL = Identifier.of(Quickiemod.MOD_ID, "drillblockentity"); | ||||||
|  | 	public static final Identifier BLOCKSTACKERUP = Identifier.of(Quickiemod.MOD_ID, "blockstackerblockentity"); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | { | ||||||
|  | 	"variants": { | ||||||
|  | 		"": { | ||||||
|  | 			"model": "quickiemod:block/blockstackerdown" | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | { | ||||||
|  | 	"variants": { | ||||||
|  | 		"": { | ||||||
|  | 			"model": "quickiemod:block/blockstackereast" | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | { | ||||||
|  | 	"variants": { | ||||||
|  | 		"": { | ||||||
|  | 			"model": "quickiemod:block/blockstackernorth" | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | { | ||||||
|  | 	"variants": { | ||||||
|  | 		"": { | ||||||
|  | 			"model": "quickiemod:block/blockstackersouth" | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | { | ||||||
|  | 	"variants": { | ||||||
|  | 		"": { | ||||||
|  | 			"model": "quickiemod:block/blockstackerup" | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | { | ||||||
|  | 	"variants": { | ||||||
|  | 		"": { | ||||||
|  | 			"model": "quickiemod:block/blockstackerwest" | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | { | ||||||
|  | 	"parent": "minecraft:block/cube_bottom_top", | ||||||
|  | 	"textures": { | ||||||
|  | 		"bottom": "quickiemod:block/blockstackerout", | ||||||
|  | 		"side": "quickiemod:block/blockstackerdown", | ||||||
|  | 		"top": "quickiemod:block/blockstackerin" | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -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" | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -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" | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -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" | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | { | ||||||
|  | 	"parent": "block/cube_bottom_top", | ||||||
|  | 	"textures": { | ||||||
|  | 		"bottom": "quickiemod:block/blockstackerin", | ||||||
|  | 		"side": "quickiemod:block/blockstackerup", | ||||||
|  | 		"top": "quickiemod:block/blockstackerout" | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -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" | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -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 ] | ||||||
|  | 				} | ||||||
|  | 		} | ||||||
|  | } | ||||||
| @@ -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 ] | ||||||
|  | 				} | ||||||
|  | 		} | ||||||
|  | } | ||||||
| @@ -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 ] | ||||||
|  | 				} | ||||||
|  | 		} | ||||||
|  | } | ||||||
| @@ -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 ] | ||||||
|  | 				} | ||||||
|  | 		} | ||||||
|  | } | ||||||
| @@ -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 ] | ||||||
|  | 				} | ||||||
|  | 		} | ||||||
|  | } | ||||||
| @@ -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 ] | ||||||
|  | 				} | ||||||
|  | 		} | ||||||
|  | } | ||||||
							
								
								
									
										
											BIN
										
									
								
								src/main/resources/assets/quickiemod/textures/gui/backpack.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/main/resources/assets/quickiemod/textures/gui/backpack.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 35 KiB | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 21 KiB | 
							
								
								
									
										
											BIN
										
									
								
								src/main/resources/assets/quickiemod/textures/gui/slot.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/main/resources/assets/quickiemod/textures/gui/slot.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 436 B | 
| @@ -0,0 +1,19 @@ | |||||||
|  | { | ||||||
|  | 	"type": "minecraft:crafting_shaped", | ||||||
|  | 	"pattern": [ | ||||||
|  | 		"s s", | ||||||
|  | 		"scs", | ||||||
|  | 		" s " | ||||||
|  | 	], | ||||||
|  | 	"key": { | ||||||
|  | 		"s": "quickiemod:speedingot", | ||||||
|  | 		"c": [ | ||||||
|  | 		  "minecraft:chest", | ||||||
|  | 		  "minecraft:barrel" | ||||||
|  | 		] | ||||||
|  | 	}, | ||||||
|  | 	"result": { | ||||||
|  | 		"id": "quickiemod:blockstackerdown", | ||||||
|  | 		"count": 4 | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,10 @@ | |||||||
|  | { | ||||||
|  | 	"type": "minecraft:crafting_shapeless", | ||||||
|  | 	"ingredients": [ | ||||||
|  | 		"quickiemod:blockstackerup" | ||||||
|  | 	], | ||||||
|  | 	"result": { | ||||||
|  | 		"id": "quickiemod:blockstackerdown", | ||||||
|  | 		"count": 1 | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,10 @@ | |||||||
|  | { | ||||||
|  | 	"type": "minecraft:crafting_shapeless", | ||||||
|  | 	"ingredients": [ | ||||||
|  | 		"quickiemod:blockstackerdown" | ||||||
|  | 	], | ||||||
|  | 	"result": { | ||||||
|  | 		"id": "quickiemod:blockstackereast", | ||||||
|  | 		"count": 1 | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,10 @@ | |||||||
|  | { | ||||||
|  | 	"type": "minecraft:crafting_shapeless", | ||||||
|  | 	"ingredients": [ | ||||||
|  | 		"quickiemod:blockstackerwest" | ||||||
|  | 	], | ||||||
|  | 	"result": { | ||||||
|  | 		"id": "quickiemod:blockstackernorth", | ||||||
|  | 		"count": 1 | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,10 @@ | |||||||
|  | { | ||||||
|  | 	"type": "minecraft:crafting_shapeless", | ||||||
|  | 	"ingredients": [ | ||||||
|  | 		"quickiemod:blockstackereast" | ||||||
|  | 	], | ||||||
|  | 	"result": { | ||||||
|  | 		"id": "quickiemod:blockstackersouth", | ||||||
|  | 		"count": 1 | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,10 @@ | |||||||
|  | { | ||||||
|  | 	"type": "minecraft:crafting_shapeless", | ||||||
|  | 	"ingredients": [ | ||||||
|  | 		"quickiemod:blockstackernorth" | ||||||
|  | 	], | ||||||
|  | 	"result": { | ||||||
|  | 		"id": "quickiemod:blockstackerup", | ||||||
|  | 		"count": 1 | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,10 @@ | |||||||
|  | { | ||||||
|  | 	"type": "minecraft:crafting_shapeless", | ||||||
|  | 	"ingredients": [ | ||||||
|  | 		"quickiemod:blockstackersouth" | ||||||
|  | 	], | ||||||
|  | 	"result": { | ||||||
|  | 		"id": "quickiemod:blockstackerwest", | ||||||
|  | 		"count": 1 | ||||||
|  | 	} | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user