use of com.minecolonies.coremod.colony.interactionhandling.StandardInteraction in project minecolonies by ldtteam.
the class EntityAIWorkSifter method sift.
/**
* The sifting process.
*
* @return the next AiState to go to.
*/
protected IAIState sift() {
final BuildingSifter sifterBuilding = getOwnBuilding();
// Go idle if we can't do any more today
if (sifterBuilding.getCurrentDailyQuantity() >= sifterBuilding.getMaxDailyQuantity()) {
return IDLE;
}
if (walkToBuilding()) {
return getState();
}
if (InventoryUtils.isItemHandlerFull(worker.getInventoryCitizen())) {
return INVENTORY_FULL;
}
if (currentRecipeStorage == null) {
final ICraftingBuildingModule module = getOwnBuilding().getFirstModuleOccurance(BuildingSifter.CraftingModule.class);
currentRecipeStorage = module.getFirstFulfillableRecipe(ItemStackUtils::isEmpty, 1, false);
}
if (currentRecipeStorage == null) {
if (InventoryUtils.getCountFromBuilding(sifterBuilding, i -> ModTags.meshes.contains(i.getItem())) == 0) {
if (InventoryUtils.getItemCountInProvider(worker, i -> ModTags.meshes.contains(i.getItem())) > 0) {
// We don't want the mesh in our inventory, we 'craft' out of the building
incrementActionsDone();
return INVENTORY_FULL;
}
if (worker.getCitizenData() != null) {
worker.getCitizenData().triggerInteraction(new StandardInteraction(new TranslationTextComponent(SIFTER_NO_MESH), ChatPriority.IMPORTANT));
setDelay(NO_MESH_DELAY);
}
}
if (!ItemStackUtils.isEmpty(worker.getMainHandItem())) {
worker.setItemInHand(Hand.MAIN_HAND, ItemStack.EMPTY);
}
if (!ItemStackUtils.isEmpty(worker.getOffhandItem())) {
worker.setItemInHand(Hand.OFF_HAND, ItemStack.EMPTY);
}
progress = 0;
return START_WORKING;
}
final ItemStack meshItem = currentRecipeStorage.getCraftingTools().get(0);
final ItemStack inputItem = currentRecipeStorage.getCleanedInput().stream().map(ItemStorage::getItemStack).filter(item -> !ItemStackUtils.compareItemStacksIgnoreStackSize(item, meshItem, false, true)).findFirst().orElse(ItemStack.EMPTY);
if (meshItem.isEmpty() || inputItem.isEmpty()) {
currentRecipeStorage = null;
return getState();
}
if (!inputItem.isEmpty() && (ItemStackUtils.isEmpty(worker.getMainHandItem()) || ItemStackUtils.compareItemStacksIgnoreStackSize(worker.getMainHandItem(), inputItem))) {
worker.setItemInHand(Hand.MAIN_HAND, inputItem);
}
if (!meshItem.isEmpty() && (ItemStackUtils.isEmpty(worker.getOffhandItem()) || ItemStackUtils.compareItemStacksIgnoreStackSize(worker.getOffhandItem(), meshItem, false, true))) {
worker.setItemInHand(Hand.OFF_HAND, meshItem);
}
WorkerUtil.faceBlock(getOwnBuilding().getPosition(), worker);
progress++;
if (progress > MAX_LEVEL - (getEffectiveSkillLevel(getSecondarySkillLevel()) / 2)) {
progress = 0;
sifterBuilding.setCurrentDailyQuantity(sifterBuilding.getCurrentDailyQuantity() + 1);
if (sifterBuilding.getCurrentDailyQuantity() >= sifterBuilding.getMaxDailyQuantity() || worker.getRandom().nextInt(ONE_HUNDRED_PERCENT) < CHANCE_TO_DUMP_INV) {
incrementActionsDoneAndDecSaturation();
}
if (!currentRecipeStorage.fullfillRecipe(getLootContext(), sifterBuilding.getHandlers())) {
currentRecipeStorage = null;
return getState();
}
worker.decreaseSaturationForContinuousAction();
worker.getCitizenExperienceHandler().addExperience(0.2);
}
Network.getNetwork().sendToTrackingEntity(new LocalizedParticleEffectMessage(meshItem, sifterBuilding.getID()), worker);
Network.getNetwork().sendToTrackingEntity(new LocalizedParticleEffectMessage(inputItem, sifterBuilding.getID().below()), worker);
worker.swing(Hand.MAIN_HAND);
SoundUtils.playSoundAtCitizen(world, getOwnBuilding().getID(), SoundEvents.LEASH_KNOT_BREAK);
return getState();
}
use of com.minecolonies.coremod.colony.interactionhandling.StandardInteraction in project minecolonies by Minecolonies.
the class AbstractEntityAIBasic method onException.
@Override
protected void onException(final RuntimeException e) {
worker.getCitizenData().triggerInteraction(new StandardInteraction(new TranslationTextComponent(WORKER_AI_EXCEPTION), ChatPriority.BLOCKING));
try {
final int timeout = EXCEPTION_TIMEOUT * exceptionTimer;
this.setDelay(FMLEnvironment.production ? timeout : EXCEPTION_TIMEOUT);
// wait for longer now
exceptionTimer *= 2;
if (worker != null) {
final String name = this.worker.getName().getString();
final BlockPos workerPosition = worker.blockPosition();
final IJob<?> colonyJob = worker.getCitizenJobHandler().getColonyJob();
final String jobName = colonyJob == null ? "null" : colonyJob.getJobRegistryEntry().getTranslationKey();
Log.getLogger().error("Pausing Entity " + name + " (" + jobName + ") at " + workerPosition + " for " + timeout + " Seconds because of error:");
} else {
Log.getLogger().error("Pausing Entity that is null for " + timeout + " Seconds because of error:");
}
// fix for printing the actual exception
e.printStackTrace();
} catch (final RuntimeException exp) {
Log.getLogger().error("Welp reporting crashed:");
exp.printStackTrace();
Log.getLogger().error("Caused by ai exception:");
e.printStackTrace();
}
}
use of com.minecolonies.coremod.colony.interactionhandling.StandardInteraction in project minecolonies by Minecolonies.
the class AbstractEntityAIBasic method dumpInventory.
/**
* Walk to building and dump inventory. If inventory is dumped, continue execution so that the state can be resolved.
*
* @return INVENTORY_FULL | IDLE
*/
@NotNull
private IAIState dumpInventory() {
final IBuilding building = getBuildingToDump();
if (building == null) {
// Uh oh, that shouldn't happen. Restart AI.
return afterDump();
}
if (!worker.isWorkerAtSiteWithMove(building.getPosition(), DEFAULT_RANGE_FOR_DELAY)) {
setDelay(WALK_DELAY);
return INVENTORY_FULL;
}
if (InventoryUtils.isProviderFull(building)) {
final ICitizenData citizenData = worker.getCitizenData();
if (citizenData != null) {
citizenData.triggerInteraction(new StandardInteraction(new TranslationTextComponent(COM_MINECOLONIES_COREMOD_ENTITY_WORKER_INVENTORYFULLCHEST), ChatPriority.IMPORTANT));
}
// Note that this will not create a pickup request when another request is already in progress.
if (building.getPickUpPriority() > 0) {
building.createPickupRequest(getMaxBuildingPriority(true));
hasDumpedItems = false;
}
alreadyKept.clear();
slotAt = 0;
this.clearActionsDone();
return afterDump();
} else if (dumpOneMoreSlot()) {
return INVENTORY_FULL;
}
alreadyKept.clear();
slotAt = 0;
this.clearActionsDone();
if (isAfterDumpPickupAllowed() && building.getPickUpPriority() > 0 && hasDumpedItems) {
// Worker is not currently crafting, pickup is allowed.
// Note that this will not create a pickup request when another request is already in progress.
building.createPickupRequest(scaledPriority(building.getPickUpPriority()));
hasDumpedItems = false;
}
return afterDump();
}
use of com.minecolonies.coremod.colony.interactionhandling.StandardInteraction in project minecolonies by Minecolonies.
the class AbstractEntityAIRequestSmelter method fillUpFurnace.
/**
* Smelt the smeltable after the required items are in the inv.
*
* @return the next state to go to.
*/
private IAIState fillUpFurnace() {
final FurnaceUserModule module = building.getFirstModuleOccurance(FurnaceUserModule.class);
if (module.getFurnaces().isEmpty()) {
if (worker.getCitizenData() != null) {
worker.getCitizenData().triggerInteraction(new StandardInteraction(new TranslationTextComponent(BAKER_HAS_NO_FURNACES_MESSAGE), ChatPriority.BLOCKING));
}
setDelay(STANDARD_DELAY);
return START_WORKING;
}
if (walkTo == null || world.getBlockState(walkTo).getBlock() != Blocks.FURNACE) {
walkTo = null;
setDelay(STANDARD_DELAY);
return START_WORKING;
}
final int burningCount = countOfBurningFurnaces();
final TileEntity entity = world.getBlockEntity(walkTo);
if (entity instanceof FurnaceTileEntity && currentRecipeStorage != null) {
final FurnaceTileEntity furnace = (FurnaceTileEntity) entity;
final int maxFurnaces = getMaxUsableFurnaces();
final Predicate<ItemStack> smeltable = stack -> ItemStackUtils.compareItemStacksIgnoreStackSize(currentRecipeStorage.getCleanedInput().get(0).getItemStack(), stack);
final int smeltableInFurnaces = getExtendedCount(currentRecipeStorage.getCleanedInput().get(0).getItemStack());
final int resultInFurnaces = getExtendedCount(currentRecipeStorage.getPrimaryOutput());
final int resultInCitizenInv = InventoryUtils.getItemCountInItemHandler(worker.getInventoryCitizen(), stack -> ItemStackUtils.compareItemStacksIgnoreStackSize(stack, currentRecipeStorage.getPrimaryOutput()));
final int targetCount = currentRequest.getRequest().getCount() - smeltableInFurnaces - resultInFurnaces - resultInCitizenInv;
if (targetCount <= 0) {
return START_WORKING;
}
final int amountOfSmeltableInBuilding = InventoryUtils.getCountFromBuilding(building, smeltable);
final int amountOfSmeltableInInv = InventoryUtils.getItemCountInItemHandler(worker.getInventoryCitizen(), smeltable);
if (worker.getItemInHand(Hand.MAIN_HAND).isEmpty()) {
worker.setItemInHand(Hand.MAIN_HAND, currentRecipeStorage.getCleanedInput().get(0).getItemStack().copy());
}
if (amountOfSmeltableInInv > 0) {
if (hasFuelInFurnaceAndNoSmeltable(furnace) || hasNeitherFuelNorSmeltAble(furnace)) {
int toTransfer = 0;
if (burningCount < maxFurnaces) {
final int availableFurnaces = maxFurnaces - burningCount;
if (targetCount > STACKSIZE * availableFurnaces) {
toTransfer = STACKSIZE;
} else {
// We need to split stacks and spread them across furnaces for best performance
// We will front-load the remainder
toTransfer = Math.min((targetCount / availableFurnaces) + (targetCount % availableFurnaces), STACKSIZE);
}
}
if (toTransfer > 0) {
if (walkToBlock(walkTo)) {
return getState();
}
worker.getCitizenItemHandler().hitBlockWithToolInHand(walkTo);
InventoryUtils.transferXInItemHandlerIntoSlotInItemHandler(worker.getInventoryCitizen(), smeltable, toTransfer, new InvWrapper(furnace), SMELTABLE_SLOT);
}
}
} else if (amountOfSmeltableInBuilding >= targetCount - amountOfSmeltableInInv && currentRecipeStorage.getIntermediate() == Blocks.FURNACE) {
needsCurrently = new Tuple<>(smeltable, targetCount);
return GATHERING_REQUIRED_MATERIALS;
} else {
// This is a safety net for the AI getting way out of sync with it's tracking. It shouldn't happen.
job.finishRequest(false);
resetValues();
walkTo = null;
return IDLE;
}
} else if (!(world.getBlockState(walkTo).getBlock() instanceof FurnaceBlock)) {
module.removeFromFurnaces(walkTo);
}
walkTo = null;
setDelay(STANDARD_DELAY);
return START_WORKING;
}
use of com.minecolonies.coremod.colony.interactionhandling.StandardInteraction in project minecolonies by Minecolonies.
the class AbstractEntityAIRequestSmelter method getActivePossibleFuels.
/**
* Get the list of possible fuels, adjusted for any inputs/outputs of the current recipe to avoid interference
*/
private List<ItemStack> getActivePossibleFuels() {
final List<ItemStack> possibleFuels = getAllowedFuel();
if (possibleFuels.isEmpty()) {
if (worker.getCitizenData() != null) {
worker.getCitizenData().triggerInteraction(new StandardInteraction(new TranslationTextComponent(FURNACE_USER_NO_FUEL), ChatPriority.IMPORTANT));
}
return ImmutableList.of();
}
if (currentRecipeStorage != null) {
possibleFuels.removeIf(stack -> ItemStackUtils.compareItemStacksIgnoreStackSize(stack, currentRecipeStorage.getPrimaryOutput()));
// There is always only one input.
possibleFuels.removeIf(stack -> ItemStackUtils.compareItemStacksIgnoreStackSize(stack, currentRecipeStorage.getCleanedInput().get(0).getItemStack()));
}
return possibleFuels;
}
Aggregations