Skip to content

Commit

Permalink
feat: deliverer falls back to other chests if priority full
Browse files Browse the repository at this point in the history
  • Loading branch information
t2pellet committed Jul 1, 2024
1 parent 9c50c05 commit 44481ef
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ static <E extends Entity & ICapabilityHaver> Deliverer getInstance(E entity) {

BlockPos getDeliverPos();
void setPriorityPos(BlockPos pos);

void deliver(BlockPos pos);

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,14 @@
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.Container;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.gameevent.GameEvent;

import java.util.Comparator;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.*;

public class DelivererImpl<E extends LivingEntity & ICapabilityHaver> extends AbstractCapability<E> implements Deliverer {

Expand Down Expand Up @@ -56,7 +53,6 @@ public void setPriorityPos(BlockPos pos) {
}
priorityContainer = pos;
}

}

private void clearData() {
Expand All @@ -66,14 +62,19 @@ private void clearData() {
}

private Optional<BlockPos> closestRememberedValidDeliverable() {
if (priorityContainer != null && VisibilityUtil.canSee(entity, priorityContainer) && ContainerUtil.isContainer(entity.level, priorityContainer)) {
if (priorityContainer != null && canDeliverToPos(entity.level, priorityContainer)) {
return Optional.of(priorityContainer);
}
return containerSet.stream()
.filter(p -> VisibilityUtil.canSee(entity, p) && ContainerUtil.isContainer(entity.level, p))
.filter(p -> canDeliverToPos(entity.level, p))
.min(Comparator.comparingDouble(p -> p.distManhattan(entity.blockPosition())));
}

private boolean canDeliverToPos(LevelAccessor level, BlockPos pos) {
ItemStack deliveringStack = entity.getMainHandItem();
return VisibilityUtil.canSee(entity, pos) && ContainerUtil.isContainer(level, pos) && !ContainerUtil.findSlotsInContainer(level, pos, deliveringStack).isEmpty();
}

private BlockPos scanForDeliverable(BlockPos query) {
for (int x = -24; x <= 24; ++x) {
for (int y = -12; y <= 12; ++y) {
Expand All @@ -91,33 +92,23 @@ private BlockPos scanForDeliverable(BlockPos query) {

@Override
public void deliver(BlockPos pos) {
ItemStack stack = entity.getItemInHand(InteractionHand.MAIN_HAND).copy();
ItemStack stack = entity.getMainHandItem().copy();
// Need an item to deliver
if (!stack.isEmpty()) {
// Deliver what we can to the container if it exists
if (ContainerUtil.isContainer(entity.level, pos)) {
Container container = (Container) entity.level.getBlockEntity(pos);
for (int i = 0; i < container.getContainerSize(); ++i) {
ItemStack containerStack = container.getItem(i);
if (containerStack.isEmpty()) {
container.setItem(i, stack);
stack = ItemStack.EMPTY;
} else if (containerStack.is(stack.getItem())) {
int placeableCount = containerStack.getMaxStackSize() - containerStack.getCount();
int placingCount = Math.min(stack.getCount(), placeableCount);
containerStack.grow(placingCount);
stack.shrink(placingCount);
}
if (stack.isEmpty()) break;
List<Integer> slots = ContainerUtil.findSlotsInContainer(entity.level, pos, stack);
if (!slots.isEmpty()) {
ContainerUtil.addToContainer(entity.level, pos, stack, slots);
}
// Drop remaining items
entity.level.addFreshEntity(new ItemEntity(entity.level, pos.getX(), pos.getY() + 1, pos.getZ(), stack));
entity.setItemInHand(InteractionHand.MAIN_HAND, ItemStack.EMPTY);
// Interactions
entity.level.gameEvent(entity, GameEvent.CONTAINER_OPEN, pos);
entity.level.playSound(null, pos, SoundEvents.CHEST_CLOSE, SoundSource.BLOCKS, 1.0F, 1.0F);
entity.level.gameEvent(entity, GameEvent.CONTAINER_CLOSE, pos);
}
// Drop remaining stack as ItemEntity
entity.level.addFreshEntity(new ItemEntity(entity.level, pos.getX(), pos.getY() + 1, pos.getZ(), stack));
entity.setItemInHand(InteractionHand.MAIN_HAND, ItemStack.EMPTY);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,56 @@

import net.minecraft.core.BlockPos;
import net.minecraft.world.Container;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.ChestBlock;
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;

public class ContainerUtil {

private ContainerUtil() {}

public static boolean isContainer(LevelAccessor level, BlockPos pos) {
return pos != null && level.getBlockEntity(pos) instanceof RandomizableContainerBlockEntity;
public static boolean isContainer(@NotNull LevelAccessor level, BlockPos pos) {
return pos != null && level.getBlockEntity(pos) instanceof Container;
}

public static List<Integer> findSlotsInContainer(@NotNull LevelAccessor level, @NotNull BlockPos pos, @Nullable ItemStack stack) {
Container container = (Container) level.getBlockEntity(pos);
Item itemToPut = stack != null ? stack.getItem() : null;
List<Integer> list = new ArrayList<>();
for (int i = 0; i < container.getContainerSize(); ++i) {
ItemStack item = container.getItem(i);
if (itemToPut != null && item.is(itemToPut) && item.getMaxStackSize() > item.getCount()) {
list.add(i);
} else if (item.isEmpty()) {
list.add(i);
}
}
return list;
}

public static int addToContainer(@NotNull LevelAccessor level, @NotNull BlockPos pos, @NotNull ItemStack stack, List<Integer> slots) {
Container container = (Container) level.getBlockEntity(pos);
int oldStackSize = stack.getCount();
for (int slot : slots) {
if (stack.isEmpty()) break;
ItemStack containerStack = container.getItem(slot);
if (containerStack.isEmpty()) {
container.setItem(slot, stack.copy());
stack.setCount(0);
return oldStackSize;
} else {
int canGrow = containerStack.getMaxStackSize() - containerStack.getCount();
int toGrow = Math.min(stack.getCount(), canGrow);
containerStack.grow(toGrow);
stack.shrink(toGrow);
}
}
return stack.getCount() - oldStackSize;
}

}

0 comments on commit 44481ef

Please sign in to comment.