Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent the cookery from keeping all empty bottles #10367

Open
wants to merge 5 commits into
base: version/main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/main/java/com/minecolonies/api/colony/buildings/IBuilding.java
Original file line number Diff line number Diff line change
Expand Up @@ -356,10 +356,21 @@ <R> ImmutableList<IRequest<? extends R>> getOpenRequestsOfTypeFiltered(
* Creates a pickup request for the building. It will make sure that only one pickup request exists per building, so it's safe to call multiple times. The call will return
* false if a pickup request already exists, or if the priority is not within the proper range, or if the pickup priority is set to NEVER (0).
*
* @param pickUpPrio The priority of the pickup request.
* @param priority the priority of the pickup request.
* @return true if a pickup request could be created, false if not.
*/
boolean createPickupRequest(final int pickUpPrio);
boolean createPickupRequest(final int priority);

/**
* Creates a pickup request for the building. It will make sure that only one pickup request exists per building, so it's safe to call multiple times. The call will return
* false if a pickup request already exists, or if the priority is not within the proper range, or if the pickup priority is set to NEVER (0).
* This overload features a filter that can be used to only pick up the one given item stack and ignore the rest.
*
* @param priority the priority of the pickup request.
* @param pickupFilter the item stacks to filter for this specific pickup.
* @return true if a pickup request could be created, false if not.
*/
boolean createPickupRequest(final int priority, final @Nullable List<ItemStack> pickupFilter);

@Override
ImmutableCollection<IRequestResolver<?>> getResolvers();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,58 +5,137 @@
import com.minecolonies.api.util.ReflectionUtils;
import com.minecolonies.api.util.constant.TypeConstants;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;

/**
* Class used to represent pickups inside the request system. This class can be used to request a pickup of
*/
public class Pickup extends AbstractDeliverymanRequestable
{
////// --------------------------- NBTConstants --------------------------- \\\\\\
protected static final String NBT_PICKUP_FILTER = "Filter";
////// --------------------------- NBTConstants --------------------------- \\\\\\

/**
* Set of type tokens belonging to this class.
*/
private final static Set<TypeToken<?>>
TYPE_TOKENS = ReflectionUtils.getSuperClasses(TypeToken.of(Pickup.class)).stream().filter(type -> !type.equals(TypeConstants.OBJECT)).collect(Collectors.toSet());

/**
* The itemstack to filter for this specific pickup.
*/
@Nullable
private List<ItemStack> pickupFilter;

/**
* Constructor for Delivery requests
*
* @param priority The priority of the request.
* @param priority the priority of the request.
* @param filter a filter to apply to the pickup request.
*/
public Pickup(final int priority)
public Pickup(final int priority, final @Nullable List<ItemStack> filter)
{
super(priority);
if (filter != null)
{
this.pickupFilter = filter.stream().map(ItemStack::copy).collect(Collectors.toList());
}
}

/**
* Get the itemstack to filter for this specific pickup.
*
* @return the itemstack or null.
*/
@Nullable
public List<ItemStack> getPickupFilter()
{
return pickupFilter;
}

/**
* Add or update a pickup filter.
*
* @param stacks the input stacks.
*/
public void addToPickupFilter(final List<ItemStack> stacks)
{
if (pickupFilter == null)
{
pickupFilter = stacks;
}
else
{
pickupFilter.addAll(stacks);
}
}

@NotNull
public static CompoundTag serialize(@NotNull final IFactoryController controller, final Pickup pickup)
{
final CompoundTag compound = new CompoundTag();
compound.put(NBT_PRIORITY, controller.serialize(pickup.getPriority()));
if (pickup.getPickupFilter() != null)
{
final ListTag listTag = new ListTag();
for (final ItemStack itemStack : pickup.getPickupFilter())
{
listTag.add(itemStack.save(new CompoundTag()));
}
compound.put(NBT_PICKUP_FILTER, listTag);
}
return compound;
}

@NotNull
public static Pickup deserialize(@NotNull final IFactoryController controller, @NotNull final CompoundTag compound)
{
final int priority = controller.deserialize(compound.getCompound(NBT_PRIORITY));
return new Pickup(priority);
final List<ItemStack> pickupFilter;
if (compound.contains(NBT_PICKUP_FILTER))
{
pickupFilter = new ArrayList<>();
final ListTag list = compound.getList(NBT_PICKUP_FILTER, Tag.TAG_COMPOUND);
for (int i = 0; i < list.size(); i++)
{
pickupFilter.add(ItemStack.of(list.getCompound(i)));
}
}
else
{
pickupFilter = null;
}
return new Pickup(priority, pickupFilter);
}

/**
* Serialize the deliverable.
*
* @param controller the controller.
* @param buffer the the buffer to write to.
* @param buffer the buffer to write to.
* @param input the input to serialize.
*/
public static void serialize(final IFactoryController controller, final FriendlyByteBuf buffer, final Pickup input)
{
buffer.writeInt(input.getPriority());
buffer.writeBoolean(input.getPickupFilter() != null);
if (input.getPickupFilter() != null)
{
buffer.writeInt(input.getPickupFilter().size());
for (final ItemStack itemStack : input.getPickupFilter())
{
buffer.writeItem(itemStack);
}
}
}

/**
Expand All @@ -69,8 +148,21 @@ public static void serialize(final IFactoryController controller, final Friendly
public static Pickup deserialize(final IFactoryController controller, final FriendlyByteBuf buffer)
{
final int priority = buffer.readInt();

return new Pickup(priority);
final List<ItemStack> pickupFilter;
if (buffer.readBoolean())
{
pickupFilter = new ArrayList<>();
final int itemCount = buffer.readInt();
for (int i = 0; i < itemCount; i++)
{
pickupFilter.add(buffer.readItem());
}
}
else
{
pickupFilter = null;
}
return new Pickup(priority, pickupFilter);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import com.minecolonies.core.colony.requestsystem.management.IStandardRequestManager;
import com.minecolonies.core.colony.requestsystem.requesters.BuildingBasedRequester;
import com.minecolonies.core.colony.requestsystem.requests.StandardRequests;
import com.minecolonies.core.colony.requestsystem.requests.StandardRequests.PickupRequest;
import com.minecolonies.core.colony.requestsystem.resolvers.BuildingRequestResolver;
import com.minecolonies.core.colony.workorders.WorkOrderBuilding;
import com.minecolonies.core.entity.ai.workers.service.EntityAIWorkDeliveryman;
Expand Down Expand Up @@ -1518,9 +1519,15 @@ public <R> ImmutableList<IRequest<? extends R>> getOpenRequestsOfType(
}

@Override
public boolean createPickupRequest(final int pickUpPrio)
public boolean createPickupRequest(final int priority)
{
int daysToPickup = 10 - pickUpPrio;
return createPickupRequest(priority, null);
}

@Override
public boolean createPickupRequest(final int priority, final @Nullable List<ItemStack> pickupFilter)
{
int daysToPickup = 10 - priority;
if (pickUpDay == -1 || pickUpDay > colony.getDay() + daysToPickup)
{
pickUpDay = colony.getDay() + daysToPickup;
Expand All @@ -1546,12 +1553,17 @@ public boolean createPickupRequest(final int pickUpPrio)
{
colony.getRequestManager().reassignRequest(req, Collections.emptyList());
}

if (request instanceof PickupRequest pickup && pickupFilter != null)
{
pickup.getRequest().addToPickupFilter(pickupFilter);
}
}
}
return false;
}

createRequest(new Pickup(pickUpPrio), true);
createRequest(new Pickup(priority, pickupFilter), true);
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,11 @@ protected IAIState craft()
module.improveRecipe(currentRecipeStorage, job.getCraftCounter(), worker.getCitizenData());
}

if (!currentRecipeStorage.getSecondaryOutputs().isEmpty())
{
building.createPickupRequest(10, currentRecipeStorage.getSecondaryOutputs());
}

currentRecipeStorage = null;
resetValues();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.stream.Collectors;

import static com.minecolonies.api.entity.ai.statemachine.states.AIWorkerState.*;
Expand Down Expand Up @@ -144,7 +145,7 @@ private IAIState pickup()
setDelay(WALK_DELAY);
final IRequest<? extends IDeliverymanRequestable> currentTask = job.getCurrentTask();

if (!(currentTask instanceof PickupRequest))
if (!(currentTask instanceof PickupRequest pickupRequest))
{
// The current task has changed since the Decision-state. Restart.
return START_WORKING;
Expand Down Expand Up @@ -172,7 +173,7 @@ private IAIState pickup()
return PICKUP;
}

if (pickupFromBuilding(pickupBuilding))
if (pickupFromBuilding(pickupBuilding, pickupRequest))
{
this.alreadyKept = new ArrayList<>();
this.currentSlot = 0;
Expand Down Expand Up @@ -203,9 +204,10 @@ else if (InventoryUtils.openSlotCount(worker.getInventoryCitizen()) <= 0)
* Gather not needed Items from building.
*
* @param building building to gather it from.
* @param request the pickup request.
* @return true when finished.
*/
private boolean pickupFromBuilding(@NotNull final IBuilding building)
private boolean pickupFromBuilding(@NotNull final IBuilding building, final PickupRequest request)
{
if (cannotHoldMoreItems() || InventoryUtils.openSlotCount(worker.getInventoryCitizen()) <= 0)
{
Expand Down Expand Up @@ -241,20 +243,49 @@ private boolean pickupFromBuilding(@NotNull final IBuilding building)
return false;
}

if (ItemStackUtils.isEmpty(handler.getStackInSlot(currentSlot)))
if (request.getRequest().getPickupFilter() != null)
{
return false;
final ListIterator<ItemStack> iterator = request.getRequest().getPickupFilter().listIterator();
while (iterator.hasNext())
{
final ItemStack filter = iterator.next();
if (ItemStackUtils.compareItemStacksIgnoreStackSize(stack, filter))
{
final ItemStack activeStack = handler.extractItem(currentSlot, filter.getCount(), false);
transferItemForPickup(activeStack);
if (filter.getCount() == activeStack.getCount())
{
iterator.remove();
}
else
{
iterator.set(filter.copyWithCount(filter.getCount() - activeStack.getCount()));
}
}
}
}
else
{
final ItemStack activeStack = handler.extractItem(currentSlot, amount, false);
transferItemForPickup(activeStack);
}
return false;
}

final ItemStack activeStack = handler.extractItem(currentSlot, amount, false);
InventoryUtils.transferItemStackIntoNextBestSlotInItemHandler(activeStack, worker.getInventoryCitizen());
/**
* Transfer an item to the courier for pickup.
*
* @param stack the stack to transfer.
*/
private void transferItemForPickup(final ItemStack stack)
{
InventoryUtils.transferItemStackIntoNextBestSlotInItemHandler(stack, worker.getInventoryCitizen());
building.markDirty();
worker.decreaseSaturationForContinuousAction();

// The worker gets a little bit of exp for every itemstack he grabs.
worker.getCitizenExperienceHandler().addExperience(0.01D);
CitizenItemUtils.setHeldItem(worker, InteractionHand.MAIN_HAND, SLOT_HAND);
return false;
}

/**
Expand Down
Loading