use of com.minecolonies.api.colony.requestsystem.requestable.deliveryman.Delivery in project minecolonies by Minecolonies.
the class EntityAIWorkDeliveryman method prepareDelivery.
/**
* Prepare deliveryman for delivery. Check if the building still needs the item and if the required items are still in the warehouse.
*
* @return the next state to go to.
*/
private IAIState prepareDelivery() {
final IRequest<? extends IRequestable> currentTask = job.getCurrentTask();
if (!(currentTask instanceof DeliveryRequest)) {
// Restart.
return START_WORKING;
}
final List<IRequest<? extends Delivery>> taskList = job.getTaskListWithSameDestination((IRequest<? extends Delivery>) currentTask);
final List<ItemStack> alreadyInInv = new ArrayList<>();
IRequest<? extends Delivery> nextPickUp = null;
int parallelDeliveryCount = 0;
for (final IRequest<? extends Delivery> task : taskList) {
parallelDeliveryCount++;
int totalCount = InventoryUtils.getItemCountInItemHandler(worker.getInventoryCitizen(), itemStack -> ItemStackUtils.compareItemStacksIgnoreStackSize(task.getRequest().getStack(), itemStack));
int hasCount = 0;
for (final ItemStack stack : alreadyInInv) {
if (ItemStackUtils.compareItemStacksIgnoreStackSize(stack, task.getRequest().getStack())) {
hasCount += stack.getCount();
}
}
if (totalCount < hasCount + task.getRequest().getStack().getCount()) {
nextPickUp = task;
break;
} else {
alreadyInInv.add(task.getRequest().getStack());
}
}
if (nextPickUp == null || parallelDeliveryCount > 1 + (getSecondarySkillLevel() / 5)) {
return DELIVERY;
}
final ILocation location = nextPickUp.getRequest().getStart();
if (!location.isReachableFromLocation(worker.getLocation())) {
job.finishRequest(false);
return START_WORKING;
}
if (walkToBlock(location.getInDimensionLocation())) {
return PREPARE_DELIVERY;
}
if (getInventory().isFull()) {
return DUMPING;
}
final TileEntity tileEntity = world.getBlockEntity(location.getInDimensionLocation());
job.addConcurrentDelivery(nextPickUp.getId());
if (gatherIfInTileEntity(tileEntity, nextPickUp.getRequest().getStack())) {
return PREPARE_DELIVERY;
}
if (parallelDeliveryCount > 1) {
job.removeConcurrentDelivery(nextPickUp.getId());
return DELIVERY;
}
job.finishRequest(false);
job.removeConcurrentDelivery(nextPickUp.getId());
return START_WORKING;
}
use of com.minecolonies.api.colony.requestsystem.requestable.deliveryman.Delivery in project minecolonies by Minecolonies.
the class JobDeliveryman method getTaskListWithSameDestination.
/**
* Build a list of all requests that have the same source/dest pair.
*
* @param request the first request.
* @return a list.
*/
public List<IRequest<? extends Delivery>> getTaskListWithSameDestination(final IRequest<? extends Delivery> request) {
final List<IRequest<? extends Delivery>> deliveryList = new ArrayList<>();
deliveryList.add(request);
for (final IToken<?> requestToken : getTaskQueue()) {
if (!requestToken.equals(request.getId())) {
final IRequest<?> compareRequest = getColony().getRequestManager().getRequestForToken(requestToken);
if (compareRequest != null && compareRequest.getRequest() instanceof Delivery) {
final Delivery current = (Delivery) compareRequest.getRequest();
final Delivery newDev = request.getRequest();
if (haveTasksSameSourceAndDest(current, newDev)) {
deliveryList.add((IRequest<? extends Delivery>) compareRequest);
}
}
}
}
return deliveryList;
}
use of com.minecolonies.api.colony.requestsystem.requestable.deliveryman.Delivery in project minecolonies by Minecolonies.
the class EntityAIWorkDeliveryman method deliver.
/**
* Deliver the items to the hut. TODO: Current precondition: The dman's inventory may only consist of the requested itemstack.
*
* @return the next state.
*/
private IAIState deliver() {
final IRequest<? extends IDeliverymanRequestable> currentTask = job.getCurrentTask();
if (!(currentTask instanceof DeliveryRequest)) {
// Since prepareDelivery() was called earlier, go dumping first and then restart.
return DUMPING;
}
worker.getCitizenData().setVisibleStatus(DELIVERING);
worker.getCitizenStatusHandler().setLatestStatus(new TranslationTextComponent("com.minecolonies.coremod.status.delivering"));
final ILocation targetBuildingLocation = ((Delivery) currentTask.getRequest()).getTarget();
if (!targetBuildingLocation.isReachableFromLocation(worker.getLocation())) {
Log.getLogger().info(worker.getCitizenColonyHandler().getColony().getName() + ": " + worker.getName() + ": Can't inter dimension yet: ");
return START_WORKING;
}
if (!worker.isWorkerAtSiteWithMove(targetBuildingLocation.getInDimensionLocation(), MIN_DISTANCE_TO_WAREHOUSE)) {
setDelay(WALK_DELAY);
return DELIVERY;
}
final TileEntity tileEntity = world.getBlockEntity(targetBuildingLocation.getInDimensionLocation());
if (!(tileEntity instanceof TileEntityColonyBuilding)) {
// TODO: Non-Colony deliveries are unsupported yet. Fix that at some point in time.
job.finishRequest(true);
return START_WORKING;
}
final IBuilding targetBuilding = ((AbstractTileEntityColonyBuilding) tileEntity).getBuilding();
boolean success = true;
boolean extracted = false;
final IItemHandler workerInventory = worker.getInventoryCitizen();
final List<ItemStorage> itemsToDeliver = job.getTaskListWithSameDestination((IRequest<? extends Delivery>) currentTask).stream().map(r -> new ItemStorage(r.getRequest().getStack())).collect(Collectors.toList());
for (int i = 0; i < workerInventory.getSlots(); i++) {
if (workerInventory.getStackInSlot(i).isEmpty()) {
continue;
}
if (!itemsToDeliver.contains(new ItemStorage(workerInventory.getStackInSlot(i)))) {
continue;
}
final ItemStack stack = workerInventory.extractItem(i, Integer.MAX_VALUE, false);
if (ItemStackUtils.isEmpty(stack)) {
continue;
}
extracted = true;
final ItemStack insertionResultStack;
// TODO: Please only push items into the target that were actually requested.
if (targetBuilding instanceof AbstractBuilding) {
insertionResultStack = InventoryUtils.forceItemStackToItemHandler(targetBuilding.getCapability(ITEM_HANDLER_CAPABILITY, null).orElseGet(null), stack, ((IBuilding) targetBuilding)::isItemStackInRequest);
} else {
// Buildings that are not inherently part of the request system, but just receive a delivery, cannot have their items replaced.
// Therefore, the keep-predicate always returns true.
insertionResultStack = InventoryUtils.forceItemStackToItemHandler(targetBuilding.getCapability(ITEM_HANDLER_CAPABILITY, null).orElseGet(null), stack, itemStack -> true);
}
if (!ItemStackUtils.isEmpty(insertionResultStack)) {
if (ItemStack.matches(insertionResultStack, stack) && worker.getCitizenData() != null) {
// The replaced stack is the same as the one we tried to put into the inventory.
// Meaning, replacing failed.
success = false;
if (targetBuilding.hasModule(WorkerBuildingModule.class)) {
worker.getCitizenData().triggerInteraction(new PosBasedInteraction(new TranslationTextComponent(COM_MINECOLONIES_COREMOD_JOB_DELIVERYMAN_NAMEDCHESTFULL, targetBuilding.getFirstModuleOccurance(WorkerBuildingModule.class).getFirstCitizen().getName()), ChatPriority.IMPORTANT, new TranslationTextComponent(COM_MINECOLONIES_COREMOD_JOB_DELIVERYMAN_CHESTFULL), targetBuilding.getID()));
} else {
worker.getCitizenData().triggerInteraction(new PosBasedInteraction(new TranslationTextComponent(COM_MINECOLONIES_COREMOD_JOB_DELIVERYMAN_CHESTFULL, new StringTextComponent(" :" + targetBuilding.getSchematicName())), ChatPriority.IMPORTANT, new TranslationTextComponent(COM_MINECOLONIES_COREMOD_JOB_DELIVERYMAN_CHESTFULL), targetBuildingLocation.getInDimensionLocation()));
}
}
// Insert the result back into the inventory so we do not lose it.
workerInventory.insertItem(i, insertionResultStack, false);
}
}
if (!extracted) {
// This can only happen if the dman's inventory was completely empty.
// Let the retry-system handle this case.
worker.decreaseSaturationForContinuousAction();
worker.getCitizenItemHandler().setHeldItem(Hand.MAIN_HAND, SLOT_HAND);
job.finishRequest(false);
// No need to go dumping in this case.
return START_WORKING;
}
worker.getCitizenExperienceHandler().addExperience(1.5D);
worker.decreaseSaturationForContinuousAction();
worker.getCitizenItemHandler().setHeldItem(Hand.MAIN_HAND, SLOT_HAND);
job.finishRequest(true);
return success ? START_WORKING : DUMPING;
}
use of com.minecolonies.api.colony.requestsystem.requestable.deliveryman.Delivery in project minecolonies by Minecolonies.
the class BuildingDeliveryman method canEat.
@Override
public boolean canEat(final ItemStack stack) {
final ICitizenData citizenData = getFirstModuleOccurance(WorkerBuildingModule.class).getFirstCitizen();
if (citizenData != null) {
final JobDeliveryman job = (JobDeliveryman) citizenData.getJob();
final IRequest<? extends IRequestable> currentTask = job.getCurrentTask();
if (currentTask == null) {
return super.canEat(stack);
}
final IRequestable request = currentTask.getRequest();
if (request instanceof Delivery && ((Delivery) request).getStack().sameItem(stack)) {
return false;
}
}
return super.canEat(stack);
}
use of com.minecolonies.api.colony.requestsystem.requestable.deliveryman.Delivery in project minecolonies by ldtteam.
the class BuildingDeliveryman method canEat.
@Override
public boolean canEat(final ItemStack stack) {
final ICitizenData citizenData = getFirstModuleOccurance(WorkerBuildingModule.class).getFirstCitizen();
if (citizenData != null) {
final JobDeliveryman job = (JobDeliveryman) citizenData.getJob();
final IRequest<? extends IRequestable> currentTask = job.getCurrentTask();
if (currentTask == null) {
return super.canEat(stack);
}
final IRequestable request = currentTask.getRequest();
if (request instanceof Delivery && ((Delivery) request).getStack().sameItem(stack)) {
return false;
}
}
return super.canEat(stack);
}
Aggregations