CraftingManager class

Пакет: com.hypixel.hytale.builtin.crafting.component

Файл: com/hypixel/hytale/builtin/crafting/component/CraftingManager.java

implements: Component<EntityStore>

Поля (191)

МодификаторыТипИмя
NORMAL, ORDERED
break
break
break
private final ItemContainer inputItemContainer
private final CraftingManager.InputRemovalType inputRemovalType
private float lastSentPercent
private final int quantity
private int quantityCompleted
private int quantityStarted
private final CraftingRecipe recipe
private final Int2ObjectMap<List<ItemStack>> removedItems
private final float timeSeconds
private final float timeSeconds
private float timeSecondsCompleted
private float timeSecondsCompleted
private final int transactionId
MaterialQuantity var1
int var1
CraftRecipeEvent.Post var10
CraftRecipeEvent.Pre var10
CraftRecipeEvent.Post var10
String var10
List var10
List var10
int var10
ItemQuantity var10000
IEventDispatcher var11
float var11
float var11
var11
boolean var11
var11
Player var11
List var11
double var11
PlayerRef var12
int var12
int var12
int var12
boolean var12
var12
ItemContainer var12
var12
String var13
BenchTierLevel var13
BenchRequirement[] var13
CombinedItemContainer var13
Map var13
double var13
boolean var14
CombinedItemContainer var14
ListTransaction var15
Vector3d var15
List var16
BlockBoundingBoxes var16
BlockBoundingBoxes.RotatedVariantBoxes var17
CraftingManager.CraftingJob var18
Box var18
double var19
String var2
CraftingRecipe var2
MaterialQuantity[] var2
String var2
ObjectList var2
String var2
MaterialQuantity[] var2
Bench var2
BenchTierLevel var2
World var2
World var2
BlockSection var21
double var21
BlockType var22
ProcessingBenchBlock var23
double var23
int var24
int var25
double var25
BlockType var26
SpatialResource var27
List var28
int var29
boolean var3
Item var3
var3
var3
ObjectList var3
List var3
List var3
ObjectList var3
int var3
String var3
JsonArray var3
int var3
var3
MaterialQuantity var3
World var3
ChunkStore var3
String[] var3
ChunkStore var3
int var30
int var31
int var32
int var33
int var34
double var35
double var37
double var39
Player var4
CraftingManager.CraftingJob var4
Player var4
String var4
Player var4
ObjectList var4
ListTransaction var4
List var4
short var4
boolean var4
var4
String var4
BenchUpgradeRequirement var4
ChunkStore var4
Ref var4
Set var4
Ref var4
double var41
double var43
double var45
ItemContainerBlock var49
Bench var5
PlayerRef var5
PlayerConfigData var5
CraftingRecipe var5
List var5
boolean var5
CombinedItemContainer var5
MaterialQuantity[] var5
int var5
List var5
Ref var5
BenchBlock var5
BenchBlock var5
BlockModule.BlockStateInfo var50
ChunkSection var51
int var52
int var53
int var54
int var6
Player var6
CraftingManager.CraftingJob var6
var6
var6
MaterialQuantity var6
PlayerSettings var6
var6
ListTransaction var6
ItemStack var6
Item var6
Player var6
Ref var6
List var6
CraftRecipeEvent.Pre var7
boolean var7
boolean var7
String var7
int var7
CombinedItemContainer var7
BlockModule.BlockStateInfo var7
List var7
World var8
int var8
int var8
World var8
ItemStack var8
CombinedItemContainer var8
CombinedItemContainer var8
BenchBlock var8
List var8
Player var9
int var9
String var9
BenchType var9
ItemContainer var9
int var9
long var9
BenchUpgradeRequirement var9
CraftingManager.ChestLookupResult var9
Store var9
private final BenchWindow window
private final CraftingWindow window

Методы (112)

МодификаторыВозвратСигнатура
private BenchUpgradingJobprivate BenchUpgradingJob(@Nonnull BenchWindow var1, float var2)
protected record ChestLookupResultrecord ChestLookupResult(List<ItemContainer> containers, List<ItemContainerBlock> states, List<ItemContainerBlock> filteredOut, Vector3d benchCenteredPos)
public CraftingJobpublic CraftingJob(@Nonnull CraftingWindow var1, int var2, @Nonnull CraftingRecipe var3, int var4, float var5, @Nonnull ItemContainer var6, @Nonnull CraftingManager.InputRemovalType var7)
abstract throw new IllegalArgumentExceptionthrow new IllegalArgumentException("blockType isn't a crafting bench!")
abstract throw new IllegalArgumentExceptionthrow new IllegalArgumentException("Queue already has jobs!")
abstract throw new IllegalArgumentExceptionthrow new IllegalArgumentException("Upgrading job is already set!")
InputRemovalType InputRemovalType()
abstract throw new RuntimeExceptionthrow new RuntimeException("QuantityCompleted is greater than the Quality! " + var6)
abstract throw new RuntimeExceptionthrow new RuntimeException("A non-existent item ID was provided! " + var4)
private boolean benchHasRequiredAugmentTagsboolean benchHasRequiredAugmentTags(@Nonnull ComponentAccessor<EntityStore> var1, @Nonnull BenchRequirement var2)
public boolean cancelAllCraftingboolean cancelAllCrafting(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2)
public boolean clearBenchboolean clearBench(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2)
public float computeLoadingPercentpublic float computeLoadingPercent()
public boolean craftItemboolean craftItem(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2, @Nonnull CraftingRecipe var3, int var4, @Nonnull ItemContainer var5)
static int feedExtraResourcesSectionint feedExtraResourcesSection(@Nonnull World var0, int var1, int var2, int var3, @Nonnull BlockType var4, int var5, @Nonnull Bench var6, int var7, @Nonnull MaterialExtraResourcesSection var8)
private int finishTierUpgradeint finishTierUpgrade(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2)
for for(CraftingManager.CraftingJob var3 : this.queuedCraftingJobs)
for for(BenchRequirement var17 : var13)
for for(ItemStack var8 : var5)
for for(MaterialQuantity var7 : var2)
for for(MaterialQuantity var6 : var0)
for for(CraftingRecipe var4 : var0)
for for(MaterialQuantity var8 : var2)
for for(String var8 : var3)
for for(ItemContainer var15 : var10)
for for(Ref var48 : var28)
abstract for for(short var5 = var2.getCapacity()
private int getBenchTierLevelint getBenchTierLevel(@Nonnull ComponentAccessor<EntityStore> var1)
abstract return getInputMaterialsreturn getInputMaterials(var0, 1)
static int getMaterialCraftLimitint getMaterialCraftLimit(@Nonnull CraftingRecipe var0, @Nonnull ItemContainer var1)
static int getOutputCraftCeilingint getOutputCraftCeiling(@Nonnull Ref<EntityStore> var0, @Nonnull ComponentAccessor<EntityStore> var1, @Nonnull CraftingRecipe var2)
abstract return getOutputItemStackreturn getOutputItemStack(var0, 1)
abstract return getOutputItemStacksreturn getOutputItemStacks(var0, 1)
public int getRemainingQueueSizeint getRemainingQueueSize()
static void giveOutputvoid giveOutput(@Nonnull Ref<EntityStore> var0, @Nonnull ComponentAccessor<EntityStore> var1, @Nonnull CraftingManager.CraftingJob var2, int var3)
static void giveOutputvoid giveOutput(@Nonnull Ref<EntityStore> var0, @Nonnull ComponentAccessor<EntityStore> var1, @Nonnull CraftingRecipe var2, int var3)
abstract giveOutput giveOutput(var1, var2, var3, var6)
abstract giveOutput giveOutput(var1, var2, var6, var12)
abstract giveOutput giveOutput(var0, var1, var5, 1)
public boolean hasBenchSetboolean hasBenchSet()
if if(this.blockType != null)
if if(this.upgradingJob != null)
if if(this.upgradingJob != null)
if if(var6 < 1)
if if(var13 != null)
if if(var1 == null)
if if(var2 == null)
if if(this.upgradingJob != null)
if if(var9 < 1)
if if(var11 > 0.0F)
if if(var12 > 1)
if if(var13 != null)
if if(!var14)
if if(!var7)
if if(var5 > var8)
if if(this.upgradingJob != null)
if if(var3 > 0.0F)
if if(this.upgradingJob.timeSecondsCompleted >= this.upgradingJob.timeSeconds)
if if(var6 != null && var6.quantityStarted < var6.quantity && var6.quantityStarted <= var6.quantityCompleted)
if if(var9 != null)
if if(!var7 && var6 != null && var6.quantityStarted < var6.quantity && var6.quantityStarted <= var6.quantityCompleted)
if if(var6 != null)
if if(var11 > 1.0F)
if if(var6.timeSecondsCompleted >= var6.timeSeconds)
if if(var6.quantityCompleted == var6.quantity)
if if(var6.quantityCompleted > var6.quantity)
if if(var13 != null)
if if(!var11)
if if(var5 == null)
if if(var4 == null)
if if(var6 == null)
if if(var4 != null)
if if(var2 == null)
if if(var8 != null)
if if(var2 == null)
if if(var2 != null)
if if(var2 != null && var2.length != 0)
if if(var9 > 0)
if if(var3 == 0)
if if(var4 == null)
if if(this.upgradingJob != null)
if if(var4 == null)
if if(this.upgradingJob == null)
if if(var6 == null)
if if(var7 == null)
if if(var9 == null)
if if(!var12)
if if(var12)
if if(var23 != null)
if if(this.blockType == null)
if if(var4 == null)
if if(var3 != null && var3.length != 0)
if if(var4 == null)
if if(var5 == null)
if if(var49 != null)
if if(var50 != null)
if if(var51 != null)
if if(var52 >= var35 && var52 <= var41 && var53 >= var37 && var53 <= var43 && var54 >= var39 && var54 <= var45)
private boolean isValidBenchForRecipeboolean isValidBenchForRecipe(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2, @Nonnull CraftingRecipe var3)
static boolean matchesboolean matches(@Nonnull MaterialQuantity var0, @Nonnull ItemStack var1)
static boolean matchesAnyRecipeboolean matchesAnyRecipe(@Nonnull List<CraftingRecipe> var0, int var1, @Nonnull ItemStack var2)
public boolean queueCraftboolean queueCraft(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2, @Nonnull CraftingWindow var3, int var4, @Nonnull CraftingRecipe var5, int var6, @Nonnull ItemContainer var7, @Nonnull CraftingManager.InputRemovalType var8)
static void refundInputToInventoryvoid refundInputToInventory(@Nonnull Ref<EntityStore> var0, @Nonnull ComponentAccessor<EntityStore> var1, @Nonnull CraftingManager.CraftingJob var2, int var3)
abstract refundInputToInventory refundInputToInventory(var1, var2, var4, var4.quantityStarted - 1)
static boolean removeInputFromInventoryboolean removeInputFromInventory(@Nonnull CraftingManager.CraftingJob var0, int var1)
static boolean removeInputFromInventoryboolean removeInputFromInventory(@Nonnull ItemContainer var0, @Nonnull CraftingRecipe var1, int var2)
private int resolveCraftQuantityint resolveCraftQuantity(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2, @Nonnull CraftingRecipe var3, @Nonnull ItemContainer var4, int var5)
public void setBenchvoid setBench(int var1, int var2, int var3, @Nonnull BlockType var4)
public boolean startTierUpgradeboolean startTierUpgrade(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2, @Nonnull BenchWindow var3)
public void tickvoid tick(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2, float var3)
public String toStringpublic String toString()
public String toStringpublic String toString()

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.builtin.crafting.component;

class="kw">import com.google.gson.JsonArray;
class="kw">import com.hypixel.hytale.builtin.adventure.memories.MemoriesPlugin;
class="kw">import com.hypixel.hytale.builtin.crafting.CraftingPlugin;
class="kw">import com.hypixel.hytale.builtin.crafting.window.BenchWindow;
class="kw">import com.hypixel.hytale.builtin.crafting.window.CraftingWindow;
class="kw">import com.hypixel.hytale.component.Component;
class="kw">import com.hypixel.hytale.component.ComponentAccessor;
class="kw">import com.hypixel.hytale.component.ComponentType;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.component.Store;
class="kw">import com.hypixel.hytale.component.spatial.SpatialResource;
class="kw">import com.hypixel.hytale.event.IEventDispatcher;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.math.shape.Box;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.protocol.BenchRequirement;
class="kw">import com.hypixel.hytale.protocol.BenchType;
class="kw">import com.hypixel.hytale.protocol.GameMode;
class="kw">import com.hypixel.hytale.protocol.ItemQuantity;
class="kw">import com.hypixel.hytale.protocol.ItemResourceType;
class="kw">import com.hypixel.hytale.protocol.SoundCategory;
class="kw">import com.hypixel.hytale.protocol.packets.interface_.NotificationStyle;
class="kw">import com.hypixel.hytale.server.core.HytaleServer;
class="kw">import com.hypixel.hytale.server.core.Message;
class="kw">import com.hypixel.hytale.server.core.asset.type.blockhitbox.BlockBoundingBoxes;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.bench.Bench;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.bench.BenchTierLevel;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.bench.BenchUpgradeRequirement;
class="kw">import com.hypixel.hytale.server.core.asset.type.item.config.CraftingRecipe;
class="kw">import com.hypixel.hytale.server.core.asset.type.item.config.Item;
class="kw">import com.hypixel.hytale.server.core.entity.EntityUtils;
class="kw">import com.hypixel.hytale.server.core.entity.entities.Player;
class="kw">import com.hypixel.hytale.server.core.entity.entities.player.data.PlayerConfigData;
class="kw">import com.hypixel.hytale.server.core.entity.entities.player.windows.MaterialExtraResourcesSection;
class="kw">import com.hypixel.hytale.server.core.event.events.ecs.CraftRecipeEvent;
class="kw">import com.hypixel.hytale.server.core.event.events.player.PlayerCraftEvent;
class="kw">import com.hypixel.hytale.server.core.inventory.InventoryComponent;
class="kw">import com.hypixel.hytale.server.core.inventory.InventoryUtils;
class="kw">import com.hypixel.hytale.server.core.inventory.ItemStack;
class="kw">import com.hypixel.hytale.server.core.inventory.MaterialQuantity;
class="kw">import com.hypixel.hytale.server.core.inventory.container.CombinedItemContainer;
class="kw">import com.hypixel.hytale.server.core.inventory.container.DelegateItemContainer;
class="kw">import com.hypixel.hytale.server.core.inventory.container.EmptyItemContainer;
class="kw">import com.hypixel.hytale.server.core.inventory.container.ItemContainer;
class="kw">import com.hypixel.hytale.server.core.inventory.container.SimpleItemContainer;
class="kw">import com.hypixel.hytale.server.core.inventory.container.filter.FilterType;
class="kw">import com.hypixel.hytale.server.core.inventory.transaction.ListTransaction;
class="kw">import com.hypixel.hytale.server.core.inventory.transaction.MaterialSlotTransaction;
class="kw">import com.hypixel.hytale.server.core.inventory.transaction.MaterialTransaction;
class="kw">import com.hypixel.hytale.server.core.modules.block.BlockModule;
class="kw">import com.hypixel.hytale.server.core.modules.block.components.ItemContainerBlock;
class="kw">import com.hypixel.hytale.server.core.modules.entity.player.PlayerSettings;
class="kw">import com.hypixel.hytale.server.core.universe.PlayerRef;
class="kw">import com.hypixel.hytale.server.core.universe.world.SoundUtil;
class="kw">import com.hypixel.hytale.server.core.universe.world.World;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.BlockOperations;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.BlockSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.ChunkSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import com.hypixel.hytale.server.core.util.NotificationUtil;
class="kw">import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
class="kw">import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectArrayList;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectList;
class="kw">import java.util.Collections;
class="kw">import java.util.List;
class="kw">import java.util.Map;
class="kw">import java.util.Objects;
class="kw">import java.util.Set;
class="kw">import java.util.concurrent.BlockingQueue;
class="kw">import java.util.concurrent.LinkedBlockingQueue;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3d;
class="kw">import org.joml.Vector3i;

class="kw">public class CraftingManager class="kw">implements Component<EntityStore> {
   @Nonnull
   class="kw">private class="kw">static class="kw">final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
   class="kw">private class="kw">static class="kw">final int QUEUED_CRAFTING_JOBS_MAX_CAPACITY = 32;
   @Nonnull
   class="kw">private class="kw">final BlockingQueue<CraftingManager.CraftingJob> queuedCraftingJobs = new LinkedBlockingQueue<>(32);
   @Nullable
   class="kw">private CraftingManager.BenchUpgradingJob upgradingJob;
   class="kw">private int x;
   class="kw">private int y;
   class="kw">private int z;
   @Nullable
   class="kw">private BlockType blockType;

   @Nonnull
   class="kw">public class="kw">static ComponentType<EntityStore, CraftingManager> getComponentType() {
      class="kw">return CraftingPlugin.get().getCraftingManagerComponentType();
   }

   class="kw">public CraftingManager() {
   }

   class="kw">private CraftingManager(@Nonnull CraftingManager var1) {
      this.x = var1.x;
      this.y = var1.y;
      this.z = var1.z;
      this.blockType = var1.blockType;
      this.queuedCraftingJobs.addAll(var1.queuedCraftingJobs);
      this.upgradingJob = var1.upgradingJob;
   }

   class="kw">public boolean hasBenchSet() {
      class="kw">return this.blockType != null;
   }

   class="kw">public void setBench(int var1, int var2, int var3, @Nonnull BlockType var4) {
      Bench var5 = var4.getBench();
      Objects.requireNonNull(var5, "blockType isn't a bench!");
      if (var5.getType() != BenchType.Crafting
         && var5.getType() != BenchType.DiagramCrafting
         && var5.getType() != BenchType.StructuralCrafting
         && var5.getType() != BenchType.Processing) {
         throw new IllegalArgumentException("blockType isn't a crafting bench!");
      }

      if (this.blockType != null) {
         throw new IllegalArgumentException("Bench blockType is already set! Must be cleared (close UI).");
      }

      if (!this.queuedCraftingJobs.isEmpty()) {
         throw new IllegalArgumentException("Queue already has jobs!");
      }

      if (this.upgradingJob != null) {
         throw new IllegalArgumentException("Upgrading job is already set!");
      }

      this.x = var1;
      this.y = var2;
      this.z = var3;
      this.blockType = var4;
   }

   class="kw">public boolean clearBench(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2) {
      boolean var3 = this.cancelAllCrafting(var1, var2);
      this.x = 0;
      this.y = 0;
      this.z = 0;
      this.blockType = null;
      this.upgradingJob = null;
      class="kw">return var3;
   }

   class="kw">public boolean craftItem(
      @Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2, @Nonnull CraftingRecipe var3, int var4, @Nonnull ItemContainer var5
   ) {
      if (this.upgradingJob != null) {
         class="kw">return false;
      }

      Objects.requireNonNull(var3, "Recipe can't be null");
      int var6 = this.resolveCraftQuantity(var1, var2, var3, var5, var4);
      if (var6 < 1) {
         class="kw">return false;
      }

      CraftRecipeEvent.Pre var7 = new CraftRecipeEvent.Pre(var3, var6);
      var2.invoke(var1, var7);
      if (var7.isCancelled()) {
         class="kw">return false;
      }

      if (!this.isValidBenchForRecipe(var1, var2, var3)) {
         class="kw">return false;
      }

      World var8 = var2.getExternalData().getWorld();
      Player var9 = var2.getComponent(var1, Player.getComponentType());
      assert var9 != null;
      if (var9.getGameMode() != GameMode.Creative && !removeInputFromInventory(var5, var3, var6)) {
         PlayerRef var12 = var2.getComponent(var1, PlayerRef.getComponentType());
         assert var12 != null;
         String var13 = getRecipeOutputTranslationKey(var3);
         if (var13 != null) {
            NotificationUtil.sendNotification(
               var12.getPacketHandler(),
               Message.translation("server.general.crafting.missingIngredient").param("item", Message.translation(var13)),
               NotificationStyle.Danger
            );
         }

         LOGGER.at(Level.FINE).log("Missing items required to craft the item: %s", var3);
         class="kw">return false;
      } else {
         CraftRecipeEvent.Post var10 = new CraftRecipeEvent.Post(var3, var6);
         var2.invoke(var1, var10);
         if (var10.isCancelled()) {
            class="kw">return true;
         }

         giveOutput(var1, var2, var3, var6);
         IEventDispatcher var11 = HytaleServer.get().getEventBus().dispatchFor(PlayerCraftEvent.class, var8.getName());
         if (var11.hasListener()) {
            var11.dispatch(new PlayerCraftEvent(var1, var9, var3, var6));
         }

         class="kw">return true;
      }
   }

   @Nullable
   class="kw">private class="kw">static String getRecipeOutputTranslationKey(@Nonnull CraftingRecipe var0) {
      MaterialQuantity var1 = var0.getPrimaryOutput();
      if (var1 == null) {
         class="kw">return null;
      }

      String var2 = var1.getItemId();
      if (var2 == null) {
         class="kw">return null;
      }

      Item var3 = Item.getAssetMap().getAsset(var2);
      class="kw">return var3 != null ? var3.getTranslationKey() : null;
   }

   class="kw">public boolean queueCraft(
      @Nonnull Ref<EntityStore> var1,
      @Nonnull ComponentAccessor<EntityStore> var2,
      @Nonnull CraftingWindow var3,
      int var4,
      @Nonnull CraftingRecipe var5,
      int var6,
      @Nonnull ItemContainer var7,
      @Nonnull CraftingManager.InputRemovalType var8
   ) {
      if (this.upgradingJob != null) {
         class="kw">return false;
      }

      Objects.requireNonNull(var5, "Recipe can't be null");
      if (!this.isValidBenchForRecipe(var1, var2, var5)) {
         class="kw">return false;
      }

      int var9 = this.resolveCraftQuantity(var1, var2, var5, var7, var6);
      if (var9 < 1) {
         class="kw">return false;
      }

      CraftRecipeEvent.Pre var10 = new CraftRecipeEvent.Pre(var5, var9);
      var2.invoke(var1, var10);
      if (var10.isCancelled()) {
         class="kw">return false;
      }

      float var11 = var5.getTimeSeconds();
      if (var11 > 0.0F) {
         int var12 = this.getBenchTierLevel(var2);
         if (var12 > 1) {
            BenchTierLevel var13 = this.getBenchTierLevelData(var12 - 1);
            if (var13 != null) {
               var11 -= var11 * var13.getCraftingTimeReductionModifier();
            }
         }
      }

      boolean var14 = this.queuedCraftingJobs.offer(new CraftingManager.CraftingJob(var3, var4, var5, var9, var11, var7, var8));
      if (!var14) {
         LOGGER.at(Level.WARNING)
            .log(
               "Rejecting crafting job for %s (%s) due to lack of queue capacity (%d, %d, %d) (%d entries)",
               EntityUtils.getEntityName(var1, var2),
               var5.getId(),
               this.x,
               this.y,
               this.z,
               this.queuedCraftingJobs.size()
            );
         class="kw">return false;
      } else {
         class="kw">return true;
      }
   }

   class="kw">private int resolveCraftQuantity(
      @Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2, @Nonnull CraftingRecipe var3, @Nonnull ItemContainer var4, int var5
   ) {
      Player var6 = var2.getComponent(var1, Player.getComponentType());
      boolean var7 = var6 != null && var6.getGameMode() == GameMode.Creative;
      if (!var7) {
         int var8 = getMaterialCraftLimit(var3, var4);
         if (var5 > var8) {
            LOGGER.at(Level.WARNING)
               .log(
                  "Crafting quantity mismatch for %s: asked for %d of %s but %d are craftable", EntityUtils.getEntityName(var1, var2), var5, var3.getId(), var8
               );
         }
      }

      class="kw">return Math.min(var5, getOutputCraftCeiling(var1, var2, var3));
   }

   class="kw">public int getRemainingQueueSize() {
      int var1 = 0;

      for (CraftingManager.CraftingJob var3 : this.queuedCraftingJobs) {
         var1 += var3.quantity - var3.quantityCompleted;
      }

      class="kw">return var1;
   }

   class="kw">public void tick(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2, float var3) {
      if (this.upgradingJob != null) {
         if (var3 > 0.0F) {
            this.upgradingJob.timeSecondsCompleted += var3;
         }

         this.upgradingJob.window.updateBenchUpgradeJob(this.upgradingJob.computeLoadingPercent());
         if (this.upgradingJob.timeSecondsCompleted >= this.upgradingJob.timeSeconds) {
            this.upgradingJob.window.updateBenchTierLevel(this.finishTierUpgrade(var1, var2));
            this.upgradingJob = null;
         }
      } else {
         Player var4 = var2.getComponent(var1, Player.getComponentType());
         assert var4 != null;
         PlayerRef var5 = var2.getComponent(var1, PlayerRef.getComponentType());
         assert var5 != null;

         while (var3 > 0.0F && !this.queuedCraftingJobs.isEmpty()) {
            CraftingManager.CraftingJob var6 = this.queuedCraftingJobs.peek();
            boolean var7 = var4.getGameMode() == GameMode.Creative;
            if (var6 != null && var6.quantityStarted < var6.quantity && var6.quantityStarted <= var6.quantityCompleted) {
               LOGGER.at(Level.FINE).log("Removing Items for next quantity: %s", var6);
               int var8 = var6.quantityStarted++;
               if (!var7 && !removeInputFromInventory(var6, var8)) {
                  String var9 = getRecipeOutputTranslationKey(var6.recipe);
                  if (var9 != null) {
                     NotificationUtil.sendNotification(
                        var5.getPacketHandler(),
                        Message.translation("server.general.crafting.missingIngredient").param("item", Message.translation(var9)),
                        NotificationStyle.Danger
                     );
                  }

                  LOGGER.at(Level.FINE).log("Missing items required to craft the item: %s", var6);
                  this.queuedCraftingJobs.poll();
                  var6.window.updateQueueSize(this.getRemainingQueueSize());
                  if (this.queuedCraftingJobs.isEmpty()) {
                     var6.window.setBlockInteractionState("class="kw">default", var2.getExternalData().getWorld());
                  }

                  var6 = null;
               }

               if (!var7 && var6 != null && var6.quantityStarted < var6.quantity && var6.quantityStarted <= var6.quantityCompleted) {
                  NotificationUtil.sendNotification(
                     var5.getPacketHandler(), Message.translation("server.general.crafting.failedTakingCorrectQuantity"), NotificationStyle.Danger
                  );
                  LOGGER.at(Level.SEVERE).log("Failed to remove the correct quantity of input, removing crafting job %s", var6);
                  this.queuedCraftingJobs.poll();
                  var6.window.updateQueueSize(this.getRemainingQueueSize());
                  if (this.queuedCraftingJobs.isEmpty()) {
                     var6.window.setBlockInteractionState("class="kw">default", var2.getExternalData().getWorld());
                  }

                  var6 = null;
               }
            }

            if (var6 != null) {
               var6.timeSecondsCompleted += var3;
               float var11 = var6.timeSeconds <= 0.0F ? 1.0F : var6.timeSecondsCompleted / var6.timeSeconds;
               if (var11 > 1.0F) {
                  var11 = 1.0F;
               }

               var6.window.updateCraftingJob(var11);
               LOGGER.at(Level.FINEST).log("Update time: %s", var6);
               var3 = 0.0F;
               if (var6.timeSecondsCompleted >= var6.timeSeconds) {
                  var3 = var6.timeSecondsCompleted - var6.timeSeconds;
                  int var12 = var6.quantityCompleted++;
                  var6.timeSecondsCompleted = 0.0F;
                  LOGGER.at(Level.FINE).log("Crafted 1 Quantity: %s", var6);
                  CraftRecipeEvent.Post var10 = new CraftRecipeEvent.Post(var6.recipe, var6.quantity);
                  var2.invoke(var1, var10);
                  if (var6.quantityCompleted == var6.quantity) {
                     if (!var10.isCancelled()) {
                        giveOutput(var1, var2, var6, var12);
                     }

                     LOGGER.at(Level.FINE).log("Crafting Finished: %s", var6);
                     this.queuedCraftingJobs.poll();
                  } else {
                     if (var6.quantityCompleted > var6.quantity) {
                        this.queuedCraftingJobs.poll();
                        throw new RuntimeException("QuantityCompleted is greater than the Quality! " + var6);
                     }

                     if (!var10.isCancelled()) {
                        giveOutput(var1, var2, var6, var12);
                     }
                  }

                  var6.window.updateQueueSize(this.getRemainingQueueSize());
                  if (this.queuedCraftingJobs.isEmpty()) {
                     var6.window.setBlockInteractionState("class="kw">default", var2.getExternalData().getWorld());
                  }
               }
            }
         }
      }
   }

   class="kw">public boolean cancelAllCrafting(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2) {
      LOGGER.at(Level.FINE).log("Cancel Crafting!");
      ObjectList var3 = new ObjectArrayList(this.queuedCraftingJobs.size());
      this.queuedCraftingJobs.drainTo(var3);
      if (!var3.isEmpty()) {
         CraftingManager.CraftingJob var4 = (CraftingManager.CraftingJob)var3.getFirst();
         LOGGER.at(Level.FINE).log("Refunding Items for: %s", var4);
         refundInputToInventory(var1, var2, var4, var4.quantityStarted - 1);
         class="kw">return true;
      } else {
         class="kw">return false;
      }
   }

   class="kw">private boolean isValidBenchForRecipe(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2, @Nonnull CraftingRecipe var3) {
      Player var4 = var2.getComponent(var1, Player.getComponentType());
      assert var4 != null;
      PlayerConfigData var5 = var4.getPlayerConfigData();
      MaterialQuantity var6 = var3.getPrimaryOutput();
      String var7 = var6 != null ? var6.getItemId() : null;
      if (!var3.isKnowledgeRequired() || var7 != null && var5.getKnownRecipes().contains(var7)) {
         World var8 = var2.getExternalData().getWorld();
         if (var3.getRequiredMemoriesLevel() > 1 && MemoriesPlugin.get().getMemoriesLevel(var8.getGameplayConfig()) < var3.getRequiredMemoriesLevel()) {
            LOGGER.at(Level.WARNING).log("Attempted to craft %s but doesn't have the required world memories level!", var3.getId());
            class="kw">return false;
         }

         BenchType var9 = this.blockType != null ? this.blockType.getBench().getType() : BenchType.Crafting;
         String var10 = this.blockType != null ? this.blockType.getBench().getId() : "Fieldcraft";
         boolean var11 = false;
         int var12 = this.getBenchTierLevel(var2);
         BenchRequirement[] var13 = var3.getBenchRequirement();
         if (var13 != null) {
            for (BenchRequirement var17 : var13) {
               if (var17.type == var9 && var10.equals(var17.id) && var17.requiredTierLevel <= var12 && this.benchHasRequiredAugmentTags(var2, var17)) {
                  var11 = true;
                  break;
               }
            }
         }

         if (!var11) {
            LOGGER.at(Level.WARNING).log("Attempted to craft %s using %s, %s but requires bench %s but a bench is NOT set!", var3.getId(), var9, var10, var13);
            class="kw">return false;
         } else if (var9 == BenchType.Crafting && !"Fieldcraft".equals(var10)) {
            CraftingManager.CraftingJob var18 = this.queuedCraftingJobs.peek();
            class="kw">return var18 == null || var18.recipe.getId().equals(var3.getId());
         } else {
            class="kw">return true;
         }
      } else {
         LOGGER.at(Level.WARNING).log("Attempted to craft %s but doesn't know the recipe!", var3.getId());
         class="kw">return false;
      }
   }

   class="kw">private class="kw">static void giveOutput(
      @Nonnull Ref<EntityStore> var0, @Nonnull ComponentAccessor<EntityStore> var1, @Nonnull CraftingManager.CraftingJob var2, int var3
   ) {
      var2.removedItems.remove(var3);
      String var4 = var2.recipe.getId();
      CraftingRecipe var5 = CraftingRecipe.getAssetMap().getAsset(var4);
      if (var5 == null) {
         throw new RuntimeException("A non-existent item ID was provided! " + var4);
      }

      giveOutput(var0, var1, var5, 1);
   }

   class="kw">private class="kw">static void giveOutput(@Nonnull Ref<EntityStore> var0, @Nonnull ComponentAccessor<EntityStore> var1, @Nonnull CraftingRecipe var2, int var3) {
      Player var4 = var1.getComponent(var0, Player.getComponentType());
      if (var4 == null) {
         LOGGER.at(Level.WARNING).log("Attempted to give output to a non-player entity: %s", var0);
      } else {
         List var5 = getOutputItemStacks(var2, var3);
         PlayerSettings var6 = var1.getComponent(var0, PlayerSettings.getComponentType());
         if (var6 == null) {
            var6 = PlayerSettings.defaults();
         }

         for (ItemStack var8 : var5) {
            if (!ItemStack.isEmpty(var8)) {
               ItemContainer var9 = InventoryUtils.getContainerForItemPickup(var0, var8.getItem(), var6, var1);
               SimpleItemContainer.addOrDropItemStack(var1, var0, var9, var8);
            }
         }
      }
   }

   class="kw">private class="kw">static boolean removeInputFromInventory(@Nonnull CraftingManager.CraftingJob var0, int var1) {
      Objects.requireNonNull(var0, "Job can't be null!");
      CraftingRecipe var2 = var0.recipe;
      Objects.requireNonNull(var2, "CraftingRecipe can't be null!");
      List var3 = getInputMaterials(var2);
      if (var3.isEmpty()) {
         class="kw">return true;
      }

      LOGGER.at(Level.FINEST).log("Removing Materials: %s - %s", var0, var3);
      ObjectList var4 = new ObjectArrayList();

      boolean var5 = class="kw">switch (var0.inputRemovalType) {
         case NORMAL -> {
            ListTransaction var11 = var0.inputItemContainer.removeMaterials(var3, true, true, true);

            for (MaterialTransaction var13 : var11.getList()) {
               for (MaterialSlotTransaction var10 : var13.getList()) {
                  if (!ItemStack.isEmpty(var10.getOutput())) {
                     var4.add(var10.getOutput());
                  }
               }
            }

            yield var11.succeeded();
         }
         case ORDERED -> {
            ListTransaction var6 = var0.inputItemContainer.removeMaterialsOrdered(var3, true, true, true);

            for (MaterialSlotTransaction var8 : var6.getList()) {
               if (!ItemStack.isEmpty(var8.getOutput())) {
                  var4.add(var8.getOutput());
               }
            }

            yield var6.succeeded();
         }
         class="kw">default -> throw new IllegalArgumentException("Unknown enum: " + var0.inputRemovalType);
      };
      var0.removedItems.put(var1, var4);
      var0.window.invalidateExtraResources();
      class="kw">return var5;
   }

   class="kw">private class="kw">static boolean removeInputFromInventory(@Nonnull ItemContainer var0, @Nonnull CraftingRecipe var1, int var2) {
      List var3 = getInputMaterials(var1, var2);
      if (var3.isEmpty()) {
         class="kw">return true;
      }

      LOGGER.at(Level.FINEST).log("Removing Materials: %s - %s", var1, var3);
      ListTransaction var4 = var0.removeMaterials(var3, true, true, true);
      class="kw">return var4.succeeded();
   }

   class="kw">private class="kw">static void refundInputToInventory(
      @Nonnull Ref<EntityStore> var0, @Nonnull ComponentAccessor<EntityStore> var1, @Nonnull CraftingManager.CraftingJob var2, int var3
   ) {
      Objects.requireNonNull(var2, "Job can't be null!");
      List var4 = (List<ItemStack>)var2.removedItems.get(var3);
      if (var4 != null) {
         CombinedItemContainer var5 = InventoryComponent.getCombined(var1, var0, InventoryComponent.HOTBAR_FIRST);
         SimpleItemContainer.addOrDropItemStacks(var1, var0, var5, var4);
      }
   }

   @Nonnull
   class="kw">public class="kw">static List<ItemStack> getOutputItemStacks(@Nonnull CraftingRecipe var0) {
      class="kw">return getOutputItemStacks(var0, 1);
   }

   @Nonnull
   class="kw">public class="kw">static List<ItemStack> getOutputItemStacks(@Nonnull CraftingRecipe var0, int var1) {
      Objects.requireNonNull(var0);
      MaterialQuantity[] var2 = var0.getOutputs();
      if (var2 == null) {
         class="kw">return List.of();
      }

      ObjectList var3 = new ObjectArrayList();

      for (MaterialQuantity var7 : var2) {
         ItemStack var8 = getOutputItemStack(var7, var1);
         if (var8 != null) {
            var3.add(var8);
         }
      }

      class="kw">return var3;
   }

   @Nullable
   class="kw">public class="kw">static ItemStack getOutputItemStack(@Nonnull MaterialQuantity var0, @Nonnull String var1) {
      class="kw">return getOutputItemStack(var0, 1);
   }

   @Nullable
   class="kw">public class="kw">static ItemStack getOutputItemStack(@Nonnull MaterialQuantity var0, int var1) {
      String var2 = var0.getItemId();
      if (var2 == null) {
         class="kw">return null;
      }

      int var3 = var0.getQuantity() <= 0 ? 1 : var0.getQuantity();
      class="kw">return new ItemStack(var2, var3 * var1, var0.getMetadata());
   }

   @Nonnull
   class="kw">public class="kw">static List<MaterialQuantity> getInputMaterials(@Nonnull CraftingRecipe var0) {
      class="kw">return getInputMaterials(var0, 1);
   }

   @Nonnull
   class="kw">private class="kw">static List<MaterialQuantity> getInputMaterials(@Nonnull MaterialQuantity[] var0) {
      class="kw">return getInputMaterials(var0, 1);
   }

   @Nonnull
   class="kw">public class="kw">static List<MaterialQuantity> getInputMaterials(@Nonnull CraftingRecipe var0, int var1) {
      Objects.requireNonNull(var0);
      class="kw">return var0.getInput() == null ? Collections.emptyList() : getInputMaterials(var0.getInput(), var1);
   }

   @Nonnull
   class="kw">private class="kw">static List<MaterialQuantity> getInputMaterials(@Nonnull MaterialQuantity[] var0, int var1) {
      ObjectList var2 = new ObjectArrayList();

      for (MaterialQuantity var6 : var0) {
         var2.add(var6.clone(var6.getQuantity() * var1));
      }

      class="kw">return var2;
   }

   class="kw">public class="kw">static boolean matches(@Nonnull MaterialQuantity var0, @Nonnull ItemStack var1) {
      String var2 = var0.getItemId();
      if (var2 != null) {
         class="kw">return var2.equals(var1.getItemId());
      }

      if (var0.isItemExcluded(var1.getItemId())) {
         class="kw">return false;
      }

      String var3 = var0.getResourceTypeId();
      if (var3 != null && var1.getItem().getResourceTypes() != null) {
         for (ItemResourceType var7 : var1.getItem().getResourceTypes()) {
            if (var3.equals(var7.id)) {
               class="kw">return true;
            }
         }
      }

      class="kw">return false;
   }

   @Nonnull
   class="kw">public class="kw">static JsonArray generateInventoryHints(@Nonnull List<CraftingRecipe> var0, int var1, @Nonnull ItemContainer var2) {
      JsonArray var3 = new JsonArray();
      short var4 = 0;

      for (short var5 = var2.getCapacity(); var4 < var5; var4++) {
         ItemStack var6 = var2.getItemStack(var4);
         if (var6 != null && !var6.isEmpty() && matchesAnyRecipe(var0, var1, var6)) {
            var3.add(var4);
         }
      }

      class="kw">return var3;
   }

   class="kw">public class="kw">static boolean matchesAnyRecipe(@Nonnull List<CraftingRecipe> var0, int var1, @Nonnull ItemStack var2) {
      for (CraftingRecipe var4 : var0) {
         MaterialQuantity[] var5 = var4.getInput();
         if (var1 < var5.length && matches(var5[var1], var2)) {
            class="kw">return true;
         }
      }

      class="kw">return false;
   }

   class="kw">private class="kw">static int getMaterialCraftLimit(@Nonnull CraftingRecipe var0, @Nonnull ItemContainer var1) {
      MaterialQuantity[] var2 = var0.getInput();
      if (var2 != null && var2.length != 0) {
         int var3 = Integer.MAX_VALUE;
         boolean var4 = false;

         for (MaterialQuantity var8 : var2) {
            int var9 = var8.getQuantity();
            if (var9 > 0) {
               var4 = true;
               var3 = Math.min(var3, var1.countRemovableMaterial(var8) / var9);
               if (var3 == 0) {
                  break;
               }
            }
         }

         class="kw">return var4 ? var3 : 1;
      } else {
         class="kw">return 1;
      }
   }

   class="kw">private class="kw">static int getOutputCraftCeiling(@Nonnull Ref<EntityStore> var0, @Nonnull ComponentAccessor<EntityStore> var1, @Nonnull CraftingRecipe var2) {
      MaterialQuantity var3 = var2.getPrimaryOutput();
      String var4 = var3 != null ? var3.getItemId() : null;
      if (var4 == null) {
         class="kw">return 1;
      }

      int var5 = Math.max(1, var3.getQuantity());
      Item var6 = Item.getAssetMap().getAsset(var4);
      int var7 = var6 != null ? Math.max(1, var6.getMaxStack()) : 1;
      CombinedItemContainer var8 = InventoryComponent.getCombined(var1, var0, InventoryComponent.BACKPACK_STORAGE_HOTBAR);
      long var9 = (long)var8.getCapacity() * var7;
      class="kw">return (int)Math.max(1L, Math.min(var9 / var5, 2147483647L));
   }

   class="kw">public boolean startTierUpgrade(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2, @Nonnull BenchWindow var3) {
      if (this.upgradingJob != null) {
         class="kw">return false;
      }

      BenchUpgradeRequirement var4 = this.getBenchUpgradeRequirement(this.getBenchTierLevel(var2));
      if (var4 == null) {
         class="kw">return false;
      }

      List var5 = getInputMaterials(var4.getInput());
      if (var5.isEmpty()) {
         class="kw">return false;
      }

      Player var6 = var2.getComponent(var1, Player.getComponentType());
      assert var6 != null;
      if (var6.getGameMode() != GameMode.Creative) {
         CombinedItemContainer var7 = InventoryComponent.getCombined(var2, var1, InventoryComponent.BACKPACK_STORAGE_HOTBAR);
         CombinedItemContainer var8 = new CombinedItemContainer(var7, var3.getExtraResourcesSection().getItemContainer());
         if (!var8.canRemoveMaterials(var5)) {
            class="kw">return false;
         }
      }

      this.upgradingJob = new CraftingManager.BenchUpgradingJob(var3, var4.getTimeSeconds());
      this.cancelAllCrafting(var1, var2);
      class="kw">return true;
   }

   class="kw">private int finishTierUpgrade(@Nonnull Ref<EntityStore> var1, @Nonnull ComponentAccessor<EntityStore> var2) {
      if (this.upgradingJob == null) {
         class="kw">return 0;
      }

      World var3 = var2.getExternalData().getWorld();
      ChunkStore var4 = var3.getChunkStore();
      Ref var5 = var4.getChunkSectionReferenceAtBlock(this.x, this.y, this.z);
      if (var5 != null && var5.isValid()) {
         Ref var6 = BlockModule.getBlockEntity(var4.getStore(), var5, this.x, this.y, this.z);
         if (var6 == null) {
            class="kw">return 0;
         }

         BlockModule.BlockStateInfo var7 = var4.getStore().getComponent(var6, BlockModule.BlockStateInfo.getComponentType());
         if (var7 == null) {
            class="kw">return 0;
         }

         BenchBlock var8 = var4.getStore().getComponent(var6, BenchBlock.getComponentType());
         if (var8 != null && var8.getTierLevel() != 0) {
            BenchUpgradeRequirement var9 = this.getBenchUpgradeRequirement(var8.getTierLevel());
            if (var9 == null) {
               class="kw">return var8.getTierLevel();
            }

            List var10 = getInputMaterials(var9.getInput());
            if (var10.isEmpty()) {
               class="kw">return var8.getTierLevel();
            }

            Player var11 = var2.getComponent(var1, Player.getComponentType());
            assert var11 != null;
            boolean var12 = var11.getGameMode() == GameMode.Creative;
            if (!var12) {
               CombinedItemContainer var13 = InventoryComponent.getCombined(var2, var1, InventoryComponent.BACKPACK_STORAGE_HOTBAR);
               CombinedItemContainer var14 = new CombinedItemContainer(var13, this.upgradingJob.window.getExtraResourcesSection().getItemContainer());
               ListTransaction var15 = var14.removeMaterials(var10);
               if (var15.succeeded()) {
                  List var16 = new ObjectArrayList();

                  for (MaterialTransaction var18 : var15.getList()) {
                     for (MaterialSlotTransaction var20 : var18.getList()) {
                        var16.add(var20.getOutput());
                     }
                  }

                  var8.addUpgradeItems(var16);
                  var7.markNeedsSaving();
                  var12 = true;
               }
            }

            if (var12) {
               var8.setTierLevel(var8.getTierLevel() + 1);
               var7.markNeedsSaving();
               BlockSection var21 = var4.getStore().getComponent(var5, BlockSection.getComponentType());
               assert var21 != null;
               BlockType var22 = BenchBlock.getBaseBlockType(this.blockType);
               BlockOperations.setBlockInteractionState(var4, var5, this.x, this.y, this.z, var22, var8.getTierStateName(), true);
               ProcessingBenchBlock var23 = var4.getStore().getComponent(var6, ProcessingBenchBlock.getComponentType());
               if (var23 != null) {
                  int var24 = var21.getRotationIndex(this.x, this.y, this.z);
                  var23.setupSlots(var3, var8, var7, this.x, this.y, this.z, this.blockType, var24);
               }

               int var25 = var21.get(this.x, this.y, this.z);
               BlockType var26 = BlockType.getAssetMap().getAsset(var25);
               if (var26 != null && var26.getBench().getBenchUpgradeCompletedSoundEventIndex() != 0) {
                  SoundUtil.playSoundEvent3d(
                     var26.getBench().getBenchUpgradeCompletedSoundEventIndex(), SoundCategory.SFX, this.x + 0.5, this.y + 0.5, this.z + 0.5, var2
                  );
               }
            }

            class="kw">return var8.getTierLevel();
         } else {
            class="kw">return 0;
         }
      } else {
         class="kw">return 0;
      }
   }

   @Nullable
   class="kw">private BenchTierLevel getBenchTierLevelData(int var1) {
      if (this.blockType == null) {
         class="kw">return null;
      }

      Bench var2 = this.blockType.getBench();
      class="kw">return var2 == null ? null : var2.getTierLevel(var1);
   }

   @Nullable
   class="kw">private BenchUpgradeRequirement getBenchUpgradeRequirement(int var1) {
      BenchTierLevel var2 = this.getBenchTierLevelData(var1);
      class="kw">return var2 == null ? null : var2.getUpgradeRequirement();
   }

   class="kw">private int getBenchTierLevel(@Nonnull ComponentAccessor<EntityStore> var1) {
      World var2 = var1.getExternalData().getWorld();
      ChunkStore var3 = var2.getChunkStore();
      Ref var4 = BlockModule.getBlockEntity(var2, this.x, this.y, this.z);
      if (var4 == null) {
         class="kw">return 0;
      }

      BenchBlock var5 = var3.getStore().getComponent(var4, BenchBlock.getComponentType());
      class="kw">return var5 != null && var5.getTierLevel() != 0 ? var5.getTierLevel() : 0;
   }

   class="kw">private boolean benchHasRequiredAugmentTags(@Nonnull ComponentAccessor<EntityStore> var1, @Nonnull BenchRequirement var2) {
      String[] var3 = var2.requiredAugmentTags;
      if (var3 != null && var3.length != 0) {
         Set var4 = this.getBenchGrantedAugmentTags(var1);

         for (String var8 : var3) {
            if (!var4.contains(var8)) {
               class="kw">return false;
            }
         }

         class="kw">return true;
      } else {
         class="kw">return true;
      }
   }

   @Nonnull
   class="kw">private Set<String> getBenchGrantedAugmentTags(@Nonnull ComponentAccessor<EntityStore> var1) {
      World var2 = var1.getExternalData().getWorld();
      ChunkStore var3 = var2.getChunkStore();
      Ref var4 = BlockModule.getBlockEntity(var2, this.x, this.y, this.z);
      if (var4 == null) {
         class="kw">return Set.of();
      }

      BenchBlock var5 = var3.getStore().getComponent(var4, BenchBlock.getComponentType());
      if (var5 == null) {
         class="kw">return Set.of();
      }

      BenchBlock.refreshGrantedAugmentTags(var3.getStore(), var4, new Vector3i(this.x, this.y, this.z));
      class="kw">return var5.getGrantedAugmentTags();
   }

   class="kw">public class="kw">static int feedExtraResourcesSection(
      @Nonnull World var0,
      int var1,
      int var2,
      int var3,
      @Nonnull BlockType var4,
      int var5,
      @Nonnull Bench var6,
      int var7,
      @Nonnull MaterialExtraResourcesSection var8
   ) {
      CraftingManager.ChestLookupResult var9 = getContainersAroundBench(var0, var1, var2, var3, var4, var5);
      List var10 = var9.containers;
      List var11 = var9.states;
      ItemContainer var12 = EmptyItemContainer.INSTANCE;
      if (!var10.isEmpty()) {
         var12 = new CombinedItemContainer(var10.stream().map(var0x -> {
            DelegateItemContainer var1 = new DelegateItemContainer<>(var0x);
            var1.setGlobalFilter(FilterType.ALLOW_OUTPUT_ONLY);
            class="kw">return var1;
         }).toArray(ItemContainer[]::new));
      }

      Map var13 = new Object2ObjectOpenHashMap();

      for (ItemContainer var15 : var10) {
         var15.forEach((var3x, var4x) -> {
            if (CraftingPlugin.isValidUpgradeMaterialForBench(var6, var7, var4x) || CraftingPlugin.isValidCraftingMaterialForBench(var6, var4x)) {
               ItemQuantity var10000 = var13.computeIfAbsent(var4x.getItemId(), var1x -> new ItemQuantity(var4x.getItemId(), 0));
               var10000.quantity = var10000.quantity + var4x.getQuantity();
            }
         });
      }

      var8.setItemContainer(var12);
      var8.setExtraMaterials(var13.values().toArray(new ItemQuantity[0]));
      var8.setValid(true);
      class="kw">return var11.size();
   }

   @Nonnull
   class="kw">protected class="kw">static CraftingManager.ChestLookupResult getContainersAroundBench(
      @Nonnull World var0, int var1, int var2, int var3, @Nonnull BlockType var4, int var5
   ) {
      List var6 = new ObjectArrayList();
      List var7 = new ObjectArrayList();
      List var8 = new ObjectArrayList();
      Store var9 = var0.getChunkStore().getStore();
      int var10 = var0.getGameplayConfig().getCraftingConfig().getBenchMaterialChestLimit();
      double var11 = var0.getGameplayConfig().getCraftingConfig().getBenchMaterialHorizontalChestSearchRadius();
      double var13 = var0.getGameplayConfig().getCraftingConfig().getBenchMaterialVerticalChestSearchRadius();
      Vector3d var15 = new Vector3d(var1, var2, var3);
      BlockBoundingBoxes var16 = BlockBoundingBoxes.getAssetMap().getAsset(var4.getHitboxTypeIndex());
      BlockBoundingBoxes.RotatedVariantBoxes var17 = var16.get(var5);
      Box var18 = var17.getBoundingBox();
      double var19 = var18.width();
      double var21 = var18.height();
      double var23 = var18.depth();
      double var25 = Math.max(var19, Math.max(var23, var21)) - 1.0;
      SpatialResource var27 = var9.getResource(BlockModule.get().getItemContainerSpatialResourceType());
      List var28 = SpatialResource.getThreadLocalReferenceList();
      var27.getSpatialStructure().ordered3DAxis(var15, var11 + var25, var13 + var25, var11 + var25, var28);
      if (!var28.isEmpty()) {
         int var29 = (int)Math.floor(var18.min.x);
         int var30 = (int)Math.floor(var18.min.y);
         int var31 = (int)Math.floor(var18.min.z);
         int var32 = (int)Math.ceil(var18.max.x) - 1;
         int var33 = (int)Math.ceil(var18.max.y) - 1;
         int var34 = (int)Math.ceil(var18.max.z) - 1;
         double var35 = var15.x + var29 - var11;
         double var37 = var15.y + var30 - var13;
         double var39 = var15.z + var31 - var11;
         double var41 = var15.x + var32 + var11;
         double var43 = var15.y + var33 + var13;
         double var45 = var15.z + var34 + var11;

         for (Ref var48 : var28) {
            if (var48.isValid()) {
               ItemContainerBlock var49 = var9.getComponent(var48, ItemContainerBlock.getComponentType());
               if (var49 != null) {
                  BlockModule.BlockStateInfo var50 = var9.getComponent(var48, BlockModule.BlockStateInfo.getComponentType());
                  if (var50 != null) {
                     ChunkSection var51 = var9.getComponent(var50.getSectionRef(), ChunkSection.getComponentType());
                     if (var51 != null) {
                        int var52 = ChunkUtil.worldCoordFromLocalCoord(var51.getX(), ChunkUtil.xFromIndex(var50.getIndex()));
                        int var53 = ChunkUtil.worldCoordFromLocalCoord(var51.getY(), ChunkUtil.yFromIndex(var50.getIndex()));
                        int var54 = ChunkUtil.worldCoordFromLocalCoord(var51.getZ(), ChunkUtil.zFromIndex(var50.getIndex()));
                        if (var52 >= var35 && var52 <= var41 && var53 >= var37 && var53 <= var43 && var54 >= var39 && var54 <= var45) {
                           var6.add(var49.getItemContainer());
                           var7.add(var49);
                           if (var6.size() >= var10) {
                              break;
                           }
                        } else {
                           var8.add(var49);
                        }
                     }
                  }
               }
            }
         }
      }

      class="kw">return new CraftingManager.ChestLookupResult(var6, var7, var8, var15);
   }

   @Nonnull
   @Override
   class="kw">public String toString() {
      class="kw">return "CraftingManager{queuedCraftingJobs="
         + this.queuedCraftingJobs
         + ", x="
         + this.x
         + ", y="
         + this.y
         + ", z="
         + this.z
         + ", blockType="
         + this.blockType
         + "}";
   }

   @Nonnull
   @Override
   class="kw">public Component<EntityStore> clone() {
      class="kw">return new CraftingManager(this);
   }

   class="kw">private class="kw">static class BenchUpgradingJob {
      @Nonnull
      class="kw">private class="kw">final BenchWindow window;
      class="kw">private class="kw">final float timeSeconds;
      class="kw">private float timeSecondsCompleted;
      class="kw">private float lastSentPercent;

      class="kw">private BenchUpgradingJob(@Nonnull BenchWindow var1, float var2) {
         this.window = var1;
         this.timeSeconds = var2;
      }

      @Nonnull
      @Override
      class="kw">public String toString() {
         class="kw">return "BenchUpgradingJob{window=" + this.window + ", timeSeconds=" + this.timeSeconds + "}";
      }

      class="kw">public float computeLoadingPercent() {
         class="kw">return this.timeSeconds <= 0.0F ? 1.0F : Math.min(this.timeSecondsCompleted / this.timeSeconds, 1.0F);
      }
   }

   class="kw">protected record ChestLookupResult(
      List<ItemContainer> containers, List<ItemContainerBlock> states, List<ItemContainerBlock> filteredOut, Vector3d benchCenteredPos
   ) {
      class="kw">protected ChestLookupResult {
      }
   }

   class="kw">private class="kw">static class CraftingJob {
      @Nonnull
      class="kw">private class="kw">final CraftingWindow window;
      class="kw">private class="kw">final int transactionId;
      @Nonnull
      class="kw">private class="kw">final CraftingRecipe recipe;
      class="kw">private class="kw">final int quantity;
      class="kw">private class="kw">final float timeSeconds;
      @Nonnull
      class="kw">private class="kw">final ItemContainer inputItemContainer;
      @Nonnull
      class="kw">private class="kw">final CraftingManager.InputRemovalType inputRemovalType;
      @Nonnull
      class="kw">private class="kw">final Int2ObjectMap<List<ItemStack>> removedItems = new Int2ObjectOpenHashMap();
      class="kw">private int quantityStarted;
      class="kw">private int quantityCompleted;
      class="kw">private float timeSecondsCompleted;

      class="kw">public CraftingJob(
         @Nonnull CraftingWindow var1,
         int var2,
         @Nonnull CraftingRecipe var3,
         int var4,
         float var5,
         @Nonnull ItemContainer var6,
         @Nonnull CraftingManager.InputRemovalType var7
      ) {
         this.window = var1;
         this.transactionId = var2;
         this.recipe = var3;
         this.quantity = var4;
         this.timeSeconds = var5;
         this.inputItemContainer = var6;
         this.inputRemovalType = var7;
      }

      @Nonnull
      @Override
      class="kw">public String toString() {
         class="kw">return "CraftingJob{window="
            + this.window
            + ", transactionId="
            + this.transactionId
            + ", recipe="
            + this.recipe
            + ", quantity="
            + this.quantity
            + ", timeSeconds="
            + this.timeSeconds
            + ", inputItemContainer="
            + this.inputItemContainer
            + ", inputRemovalType="
            + this.inputRemovalType
            + ", removedItems="
            + this.removedItems
            + ", quantityStarted="
            + this.quantityStarted
            + ", quantityCompleted="
            + this.quantityCompleted
            + ", timeSecondsCompleted="
            + this.timeSecondsCompleted
            + "}";
      }
   }

   class="kw">public enum InputRemovalType {
      NORMAL,
      ORDERED;

      InputRemovalType() {
      }
   }
}