mirror of
				https://github.com/Theta-Dev/ConstructionWand.git
				synced 2025-10-31 19:23:47 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			144 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			144 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package thetadev.constructionwand.wand.supplier;
 | |
| 
 | |
| import net.minecraft.block.BlockState;
 | |
| import net.minecraft.entity.player.PlayerEntity;
 | |
| import net.minecraft.item.BlockItem;
 | |
| import net.minecraft.item.Item;
 | |
| import net.minecraft.item.ItemStack;
 | |
| import net.minecraft.item.Items;
 | |
| import net.minecraft.util.Hand;
 | |
| import net.minecraft.util.math.BlockPos;
 | |
| import net.minecraft.util.math.BlockRayTraceResult;
 | |
| import net.minecraft.world.World;
 | |
| import thetadev.constructionwand.ConstructionWand;
 | |
| import thetadev.constructionwand.api.IWandSupplier;
 | |
| import thetadev.constructionwand.basics.ReplacementRegistry;
 | |
| import thetadev.constructionwand.basics.WandUtil;
 | |
| import thetadev.constructionwand.basics.option.WandOptions;
 | |
| import thetadev.constructionwand.basics.pool.IPool;
 | |
| import thetadev.constructionwand.basics.pool.OrderedPool;
 | |
| import thetadev.constructionwand.containers.ContainerManager;
 | |
| import thetadev.constructionwand.wand.undo.PlaceSnapshot;
 | |
| 
 | |
| import javax.annotation.Nullable;
 | |
| import java.util.HashMap;
 | |
| import java.util.LinkedHashMap;
 | |
| import java.util.List;
 | |
| 
 | |
| /**
 | |
|  * Default WandSupplier. Takes items from player inventory.
 | |
|  */
 | |
| public class SupplierInventory implements IWandSupplier
 | |
| {
 | |
|     protected final PlayerEntity player;
 | |
|     protected final WandOptions options;
 | |
| 
 | |
|     protected HashMap<BlockItem, Integer> itemCounts;
 | |
|     protected IPool<BlockItem> itemPool;
 | |
| 
 | |
|     public SupplierInventory(PlayerEntity player, WandOptions options) {
 | |
|         this.player = player;
 | |
|         this.options = options;
 | |
|     }
 | |
| 
 | |
|     public void getSupply(@Nullable BlockItem target) {
 | |
|         itemCounts = new LinkedHashMap<>();
 | |
|         ItemStack offhandStack = player.getHeldItem(Hand.OFF_HAND);
 | |
| 
 | |
|         itemPool = new OrderedPool<>();
 | |
| 
 | |
|         // Block in offhand -> override
 | |
|         if(!offhandStack.isEmpty() && offhandStack.getItem() instanceof BlockItem) {
 | |
|             addBlockItem((BlockItem) offhandStack.getItem());
 | |
|         }
 | |
|         // Otherwise use target block
 | |
|         else if(target != null && target != Items.AIR) {
 | |
|             addBlockItem(target);
 | |
| 
 | |
|             // Add replacement items
 | |
|             if(options.match.get() != WandOptions.MATCH.EXACT) {
 | |
|                 for(Item it : ReplacementRegistry.getMatchingSet(target)) {
 | |
|                     if(it instanceof BlockItem) addBlockItem((BlockItem) it);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     protected void addBlockItem(BlockItem item) {
 | |
|         int count = WandUtil.countItem(player, item);
 | |
|         if(count > 0) {
 | |
|             itemCounts.put(item, count);
 | |
|             itemPool.add(item);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     @Override
 | |
|     @Nullable
 | |
|     public PlaceSnapshot getPlaceSnapshot(World world, BlockPos pos, BlockRayTraceResult rayTraceResult,
 | |
|                                           @Nullable BlockState supportingBlock) {
 | |
|         if(!WandUtil.isPositionPlaceable(world, player, pos, options.replace.get())) return null;
 | |
|         itemPool.reset();
 | |
| 
 | |
|         while(true) {
 | |
|             // Draw item from pool (returns null if none are left)
 | |
|             BlockItem item = itemPool.draw();
 | |
|             if(item == null) return null;
 | |
| 
 | |
|             int count = itemCounts.get(item);
 | |
|             if(count == 0) continue;
 | |
| 
 | |
|             PlaceSnapshot placeSnapshot = PlaceSnapshot.get(world, player, rayTraceResult, pos, item, supportingBlock, options);
 | |
|             if(placeSnapshot != null) {
 | |
|                 int ncount = count - 1;
 | |
|                 itemCounts.put(item, ncount);
 | |
| 
 | |
|                 // Remove item from pool if there are no items left
 | |
|                 if(ncount == 0) itemPool.remove(item);
 | |
| 
 | |
|                 return placeSnapshot;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     @Override
 | |
|     public int takeItemStack(ItemStack stack) {
 | |
|         int count = stack.getCount();
 | |
|         Item item = stack.getItem();
 | |
| 
 | |
|         if(player.inventory == null || player.inventory.mainInventory == null) return count;
 | |
|         if(player.isCreative()) return 0;
 | |
| 
 | |
|         List<ItemStack> hotbar = WandUtil.getHotbarWithOffhand(player);
 | |
|         List<ItemStack> mainInv = WandUtil.getMainInv(player);
 | |
| 
 | |
|         // Take items from main inv, loose items first
 | |
|         count = takeItemsInvList(count, item, mainInv, false);
 | |
|         count = takeItemsInvList(count, item, mainInv, true);
 | |
| 
 | |
|         // Take items from hotbar, containers first
 | |
|         count = takeItemsInvList(count, item, hotbar, true);
 | |
|         count = takeItemsInvList(count, item, hotbar, false);
 | |
| 
 | |
|         return count;
 | |
|     }
 | |
| 
 | |
|     private int takeItemsInvList(int count, Item item, List<ItemStack> inv, boolean container) {
 | |
|         ContainerManager containerManager = ConstructionWand.instance.containerManager;
 | |
| 
 | |
|         for(ItemStack stack : inv) {
 | |
|             if(count == 0) break;
 | |
| 
 | |
|             if(container) {
 | |
|                 count = containerManager.useItems(player, new ItemStack(item), stack, count);
 | |
|             }
 | |
| 
 | |
|             if(!container && WandUtil.stackEquals(stack, item)) {
 | |
|                 int toTake = Math.min(count, stack.getCount());
 | |
|                 stack.shrink(toTake);
 | |
|                 count -= toTake;
 | |
|                 player.inventory.markDirty();
 | |
|             }
 | |
|         }
 | |
|         return count;
 | |
|     }
 | |
| }
 |