Compare commits
	
		
			3 Commits
		
	
	
		
			9f869668c9
			...
			blockstack
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 0338c7c5ef | ||
|  | 72b9c7dece | ||
|  | caef9eed83 | 
| @@ -1,5 +1,5 @@ | |||||||
| # | # | ||||||
| #Sat Jun 01 10:37:20 CEST 2024 | #Mon Jun 24 21:17:32 CEST 2024 | ||||||
| eclipse.preferences.version=1 | eclipse.preferences.version=1 | ||||||
| org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled | ||||||
| org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 | ||||||
|   | |||||||
| @@ -4,14 +4,14 @@ org.gradle.parallel=true | |||||||
|  |  | ||||||
| # Fabric Properties | # Fabric Properties | ||||||
| # check these on https://fabricmc.net/develop | # check these on https://fabricmc.net/develop | ||||||
| minecraft_version=1.20.6 | minecraft_version=1.21 | ||||||
| yarn_mappings=1.20.6+build.3 | yarn_mappings=1.21+build.2 | ||||||
| loader_version=0.15.11 | loader_version=0.15.11 | ||||||
|  |  | ||||||
| # Mod Properties | # Mod Properties | ||||||
| mod_version=1.20.6.0 | mod_version=1.21.0.2 | ||||||
| maven_group=de.jottyfan.quickiemod | maven_group=de.jottyfan.quickiemod | ||||||
| archives_base_name=quickiemod | archives_base_name=quickiemod | ||||||
|  |  | ||||||
| # Dependencies | # Dependencies | ||||||
| fabric_version=0.100.0+1.20.6 | fabric_version=0.100.0+1.21 | ||||||
| @@ -14,13 +14,16 @@ import net.fabricmc.api.ModInitializer; | |||||||
| public class QuickieMod implements ModInitializer { | public class QuickieMod implements ModInitializer { | ||||||
| 	public static final String MODID = "quickiemod"; | 	public static final String MODID = "quickiemod"; | ||||||
|  |  | ||||||
|   private static final Logger LOGGER = LoggerFactory.getLogger(MODID); |   public static final Logger LOGGER = LoggerFactory.getLogger(MODID); | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
| 	public void onInitialize() { | 	public void onInitialize() { | ||||||
| 		LOGGER.info("loading {}", MODID); | 		LOGGER.info("loading {}", MODID); | ||||||
|  |  | ||||||
| 		RegistryManager.registerBlockEntityTypes(); | 		RegistryManager.registerBlockEntityTypes(); | ||||||
|  | 		RegistryManager.registerScreenHandlerTypes(); | ||||||
| 		RegistryManager.registerItems(); | 		RegistryManager.registerItems(); | ||||||
|  | 		RegistryManager.registerEvents(); | ||||||
| 		RegistryManager.registerBlocks(); | 		RegistryManager.registerBlocks(); | ||||||
| 		RegistryManager.registerFeatures(); | 		RegistryManager.registerFeatures(); | ||||||
| 		RegistryManager.registerItemGroup(); | 		RegistryManager.registerItemGroup(); | ||||||
|   | |||||||
| @@ -1,10 +1,13 @@ | |||||||
| package de.jottyfan.quickiemod; | package de.jottyfan.quickiemod; | ||||||
|  |  | ||||||
| import de.jottyfan.quickiemod.blocks.QuickieBlocks; | import de.jottyfan.quickiemod.blocks.QuickieBlocks; | ||||||
|  | import de.jottyfan.quickiemod.container.BlockStackerScreen; | ||||||
|  | import de.jottyfan.quickiemod.container.ScreenHandlerTypes; | ||||||
| import net.fabricmc.api.ClientModInitializer; | import net.fabricmc.api.ClientModInitializer; | ||||||
| import net.fabricmc.api.EnvType; | import net.fabricmc.api.EnvType; | ||||||
| import net.fabricmc.api.Environment; | import net.fabricmc.api.Environment; | ||||||
| import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; | import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; | ||||||
|  | import net.minecraft.client.gui.screen.ingame.HandledScreens; | ||||||
| import net.minecraft.client.render.RenderLayer; | import net.minecraft.client.render.RenderLayer; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -16,6 +19,7 @@ import net.minecraft.client.render.RenderLayer; | |||||||
| public class QuickieModClient implements ClientModInitializer { | public class QuickieModClient implements ClientModInitializer { | ||||||
| 	@Override | 	@Override | ||||||
| 	public void onInitializeClient() { | 	public void onInitializeClient() { | ||||||
|  | //			HandledScreens.register(ScreenHandlerTypes.BLOCKSTACKER_SCREEN_HANDLER, BlockStackerScreen::new); | ||||||
| 		BlockRenderLayerMap.INSTANCE.putBlock(QuickieBlocks.COTTONPLANT.getBlock(), RenderLayer.getCutout()); | 		BlockRenderLayerMap.INSTANCE.putBlock(QuickieBlocks.COTTONPLANT.getBlock(), RenderLayer.getCutout()); | ||||||
| 		BlockRenderLayerMap.INSTANCE.putBlock(QuickieBlocks.CANOLAPLANT.getBlock(), RenderLayer.getCutout()); | 		BlockRenderLayerMap.INSTANCE.putBlock(QuickieBlocks.CANOLAPLANT.getBlock(), RenderLayer.getCutout()); | ||||||
| 	} | 	} | ||||||
|   | |||||||
							
								
								
									
										84
									
								
								src/main/java/de/jottyfan/quickiemod/api/Neighborhood.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,84 @@ | |||||||
|  | package de.jottyfan.quickiemod.api; | ||||||
|  |  | ||||||
|  | import java.util.HashSet; | ||||||
|  | import java.util.Iterator; | ||||||
|  | import java.util.Set; | ||||||
|  | import java.util.function.BiFunction; | ||||||
|  |  | ||||||
|  | import net.minecraft.util.math.BlockPos; | ||||||
|  | import net.minecraft.world.World; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  *  | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class Neighborhood { | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * find the same blocks that is next to the current position pos | ||||||
|  | 	 *  | ||||||
|  | 	 * @param world       the world to look for the blocks | ||||||
|  | 	 * @param pos         the starting position | ||||||
|  | 	 * @param seekLimit   the limit of seek operations | ||||||
|  | 	 * @param checkLambda check functionality | ||||||
|  | 	 * @return a set of found block positions | ||||||
|  | 	 */ | ||||||
|  | 	public static final Set<BlockPos> findEqualBlock(World world, BlockPos pos, int seekLimit, | ||||||
|  | 			BiFunction<World, BlockPos, Boolean> checkLambda) { | ||||||
|  | 		Set<NeighborhoodBean> found = new HashSet<>(); | ||||||
|  | 		found.add(new NeighborhoodBean(pos, true)); | ||||||
|  |  | ||||||
|  | 		while (pos != null && found.size() < seekLimit) { | ||||||
|  | 			findNewNeihgbor(world, pos.east(), found, checkLambda); | ||||||
|  | 			findNewNeihgbor(world, pos.south(), found, checkLambda); | ||||||
|  | 			findNewNeihgbor(world, pos.west(), found, checkLambda); | ||||||
|  | 			findNewNeihgbor(world, pos.north(), found, checkLambda); | ||||||
|  | 			pos = findNextUncheckedField(found); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		Set<BlockPos> finals = new HashSet<>(); | ||||||
|  | 		for (NeighborhoodBean bean : found) { | ||||||
|  | 			finals.add(bean.getPos()); | ||||||
|  | 		} | ||||||
|  | 		return finals; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	private static final BlockPos findNextUncheckedField(Set<NeighborhoodBean> found) { | ||||||
|  | 		Iterator<NeighborhoodBean> i = found.iterator(); | ||||||
|  | 		while (i.hasNext()) { | ||||||
|  | 			NeighborhoodBean bean = i.next(); | ||||||
|  | 			if (!bean.isChecked()) { | ||||||
|  | 				bean.setChecked(true); | ||||||
|  | 				return bean.getPos(); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		return null; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * find new neighbor at pos | ||||||
|  | 	 *  | ||||||
|  | 	 * @param world the world | ||||||
|  | 	 * @param pos   the position | ||||||
|  | 	 * @param found the set with all already found positions | ||||||
|  | 	 * @return true or false | ||||||
|  | 	 */ | ||||||
|  | 	private static final boolean findNewNeihgbor(World world, BlockPos pos, Set<NeighborhoodBean> found, | ||||||
|  | 			BiFunction<World, BlockPos, Boolean> checkLambda) { | ||||||
|  | 		NeighborhoodBean bean = new NeighborhoodBean(pos); | ||||||
|  | 		if (found.contains(bean) || found.contains(bean.over()) || found.contains(bean.below())) { | ||||||
|  | 			return false; | ||||||
|  | 		} else if (checkLambda.apply(world, pos).booleanValue()) { | ||||||
|  | 			found.add(bean); | ||||||
|  | 			return true; | ||||||
|  | 		} else if (checkLambda.apply(world, pos.up()).booleanValue()) { | ||||||
|  | 			found.add(new NeighborhoodBean(pos.up())); | ||||||
|  | 			return true; | ||||||
|  | 		} else if (checkLambda.apply(world, pos.down()).booleanValue()) { | ||||||
|  | 			found.add(new NeighborhoodBean(pos.down())); | ||||||
|  | 			return true; | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,77 @@ | |||||||
|  | package de.jottyfan.quickiemod.api; | ||||||
|  |  | ||||||
|  | import java.util.Objects; | ||||||
|  |  | ||||||
|  | import net.minecraft.util.math.BlockPos; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  *  | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class NeighborhoodBean { | ||||||
|  | 	private final BlockPos pos; | ||||||
|  | 	private boolean checked; | ||||||
|  |  | ||||||
|  | 	public NeighborhoodBean(BlockPos pos, boolean checked) { | ||||||
|  | 		super(); | ||||||
|  | 		this.pos = pos; | ||||||
|  | 		this.checked = checked; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public NeighborhoodBean(BlockPos pos) { | ||||||
|  | 		super(); | ||||||
|  | 		this.pos = pos; | ||||||
|  | 		this.checked = false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public NeighborhoodBean over() { | ||||||
|  | 		return new NeighborhoodBean(pos.up(), checked); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public NeighborhoodBean below() { | ||||||
|  | 		return new NeighborhoodBean(pos.down(), checked); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public int hashCode() { | ||||||
|  | 		return Objects.hash(pos); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public boolean equals(Object obj) { | ||||||
|  | 		Boolean result = null; | ||||||
|  | 		if (this == obj) { | ||||||
|  | 			result = true; | ||||||
|  | 		} else if (obj == null) { | ||||||
|  | 			result = false; | ||||||
|  | 		} else if (getClass() != obj.getClass()) { | ||||||
|  | 			result = false; | ||||||
|  | 		} else { | ||||||
|  | 			NeighborhoodBean other = (NeighborhoodBean) obj; | ||||||
|  | 			result = Objects.equals(pos, other.pos); | ||||||
|  | 		} | ||||||
|  | 		return result; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * @return the checked | ||||||
|  | 	 */ | ||||||
|  | 	public boolean isChecked() { | ||||||
|  | 		return checked; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * @param checked the checked to set | ||||||
|  | 	 */ | ||||||
|  | 	public void setChecked(boolean checked) { | ||||||
|  | 		this.checked = checked; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * @return the pos | ||||||
|  | 	 */ | ||||||
|  | 	public BlockPos getPos() { | ||||||
|  | 		return pos; | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -29,4 +29,9 @@ public class BlockEntityTypes { | |||||||
| 			BlockEntityType.Builder.create(DrillBlockWestEntity::new, QuickieBlocks.DRILL_WEST.getBlock()).build(null)); | 			BlockEntityType.Builder.create(DrillBlockWestEntity::new, QuickieBlocks.DRILL_WEST.getBlock()).build(null)); | ||||||
| 	public static final BlockEntityType<DrillBlockNorthEntity> DRILL_NORTH = Registry.register(Registries.BLOCK_ENTITY_TYPE, BlockEntityIdentity.DRILL_NORTH, | 	public static final BlockEntityType<DrillBlockNorthEntity> DRILL_NORTH = Registry.register(Registries.BLOCK_ENTITY_TYPE, BlockEntityIdentity.DRILL_NORTH, | ||||||
| 			BlockEntityType.Builder.create(DrillBlockNorthEntity::new, QuickieBlocks.DRILL_NORTH.getBlock()).build(null)); | 			BlockEntityType.Builder.create(DrillBlockNorthEntity::new, QuickieBlocks.DRILL_NORTH.getBlock()).build(null)); | ||||||
|  | 	public static final BlockEntityType<BlockStackerEntity> BLOCKSTACKER_ENTITY = Registry.register(Registries.BLOCK_ENTITY_TYPE, | ||||||
|  | 			BlockEntityIdentity.BLOCKSTACKERUP, | ||||||
|  | 			BlockEntityType.Builder.create(BlockStackerEntity::new, QuickieBlocks.BLOCKSTACKERUP.getBlock(), QuickieBlocks.BLOCKSTACKERDOWN.getBlock(), | ||||||
|  | 					QuickieBlocks.BLOCKSTACKEREAST.getBlock(), QuickieBlocks.BLOCKSTACKERWEST.getBlock(), QuickieBlocks.BLOCKSTACKERNORTH.getBlock(), | ||||||
|  | 					QuickieBlocks.BLOCKSTACKERSOUTH.getBlock()).build(null)); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,265 @@ | |||||||
|  | package de.jottyfan.quickiemod.blockentity; | ||||||
|  |  | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
|  | import de.jottyfan.quickiemod.QuickieMod; | ||||||
|  | import de.jottyfan.quickiemod.blocks.help.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 static final Logger LOGGER = LoggerFactory.getLogger(QuickieMod.MODID); | ||||||
|  |  | ||||||
|  | 	private final DefaultedList<ItemStack> inventory = DefaultedList.ofSize(BlockStackerScreenHandler.SLOTSIZE, ItemStack.EMPTY); | ||||||
|  |  | ||||||
|  | 	public BlockStackerEntity(BlockPos blockPos, BlockState blockState) { | ||||||
|  | 		super(BlockEntityTypes.BLOCKSTACKER_ENTITY, 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) { | ||||||
|  | 					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) { | ||||||
|  | 					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; | ||||||
|  | 			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(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -5,11 +5,11 @@ import java.util.List; | |||||||
|  |  | ||||||
| import de.jottyfan.quickiemod.blocks.help.IntProviderHelper; | import de.jottyfan.quickiemod.blocks.help.IntProviderHelper; | ||||||
| import de.jottyfan.quickiemod.items.QuickieItems; | import de.jottyfan.quickiemod.items.QuickieItems; | ||||||
| import net.minecraft.block.AbstractBlock; |  | ||||||
| import net.minecraft.block.BlockState; | import net.minecraft.block.BlockState; | ||||||
| import net.minecraft.block.ExperienceDroppingBlock; | import net.minecraft.block.ExperienceDroppingBlock; | ||||||
| import net.minecraft.item.ItemStack; | import net.minecraft.item.ItemStack; | ||||||
| import net.minecraft.loot.context.LootContextParameterSet.Builder; | import net.minecraft.loot.context.LootContextParameterSet.Builder; | ||||||
|  | import net.minecraft.sound.BlockSoundGroup; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -20,7 +20,7 @@ import net.minecraft.loot.context.LootContextParameterSet.Builder; | |||||||
| public class BlockOreDeepslateSulphor extends ExperienceDroppingBlock { | public class BlockOreDeepslateSulphor extends ExperienceDroppingBlock { | ||||||
|  |  | ||||||
| 	public BlockOreDeepslateSulphor() { | 	public BlockOreDeepslateSulphor() { | ||||||
| 		super(IntProviderHelper.of(0, 2), AbstractBlock.Settings.create().hardness(1.9f).requiresTool()); | 		super(IntProviderHelper.of(0,  2), Settings.create().strength(2.5f).hardness(1.9f).sounds(BlockSoundGroup.SOUL_SAND).requiresTool()); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
|   | |||||||
| @@ -5,11 +5,11 @@ import java.util.List; | |||||||
|  |  | ||||||
| import de.jottyfan.quickiemod.blocks.help.IntProviderHelper; | import de.jottyfan.quickiemod.blocks.help.IntProviderHelper; | ||||||
| import de.jottyfan.quickiemod.items.QuickieItems; | import de.jottyfan.quickiemod.items.QuickieItems; | ||||||
| import net.minecraft.block.AbstractBlock; |  | ||||||
| import net.minecraft.block.BlockState; | import net.minecraft.block.BlockState; | ||||||
| import net.minecraft.block.ExperienceDroppingBlock; | import net.minecraft.block.ExperienceDroppingBlock; | ||||||
| import net.minecraft.item.ItemStack; | import net.minecraft.item.ItemStack; | ||||||
| import net.minecraft.loot.context.LootContextParameterSet.Builder; | import net.minecraft.loot.context.LootContextParameterSet.Builder; | ||||||
|  | import net.minecraft.sound.BlockSoundGroup; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * |  * | ||||||
| @@ -19,7 +19,7 @@ import net.minecraft.loot.context.LootContextParameterSet.Builder; | |||||||
| public class BlockOreNetherSulphor extends ExperienceDroppingBlock { | public class BlockOreNetherSulphor extends ExperienceDroppingBlock { | ||||||
|  |  | ||||||
| 	public BlockOreNetherSulphor() { | 	public BlockOreNetherSulphor() { | ||||||
| 		super(IntProviderHelper.of(0, 2), AbstractBlock.Settings.create().hardness(2.1f).requiresTool()); | 		super(IntProviderHelper.of(0,  2), Settings.create().strength(2.5f).hardness(2.1f).sounds(BlockSoundGroup.SOUL_SAND).requiresTool()); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
|   | |||||||
| @@ -5,11 +5,11 @@ import java.util.List; | |||||||
|  |  | ||||||
| import de.jottyfan.quickiemod.blocks.help.IntProviderHelper; | import de.jottyfan.quickiemod.blocks.help.IntProviderHelper; | ||||||
| import de.jottyfan.quickiemod.items.QuickieItems; | import de.jottyfan.quickiemod.items.QuickieItems; | ||||||
| import net.minecraft.block.AbstractBlock; |  | ||||||
| import net.minecraft.block.BlockState; | import net.minecraft.block.BlockState; | ||||||
| import net.minecraft.block.ExperienceDroppingBlock; | import net.minecraft.block.ExperienceDroppingBlock; | ||||||
| import net.minecraft.item.ItemStack; | import net.minecraft.item.ItemStack; | ||||||
| import net.minecraft.loot.context.LootContextParameterSet.Builder; | import net.minecraft.loot.context.LootContextParameterSet.Builder; | ||||||
|  | import net.minecraft.sound.BlockSoundGroup; | ||||||
| import net.minecraft.util.math.random.Random; | import net.minecraft.util.math.random.Random; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -20,7 +20,7 @@ import net.minecraft.util.math.random.Random; | |||||||
| public class BlockOreSalpeter extends ExperienceDroppingBlock { | public class BlockOreSalpeter extends ExperienceDroppingBlock { | ||||||
|  |  | ||||||
| 	public BlockOreSalpeter() { | 	public BlockOreSalpeter() { | ||||||
| 		super(IntProviderHelper.of(0, 2), AbstractBlock.Settings.create().hardness(3.1f).requiresTool()); | 		super(IntProviderHelper.of(0,  2), Settings.create().strength(2.5f).hardness(3.1f).sounds(BlockSoundGroup.SOUL_SAND).requiresTool()); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
|   | |||||||
| @@ -5,12 +5,12 @@ import java.util.List; | |||||||
|  |  | ||||||
| import de.jottyfan.quickiemod.blocks.help.IntProviderHelper; | import de.jottyfan.quickiemod.blocks.help.IntProviderHelper; | ||||||
| import de.jottyfan.quickiemod.items.QuickieItems; | import de.jottyfan.quickiemod.items.QuickieItems; | ||||||
| import net.minecraft.block.AbstractBlock; |  | ||||||
| import net.minecraft.block.BlockState; | import net.minecraft.block.BlockState; | ||||||
| import net.minecraft.block.Blocks; | import net.minecraft.block.Blocks; | ||||||
| import net.minecraft.block.ExperienceDroppingBlock; | import net.minecraft.block.ExperienceDroppingBlock; | ||||||
| import net.minecraft.item.ItemStack; | import net.minecraft.item.ItemStack; | ||||||
| import net.minecraft.loot.context.LootContextParameterSet.Builder; | import net.minecraft.loot.context.LootContextParameterSet.Builder; | ||||||
|  | import net.minecraft.sound.BlockSoundGroup; | ||||||
| import net.minecraft.util.math.random.Random; | import net.minecraft.util.math.random.Random; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -21,7 +21,7 @@ import net.minecraft.util.math.random.Random; | |||||||
| public class BlockOreSandSalpeter extends ExperienceDroppingBlock { | public class BlockOreSandSalpeter extends ExperienceDroppingBlock { | ||||||
|  |  | ||||||
| 	public BlockOreSandSalpeter() { | 	public BlockOreSandSalpeter() { | ||||||
| 		super(IntProviderHelper.of(0, 2), AbstractBlock.Settings.create().hardness(2.9f).requiresTool()); | 		super(IntProviderHelper.of(0,  2), Settings.create().strength(2.5f).hardness(2.9f).sounds(BlockSoundGroup.SOUL_SAND).requiresTool()); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
|   | |||||||
| @@ -5,11 +5,11 @@ import java.util.List; | |||||||
|  |  | ||||||
| import de.jottyfan.quickiemod.blocks.help.IntProviderHelper; | import de.jottyfan.quickiemod.blocks.help.IntProviderHelper; | ||||||
| import de.jottyfan.quickiemod.items.QuickieItems; | import de.jottyfan.quickiemod.items.QuickieItems; | ||||||
| import net.minecraft.block.AbstractBlock; |  | ||||||
| import net.minecraft.block.BlockState; | import net.minecraft.block.BlockState; | ||||||
| import net.minecraft.block.ExperienceDroppingBlock; | import net.minecraft.block.ExperienceDroppingBlock; | ||||||
| import net.minecraft.item.ItemStack; | import net.minecraft.item.ItemStack; | ||||||
| import net.minecraft.loot.context.LootContextParameterSet.Builder; | import net.minecraft.loot.context.LootContextParameterSet.Builder; | ||||||
|  | import net.minecraft.sound.BlockSoundGroup; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -20,7 +20,7 @@ import net.minecraft.loot.context.LootContextParameterSet.Builder; | |||||||
| public class BlockOreSulphor extends ExperienceDroppingBlock { | public class BlockOreSulphor extends ExperienceDroppingBlock { | ||||||
|  |  | ||||||
| 	public BlockOreSulphor() { | 	public BlockOreSulphor() { | ||||||
| 		super(IntProviderHelper.of(0, 2), AbstractBlock.Settings.create().hardness(1.9f).requiresTool()); | 		super(IntProviderHelper.of(0,  2), Settings.create().strength(2.5f).hardness(1.9f).sounds(BlockSoundGroup.SOUL_SAND).requiresTool()); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
|   | |||||||
| @@ -5,11 +5,11 @@ import java.util.List; | |||||||
|  |  | ||||||
| import de.jottyfan.quickiemod.blocks.help.IntProviderHelper; | import de.jottyfan.quickiemod.blocks.help.IntProviderHelper; | ||||||
| import de.jottyfan.quickiemod.items.QuickieItems; | import de.jottyfan.quickiemod.items.QuickieItems; | ||||||
| import net.minecraft.block.AbstractBlock; |  | ||||||
| import net.minecraft.block.BlockState; | import net.minecraft.block.BlockState; | ||||||
| import net.minecraft.block.ExperienceDroppingBlock; | import net.minecraft.block.ExperienceDroppingBlock; | ||||||
| import net.minecraft.item.ItemStack; | import net.minecraft.item.ItemStack; | ||||||
| import net.minecraft.loot.context.LootContextParameterSet.Builder; | import net.minecraft.loot.context.LootContextParameterSet.Builder; | ||||||
|  | import net.minecraft.sound.BlockSoundGroup; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * |  * | ||||||
| @@ -19,7 +19,7 @@ import net.minecraft.loot.context.LootContextParameterSet.Builder; | |||||||
| public class BlockSalpeter extends ExperienceDroppingBlock { | public class BlockSalpeter extends ExperienceDroppingBlock { | ||||||
|  |  | ||||||
| 	public BlockSalpeter() { | 	public BlockSalpeter() { | ||||||
| 		super(IntProviderHelper.of(0, 2), AbstractBlock.Settings.create().hardness(0.5f)); | 		super(IntProviderHelper.of(0,  2), Settings.create().strength(2.5f).hardness(0.5f).sounds(BlockSoundGroup.SOUL_SAND).requiresTool()); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
|   | |||||||
| @@ -6,12 +6,12 @@ import java.util.List; | |||||||
| import com.mojang.serialization.MapCodec; | import com.mojang.serialization.MapCodec; | ||||||
|  |  | ||||||
| import de.jottyfan.quickiemod.items.QuickieItems; | import de.jottyfan.quickiemod.items.QuickieItems; | ||||||
| import net.minecraft.block.AbstractBlock; |  | ||||||
| import net.minecraft.block.BlockState; | import net.minecraft.block.BlockState; | ||||||
| import net.minecraft.block.Blocks; | import net.minecraft.block.Blocks; | ||||||
| import net.minecraft.block.FallingBlock; | import net.minecraft.block.FallingBlock; | ||||||
| import net.minecraft.item.ItemStack; | import net.minecraft.item.ItemStack; | ||||||
| import net.minecraft.loot.context.LootContextParameterSet.Builder; | import net.minecraft.loot.context.LootContextParameterSet.Builder; | ||||||
|  | import net.minecraft.sound.BlockSoundGroup; | ||||||
| import net.minecraft.util.math.random.Random; | import net.minecraft.util.math.random.Random; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -22,7 +22,7 @@ import net.minecraft.util.math.random.Random; | |||||||
| public class BlockSandSalpeter extends FallingBlock { | public class BlockSandSalpeter extends FallingBlock { | ||||||
|  |  | ||||||
| 	public BlockSandSalpeter() { | 	public BlockSandSalpeter() { | ||||||
| 		super(AbstractBlock.Settings.create().hardness(3.1f).requiresTool()); | 		super(Settings.create().strength(2.5f).hardness(3.1f).sounds(BlockSoundGroup.SOUL_SAND).requiresTool()); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
|   | |||||||
| @@ -0,0 +1,111 @@ | |||||||
|  | package de.jottyfan.quickiemod.blocks; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import com.mojang.serialization.MapCodec; | ||||||
|  |  | ||||||
|  | import de.jottyfan.quickiemod.blockentity.BlockEntityTypes; | ||||||
|  | import de.jottyfan.quickiemod.blockentity.BlockStackerEntity; | ||||||
|  | import de.jottyfan.quickiemod.blocks.help.BlockStacker; | ||||||
|  | import net.minecraft.block.AbstractBlock; | ||||||
|  | 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.item.ItemStack; | ||||||
|  | import net.minecraft.loot.context.LootContextParameterSet.Builder; | ||||||
|  | import net.minecraft.screen.NamedScreenHandlerFactory; | ||||||
|  | import net.minecraft.screen.ScreenHandler; | ||||||
|  | import net.minecraft.util.ActionResult; | ||||||
|  | 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 BlockStackerDown extends BlockWithEntity implements BlockStacker { | ||||||
|  |  | ||||||
|  | 	public BlockStackerDown() { | ||||||
|  | 		super(AbstractBlock.Settings.create().hardness(2.5f)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public Direction getSourceOffset() { | ||||||
|  | 		return Direction.UP; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public Direction getDestOffset() { | ||||||
|  | 		return Direction.DOWN; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { | ||||||
|  | 		return new BlockStackerEntity(pos, state); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public BlockRenderType getRenderType(BlockState state) { | ||||||
|  | 		return BlockRenderType.MODEL; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public List<ItemStack> getDroppedStacks(BlockState state, Builder builder) { | ||||||
|  | 		return List.of(new ItemStack(QuickieBlocks.BLOCKSTACKERDOWN.getBlock())); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, | ||||||
|  | 			BlockEntityType<T> type) { | ||||||
|  | 		return validateTicker(type, BlockEntityTypes.BLOCKSTACKER_ENTITY, | ||||||
|  | 				(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)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	protected MapCodec<? extends BlockWithEntity> getCodec() { | ||||||
|  | 		// TODO Auto-generated method stub | ||||||
|  | 		return null; | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,111 @@ | |||||||
|  | package de.jottyfan.quickiemod.blocks; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import com.mojang.serialization.MapCodec; | ||||||
|  |  | ||||||
|  | import de.jottyfan.quickiemod.blockentity.BlockEntityTypes; | ||||||
|  | import de.jottyfan.quickiemod.blockentity.BlockStackerEntity; | ||||||
|  | import de.jottyfan.quickiemod.blocks.help.BlockStacker; | ||||||
|  | import net.minecraft.block.AbstractBlock; | ||||||
|  | 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.item.ItemStack; | ||||||
|  | import net.minecraft.loot.context.LootContextParameterSet.Builder; | ||||||
|  | import net.minecraft.screen.NamedScreenHandlerFactory; | ||||||
|  | import net.minecraft.screen.ScreenHandler; | ||||||
|  | import net.minecraft.util.ActionResult; | ||||||
|  | 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 BlockStackerEast extends BlockWithEntity implements BlockStacker { | ||||||
|  |  | ||||||
|  | 	public BlockStackerEast() { | ||||||
|  | 		super(AbstractBlock.Settings.create().hardness(2.5f)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public Direction getSourceOffset() { | ||||||
|  | 		return Direction.WEST; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public Direction getDestOffset() { | ||||||
|  | 		return Direction.EAST; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { | ||||||
|  | 		return new BlockStackerEntity(pos, state); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public BlockRenderType getRenderType(BlockState state) { | ||||||
|  | 		return BlockRenderType.MODEL; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public List<ItemStack> getDroppedStacks(BlockState state, Builder builder) { | ||||||
|  | 		return List.of(new ItemStack(QuickieBlocks.BLOCKSTACKEREAST.getBlock())); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, | ||||||
|  | 			BlockEntityType<T> type) { | ||||||
|  | 		return validateTicker(type, BlockEntityTypes.BLOCKSTACKER_ENTITY, | ||||||
|  | 				(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)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	protected MapCodec<? extends BlockWithEntity> getCodec() { | ||||||
|  | 		// TODO Auto-generated method stub | ||||||
|  | 		return null; | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,111 @@ | |||||||
|  | package de.jottyfan.quickiemod.blocks; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import com.mojang.serialization.MapCodec; | ||||||
|  |  | ||||||
|  | import de.jottyfan.quickiemod.blockentity.BlockEntityTypes; | ||||||
|  | import de.jottyfan.quickiemod.blockentity.BlockStackerEntity; | ||||||
|  | import de.jottyfan.quickiemod.blocks.help.BlockStacker; | ||||||
|  | import net.minecraft.block.AbstractBlock; | ||||||
|  | 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.item.ItemStack; | ||||||
|  | import net.minecraft.loot.context.LootContextParameterSet.Builder; | ||||||
|  | import net.minecraft.screen.NamedScreenHandlerFactory; | ||||||
|  | import net.minecraft.screen.ScreenHandler; | ||||||
|  | import net.minecraft.util.ActionResult; | ||||||
|  | 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 BlockStackerNorth extends BlockWithEntity implements BlockStacker { | ||||||
|  |  | ||||||
|  | 	public BlockStackerNorth() { | ||||||
|  | 		super(AbstractBlock.Settings.create().hardness(2.5f)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public Direction getSourceOffset() { | ||||||
|  | 		return Direction.SOUTH; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public Direction getDestOffset() { | ||||||
|  | 		return Direction.NORTH; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { | ||||||
|  | 		return new BlockStackerEntity(pos, state); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public BlockRenderType getRenderType(BlockState state) { | ||||||
|  | 		return BlockRenderType.MODEL; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public List<ItemStack> getDroppedStacks(BlockState state, Builder builder) { | ||||||
|  | 		return List.of(new ItemStack(QuickieBlocks.BLOCKSTACKERNORTH.getBlock())); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, | ||||||
|  | 			BlockEntityType<T> type) { | ||||||
|  | 		return validateTicker(type, BlockEntityTypes.BLOCKSTACKER_ENTITY, | ||||||
|  | 				(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)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	protected MapCodec<? extends BlockWithEntity> getCodec() { | ||||||
|  | 		// TODO Auto-generated method stub | ||||||
|  | 		return null; | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,111 @@ | |||||||
|  | package de.jottyfan.quickiemod.blocks; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import com.mojang.serialization.MapCodec; | ||||||
|  |  | ||||||
|  | import de.jottyfan.quickiemod.blockentity.BlockEntityTypes; | ||||||
|  | import de.jottyfan.quickiemod.blockentity.BlockStackerEntity; | ||||||
|  | import de.jottyfan.quickiemod.blocks.help.BlockStacker; | ||||||
|  | import net.minecraft.block.AbstractBlock; | ||||||
|  | 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.item.ItemStack; | ||||||
|  | import net.minecraft.loot.context.LootContextParameterSet.Builder; | ||||||
|  | import net.minecraft.screen.NamedScreenHandlerFactory; | ||||||
|  | import net.minecraft.screen.ScreenHandler; | ||||||
|  | import net.minecraft.util.ActionResult; | ||||||
|  | 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 BlockStackerSouth extends BlockWithEntity implements BlockStacker { | ||||||
|  |  | ||||||
|  | 	public BlockStackerSouth() { | ||||||
|  | 		super(AbstractBlock.Settings.create().hardness(2.5f)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public Direction getSourceOffset() { | ||||||
|  | 		return Direction.NORTH; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public Direction getDestOffset() { | ||||||
|  | 		return Direction.SOUTH; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { | ||||||
|  | 		return new BlockStackerEntity(pos, state); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public BlockRenderType getRenderType(BlockState state) { | ||||||
|  | 		return BlockRenderType.MODEL; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public List<ItemStack> getDroppedStacks(BlockState state, Builder builder) { | ||||||
|  | 		return List.of(new ItemStack(QuickieBlocks.BLOCKSTACKERSOUTH.getBlock())); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, | ||||||
|  | 			BlockEntityType<T> type) { | ||||||
|  | 		return validateTicker(type, BlockEntityTypes.BLOCKSTACKER_ENTITY, | ||||||
|  | 				(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)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	protected MapCodec<? extends BlockWithEntity> getCodec() { | ||||||
|  | 		// TODO Auto-generated method stub | ||||||
|  | 		return null; | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										111
									
								
								src/main/java/de/jottyfan/quickiemod/blocks/BlockStackerUp.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,111 @@ | |||||||
|  | package de.jottyfan.quickiemod.blocks; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import com.mojang.serialization.MapCodec; | ||||||
|  |  | ||||||
|  | import de.jottyfan.quickiemod.blockentity.BlockEntityTypes; | ||||||
|  | import de.jottyfan.quickiemod.blockentity.BlockStackerEntity; | ||||||
|  | import de.jottyfan.quickiemod.blocks.help.BlockStacker; | ||||||
|  | import net.minecraft.block.AbstractBlock; | ||||||
|  | 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.item.ItemStack; | ||||||
|  | import net.minecraft.loot.context.LootContextParameterSet.Builder; | ||||||
|  | import net.minecraft.screen.NamedScreenHandlerFactory; | ||||||
|  | import net.minecraft.screen.ScreenHandler; | ||||||
|  | import net.minecraft.util.ActionResult; | ||||||
|  | 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 BlockStackerUp extends BlockWithEntity implements BlockStacker { | ||||||
|  |  | ||||||
|  | 	public BlockStackerUp() { | ||||||
|  | 		super(AbstractBlock.Settings.create().hardness(2.5f)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public Direction getSourceOffset() { | ||||||
|  | 		return Direction.DOWN; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public Direction getDestOffset() { | ||||||
|  | 		return Direction.UP; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { | ||||||
|  | 		return new BlockStackerEntity(pos, state); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public BlockRenderType getRenderType(BlockState state) { | ||||||
|  | 		return BlockRenderType.MODEL; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public List<ItemStack> getDroppedStacks(BlockState state, Builder builder) { | ||||||
|  | 		return List.of(new ItemStack(QuickieBlocks.BLOCKSTACKERUP.getBlock())); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, | ||||||
|  | 			BlockEntityType<T> type) { | ||||||
|  | 		return validateTicker(type, BlockEntityTypes.BLOCKSTACKER_ENTITY, | ||||||
|  | 				(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)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	protected MapCodec<? extends BlockWithEntity> getCodec() { | ||||||
|  | 		// TODO Auto-generated method stub | ||||||
|  | 		return null; | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,111 @@ | |||||||
|  | package de.jottyfan.quickiemod.blocks; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import com.mojang.serialization.MapCodec; | ||||||
|  |  | ||||||
|  | import de.jottyfan.quickiemod.blockentity.BlockEntityTypes; | ||||||
|  | import de.jottyfan.quickiemod.blockentity.BlockStackerEntity; | ||||||
|  | import de.jottyfan.quickiemod.blocks.help.BlockStacker; | ||||||
|  | import net.minecraft.block.AbstractBlock; | ||||||
|  | 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.item.ItemStack; | ||||||
|  | import net.minecraft.loot.context.LootContextParameterSet.Builder; | ||||||
|  | import net.minecraft.screen.NamedScreenHandlerFactory; | ||||||
|  | import net.minecraft.screen.ScreenHandler; | ||||||
|  | import net.minecraft.util.ActionResult; | ||||||
|  | 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 BlockStackerWest extends BlockWithEntity implements BlockStacker { | ||||||
|  |  | ||||||
|  | 	public BlockStackerWest() { | ||||||
|  | 		super(AbstractBlock.Settings.create().hardness(2.5f)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public List<ItemStack> getDroppedStacks(BlockState state, Builder builder) { | ||||||
|  | 		return List.of(new ItemStack(QuickieBlocks.BLOCKSTACKERWEST.getBlock())); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public Direction getSourceOffset() { | ||||||
|  | 		return Direction.EAST; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public Direction getDestOffset() { | ||||||
|  | 		return Direction.WEST; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { | ||||||
|  | 		return new BlockStackerEntity(pos, state); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public BlockRenderType getRenderType(BlockState state) { | ||||||
|  | 		return BlockRenderType.MODEL; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, | ||||||
|  | 			BlockEntityType<T> type) { | ||||||
|  | 		return validateTicker(type, BlockEntityTypes.BLOCKSTACKER_ENTITY, | ||||||
|  | 				(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)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	protected MapCodec<? extends BlockWithEntity> getCodec() { | ||||||
|  | 		// TODO Auto-generated method stub | ||||||
|  | 		return null; | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -5,11 +5,11 @@ import java.util.List; | |||||||
|  |  | ||||||
| import de.jottyfan.quickiemod.blocks.help.IntProviderHelper; | import de.jottyfan.quickiemod.blocks.help.IntProviderHelper; | ||||||
| import de.jottyfan.quickiemod.items.QuickieItems; | import de.jottyfan.quickiemod.items.QuickieItems; | ||||||
| import net.minecraft.block.AbstractBlock; |  | ||||||
| import net.minecraft.block.BlockState; | import net.minecraft.block.BlockState; | ||||||
| import net.minecraft.block.ExperienceDroppingBlock; | import net.minecraft.block.ExperienceDroppingBlock; | ||||||
| import net.minecraft.item.ItemStack; | import net.minecraft.item.ItemStack; | ||||||
| import net.minecraft.loot.context.LootContextParameterSet.Builder; | import net.minecraft.loot.context.LootContextParameterSet.Builder; | ||||||
|  | import net.minecraft.sound.BlockSoundGroup; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * |  * | ||||||
| @@ -19,7 +19,7 @@ import net.minecraft.loot.context.LootContextParameterSet.Builder; | |||||||
| public class BlockSulphor extends ExperienceDroppingBlock { | public class BlockSulphor extends ExperienceDroppingBlock { | ||||||
|  |  | ||||||
| 	public BlockSulphor() { | 	public BlockSulphor() { | ||||||
| 		super(IntProviderHelper.of(0, 2), AbstractBlock.Settings.create().hardness(0.5f)); | 		super(IntProviderHelper.of(0,  2), Settings.create().strength(2.5f).hardness(0.5f).sounds(BlockSoundGroup.SOUL_SAND).requiresTool()); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
|   | |||||||
| @@ -9,6 +9,12 @@ import net.minecraft.block.Block; | |||||||
|  */ |  */ | ||||||
| public enum QuickieBlocks { | public enum QuickieBlocks { | ||||||
| 	// @formatter:off | 	// @formatter:off | ||||||
|  | 	BLOCKSTACKERUP(new BlockStackerUp(), "blockstackerup"), | ||||||
|  | 	BLOCKSTACKERDOWN(new BlockStackerDown(), "blockstackerdown"), | ||||||
|  | 	BLOCKSTACKEREAST(new BlockStackerEast(), "blockstackereast"), | ||||||
|  | 	BLOCKSTACKERWEST(new BlockStackerWest(), "blockstackerwest"), | ||||||
|  | 	BLOCKSTACKERNORTH(new BlockStackerNorth(), "blockstackernorth"), | ||||||
|  | 	BLOCKSTACKERSOUTH(new BlockStackerSouth(), "blockstackersouth"), | ||||||
| 	DRILL_DOWN(new BlockDrillDown(), "drill"), | 	DRILL_DOWN(new BlockDrillDown(), "drill"), | ||||||
| 	DRILL_EAST(new BlockDrillEast(), "drilleast"), | 	DRILL_EAST(new BlockDrillEast(), "drilleast"), | ||||||
| 	DRILL_SOUTH(new BlockDrillSouth(), "drillsouth"), | 	DRILL_SOUTH(new BlockDrillSouth(), "drillsouth"), | ||||||
|   | |||||||
| @@ -0,0 +1,25 @@ | |||||||
|  | package de.jottyfan.quickiemod.blocks.help; | ||||||
|  |  | ||||||
|  | import net.minecraft.block.BlockEntityProvider; | ||||||
|  | import net.minecraft.util.math.Direction; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public interface BlockStacker extends BlockEntityProvider { | ||||||
|  | 	/** | ||||||
|  | 	 * define the source offset | ||||||
|  | 	 * | ||||||
|  | 	 * @return the direction of the source offset (1 block beside) | ||||||
|  | 	 */ | ||||||
|  | 	public Direction getSourceOffset(); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * define the dest offset | ||||||
|  | 	 * | ||||||
|  | 	 * @return the direction of the dest offset (1 block beside) | ||||||
|  | 	 */ | ||||||
|  | 	public Direction getDestOffset(); | ||||||
|  | } | ||||||
| @@ -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.MODID, "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, 0, 0, containerWidth, containerHeight); | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -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); | ||||||
|  | } | ||||||
| @@ -0,0 +1,29 @@ | |||||||
|  | package de.jottyfan.quickiemod.event; | ||||||
|  |  | ||||||
|  | import net.fabricmc.fabric.api.event.Event; | ||||||
|  | import net.fabricmc.fabric.api.event.EventFactory; | ||||||
|  | import net.minecraft.block.BlockState; | ||||||
|  | import net.minecraft.entity.player.PlayerEntity; | ||||||
|  | import net.minecraft.util.ActionResult; | ||||||
|  | import net.minecraft.util.math.BlockPos; | ||||||
|  | import net.minecraft.world.World; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  *  | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public interface BreakBlockCallback {	 | ||||||
|  | 	Event<BreakBlockCallback> EVENT = EventFactory.createArrayBacked(BreakBlockCallback.class, | ||||||
|  | 		(listeners) -> (world, blockPos, blockState, playerEntity) -> { | ||||||
|  | 			for (BreakBlockCallback listener : listeners) { | ||||||
|  | 				ActionResult result = listener.injectBlockBreakCallback(world, blockPos, blockState, playerEntity); | ||||||
|  | 				if (result != ActionResult.PASS) { | ||||||
|  | 					return result; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			return ActionResult.PASS; | ||||||
|  | 		}); | ||||||
|  | 		 | ||||||
|  | 	ActionResult injectBlockBreakCallback(World world, BlockPos blockPos, BlockState blockState, PlayerEntity playerEntity); | ||||||
|  | } | ||||||
							
								
								
									
										193
									
								
								src/main/java/de/jottyfan/quickiemod/event/EventBlockBreak.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,193 @@ | |||||||
|  | package de.jottyfan.quickiemod.event; | ||||||
|  |  | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import org.apache.logging.log4j.LogManager; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  |  | ||||||
|  | import de.jottyfan.quickiemod.QuickieMod; | ||||||
|  | import de.jottyfan.quickiemod.items.HarvestRange; | ||||||
|  | import de.jottyfan.quickiemod.items.QuickieItems; | ||||||
|  | import de.jottyfan.quickiemod.items.ToolRangeable; | ||||||
|  | import net.minecraft.block.Block; | ||||||
|  | import net.minecraft.block.BlockState; | ||||||
|  | import net.minecraft.block.Blocks; | ||||||
|  | import net.minecraft.entity.EquipmentSlot; | ||||||
|  | import net.minecraft.entity.ExperienceOrbEntity; | ||||||
|  | import net.minecraft.entity.player.PlayerEntity; | ||||||
|  | import net.minecraft.item.Item; | ||||||
|  | import net.minecraft.item.ItemStack; | ||||||
|  | import net.minecraft.util.math.BlockPos; | ||||||
|  | import net.minecraft.world.World; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class EventBlockBreak { | ||||||
|  | 	private static final Logger LOGGER = LogManager.getLogger(QuickieMod.MODID); | ||||||
|  |  | ||||||
|  | 	private enum BlockBreakDirection { | ||||||
|  | 		UPWARDS, ALL; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public void doBreakBlock(World world, BlockPos blockPos, BlockState blockState, PlayerEntity playerEntity) { | ||||||
|  | 		ItemStack mainHandItemStack = playerEntity.getEquippedStack(EquipmentSlot.MAINHAND); | ||||||
|  | 		if (mainHandItemStack != null) { | ||||||
|  | 			Item item = mainHandItemStack.getItem(); | ||||||
|  | 			if (item instanceof ToolRangeable) { | ||||||
|  | 				ToolRangeable tool = (ToolRangeable) item; | ||||||
|  | 				Block block = blockState.getBlock(); | ||||||
|  | 				int handled = handleRangeableTools(tool, mainHandItemStack, world, block, blockPos, playerEntity); | ||||||
|  | 				if (handled >= 255) { | ||||||
|  | 					// reward for using rangeable tool very successful | ||||||
|  | 					world.spawnEntity( | ||||||
|  | 							new ExperienceOrbEntity(world, blockPos.getX(), blockPos.getY(), blockPos.getZ(), handled / 255)); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * handle the rangeable tools break event | ||||||
|  | 	 * | ||||||
|  | 	 * @param tool      the tool that has been used | ||||||
|  | 	 * @param itemStack the item stack | ||||||
|  | 	 * @param world     the world | ||||||
|  | 	 * @param block     the block to break | ||||||
|  | 	 * @param pos       the position of the current block | ||||||
|  | 	 * @param player    the current player | ||||||
|  | 	 * @return number of affected blocks | ||||||
|  | 	 */ | ||||||
|  | 	private int handleRangeableTools(ToolRangeable tool, ItemStack itemStack, World world, Block currentBlock, | ||||||
|  | 			BlockPos pos, PlayerEntity player) { | ||||||
|  | 		List<Block> validBlocks = tool.getBlockList(currentBlock); | ||||||
|  | 		HarvestRange range = tool.getRange(itemStack); | ||||||
|  |  | ||||||
|  | 		LOGGER.debug("current tool: {}", tool); | ||||||
|  |  | ||||||
|  | 		if (QuickieItems.SPEEDPOWDERAXE.getItem().equals(tool)) { | ||||||
|  | 			return breakBlockRecursive(new ArrayList<>(), world, validBlocks, pos, tool, range, BlockBreakDirection.UPWARDS, | ||||||
|  | 					player, true); | ||||||
|  | 		} else if (QuickieItems.SPEEDPOWDERPICKAXE.getItem().equals(tool)) { | ||||||
|  | 			return breakBlockRecursive(new ArrayList<>(), world, validBlocks, pos, tool, range, BlockBreakDirection.ALL, | ||||||
|  | 					player, false); | ||||||
|  | 		} else if (QuickieItems.SPEEDPOWDERSHOVEL.getItem().equals(tool)) { | ||||||
|  | 			return breakBlockRecursive(new ArrayList<>(), world, validBlocks, pos, tool, range, BlockBreakDirection.ALL, | ||||||
|  | 					player, false); | ||||||
|  | 		} else if (QuickieItems.SPEEDPOWDERHOE.getItem().equals(tool)) { | ||||||
|  | 			return breakBlockRecursive(new ArrayList<>(), world, validBlocks, pos, tool, range, BlockBreakDirection.ALL, | ||||||
|  | 					player, false); | ||||||
|  | 		} else if (QuickieItems.QUICKIEPOWDERAXE.getItem().equals(tool)) { | ||||||
|  | 				return breakBlockRecursive(new ArrayList<>(), world, validBlocks, pos, tool, range, BlockBreakDirection.UPWARDS, | ||||||
|  | 						player, true); | ||||||
|  | 		} else if (QuickieItems.QUICKIEPOWDERPICKAXE.getItem().equals(tool)) { | ||||||
|  | 			return breakBlockRecursive(new ArrayList<>(), world, validBlocks, pos, tool, range, BlockBreakDirection.ALL, | ||||||
|  | 					player, false); | ||||||
|  | 		} else if (QuickieItems.QUICKIEPOWDERSHOVEL.getItem().equals(tool)) { | ||||||
|  | 			return breakBlockRecursive(new ArrayList<>(), world, validBlocks, pos, tool, range, BlockBreakDirection.ALL, | ||||||
|  | 					player, false); | ||||||
|  | 		} else if (QuickieItems.QUICKIEPOWDERHOE.getItem().equals(tool)) { | ||||||
|  | 			return breakBlockRecursive(new ArrayList<>(), world, validBlocks, pos, tool, range, BlockBreakDirection.ALL, | ||||||
|  | 					player, false); | ||||||
|  | 		} else { | ||||||
|  | 			return 0; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * break block recursively; | ||||||
|  | 	 * | ||||||
|  | 	 * @param visitedBlocks       the positions of visited blocks | ||||||
|  | 	 * @param world               the world | ||||||
|  | 	 * @param validBlocks         the blocks to break | ||||||
|  | 	 * @param tool                the tool used | ||||||
|  | 	 * @param range               the range left over | ||||||
|  | 	 * @param pos                 the position | ||||||
|  | 	 * @param blockBreakDirection the direction for the recursive call | ||||||
|  | 	 * @param player              the player | ||||||
|  | 	 * @return number of affected blocks | ||||||
|  | 	 */ | ||||||
|  | 	private int breakBlockRecursive(List<String> visitedBlocks, World world, List<Block> validBlocks, BlockPos pos, | ||||||
|  | 			ToolRangeable tool, HarvestRange range, BlockBreakDirection blockBreakDirection, PlayerEntity player, | ||||||
|  | 			boolean breakLeaves) { | ||||||
|  | 		if (visitedBlocks.contains(pos.toString())) { | ||||||
|  | 			return 0; | ||||||
|  | 		} else if (validBlocks == null) { | ||||||
|  | 			return 0; | ||||||
|  | 		} else { | ||||||
|  | 			visitedBlocks.add(pos.toString()); | ||||||
|  | 		} | ||||||
|  | 		Integer affected = 0; | ||||||
|  | 		BlockState blockState = world.getBlockState(pos); | ||||||
|  | 		if (tool.canBreakNeighbors(blockState)) { | ||||||
|  | 			Block currentBlock = blockState.getBlock(); | ||||||
|  | 			if (validBlocks.contains(currentBlock)) { | ||||||
|  | 				Block.dropStacks(blockState, world, pos); // includes xorbs | ||||||
|  | 				affected += 1; | ||||||
|  | 				world.setBlockState(pos, Blocks.AIR.getDefaultState()); | ||||||
|  | 				if (range == null || range.getxRange() > 1 || range.getyRange() > 1 || range.getzRange() > 1) { | ||||||
|  | 					HarvestRange nextRadius = range == null ? null : range.addXYZ(-1); | ||||||
|  | 					affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.north(), tool, nextRadius, | ||||||
|  | 							blockBreakDirection, player, breakLeaves); | ||||||
|  | 					affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.north().east(), tool, nextRadius, | ||||||
|  | 							blockBreakDirection, player, breakLeaves); | ||||||
|  | 					affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.north().west(), tool, nextRadius, | ||||||
|  | 							blockBreakDirection, player, breakLeaves); | ||||||
|  | 					affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.south(), tool, nextRadius, | ||||||
|  | 							blockBreakDirection, player, breakLeaves); | ||||||
|  | 					affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.south().east(), tool, nextRadius, | ||||||
|  | 							blockBreakDirection, player, breakLeaves); | ||||||
|  | 					affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.south().west(), tool, nextRadius, | ||||||
|  | 							blockBreakDirection, player, breakLeaves); | ||||||
|  | 					affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.east(), tool, nextRadius, | ||||||
|  | 							blockBreakDirection, player, breakLeaves); | ||||||
|  | 					affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.west(), tool, nextRadius, | ||||||
|  | 							blockBreakDirection, player, breakLeaves); | ||||||
|  | 					affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.up(), tool, nextRadius, | ||||||
|  | 							blockBreakDirection, player, breakLeaves); | ||||||
|  | 					affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.up().north(), tool, nextRadius, | ||||||
|  | 							blockBreakDirection, player, breakLeaves); | ||||||
|  | 					affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.up().north().east(), tool, nextRadius, | ||||||
|  | 							blockBreakDirection, player, breakLeaves); | ||||||
|  | 					affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.up().north().west(), tool, nextRadius, | ||||||
|  | 							blockBreakDirection, player, breakLeaves); | ||||||
|  | 					affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.up().east(), tool, nextRadius, | ||||||
|  | 							blockBreakDirection, player, breakLeaves); | ||||||
|  | 					affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.up().west(), tool, nextRadius, | ||||||
|  | 							blockBreakDirection, player, breakLeaves); | ||||||
|  | 					affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.up().south().east(), tool, nextRadius, | ||||||
|  | 							blockBreakDirection, player, breakLeaves); | ||||||
|  | 					affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.up().south().west(), tool, nextRadius, | ||||||
|  | 							blockBreakDirection, player, breakLeaves); | ||||||
|  | 					affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.up().south(), tool, nextRadius, | ||||||
|  | 							blockBreakDirection, player, breakLeaves); | ||||||
|  |  | ||||||
|  | 					if (BlockBreakDirection.ALL.equals(blockBreakDirection)) { | ||||||
|  | 						affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.down(), tool, nextRadius, | ||||||
|  | 								blockBreakDirection, player, breakLeaves); | ||||||
|  | 						affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.down().north(), tool, nextRadius, | ||||||
|  | 								blockBreakDirection, player, breakLeaves); | ||||||
|  | 						affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.down().south(), tool, nextRadius, | ||||||
|  | 								blockBreakDirection, player, breakLeaves); | ||||||
|  | 						affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.down().east(), tool, nextRadius, | ||||||
|  | 								blockBreakDirection, player, breakLeaves); | ||||||
|  | 						affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.down().west(), tool, nextRadius, | ||||||
|  | 								blockBreakDirection, player, breakLeaves); | ||||||
|  | 						affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.down().north().east(), tool, | ||||||
|  | 								nextRadius, blockBreakDirection, player, breakLeaves); | ||||||
|  | 						affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.down().north().west(), tool, | ||||||
|  | 								nextRadius, blockBreakDirection, player, breakLeaves); | ||||||
|  | 						affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.down().south().east(), tool, | ||||||
|  | 								nextRadius, blockBreakDirection, player, breakLeaves); | ||||||
|  | 						affected += breakBlockRecursive(visitedBlocks, world, validBlocks, pos.down().south().west(), tool, | ||||||
|  | 								nextRadius, blockBreakDirection, player, breakLeaves); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		return affected; | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -9,14 +9,14 @@ import net.minecraft.util.Identifier; | |||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| public class BlockEntityIdentity { | public class BlockEntityIdentity { | ||||||
| 	public static final Identifier ITEMHOARDER = new Identifier(QuickieMod.MODID, "itemhoarderblockentity"); | 	public static final Identifier ITEMHOARDER = Identifier.of(QuickieMod.MODID, "itemhoarderblockentity"); | ||||||
| 	public static final Identifier BLOCKSPREADER = new Identifier(QuickieMod.MODID, "blockspreaderblockentity"); | 	public static final Identifier BLOCKSPREADER = Identifier.of(QuickieMod.MODID, "blockspreaderblockentity"); | ||||||
| 	public static final Identifier BLOCKSTACKERUP = new Identifier(QuickieMod.MODID, "blockstackerblockentity"); | 	public static final Identifier BLOCKSTACKERUP = Identifier.of(QuickieMod.MODID, "blockstackerblockentity"); | ||||||
| 	public static final Identifier MONSTERHOARDER = new Identifier(QuickieMod.MODID, "monsterhoarderblockentity"); | 	public static final Identifier MONSTERHOARDER = Identifier.of(QuickieMod.MODID, "monsterhoarderblockentity"); | ||||||
| 	public static final Identifier EMPTYLAVALHOARDER = new Identifier(QuickieMod.MODID, "emptylavahoarderblockentity"); | 	public static final Identifier EMPTYLAVALHOARDER = Identifier.of(QuickieMod.MODID, "emptylavahoarderblockentity"); | ||||||
| 	public static final Identifier DRILL_DOWN = new Identifier(QuickieMod.MODID, "drillblockdownblockentity"); | 	public static final Identifier DRILL_DOWN = Identifier.of(QuickieMod.MODID, "drillblockdownblockentity"); | ||||||
| 	public static final Identifier DRILL_EAST = new Identifier(QuickieMod.MODID, "drillblockeastblockentity"); | 	public static final Identifier DRILL_EAST = Identifier.of(QuickieMod.MODID, "drillblockeastblockentity"); | ||||||
| 	public static final Identifier DRILL_SOUTH = new Identifier(QuickieMod.MODID, "drillblocksouthblockentity"); | 	public static final Identifier DRILL_SOUTH = Identifier.of(QuickieMod.MODID, "drillblocksouthblockentity"); | ||||||
| 	public static final Identifier DRILL_WEST = new Identifier(QuickieMod.MODID, "drillblockwestblockentity"); | 	public static final Identifier DRILL_WEST = Identifier.of(QuickieMod.MODID, "drillblockwestblockentity"); | ||||||
| 	public static final Identifier DRILL_NORTH = new Identifier(QuickieMod.MODID, "drillblocknorthblockentity"); | 	public static final Identifier DRILL_NORTH = Identifier.of(QuickieMod.MODID, "drillblocknorthblockentity"); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -38,11 +38,11 @@ public class FeaturesManager { | |||||||
|   public static final RegistryKey<PlacedFeature> PF_ORESANDSALPETER  = genPf("oresandsalpeter"); |   public static final RegistryKey<PlacedFeature> PF_ORESANDSALPETER  = genPf("oresandsalpeter"); | ||||||
|  |  | ||||||
|   private static final RegistryKey<ConfiguredFeature<?, ?>> genCf(String name) { |   private static final RegistryKey<ConfiguredFeature<?, ?>> genCf(String name) { | ||||||
|   	return RegistryKey.of(RegistryKeys.CONFIGURED_FEATURE, new Identifier(QuickieMod.MODID, name)); |   	return RegistryKey.of(RegistryKeys.CONFIGURED_FEATURE, Identifier.of(QuickieMod.MODID, name)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| 	private static final RegistryKey<PlacedFeature> genPf(String name) { | 	private static final RegistryKey<PlacedFeature> genPf(String name) { | ||||||
|   	return RegistryKey.of(RegistryKeys.PLACED_FEATURE, new Identifier(QuickieMod.MODID, name)); |   	return RegistryKey.of(RegistryKeys.PLACED_FEATURE, Identifier.of(QuickieMod.MODID, name)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| 	protected static final BiConsumer<BiomeSelectionContext, BiomeModificationContext> overworldOres() { | 	protected static final BiConsumer<BiomeSelectionContext, BiomeModificationContext> overworldOres() { | ||||||
|   | |||||||
| @@ -6,6 +6,8 @@ import org.slf4j.LoggerFactory; | |||||||
| import de.jottyfan.quickiemod.QuickieMod; | import de.jottyfan.quickiemod.QuickieMod; | ||||||
| import de.jottyfan.quickiemod.blockentity.BlockEntityTypes; | import de.jottyfan.quickiemod.blockentity.BlockEntityTypes; | ||||||
| import de.jottyfan.quickiemod.blocks.QuickieBlocks; | import de.jottyfan.quickiemod.blocks.QuickieBlocks; | ||||||
|  | import de.jottyfan.quickiemod.event.BreakBlockCallback; | ||||||
|  | import de.jottyfan.quickiemod.event.EventBlockBreak; | ||||||
| import de.jottyfan.quickiemod.items.QuickieItems; | import de.jottyfan.quickiemod.items.QuickieItems; | ||||||
| import net.fabricmc.fabric.api.biome.v1.BiomeModifications; | import net.fabricmc.fabric.api.biome.v1.BiomeModifications; | ||||||
| import net.fabricmc.fabric.api.biome.v1.BiomeSelectors; | import net.fabricmc.fabric.api.biome.v1.BiomeSelectors; | ||||||
| @@ -21,6 +23,7 @@ import net.minecraft.registry.Registry; | |||||||
| import net.minecraft.registry.RegistryKey; | import net.minecraft.registry.RegistryKey; | ||||||
| import net.minecraft.registry.RegistryKeys; | import net.minecraft.registry.RegistryKeys; | ||||||
| import net.minecraft.text.Text; | import net.minecraft.text.Text; | ||||||
|  | import net.minecraft.util.ActionResult; | ||||||
| import net.minecraft.util.Identifier; | import net.minecraft.util.Identifier; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -32,7 +35,7 @@ public class RegistryManager { | |||||||
| 	private static final Logger LOGGER = LoggerFactory.getLogger(QuickieMod.MODID); | 	private static final Logger LOGGER = LoggerFactory.getLogger(QuickieMod.MODID); | ||||||
|  |  | ||||||
| 	public static final void registerItemGroup() { | 	public static final void registerItemGroup() { | ||||||
| 		Registry.register(Registries.ITEM_GROUP, RegistryKey.of(RegistryKeys.ITEM_GROUP, new Identifier(QuickieMod.MODID, "itemgroups")), | 		Registry.register(Registries.ITEM_GROUP, RegistryKey.of(RegistryKeys.ITEM_GROUP, Identifier.of(QuickieMod.MODID, "itemgroups")), | ||||||
| 				FabricItemGroup.builder().icon(() -> new ItemStack(QuickieItems.ROTTEN_FLESH_STRIPES.getItem())).displayName(Text.literal(QuickieMod.MODID)) | 				FabricItemGroup.builder().icon(() -> new ItemStack(QuickieItems.ROTTEN_FLESH_STRIPES.getItem())).displayName(Text.literal(QuickieMod.MODID)) | ||||||
| 						.entries((enabledFeatures, stacks) -> { | 						.entries((enabledFeatures, stacks) -> { | ||||||
| 							for (QuickieItems i : QuickieItems.values()) { | 							for (QuickieItems i : QuickieItems.values()) { | ||||||
| @@ -47,9 +50,9 @@ public class RegistryManager { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	public static final void registerItems() { | 	public static final void registerItems() { | ||||||
| 		LOGGER.debug("registering items"); | 		LOGGER.info("registering items"); | ||||||
| 		for (QuickieItems i : QuickieItems.values()) { | 		for (QuickieItems i : QuickieItems.values()) { | ||||||
| 			Registry.register(Registries.ITEM, new Identifier(QuickieMod.MODID, i.getName()), i.getItem()); | 			Registry.register(Registries.ITEM, Identifier.of(QuickieMod.MODID, i.getName()), i.getItem()); | ||||||
| 		} | 		} | ||||||
| 		ComposterBlock.ITEM_TO_LEVEL_INCREASE_CHANCE.put(QuickieItems.COTTONSEED.getItem(), 0.5f); | 		ComposterBlock.ITEM_TO_LEVEL_INCREASE_CHANCE.put(QuickieItems.COTTONSEED.getItem(), 0.5f); | ||||||
| 		ComposterBlock.ITEM_TO_LEVEL_INCREASE_CHANCE.put(QuickieItems.COTTON.getItem(), 0.75f); | 		ComposterBlock.ITEM_TO_LEVEL_INCREASE_CHANCE.put(QuickieItems.COTTON.getItem(), 0.75f); | ||||||
| @@ -60,24 +63,40 @@ public class RegistryManager { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	public static final void registerBlocks() { | 	public static final void registerBlocks() { | ||||||
| 		LOGGER.debug("registering blocks"); | 		LOGGER.info("registering blocks"); | ||||||
| 		for (QuickieBlocks b : QuickieBlocks.values()) { | 		for (QuickieBlocks b : QuickieBlocks.values()) { | ||||||
| 			Registry.register(Registries.BLOCK, new Identifier(QuickieMod.MODID, b.getName()), b.getBlock()); | 			Registry.register(Registries.BLOCK, Identifier.of(QuickieMod.MODID, b.getName()), b.getBlock()); | ||||||
| 			Registry.register(Registries.ITEM, new Identifier(QuickieMod.MODID, b.getName()), new BlockItem(b.getBlock(), new Settings())); | 			Registry.register(Registries.ITEM, Identifier.of(QuickieMod.MODID, b.getName()), new BlockItem(b.getBlock(), new Settings())); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	public static final void registerFeatures() { | 	public static final void registerFeatures() { | ||||||
| 		// Overworld features | 		// Overworld features | ||||||
| 		BiomeModifications.create(new Identifier(QuickieMod.MODID, "features")).add(ModificationPhase.ADDITIONS, BiomeSelectors.foundInOverworld(), | 		BiomeModifications.create(Identifier.of(QuickieMod.MODID, "features")).add(ModificationPhase.ADDITIONS, BiomeSelectors.foundInOverworld(), | ||||||
| 				FeaturesManager.overworldOres()); | 				FeaturesManager.overworldOres()); | ||||||
|  |  | ||||||
| 		// Nether features | 		// Nether features | ||||||
| 		BiomeModifications.create(new Identifier(QuickieMod.MODID, "nether_features")).add(ModificationPhase.ADDITIONS, BiomeSelectors.foundInTheNether(), | 		BiomeModifications.create(Identifier.of(QuickieMod.MODID, "nether_features")).add(ModificationPhase.ADDITIONS, BiomeSelectors.foundInTheNether(), | ||||||
| 				FeaturesManager.netherOres()); | 				FeaturesManager.netherOres()); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	public static final void registerEvents() { | ||||||
|  | 		LOGGER.info("registering events"); | ||||||
|  | 		BreakBlockCallback.EVENT.register((world, blockPos, blockState, playerEntity) -> { | ||||||
|  | 			new EventBlockBreak().doBreakBlock(world, blockPos, blockState, playerEntity); | ||||||
|  | 			return ActionResult.SUCCESS; | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	public static final void registerBlockEntityTypes() { | 	public static final void registerBlockEntityTypes() { | ||||||
| 		new BlockEntityTypes(); | 		try { | ||||||
|  | 			Class.forName(BlockEntityTypes.class.getName()); | ||||||
|  | 			LOGGER.info("registering block entity types"); | ||||||
|  | 		} catch (ClassNotFoundException e) { | ||||||
|  | 			LOGGER.error("class BlockEntityType not loaded", e); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public static final void registerScreenHandlerTypes() { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										101
									
								
								src/main/java/de/jottyfan/quickiemod/items/HarvestRange.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,101 @@ | |||||||
|  | package de.jottyfan.quickiemod.items; | ||||||
|  |  | ||||||
|  | import java.io.Serializable; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  *  | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class HarvestRange implements Serializable { | ||||||
|  | 	private static final long serialVersionUID = 1L; | ||||||
|  | 	private int xRange; | ||||||
|  | 	private int yRange; | ||||||
|  | 	private int zRange; | ||||||
|  |  | ||||||
|  | 	public HarvestRange(int xyzRange) { | ||||||
|  | 		super(); | ||||||
|  | 		this.xRange = xyzRange; | ||||||
|  | 		this.yRange = xyzRange; | ||||||
|  | 		this.zRange = xyzRange; | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	public HarvestRange(int[] xyzRange) { | ||||||
|  | 		super(); | ||||||
|  | 		this.xRange = xyzRange[0]; | ||||||
|  | 		this.yRange = xyzRange[1]; | ||||||
|  | 		this.zRange = xyzRange[2]; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public HarvestRange(int xRange, int yRange, int zRange) { | ||||||
|  | 		super(); | ||||||
|  | 		this.xRange = xRange; | ||||||
|  | 		this.yRange = yRange; | ||||||
|  | 		this.zRange = zRange; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * add i to x, y and z and return the resulting class as a new one | ||||||
|  | 	 *  | ||||||
|  | 	 * @param i | ||||||
|  | 	 *          the summand | ||||||
|  | 	 * @return the new class | ||||||
|  | 	 */ | ||||||
|  | 	public HarvestRange addXYZ(int i) { | ||||||
|  | 		return new HarvestRange(xRange + i, yRange + i, zRange + i); | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	/** | ||||||
|  | 	 * get range as int array | ||||||
|  | 	 *  | ||||||
|  | 	 * @return the int array | ||||||
|  | 	 */ | ||||||
|  | 	public int[] getRangeAsArray() { | ||||||
|  | 		return new int[] {xRange, yRange, zRange}; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * @return the xRange | ||||||
|  | 	 */ | ||||||
|  | 	public int getxRange() { | ||||||
|  | 		return xRange; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * @param xRange | ||||||
|  | 	 *          the xRange to set | ||||||
|  | 	 */ | ||||||
|  | 	public void setxRange(int xRange) { | ||||||
|  | 		this.xRange = xRange; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * @return the yRange | ||||||
|  | 	 */ | ||||||
|  | 	public int getyRange() { | ||||||
|  | 		return yRange; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * @param yRange | ||||||
|  | 	 *          the yRange to set | ||||||
|  | 	 */ | ||||||
|  | 	public void setyRange(int yRange) { | ||||||
|  | 		this.yRange = yRange; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * @return the zRange | ||||||
|  | 	 */ | ||||||
|  | 	public int getzRange() { | ||||||
|  | 		return zRange; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * @param zRange | ||||||
|  | 	 *          the zRange to set | ||||||
|  | 	 */ | ||||||
|  | 	public void setzRange(int zRange) { | ||||||
|  | 		this.zRange = zRange; | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -9,7 +9,22 @@ import net.minecraft.item.Item; | |||||||
|  */ |  */ | ||||||
| public enum QuickieItems { | public enum QuickieItems { | ||||||
| 	// @formatter:off | 	// @formatter:off | ||||||
| 	SPEEDPOWDERSHEARS(new ItemSpeedpowdershears(), "speedpowdershears"), | 	SPEEDPOWDER(new ItemSpeedpowder(), "speedpowder"), | ||||||
|  | 	QUICKIEPOWDER(new ItemQuickiepowder(), "quickiepowder"), | ||||||
|  | 	OXIDIZEDCOPPERPOWDER(new ItemOxidizedcopperpowder(), "oxidizedcopperpowder"), | ||||||
|  | 	SPEEDINGOT(new ItemSpeedingot(), "speedingot"), | ||||||
|  | 	QUICKIEINGOT(new ItemQuickieingot(), "quickieingot"), | ||||||
|  | 	SPEEDPOWDERAXE(new ToolSpeedpowderAxe(), "speedpowderaxe"), | ||||||
|  | 	SPEEDPOWDERPICKAXE(new ToolSpeedpowderPickaxe(), "speedpowderpickaxe"), | ||||||
|  | 	SPEEDPOWDERSHOVEL(new ToolSpeedpowderShovel(), "speedpowdershovel"), | ||||||
|  | 	SPEEDPOWDERHOE(new ToolSpeedpowderHoe(), "speedpowderhoe"), | ||||||
|  | 	SPEEDPOWDERWATERHOE(new ToolSpeedpowderWaterHoe(), "speedpowderwaterhoe"), | ||||||
|  |   SPEEDPOWDERSHEARS(new ToolSpeedpowderShears(), "speedpowdershears"), | ||||||
|  | 	QUICKIEPOWDERAXE(new ToolQuickiepowderAxe(), "quickiepowderaxe"), | ||||||
|  | 	QUICKIEPOWDERPICKAXE(new ToolQuickiepowderPickaxe(), "quickiepowderpickaxe"), | ||||||
|  | 	QUICKIEPOWDERSHOVEL(new ToolQuickiepowderShovel(), "quickiepowdershovel"), | ||||||
|  | 	QUICKIEPOWDERHOE(new ToolQuickiepowderHoe(), "quickiepowderhoe"), | ||||||
|  | 	QUICKIEPOWDERWATERHOE(new ToolQuickiepowderWaterHoe(), "quickiepowderwaterhoe"), | ||||||
| 	ROTTEN_FLESH_STRIPES(new ItemRottenFleshStripes(), "rotten_flesh_stripes"), | 	ROTTEN_FLESH_STRIPES(new ItemRottenFleshStripes(), "rotten_flesh_stripes"), | ||||||
| 	CARROTSTACK(new ItemCarrotstack(), "carrotstack"), | 	CARROTSTACK(new ItemCarrotstack(), "carrotstack"), | ||||||
| 	COTTON(new ItemCotton(), "cotton"), | 	COTTON(new ItemCotton(), "cotton"), | ||||||
| @@ -20,12 +35,7 @@ public enum QuickieItems { | |||||||
| 	CANOLABOTTLESTACK(new ItemCanolabottlestack(), "canolabottlestack"), | 	CANOLABOTTLESTACK(new ItemCanolabottlestack(), "canolabottlestack"), | ||||||
| 	STUB(new ItemStub(), "stub"), | 	STUB(new ItemStub(), "stub"), | ||||||
| 	SALPETER(new ItemSalpeter(), "salpeter"), | 	SALPETER(new ItemSalpeter(), "salpeter"), | ||||||
| 	SULPHOR(new ItemSulphor(), "sulphor"), | 	SULPHOR(new ItemSulphor(), "sulphor"); | ||||||
| 	SPEEDPOWDER(new ItemSpeedpowder(), "speedpowder"), |  | ||||||
| 	QUICKIEPOWDER(new ItemQuickiepowder(), "quickiepowder"), |  | ||||||
| 	OXIDIZEDCOPPERPOWDER(new ItemOxidizedcopperpowder(), "oxidizedcopperpowder"), |  | ||||||
| 	SPEEDINGOT(new ItemSpeedingot(), "speedingot"), |  | ||||||
| 	QUICKIEINGOT(new ItemQuickieingot(), "quickieingot"); |  | ||||||
| 	// @formatter:on | 	// @formatter:on | ||||||
|  |  | ||||||
| 	private final Item item; | 	private final Item item; | ||||||
|   | |||||||
| @@ -0,0 +1,26 @@ | |||||||
|  | package de.jottyfan.quickiemod.items; | ||||||
|  |  | ||||||
|  | import de.jottyfan.quickiemod.items.mat.QuickieToolMaterial; | ||||||
|  | import net.minecraft.item.AxeItem; | ||||||
|  | import net.minecraft.item.Item; | ||||||
|  | import net.minecraft.item.ItemStack; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class ToolQuickiepowderAxe extends ToolRangeableAxe { | ||||||
|  |  | ||||||
|  | 	private final static QuickieToolMaterial MATERIAL = QuickieToolMaterial.of(7f, 2400, 15, 1f, QuickieItems.SPEEDINGOT.getItem()); | ||||||
|  |  | ||||||
|  | 	public ToolQuickiepowderAxe() { | ||||||
|  | 		super(MATERIAL, new Item.Settings().attributeModifiers(AxeItem.createAttributeModifiers(MATERIAL, 7F, -3.1F))); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public HarvestRange getRange(ItemStack stack) { | ||||||
|  | 		// TODO: get the range from the stack | ||||||
|  | 		return new HarvestRange(64, 128, 64); // trees bigger than that are too heavy for one small axe... | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,20 @@ | |||||||
|  | package de.jottyfan.quickiemod.items; | ||||||
|  |  | ||||||
|  | import de.jottyfan.quickiemod.items.mat.QuickieToolMaterial; | ||||||
|  | import net.minecraft.item.HoeItem; | ||||||
|  | import net.minecraft.item.Item; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class ToolQuickiepowderHoe extends ToolRangeableHoe { | ||||||
|  |  | ||||||
|  | 	public static final Integer DEFAULT_PLOW_RANGE = 4; | ||||||
|  | 	private final static QuickieToolMaterial MATERIAL = QuickieToolMaterial.of(7f, 2400, 15, 1f, QuickieItems.SPEEDINGOT.getItem()); | ||||||
|  |  | ||||||
|  | 	public ToolQuickiepowderHoe() { | ||||||
|  | 		super(MATERIAL, new Item.Settings().attributeModifiers(HoeItem.createAttributeModifiers(MATERIAL, 7F, -3.1F)), new HarvestRange(DEFAULT_PLOW_RANGE)); | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,54 @@ | |||||||
|  | package de.jottyfan.quickiemod.items; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import com.google.common.collect.Lists; | ||||||
|  |  | ||||||
|  | import de.jottyfan.quickiemod.items.mat.QuickieToolMaterial; | ||||||
|  | import net.minecraft.block.Block; | ||||||
|  | import net.minecraft.block.BlockState; | ||||||
|  | import net.minecraft.item.Item; | ||||||
|  | import net.minecraft.item.ItemStack; | ||||||
|  | import net.minecraft.item.PickaxeItem; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class ToolQuickiepowderPickaxe extends PickaxeItem implements ToolRangeable { | ||||||
|  |  | ||||||
|  | 	public static final int[] DEFAULT_HARVEST_RANGE = new int[] { 6, 6, 6 }; | ||||||
|  | 	private final static QuickieToolMaterial MATERIAL = QuickieToolMaterial.of(7f, 2400, 15, 1f, QuickieItems.SPEEDINGOT.getItem()); | ||||||
|  |  | ||||||
|  | 	public ToolQuickiepowderPickaxe() { | ||||||
|  | 		super(MATERIAL, new Item.Settings().attributeModifiers(PickaxeItem.createAttributeModifiers(MATERIAL, 7F, -3.1F))); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public HarvestRange getRange(ItemStack stack) { | ||||||
|  | 		return new HarvestRange(DEFAULT_HARVEST_RANGE); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public boolean canBreakNeighbors(BlockState blockIn) { | ||||||
|  | 		return new ItemStack(this).isSuitableFor(blockIn); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public List<Block> getBlockList(Block block) { | ||||||
|  | 		return Lists.newArrayList(block); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | //	@Override | ||||||
|  | //	public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) { | ||||||
|  | //		CommonToolCode.onItemRightClick(worldIn, playerIn, handIn); | ||||||
|  | //		return super.onItemRightClick(worldIn, playerIn, handIn); | ||||||
|  | //	} | ||||||
|  | // | ||||||
|  | //	@Override | ||||||
|  | //	public void addInformation(ItemStack stack, World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) { | ||||||
|  | //		CommonToolCode.addInformation(stack, worldIn, tooltip, flagIn); | ||||||
|  | //		super.addInformation(stack, worldIn, tooltip, flagIn); | ||||||
|  | //	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,97 @@ | |||||||
|  | package de.jottyfan.quickiemod.items; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import com.google.common.collect.Lists; | ||||||
|  |  | ||||||
|  | import de.jottyfan.quickiemod.items.mat.QuickieToolMaterial; | ||||||
|  | import net.minecraft.block.Block; | ||||||
|  | import net.minecraft.block.BlockState; | ||||||
|  | import net.minecraft.item.Item; | ||||||
|  | import net.minecraft.item.ItemStack; | ||||||
|  | import net.minecraft.item.ItemUsageContext; | ||||||
|  | import net.minecraft.item.ShovelItem; | ||||||
|  | import net.minecraft.util.ActionResult; | ||||||
|  | import net.minecraft.util.math.BlockPos; | ||||||
|  | import net.minecraft.util.math.Direction; | ||||||
|  | import net.minecraft.world.World; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class ToolQuickiepowderShovel extends ShovelItem implements ToolRangeable { | ||||||
|  | 	public static final Integer DEFAULT_HARVEST_RANGE = 6; | ||||||
|  | 	private final static QuickieToolMaterial MATERIAL =  QuickieToolMaterial.of(7f, 2400, 15, 1f, QuickieItems.SPEEDINGOT.getItem()); | ||||||
|  | 	public HarvestRange range; | ||||||
|  |  | ||||||
|  | 	public ToolQuickiepowderShovel() { | ||||||
|  | 		super(MATERIAL, new Item.Settings().attributeModifiers(ShovelItem.createAttributeModifiers(MATERIAL, 7F, -3.1F))); | ||||||
|  | 		this.range = new HarvestRange(DEFAULT_HARVEST_RANGE); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	private void createPathOnGrass(World world, BlockPos pos, Direction side) { | ||||||
|  | 		BlockState blockState = world.getBlockState(pos); | ||||||
|  | 		if (blockState.isAir()) { | ||||||
|  | 			// try to find one underneath | ||||||
|  | 			pos = pos.down(); | ||||||
|  | 			blockState = world.getBlockState(pos); | ||||||
|  | 		} else if (!world.getBlockState(pos.up()).isAir()) { | ||||||
|  | 			pos = pos.up(); | ||||||
|  | 			blockState = world.getBlockState(pos); | ||||||
|  | 		} | ||||||
|  | 		if (side != Direction.DOWN) { | ||||||
|  | 			BlockState blockState2 = (BlockState) PATH_STATES.get(blockState.getBlock()); | ||||||
|  | 			if (blockState2 != null && world.getBlockState(pos.up()).isAir()) { | ||||||
|  | 				if (!world.isClient) { | ||||||
|  | 					world.setBlockState(pos, blockState2, 11); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public ActionResult useOnBlock(ItemUsageContext context) { | ||||||
|  | 		World world = context.getWorld(); | ||||||
|  | 		BlockPos pos = context.getBlockPos(); | ||||||
|  | 		BlockPos[] positions = new BlockPos[] { pos.north().north().west().west(), pos.north().north().west(), | ||||||
|  | 				pos.north().north(), pos.north().north().east(), pos.north().north().east().east(), pos.north().west().west(), | ||||||
|  | 				pos.north().west(), pos.north(), pos.north().east(), pos.north().east().east(), pos.west().west(), pos.west(), | ||||||
|  | 				pos, pos.east(), pos.east().east(), pos.south().west().west(), pos.south().west(), pos.south(), | ||||||
|  | 				pos.south().east(), pos.south().east().east(), pos.south().south().west().west(), pos.south().south().west(), | ||||||
|  | 				pos.south().south(), pos.south().south().east(), pos.south().south().east().east() }; | ||||||
|  | 		for (BlockPos p : positions) { | ||||||
|  | 			createPathOnGrass(world, p, context.getSide()); | ||||||
|  | 		} | ||||||
|  | 		return super.useOnBlock(context); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public HarvestRange getRange(ItemStack stack) { | ||||||
|  | 		// TODO: get range from stack | ||||||
|  | 		return range; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public boolean canBreakNeighbors(BlockState blockState) { | ||||||
|  | 		return new ItemStack(this).isSuitableFor(blockState); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public List<Block> getBlockList(Block block) { | ||||||
|  | 		return Lists.newArrayList(block); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | //	@Override | ||||||
|  | //	public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) { | ||||||
|  | //		CommonToolCode.onItemRightClick(worldIn, playerIn, handIn); | ||||||
|  | //		return super.onItemRightClick(worldIn, playerIn, handIn); | ||||||
|  | //	} | ||||||
|  | // | ||||||
|  | //	@Override | ||||||
|  | //	public void addInformation(ItemStack stack, World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) { | ||||||
|  | //		CommonToolCode.addInformation(stack, worldIn, tooltip, flagIn); | ||||||
|  | //		super.addInformation(stack, worldIn, tooltip, flagIn); | ||||||
|  | //	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,38 @@ | |||||||
|  | package de.jottyfan.quickiemod.items; | ||||||
|  |  | ||||||
|  | import net.minecraft.block.BlockState; | ||||||
|  | import net.minecraft.block.Blocks; | ||||||
|  | import net.minecraft.entity.ItemEntity; | ||||||
|  | import net.minecraft.entity.player.PlayerEntity; | ||||||
|  | import net.minecraft.item.ItemStack; | ||||||
|  | import net.minecraft.item.ItemUsageContext; | ||||||
|  | import net.minecraft.util.ActionResult; | ||||||
|  | import net.minecraft.util.Hand; | ||||||
|  | import net.minecraft.util.math.BlockPos; | ||||||
|  | import net.minecraft.world.World; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class ToolQuickiepowderWaterHoe extends ToolQuickiepowderHoe { | ||||||
|  | 	@Override | ||||||
|  | 	public ActionResult useOnBlock(ItemUsageContext context) { | ||||||
|  | 		ActionResult res = super.useOnBlock(context); | ||||||
|  | 		if (!ActionResult.PASS.equals(res)) { | ||||||
|  | 			BlockPos pos = context.getBlockPos(); | ||||||
|  | 			World world = context.getWorld(); | ||||||
|  | 			BlockState oldBlockState = world.getBlockState(pos); | ||||||
|  | 			world.setBlockState(pos, Blocks.WATER.getDefaultState()); | ||||||
|  | 			Hand hand = context.getHand(); | ||||||
|  | 			PlayerEntity player = context.getPlayer(); | ||||||
|  | 			ItemStack oldTool = player.getStackInHand(hand); | ||||||
|  | 			ItemStack newTool = new ItemStack(QuickieItems.QUICKIEPOWDERHOE.getItem()); | ||||||
|  | 			newTool.setDamage(oldTool.getDamage()); | ||||||
|  | 			world.spawnEntity(new ItemEntity(world, pos.getX(), pos.getY(), pos.getZ(), new ItemStack(oldBlockState.getBlock()))); | ||||||
|  | 			player.setStackInHand(hand, newTool); | ||||||
|  | 		} | ||||||
|  | 		return res; | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,38 @@ | |||||||
|  | package de.jottyfan.quickiemod.items; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import net.minecraft.block.Block; | ||||||
|  | import net.minecraft.block.BlockState; | ||||||
|  | import net.minecraft.item.ItemStack; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public interface ToolRangeable { | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * @param stack the item stack that keeps the range | ||||||
|  | 	 * @return range of blocks to be harvested | ||||||
|  | 	 */ | ||||||
|  | 	public HarvestRange getRange(ItemStack stack); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * check if this block state is one that affects the neighbor blocks to break | ||||||
|  | 	 * also if they are from the same type | ||||||
|  | 	 * | ||||||
|  | 	 * @param blockState the block state of the current block | ||||||
|  | 	 * @return true or false | ||||||
|  | 	 */ | ||||||
|  | 	public boolean canBreakNeighbors(BlockState blockState); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * get list of blocks that belong together (could be useful for stripped logs) | ||||||
|  | 	 * | ||||||
|  | 	 * @param block of the set | ||||||
|  | 	 * @return the list of blocks or null if not found | ||||||
|  | 	 */ | ||||||
|  | 	public List<Block> getBlockList(Block block); | ||||||
|  | } | ||||||
| @@ -0,0 +1,63 @@ | |||||||
|  | package de.jottyfan.quickiemod.items; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import com.google.common.collect.Lists; | ||||||
|  |  | ||||||
|  | import net.minecraft.block.Block; | ||||||
|  | import net.minecraft.block.BlockState; | ||||||
|  | import net.minecraft.block.LeavesBlock; | ||||||
|  | import net.minecraft.item.AxeItem; | ||||||
|  | import net.minecraft.item.Item; | ||||||
|  | import net.minecraft.item.ItemStack; | ||||||
|  | import net.minecraft.item.ToolMaterial; | ||||||
|  | import net.minecraft.registry.tag.BlockTags; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public abstract class ToolRangeableAxe extends AxeItem implements ToolRangeable { | ||||||
|  |  | ||||||
|  | 	protected ToolRangeableAxe(ToolMaterial material, Item.Settings settings) { | ||||||
|  | 		super(material, settings); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public HarvestRange getRange(ItemStack stack) { | ||||||
|  | 		// TODO: get the range from the stack | ||||||
|  | 		return new HarvestRange(16, 32, 16); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * check if the block is a leaves block | ||||||
|  | 	 * | ||||||
|  | 	 * @param blockIn the block | ||||||
|  | 	 * @return true or false | ||||||
|  | 	 */ | ||||||
|  | 	private boolean isLeavesBlock(BlockState blockIn) { | ||||||
|  | 		boolean vanillaLeaves = blockIn.getBlock() instanceof LeavesBlock; | ||||||
|  | 		boolean terrestriaLeaves = false; | ||||||
|  | 		try { | ||||||
|  | 			Class<?> extendedLeavesBlock = Class.forName("com.terraformersmc.terraform.leaves.block.ExtendedLeavesBlock"); | ||||||
|  | 			terrestriaLeaves = extendedLeavesBlock.isInstance(blockIn.getBlock()); | ||||||
|  | 		} catch (ClassNotFoundException e) { | ||||||
|  | 			// no terrestria mod available, so ignore this | ||||||
|  | 			// using this approach instead of the instanceof functionality, we don't need to refer to terrestria | ||||||
|  | 			// and omit a crash on installations that do not have or want terrestria available | ||||||
|  | 		} | ||||||
|  | 		boolean blockTagLeaves = blockIn.isIn(BlockTags.LEAVES); | ||||||
|  | 		return vanillaLeaves || terrestriaLeaves || blockTagLeaves; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public boolean canBreakNeighbors(BlockState blockIn) { | ||||||
|  | 		return  new ItemStack(this).isSuitableFor(blockIn) || isLeavesBlock(blockIn) || blockIn.isIn(BlockTags.LOGS); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public List<Block> getBlockList(Block block) { | ||||||
|  | 		return Lists.newArrayList(block); | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,97 @@ | |||||||
|  | package de.jottyfan.quickiemod.items; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import com.google.common.collect.Lists; | ||||||
|  |  | ||||||
|  | import net.minecraft.block.Block; | ||||||
|  | import net.minecraft.block.BlockState; | ||||||
|  | import net.minecraft.block.Blocks; | ||||||
|  | import net.minecraft.block.CropBlock; | ||||||
|  | import net.minecraft.item.HoeItem; | ||||||
|  | import net.minecraft.item.ItemStack; | ||||||
|  | import net.minecraft.item.ItemUsageContext; | ||||||
|  | import net.minecraft.item.ToolMaterial; | ||||||
|  | import net.minecraft.util.ActionResult; | ||||||
|  | import net.minecraft.util.hit.BlockHitResult; | ||||||
|  | import net.minecraft.util.math.BlockPos; | ||||||
|  | import net.minecraft.util.math.Direction; | ||||||
|  | import net.minecraft.util.math.Vec3i; | ||||||
|  | import net.minecraft.world.World; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public abstract class ToolRangeableHoe extends HoeItem implements ToolRangeable { | ||||||
|  |  | ||||||
|  | 	public HarvestRange range; | ||||||
|  |  | ||||||
|  | 	public ToolRangeableHoe(ToolMaterial material, Settings settings, HarvestRange range) { | ||||||
|  | 		super(material, settings); | ||||||
|  | 		this.range = range; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public ActionResult useOnBlock(ItemUsageContext context) { | ||||||
|  | 		ActionResult res = super.useOnBlock(context); | ||||||
|  | 		boolean isCrop = context.getWorld().getBlockState(context.getBlockPos()).getBlock() instanceof CropBlock; | ||||||
|  | 		if (!ActionResult.PASS.equals(res) || isCrop) { | ||||||
|  | 			for (int x = -this.range.getxRange(); x <= this.range.getxRange(); x++) { | ||||||
|  | 				for (int y = -this.range.getyRange(); y <= this.range.getyRange(); y++) { | ||||||
|  | 					for (int z = -this.range.getzRange(); z <= this.range.getzRange(); z++) { | ||||||
|  | 						if (!isCrop) { | ||||||
|  | 							removePossibleGrass(context.getWorld(), new BlockPos(x, y, z)); | ||||||
|  | 							BlockHitResult bhr = new BlockHitResult(context.getHitPos(), Direction.UP, | ||||||
|  | 									context.getBlockPos().add(new Vec3i(x, y, z)), false); | ||||||
|  | 							ItemUsageContext ctx = new ItemUsageContext(context.getPlayer(), context.getHand(), bhr); | ||||||
|  | 							super.useOnBlock(ctx); | ||||||
|  | 						} else { | ||||||
|  | 							harvestIfPossible(context.getBlockPos().add(x, y, z), context.getWorld()); | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		return res; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	private void removePossibleGrass(World world, BlockPos pos) { | ||||||
|  | 		Block block = world.getBlockState(pos).getBlock(); | ||||||
|  | 		Boolean grassFound = Blocks.FERN.equals(block) || Blocks.LARGE_FERN.equals(block) | ||||||
|  | 				|| Blocks.SHORT_GRASS.equals(block) || Blocks.TALL_GRASS.equals(block); | ||||||
|  | 		if (grassFound) { | ||||||
|  | 			world.breakBlock(pos, true); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	private void harvestIfPossible(BlockPos pos, World world) { | ||||||
|  | 		BlockState blockState = world.getBlockState(pos); | ||||||
|  | 		Block block = blockState.getBlock(); | ||||||
|  | 		if (block instanceof CropBlock) { | ||||||
|  | 			CropBlock cBlock = (CropBlock) block; | ||||||
|  | 			if (cBlock.isMature(blockState)) { | ||||||
|  | 				Block.dropStacks(blockState, world, pos); | ||||||
|  | 				world.setBlockState(pos, cBlock.withAge(0)); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public HarvestRange getRange(ItemStack stack) { | ||||||
|  | 		// TODO: get range from stack | ||||||
|  | 		return range; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public boolean canBreakNeighbors(BlockState blockState) { | ||||||
|  | 		return new ItemStack(this).isSuitableFor(blockState) || Blocks.TALL_GRASS.equals(blockState.getBlock()) | ||||||
|  | 				|| Blocks.FERN.equals(blockState.getBlock()) || Blocks.LARGE_FERN.equals(blockState.getBlock()); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public List<Block> getBlockList(Block block) { | ||||||
|  | 		return Lists.newArrayList(block); | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,26 @@ | |||||||
|  | package de.jottyfan.quickiemod.items; | ||||||
|  |  | ||||||
|  | import de.jottyfan.quickiemod.items.mat.QuickieToolMaterial; | ||||||
|  | import net.minecraft.item.Item; | ||||||
|  | import net.minecraft.item.ItemStack; | ||||||
|  | import net.minecraft.item.PickaxeItem; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class ToolSpeedpowderAxe extends ToolRangeableAxe { | ||||||
|  |  | ||||||
|  | 	private final static QuickieToolMaterial MATERIAL = QuickieToolMaterial.of(7f, 800, 15, 1f, QuickieItems.SPEEDINGOT.getItem()); | ||||||
|  |  | ||||||
|  | 	public ToolSpeedpowderAxe() { | ||||||
|  | 		super(MATERIAL, new Item.Settings().attributeModifiers(PickaxeItem.createAttributeModifiers(MATERIAL, 7f, -3.1f))); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public HarvestRange getRange(ItemStack stack) { | ||||||
|  | 		// TODO: get the range from the stack | ||||||
|  | 		return new HarvestRange(32, 64, 32); | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,20 @@ | |||||||
|  | package de.jottyfan.quickiemod.items; | ||||||
|  |  | ||||||
|  | import de.jottyfan.quickiemod.items.mat.QuickieToolMaterial; | ||||||
|  | import net.minecraft.item.HoeItem; | ||||||
|  | import net.minecraft.item.Item; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class ToolSpeedpowderHoe extends ToolRangeableHoe { | ||||||
|  |  | ||||||
|  | 	public static final Integer DEFAULT_PLOW_RANGE = 2; | ||||||
|  | 	private final static QuickieToolMaterial MATERIAL = QuickieToolMaterial.of(7f, 800, 15, 1f, QuickieItems.SPEEDINGOT.getItem()); | ||||||
|  |  | ||||||
|  | 	public ToolSpeedpowderHoe() { | ||||||
|  | 		super(MATERIAL, new Item.Settings().attributeModifiers(HoeItem.createAttributeModifiers(MATERIAL, 7F, -3.1F)), new HarvestRange(DEFAULT_PLOW_RANGE)); | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,55 @@ | |||||||
|  | package de.jottyfan.quickiemod.items; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import com.google.common.collect.Lists; | ||||||
|  |  | ||||||
|  | import de.jottyfan.quickiemod.items.mat.QuickieToolMaterial; | ||||||
|  | import net.minecraft.block.Block; | ||||||
|  | import net.minecraft.block.BlockState; | ||||||
|  | import net.minecraft.item.AxeItem; | ||||||
|  | import net.minecraft.item.Item; | ||||||
|  | import net.minecraft.item.ItemStack; | ||||||
|  | import net.minecraft.item.PickaxeItem; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class ToolSpeedpowderPickaxe extends PickaxeItem implements ToolRangeable { | ||||||
|  |  | ||||||
|  | 	public static final int[] DEFAULT_HARVEST_RANGE = new int[] { 3, 3, 3 }; | ||||||
|  | 	private final static QuickieToolMaterial MATERIAL = QuickieToolMaterial.of(7f, 800, 15, 1f, QuickieItems.SPEEDINGOT.getItem()); | ||||||
|  |  | ||||||
|  | 	public ToolSpeedpowderPickaxe() { | ||||||
|  | 		super(MATERIAL, new Item.Settings().attributeModifiers(AxeItem.createAttributeModifiers(MATERIAL, 7F, -3.1F))); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public HarvestRange getRange(ItemStack stack) { | ||||||
|  | 		return new HarvestRange(DEFAULT_HARVEST_RANGE); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public boolean canBreakNeighbors(BlockState blockIn) { | ||||||
|  | 		return new ItemStack(this).isSuitableFor(blockIn); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public List<Block> getBlockList(Block block) { | ||||||
|  | 		return Lists.newArrayList(block); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | //	@Override | ||||||
|  | //	public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) { | ||||||
|  | //		CommonToolCode.onItemRightClick(worldIn, playerIn, handIn); | ||||||
|  | //		return super.onItemRightClick(worldIn, playerIn, handIn); | ||||||
|  | //	} | ||||||
|  | // | ||||||
|  | //	@Override | ||||||
|  | //	public void addInformation(ItemStack stack, World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) { | ||||||
|  | //		CommonToolCode.addInformation(stack, worldIn, tooltip, flagIn); | ||||||
|  | //		super.addInformation(stack, worldIn, tooltip, flagIn); | ||||||
|  | //	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,96 @@ | |||||||
|  | package de.jottyfan.quickiemod.items; | ||||||
|  |  | ||||||
|  | import java.util.Random; | ||||||
|  |  | ||||||
|  | import net.minecraft.component.DataComponentTypes; | ||||||
|  | import net.minecraft.entity.ItemEntity; | ||||||
|  | import net.minecraft.entity.LivingEntity; | ||||||
|  | import net.minecraft.entity.passive.ChickenEntity; | ||||||
|  | import net.minecraft.entity.passive.CowEntity; | ||||||
|  | import net.minecraft.entity.passive.HorseEntity; | ||||||
|  | import net.minecraft.entity.passive.SheepEntity; | ||||||
|  | import net.minecraft.entity.player.PlayerEntity; | ||||||
|  | import net.minecraft.item.Item; | ||||||
|  | import net.minecraft.item.ItemStack; | ||||||
|  | import net.minecraft.item.Items; | ||||||
|  | import net.minecraft.item.ShearsItem; | ||||||
|  | import net.minecraft.util.ActionResult; | ||||||
|  | import net.minecraft.util.DyeColor; | ||||||
|  | import net.minecraft.util.Hand; | ||||||
|  | import net.minecraft.util.math.Vec3d; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class ToolSpeedpowderShears extends ShearsItem { | ||||||
|  |  | ||||||
|  | 	public ToolSpeedpowderShears() { | ||||||
|  | 		super(new Item.Settings().component(DataComponentTypes.TOOL, ShearsItem.createToolComponent())); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public ActionResult useOnEntity(ItemStack stack, PlayerEntity user, LivingEntity entity, Hand hand) { | ||||||
|  | 		Vec3d pos = entity.getPos(); | ||||||
|  | 		Integer amount = 3 + new Random().nextInt(4); | ||||||
|  | 		if (entity instanceof SheepEntity) { | ||||||
|  | 			SheepEntity sheep = (SheepEntity) entity; | ||||||
|  | 			if (sheep.isShearable()) { | ||||||
|  | 				sheep.setSheared(true); | ||||||
|  | 				sheep.playAmbientSound(); | ||||||
|  | 				DyeColor color = sheep.getColor(); | ||||||
|  | 				Item item = Items.WHITE_WOOL; | ||||||
|  | 				if (color.equals(DyeColor.BLACK)) { | ||||||
|  | 					item = Items.BLACK_WOOL; | ||||||
|  | 				} else if (color.equals(DyeColor.GRAY)) { | ||||||
|  | 					item = Items.GRAY_WOOL; | ||||||
|  | 				} else if (color.equals(DyeColor.LIGHT_GRAY)) { | ||||||
|  | 					item = Items.LIGHT_GRAY_WOOL; | ||||||
|  | 				} else if (color.equals(DyeColor.BROWN)) { | ||||||
|  | 					item = Items.BROWN_WOOL; | ||||||
|  | 				} else if (color.equals(DyeColor.BLUE)) { | ||||||
|  | 					item = Items.BLUE_WOOL; | ||||||
|  | 				} else if (color.equals(DyeColor.LIGHT_BLUE)) { | ||||||
|  | 					item = Items.LIGHT_BLUE_WOOL; | ||||||
|  | 				} else if (color.equals(DyeColor.GREEN)) { | ||||||
|  | 					item = Items.GREEN_WOOL; | ||||||
|  | 				} else if (color.equals(DyeColor.LIME)) { | ||||||
|  | 					item = Items.LIME_WOOL; | ||||||
|  | 				} else if (color.equals(DyeColor.CYAN)) { | ||||||
|  | 					item = Items.CYAN_WOOL; | ||||||
|  | 				} else if (color.equals(DyeColor.MAGENTA)) { | ||||||
|  | 					item = Items.MAGENTA_WOOL; | ||||||
|  | 				} else if (color.equals(DyeColor.ORANGE)) { | ||||||
|  | 					item = Items.ORANGE_WOOL; | ||||||
|  | 				} else if (color.equals(DyeColor.PINK)) { | ||||||
|  | 					item = Items.PINK_WOOL; | ||||||
|  | 				} else if (color.equals(DyeColor.PURPLE)) { | ||||||
|  | 					item = Items.PURPLE_WOOL; | ||||||
|  | 				} else if (color.equals(DyeColor.RED)) { | ||||||
|  | 					item = Items.RED_WOOL; | ||||||
|  | 				} else if (color.equals(DyeColor.YELLOW)) { | ||||||
|  | 					item = Items.YELLOW_WOOL; | ||||||
|  | 				} | ||||||
|  | 				user.getWorld().spawnEntity(new ItemEntity(user.getWorld(), pos.getX(), pos.getY(), pos.getZ(), new ItemStack(item, amount))); | ||||||
|  | 				return ActionResult.SUCCESS; | ||||||
|  | 			} | ||||||
|  | 		} else if (entity instanceof HorseEntity) { | ||||||
|  | 			HorseEntity horse = (HorseEntity) entity; | ||||||
|  | 			horse.playAmbientSound(); | ||||||
|  | 			user.getWorld().spawnEntity(new ItemEntity(user.getWorld(), pos.getX(), pos.getY(), pos.getZ(), new ItemStack(Items.LEATHER, amount))); | ||||||
|  | 			return ActionResult.SUCCESS; | ||||||
|  | 		} else if (entity instanceof CowEntity) { | ||||||
|  | 			CowEntity cow = (CowEntity) entity; | ||||||
|  | 			cow.playAmbientSound(); | ||||||
|  | 			user.getWorld().spawnEntity(new ItemEntity(user.getWorld(), pos.getX(), pos.getY(), pos.getZ(), new ItemStack(Items.LEATHER, amount))); | ||||||
|  | 			return ActionResult.SUCCESS; | ||||||
|  | 		} else if (entity instanceof ChickenEntity) { | ||||||
|  | 			ChickenEntity cow = (ChickenEntity) entity; | ||||||
|  | 			cow.playAmbientSound(); | ||||||
|  | 			user.getWorld().spawnEntity(new ItemEntity(user.getWorld(), pos.getX(), pos.getY(), pos.getZ(), new ItemStack(Items.FEATHER, amount))); | ||||||
|  | 			return ActionResult.SUCCESS; | ||||||
|  | 		} | ||||||
|  | 		return ActionResult.PASS; | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,96 @@ | |||||||
|  | package de.jottyfan.quickiemod.items; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import com.google.common.collect.Lists; | ||||||
|  |  | ||||||
|  | import de.jottyfan.quickiemod.items.mat.QuickieToolMaterial; | ||||||
|  | import net.minecraft.block.Block; | ||||||
|  | import net.minecraft.block.BlockState; | ||||||
|  | import net.minecraft.item.Item; | ||||||
|  | import net.minecraft.item.ItemStack; | ||||||
|  | import net.minecraft.item.ItemUsageContext; | ||||||
|  | import net.minecraft.item.ShovelItem; | ||||||
|  | import net.minecraft.util.ActionResult; | ||||||
|  | import net.minecraft.util.math.BlockPos; | ||||||
|  | import net.minecraft.util.math.Direction; | ||||||
|  | import net.minecraft.world.World; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class ToolSpeedpowderShovel extends ShovelItem implements ToolRangeable { | ||||||
|  | 	public static final Integer DEFAULT_HARVEST_RANGE = 3; | ||||||
|  | 	private final static QuickieToolMaterial MATERIAL = QuickieToolMaterial.of(7f, 800, 15, 1f, QuickieItems.SPEEDINGOT.getItem()); | ||||||
|  | 	public HarvestRange range; | ||||||
|  |  | ||||||
|  | 	public ToolSpeedpowderShovel() { | ||||||
|  | 		super(MATERIAL, new Item.Settings().attributeModifiers(ShovelItem.createAttributeModifiers(MATERIAL, 7F, -3.1F))); | ||||||
|  | 		this.range = new HarvestRange(DEFAULT_HARVEST_RANGE); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	private void createPathOnGrass(World world, BlockPos pos, Direction side) { | ||||||
|  | 		BlockState blockState = world.getBlockState(pos); | ||||||
|  | 		if (blockState.isAir()) { | ||||||
|  | 			// try to find one underneath | ||||||
|  | 			pos = pos.down(); | ||||||
|  | 			blockState = world.getBlockState(pos); | ||||||
|  | 		} else if (!world.getBlockState(pos.up()).isAir()) { | ||||||
|  | 			pos = pos.up(); | ||||||
|  | 			blockState = world.getBlockState(pos); | ||||||
|  | 		} | ||||||
|  | 		if (side != Direction.DOWN) { | ||||||
|  | 			BlockState blockState2 = (BlockState) PATH_STATES.get(blockState.getBlock()); | ||||||
|  | 			if (blockState2 != null && world.getBlockState(pos.up()).isAir()) { | ||||||
|  | 				if (!world.isClient) { | ||||||
|  | 					world.setBlockState(pos, blockState2, 11); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public ActionResult useOnBlock(ItemUsageContext context) { | ||||||
|  | 		World world = context.getWorld(); | ||||||
|  | 		BlockPos pos = context.getBlockPos(); | ||||||
|  | 		createPathOnGrass(world, pos.north(), context.getSide()); | ||||||
|  | 		createPathOnGrass(world, pos.north().east(), context.getSide()); | ||||||
|  | 		createPathOnGrass(world, pos.north().west(), context.getSide()); | ||||||
|  | 		createPathOnGrass(world, pos.east(), context.getSide()); | ||||||
|  | 		createPathOnGrass(world, pos.west(), context.getSide()); | ||||||
|  | 		createPathOnGrass(world, pos.south(), context.getSide()); | ||||||
|  | 		createPathOnGrass(world, pos.south().east(), context.getSide()); | ||||||
|  | 		createPathOnGrass(world, pos.south().west(), context.getSide()); | ||||||
|  | 		return super.useOnBlock(context); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public HarvestRange getRange(ItemStack stack) { | ||||||
|  | 		// TODO: get range from stack | ||||||
|  | 		return range; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public boolean canBreakNeighbors(BlockState blockState) { | ||||||
|  | 		return new ItemStack(this).isSuitableFor(blockState); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public List<Block> getBlockList(Block block) { | ||||||
|  | 		return Lists.newArrayList(block); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | //	@Override | ||||||
|  | //	public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) { | ||||||
|  | //		CommonToolCode.onItemRightClick(worldIn, playerIn, handIn); | ||||||
|  | //		return super.onItemRightClick(worldIn, playerIn, handIn); | ||||||
|  | //	} | ||||||
|  | // | ||||||
|  | //	@Override | ||||||
|  | //	public void addInformation(ItemStack stack, World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) { | ||||||
|  | //		CommonToolCode.addInformation(stack, worldIn, tooltip, flagIn); | ||||||
|  | //		super.addInformation(stack, worldIn, tooltip, flagIn); | ||||||
|  | //	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,38 @@ | |||||||
|  | package de.jottyfan.quickiemod.items; | ||||||
|  |  | ||||||
|  | import net.minecraft.block.BlockState; | ||||||
|  | import net.minecraft.block.Blocks; | ||||||
|  | import net.minecraft.entity.ItemEntity; | ||||||
|  | import net.minecraft.entity.player.PlayerEntity; | ||||||
|  | import net.minecraft.item.ItemStack; | ||||||
|  | import net.minecraft.item.ItemUsageContext; | ||||||
|  | import net.minecraft.util.ActionResult; | ||||||
|  | import net.minecraft.util.Hand; | ||||||
|  | import net.minecraft.util.math.BlockPos; | ||||||
|  | import net.minecraft.world.World; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class ToolSpeedpowderWaterHoe extends ToolSpeedpowderHoe { | ||||||
|  | 	@Override | ||||||
|  | 	public ActionResult useOnBlock(ItemUsageContext context) { | ||||||
|  | 		ActionResult res = super.useOnBlock(context); | ||||||
|  | 		if (!ActionResult.PASS.equals(res)) { | ||||||
|  | 			BlockPos pos = context.getBlockPos(); | ||||||
|  | 			World world = context.getWorld(); | ||||||
|  | 			BlockState oldBlockState = world.getBlockState(pos); | ||||||
|  | 			world.setBlockState(pos, Blocks.WATER.getDefaultState()); | ||||||
|  | 			Hand hand = context.getHand(); | ||||||
|  | 			PlayerEntity player = context.getPlayer(); | ||||||
|  | 			ItemStack oldTool = player.getStackInHand(hand); | ||||||
|  | 			ItemStack newTool = new ItemStack(QuickieItems.SPEEDPOWDERHOE.getItem()); | ||||||
|  | 			newTool.setDamage(oldTool.getDamage()); | ||||||
|  | 			world.spawnEntity(new ItemEntity(world, pos.getX(), pos.getY(), pos.getZ(), new ItemStack(oldBlockState.getBlock()))); | ||||||
|  | 			player.setStackInHand(hand, newTool); | ||||||
|  | 		} | ||||||
|  | 		return res; | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,64 @@ | |||||||
|  | package de.jottyfan.quickiemod.items.mat; | ||||||
|  |  | ||||||
|  | import net.minecraft.block.Block; | ||||||
|  | import net.minecraft.item.Item; | ||||||
|  | import net.minecraft.item.ToolMaterial; | ||||||
|  | import net.minecraft.recipe.Ingredient; | ||||||
|  | import net.minecraft.registry.tag.BlockTags; | ||||||
|  | import net.minecraft.registry.tag.TagKey; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class QuickieToolMaterial implements ToolMaterial { | ||||||
|  |  | ||||||
|  | 	private final float attackDamage; | ||||||
|  | 	private final int durability; | ||||||
|  | 	private final int enchantability; | ||||||
|  | 	private final float miningSpeedMuliplier; | ||||||
|  | 	private final Item item; | ||||||
|  |  | ||||||
|  | 	private QuickieToolMaterial(float attackDamage, int durability, int enchantability, float miningSpeedMultiplier, Item item) { | ||||||
|  | 		this.attackDamage = attackDamage; | ||||||
|  | 		this.durability = durability; | ||||||
|  | 		this.enchantability = enchantability; | ||||||
|  | 		this.miningSpeedMuliplier = miningSpeedMultiplier; | ||||||
|  | 		this.item = item; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public static final QuickieToolMaterial of(float attackDamage, int durability, int enchantability, float miningSpeedMultiplier, Item item) { | ||||||
|  | 		return new QuickieToolMaterial(attackDamage, durability, enchantability, miningSpeedMultiplier, item); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public float getAttackDamage() { | ||||||
|  | 		return attackDamage; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public int getDurability() { | ||||||
|  | 		return durability; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public int getEnchantability() { | ||||||
|  | 		return enchantability; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public TagKey<Block> getInverseTag() { | ||||||
|  | 		return BlockTags.INCORRECT_FOR_IRON_TOOL; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public float getMiningSpeedMultiplier() { | ||||||
|  | 		return miningSpeedMuliplier; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@Override | ||||||
|  | 	public Ingredient getRepairIngredient() { | ||||||
|  | 		return Ingredient.ofItems(item); | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -0,0 +1,33 @@ | |||||||
|  | package de.jottyfan.quickiemod.mixin; | ||||||
|  |  | ||||||
|  | import org.spongepowered.asm.mixin.Mixin; | ||||||
|  | import org.spongepowered.asm.mixin.injection.At; | ||||||
|  | import org.spongepowered.asm.mixin.injection.Inject; | ||||||
|  | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; | ||||||
|  |  | ||||||
|  | import de.jottyfan.quickiemod.event.BreakBlockCallback; | ||||||
|  | import net.minecraft.block.Block; | ||||||
|  | import net.minecraft.block.BlockState; | ||||||
|  | import net.minecraft.entity.player.PlayerEntity; | ||||||
|  | import net.minecraft.util.ActionResult; | ||||||
|  | import net.minecraft.util.math.BlockPos; | ||||||
|  | import net.minecraft.world.World; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | @Mixin(Block.class) | ||||||
|  | public class BlockBreakMixin { | ||||||
|  |  | ||||||
|  | 	@Inject(at = @At("HEAD"), method = "onBreak(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/entity/player/PlayerEntity;)Lnet/minecraft/block/BlockState;") | ||||||
|  | 	private void onBreak(final World world, final BlockPos blockPos, final BlockState blockState, | ||||||
|  | 			final PlayerEntity playerEntity, final CallbackInfoReturnable<BlockBreakMixin> info) { | ||||||
|  | 		ActionResult result = BreakBlockCallback.EVENT.invoker().injectBlockBreakCallback(world, blockPos, blockState, | ||||||
|  | 				playerEntity); | ||||||
|  | 		if (result == ActionResult.FAIL) { | ||||||
|  | 			info.cancel(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -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": "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 ] | ||||||
|  | 				} | ||||||
|  | 		} | ||||||
|  | } | ||||||
| @@ -0,0 +1,6 @@ | |||||||
|  | { | ||||||
|  |     "parent": "minecraft:item/handheld", | ||||||
|  |     "textures": { | ||||||
|  |         "layer0": "quickiemod:item/quickiepowderaxe" | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,6 @@ | |||||||
|  | { | ||||||
|  |     "parent": "item/generated", | ||||||
|  |     "textures": { | ||||||
|  |         "layer0": "quickiemod:item/quickiepowderhoe" | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,6 @@ | |||||||
|  | { | ||||||
|  |     "parent": "item/generated", | ||||||
|  |     "textures": { | ||||||
|  |         "layer0": "quickiemod:item/quickiepowderpickaxe" | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,6 @@ | |||||||
|  | { | ||||||
|  |     "parent": "item/generated", | ||||||
|  |     "textures": { | ||||||
|  |         "layer0": "quickiemod:item/quickiepowdershovel" | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,6 @@ | |||||||
|  | { | ||||||
|  |     "parent": "item/generated", | ||||||
|  |     "textures": { | ||||||
|  |         "layer0": "quickiemod:item/quickiepowderwaterhoe" | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,6 @@ | |||||||
|  | { | ||||||
|  |     "parent": "item/generated", | ||||||
|  |     "textures": { | ||||||
|  |         "layer0": "quickiemod:item/speedpowderaxe" | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,6 @@ | |||||||
|  | { | ||||||
|  |     "parent": "item/generated", | ||||||
|  |     "textures": { | ||||||
|  |         "layer0": "quickiemod:item/speedpowderhoe" | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,6 @@ | |||||||
|  | { | ||||||
|  |     "parent": "item/generated", | ||||||
|  |     "textures": { | ||||||
|  |         "layer0": "quickiemod:item/speedpowderpickaxe" | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,6 @@ | |||||||
|  | { | ||||||
|  |     "parent": "item/generated", | ||||||
|  |     "textures": { | ||||||
|  |         "layer0": "quickiemod:item/speedpowdershovel" | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,6 @@ | |||||||
|  | { | ||||||
|  |     "parent": "item/generated", | ||||||
|  |     "textures": { | ||||||
|  |         "layer0": "quickiemod:item/speedpowderwaterhoe" | ||||||
|  |     } | ||||||
|  | } | ||||||
| After Width: | Height: | Size: 6.7 KiB | 
| After Width: | Height: | Size: 6.5 KiB | 
| After Width: | Height: | Size: 6.8 KiB | 
| After Width: | Height: | Size: 6.5 KiB | 
| After Width: | Height: | Size: 6.8 KiB | 
| After Width: | Height: | Size: 6.5 KiB | 
							
								
								
									
										
											BIN
										
									
								
								src/main/resources/assets/quickiemod/textures/gui/backpack.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 35 KiB | 
| After Width: | Height: | Size: 21 KiB | 
							
								
								
									
										
											BIN
										
									
								
								src/main/resources/assets/quickiemod/textures/gui/slot.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 436 B | 
| After Width: | Height: | Size: 4.3 KiB | 
| After Width: | Height: | Size: 4.3 KiB | 
| After Width: | Height: | Size: 4.3 KiB | 
| After Width: | Height: | Size: 4.3 KiB | 
| After Width: | Height: | Size: 4.3 KiB | 
| After Width: | Height: | Size: 4.3 KiB | 
| After Width: | Height: | Size: 5.9 KiB | 
| After Width: | Height: | Size: 4.3 KiB | 
| After Width: | Height: | Size: 4.3 KiB | 
| After Width: | Height: | Size: 6.0 KiB | 
							
								
								
									
										7
									
								
								src/main/resources/data/c/tags/item/axes.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,7 @@ | |||||||
|  | { | ||||||
|  |   "replace": false, | ||||||
|  |   "values": [ | ||||||
|  |     "quickiemod:speedpowderaxe", | ||||||
|  |     "quickiemod:quickiepowderaxe" | ||||||
|  |   ] | ||||||
|  | } | ||||||