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 | ||||
| org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled | ||||
| org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 | ||||
|   | ||||
| @@ -4,14 +4,14 @@ org.gradle.parallel=true | ||||
|  | ||||
| # Fabric Properties | ||||
| # check these on https://fabricmc.net/develop | ||||
| minecraft_version=1.20.6 | ||||
| yarn_mappings=1.20.6+build.3 | ||||
| minecraft_version=1.21 | ||||
| yarn_mappings=1.21+build.2 | ||||
| loader_version=0.15.11 | ||||
|  | ||||
| # Mod Properties | ||||
| mod_version=1.20.6.0 | ||||
| mod_version=1.21.0.2 | ||||
| maven_group=de.jottyfan.quickiemod | ||||
| archives_base_name=quickiemod | ||||
|  | ||||
| # 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 static final String MODID = "quickiemod"; | ||||
|  | ||||
|   private static final Logger LOGGER = LoggerFactory.getLogger(MODID); | ||||
|   public static final Logger LOGGER = LoggerFactory.getLogger(MODID); | ||||
|  | ||||
| 	@Override | ||||
| 	public void onInitialize() { | ||||
| 		LOGGER.info("loading {}", MODID); | ||||
|  | ||||
| 		RegistryManager.registerBlockEntityTypes(); | ||||
| 		RegistryManager.registerScreenHandlerTypes(); | ||||
| 		RegistryManager.registerItems(); | ||||
| 		RegistryManager.registerEvents(); | ||||
| 		RegistryManager.registerBlocks(); | ||||
| 		RegistryManager.registerFeatures(); | ||||
| 		RegistryManager.registerItemGroup(); | ||||
|   | ||||
| @@ -1,10 +1,13 @@ | ||||
| package de.jottyfan.quickiemod; | ||||
|  | ||||
| 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.EnvType; | ||||
| import net.fabricmc.api.Environment; | ||||
| import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; | ||||
| import net.minecraft.client.gui.screen.ingame.HandledScreens; | ||||
| import net.minecraft.client.render.RenderLayer; | ||||
|  | ||||
| /** | ||||
| @@ -16,6 +19,7 @@ import net.minecraft.client.render.RenderLayer; | ||||
| public class QuickieModClient implements ClientModInitializer { | ||||
| 	@Override | ||||
| 	public void onInitializeClient() { | ||||
| //			HandledScreens.register(ScreenHandlerTypes.BLOCKSTACKER_SCREEN_HANDLER, BlockStackerScreen::new); | ||||
| 		BlockRenderLayerMap.INSTANCE.putBlock(QuickieBlocks.COTTONPLANT.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)); | ||||
| 	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)); | ||||
| 	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.items.QuickieItems; | ||||
| import net.minecraft.block.AbstractBlock; | ||||
| import net.minecraft.block.BlockState; | ||||
| import net.minecraft.block.ExperienceDroppingBlock; | ||||
| import net.minecraft.item.ItemStack; | ||||
| 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 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 | ||||
|   | ||||
| @@ -5,11 +5,11 @@ import java.util.List; | ||||
|  | ||||
| import de.jottyfan.quickiemod.blocks.help.IntProviderHelper; | ||||
| import de.jottyfan.quickiemod.items.QuickieItems; | ||||
| import net.minecraft.block.AbstractBlock; | ||||
| import net.minecraft.block.BlockState; | ||||
| import net.minecraft.block.ExperienceDroppingBlock; | ||||
| import net.minecraft.item.ItemStack; | ||||
| 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 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 | ||||
|   | ||||
| @@ -5,11 +5,11 @@ import java.util.List; | ||||
|  | ||||
| import de.jottyfan.quickiemod.blocks.help.IntProviderHelper; | ||||
| import de.jottyfan.quickiemod.items.QuickieItems; | ||||
| import net.minecraft.block.AbstractBlock; | ||||
| import net.minecraft.block.BlockState; | ||||
| import net.minecraft.block.ExperienceDroppingBlock; | ||||
| import net.minecraft.item.ItemStack; | ||||
| import net.minecraft.loot.context.LootContextParameterSet.Builder; | ||||
| import net.minecraft.sound.BlockSoundGroup; | ||||
| import net.minecraft.util.math.random.Random; | ||||
|  | ||||
| /** | ||||
| @@ -20,7 +20,7 @@ import net.minecraft.util.math.random.Random; | ||||
| public class BlockOreSalpeter extends ExperienceDroppingBlock { | ||||
|  | ||||
| 	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 | ||||
|   | ||||
| @@ -5,12 +5,12 @@ import java.util.List; | ||||
|  | ||||
| import de.jottyfan.quickiemod.blocks.help.IntProviderHelper; | ||||
| import de.jottyfan.quickiemod.items.QuickieItems; | ||||
| import net.minecraft.block.AbstractBlock; | ||||
| import net.minecraft.block.BlockState; | ||||
| import net.minecraft.block.Blocks; | ||||
| import net.minecraft.block.ExperienceDroppingBlock; | ||||
| import net.minecraft.item.ItemStack; | ||||
| import net.minecraft.loot.context.LootContextParameterSet.Builder; | ||||
| import net.minecraft.sound.BlockSoundGroup; | ||||
| import net.minecraft.util.math.random.Random; | ||||
|  | ||||
| /** | ||||
| @@ -21,7 +21,7 @@ import net.minecraft.util.math.random.Random; | ||||
| public class BlockOreSandSalpeter extends ExperienceDroppingBlock { | ||||
|  | ||||
| 	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 | ||||
|   | ||||
| @@ -5,11 +5,11 @@ import java.util.List; | ||||
|  | ||||
| import de.jottyfan.quickiemod.blocks.help.IntProviderHelper; | ||||
| import de.jottyfan.quickiemod.items.QuickieItems; | ||||
| import net.minecraft.block.AbstractBlock; | ||||
| import net.minecraft.block.BlockState; | ||||
| import net.minecraft.block.ExperienceDroppingBlock; | ||||
| import net.minecraft.item.ItemStack; | ||||
| 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 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 | ||||
|   | ||||
| @@ -5,11 +5,11 @@ import java.util.List; | ||||
|  | ||||
| import de.jottyfan.quickiemod.blocks.help.IntProviderHelper; | ||||
| import de.jottyfan.quickiemod.items.QuickieItems; | ||||
| import net.minecraft.block.AbstractBlock; | ||||
| import net.minecraft.block.BlockState; | ||||
| import net.minecraft.block.ExperienceDroppingBlock; | ||||
| import net.minecraft.item.ItemStack; | ||||
| 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 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 | ||||
|   | ||||
| @@ -6,12 +6,12 @@ import java.util.List; | ||||
| import com.mojang.serialization.MapCodec; | ||||
|  | ||||
| import de.jottyfan.quickiemod.items.QuickieItems; | ||||
| import net.minecraft.block.AbstractBlock; | ||||
| import net.minecraft.block.BlockState; | ||||
| import net.minecraft.block.Blocks; | ||||
| import net.minecraft.block.FallingBlock; | ||||
| import net.minecraft.item.ItemStack; | ||||
| import net.minecraft.loot.context.LootContextParameterSet.Builder; | ||||
| import net.minecraft.sound.BlockSoundGroup; | ||||
| import net.minecraft.util.math.random.Random; | ||||
|  | ||||
| /** | ||||
| @@ -22,7 +22,7 @@ import net.minecraft.util.math.random.Random; | ||||
| public class BlockSandSalpeter extends FallingBlock { | ||||
|  | ||||
| 	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 | ||||
|   | ||||
| @@ -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.items.QuickieItems; | ||||
| import net.minecraft.block.AbstractBlock; | ||||
| import net.minecraft.block.BlockState; | ||||
| import net.minecraft.block.ExperienceDroppingBlock; | ||||
| import net.minecraft.item.ItemStack; | ||||
| 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 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 | ||||
|   | ||||
| @@ -9,6 +9,12 @@ import net.minecraft.block.Block; | ||||
|  */ | ||||
| public enum QuickieBlocks { | ||||
| 	// @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_EAST(new BlockDrillEast(), "drilleast"), | ||||
| 	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 static final Identifier ITEMHOARDER = new Identifier(QuickieMod.MODID, "itemhoarderblockentity"); | ||||
| 	public static final Identifier BLOCKSPREADER = new Identifier(QuickieMod.MODID, "blockspreaderblockentity"); | ||||
| 	public static final Identifier BLOCKSTACKERUP = new Identifier(QuickieMod.MODID, "blockstackerblockentity"); | ||||
| 	public static final Identifier MONSTERHOARDER = new Identifier(QuickieMod.MODID, "monsterhoarderblockentity"); | ||||
| 	public static final Identifier EMPTYLAVALHOARDER = new Identifier(QuickieMod.MODID, "emptylavahoarderblockentity"); | ||||
| 	public static final Identifier DRILL_DOWN = new Identifier(QuickieMod.MODID, "drillblockdownblockentity"); | ||||
| 	public static final Identifier DRILL_EAST = new Identifier(QuickieMod.MODID, "drillblockeastblockentity"); | ||||
| 	public static final Identifier DRILL_SOUTH = new Identifier(QuickieMod.MODID, "drillblocksouthblockentity"); | ||||
| 	public static final Identifier DRILL_WEST = new Identifier(QuickieMod.MODID, "drillblockwestblockentity"); | ||||
| 	public static final Identifier DRILL_NORTH = new Identifier(QuickieMod.MODID, "drillblocknorthblockentity"); | ||||
| 	public static final Identifier ITEMHOARDER = Identifier.of(QuickieMod.MODID, "itemhoarderblockentity"); | ||||
| 	public static final Identifier BLOCKSPREADER = Identifier.of(QuickieMod.MODID, "blockspreaderblockentity"); | ||||
| 	public static final Identifier BLOCKSTACKERUP = Identifier.of(QuickieMod.MODID, "blockstackerblockentity"); | ||||
| 	public static final Identifier MONSTERHOARDER = Identifier.of(QuickieMod.MODID, "monsterhoarderblockentity"); | ||||
| 	public static final Identifier EMPTYLAVALHOARDER = Identifier.of(QuickieMod.MODID, "emptylavahoarderblockentity"); | ||||
| 	public static final Identifier DRILL_DOWN = Identifier.of(QuickieMod.MODID, "drillblockdownblockentity"); | ||||
| 	public static final Identifier DRILL_EAST = Identifier.of(QuickieMod.MODID, "drillblockeastblockentity"); | ||||
| 	public static final Identifier DRILL_SOUTH = Identifier.of(QuickieMod.MODID, "drillblocksouthblockentity"); | ||||
| 	public static final Identifier DRILL_WEST = Identifier.of(QuickieMod.MODID, "drillblockwestblockentity"); | ||||
| 	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"); | ||||
|  | ||||
|   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) { | ||||
|   	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() { | ||||
|   | ||||
| @@ -6,6 +6,8 @@ import org.slf4j.LoggerFactory; | ||||
| import de.jottyfan.quickiemod.QuickieMod; | ||||
| import de.jottyfan.quickiemod.blockentity.BlockEntityTypes; | ||||
| 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 net.fabricmc.fabric.api.biome.v1.BiomeModifications; | ||||
| 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.RegistryKeys; | ||||
| import net.minecraft.text.Text; | ||||
| import net.minecraft.util.ActionResult; | ||||
| import net.minecraft.util.Identifier; | ||||
|  | ||||
| /** | ||||
| @@ -32,7 +35,7 @@ public class RegistryManager { | ||||
| 	private static final Logger LOGGER = LoggerFactory.getLogger(QuickieMod.MODID); | ||||
|  | ||||
| 	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)) | ||||
| 						.entries((enabledFeatures, stacks) -> { | ||||
| 							for (QuickieItems i : QuickieItems.values()) { | ||||
| @@ -47,9 +50,9 @@ public class RegistryManager { | ||||
| 	} | ||||
|  | ||||
| 	public static final void registerItems() { | ||||
| 		LOGGER.debug("registering items"); | ||||
| 		LOGGER.info("registering items"); | ||||
| 		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.COTTON.getItem(), 0.75f); | ||||
| @@ -60,24 +63,40 @@ public class RegistryManager { | ||||
| 	} | ||||
|  | ||||
| 	public static final void registerBlocks() { | ||||
| 		LOGGER.debug("registering blocks"); | ||||
| 		LOGGER.info("registering blocks"); | ||||
| 		for (QuickieBlocks b : QuickieBlocks.values()) { | ||||
| 			Registry.register(Registries.BLOCK, new Identifier(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.BLOCK, Identifier.of(QuickieMod.MODID, b.getName()), b.getBlock()); | ||||
| 			Registry.register(Registries.ITEM, Identifier.of(QuickieMod.MODID, b.getName()), new BlockItem(b.getBlock(), new Settings())); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public static final void registerFeatures() { | ||||
| 		// 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()); | ||||
|  | ||||
| 		// 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()); | ||||
| 	} | ||||
|  | ||||
| 	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() { | ||||
| 		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 { | ||||
| 	// @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"), | ||||
| 	CARROTSTACK(new ItemCarrotstack(), "carrotstack"), | ||||
| 	COTTON(new ItemCotton(), "cotton"), | ||||
| @@ -20,12 +35,7 @@ public enum QuickieItems { | ||||
| 	CANOLABOTTLESTACK(new ItemCanolabottlestack(), "canolabottlestack"), | ||||
| 	STUB(new ItemStub(), "stub"), | ||||
| 	SALPETER(new ItemSalpeter(), "salpeter"), | ||||
| 	SULPHOR(new ItemSulphor(), "sulphor"), | ||||
| 	SPEEDPOWDER(new ItemSpeedpowder(), "speedpowder"), | ||||
| 	QUICKIEPOWDER(new ItemQuickiepowder(), "quickiepowder"), | ||||
| 	OXIDIZEDCOPPERPOWDER(new ItemOxidizedcopperpowder(), "oxidizedcopperpowder"), | ||||
| 	SPEEDINGOT(new ItemSpeedingot(), "speedingot"), | ||||
| 	QUICKIEINGOT(new ItemQuickieingot(), "quickieingot"); | ||||
| 	SULPHOR(new ItemSulphor(), "sulphor"); | ||||
| 	// @formatter:on | ||||
|  | ||||
| 	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" | ||||
|   ] | ||||
| } | ||||