-
Notifications
You must be signed in to change notification settings - Fork 1
Vanilla Code Paths
gniftygnome edited this page Mar 8, 2022
·
2 revisions
The following discussion was developed using Yarn mappings.
Relevant variables:
private long lastTickTime;
private int transferCooldown;World ticking calls the following method:
public static void serverTick(World world, BlockPos pos, BlockState state, HopperBlockEntity blockEntity) {
// decrement transferCooldown
// set lastTickTime to world.getTime(); <----------------------------------- TICK TIME JUST BEFORE INSERT/EXTRACT
// check if cooldown is NOT needed and if so:
// set the processing hopper's transferCooldown to 0
// call insertAndExtractHopperBlockEntity.insertAndExtract:
private static boolean insertAndExtract(World world, BlockPos pos, BlockState state, HopperBlockEntity blockEntity, BooleanSupplier booleanSupplier) {
// abort if running in the client (world)
// if the the processing hopper still don't need a cooldown and is not disabled:
// if the processing hopper's inventory is NOT empty, try to insert to the target block entity
// if the processing hopper's inventory is NOT full, try to extract (tries any Inventory directly above, tries gathering items)
// if either above transfer succeeded:
// set the processing hopper's transferCooldown to 8 <-------------- LOCAL COOLDOWN (can be EITHER source OR target)
// mark the processing hopper's inventory as dirty using HopperBlockEntity.markDirty(world, pos, state)There are several implementations of extract and insert but it turns out we are only interested in the case where those functions may set a cooldown for another hopper besides the one doing the processing, so the important implementation is the innermost private transfer method. Note in the method below the processing hopper may be either the source or the target.
HopperBlockEntity.transfer: (the one transfer implementation we care about)
private static ItemStack transfer(@Nullable Inventory from, Inventory to, ItemStack stack, int slot, @Nullable Direction side) {
// if the source (as a hopper) can insert into an inventory found at the target location:
// if the target slot is empty, just set it
// if the target slot is not empty, move as much of the requested amount (practically always 1) as possible
// if either of the above moved anything, AND the target is a HopperBlockEntity AND the target is not disabled:
// set k to 0
// if the source is also a HopperBlockEntity:
// if the target's lastTickTime is >= the source's lastTickTime (see [[Transfer Analysis]]):
// set k to 1
// set the target's transferCooldown to (8 - k) <------------------- DESTINATION COOLDOWN (k is 0 or 1)
// if either of the above moved anything:
// call the target's markDirty