use of com.minecolonies.api.entity.ai.statemachine.states.IAIState in project minecolonies by Minecolonies.
the class EntityAIWorkLumberjack method findTree.
/**
* Search for a tree.
*
* @return LUMBERJACK_GATHERING if job was canceled.
*/
private IAIState findTree() {
final BuildingLumberjack building = getOwnBuilding();
worker.getCitizenData().setVisibleStatus(SEARCH);
if (pathResult != null && pathResult.isComputing()) {
return getState();
}
if (pathResult == null) {
if (building.shouldRestrict()) {
final BlockPos startPos = building.getStartRestriction();
final BlockPos endPos = building.getEndRestriction();
pathResult = worker.getNavigation().moveToTree(startPos, endPos, 1.0D, building.getModuleMatching(ItemListModule.class, m -> m.getId().equals(SAPLINGS_LIST)).getList(), building.getSetting(BuildingLumberjack.DYNAMIC_TREES_SIZE).getValue(), worker.getCitizenColonyHandler().getColony());
} else {
pathResult = worker.getNavigation().moveToTree(SEARCH_RANGE + searchIncrement, 1.0D, building.getModuleMatching(ItemListModule.class, m -> m.getId().equals(SAPLINGS_LIST)).getList(), building.getSetting(BuildingLumberjack.DYNAMIC_TREES_SIZE).getValue(), worker.getCitizenColonyHandler().getColony());
}
return getState();
}
if (pathResult.isDone()) {
return setNewTree(building);
}
// None of the above yielded a result, report no trees found.
return LUMBERJACK_NO_TREES_FOUND;
}
use of com.minecolonies.api.entity.ai.statemachine.states.IAIState in project minecolonies by Minecolonies.
the class EntityAIWorkPlanter method decide.
@Override
protected IAIState decide() {
final IAIState nextState = super.decide();
if (nextState != START_WORKING && nextState != IDLE) {
return nextState;
}
final BuildingPlantation plantation = getOwnBuilding();
final List<BlockPos> list = plantation.getPosForPhase();
for (final BlockPos pos : list) {
if (isAtLeastThreeHigh(pos)) {
this.workPos = pos;
return PLANTATION_FARM;
}
}
final Item current = plantation.nextPlantPhase();
final int plantInBuilding = InventoryUtils.getCountFromBuilding(getOwnBuilding(), itemStack -> itemStack.sameItem(new ItemStack(current)));
final int plantInInv = InventoryUtils.getItemCountInItemHandler((worker.getInventoryCitizen()), itemStack -> itemStack.sameItem(new ItemStack(current)));
if (plantInBuilding + plantInInv <= 0) {
requestPlantable(current);
return START_WORKING;
}
if (plantInInv == 0 && plantInBuilding > 0) {
needsCurrently = new Tuple<>(itemStack -> itemStack.sameItem(new ItemStack(current)), Math.min(plantInBuilding, PLANT_TO_REQUEST));
return GATHERING_REQUIRED_MATERIALS;
}
for (final BlockPos pos : list) {
if (world.getBlockState(pos.above()).getBlock() instanceof AirBlock) {
this.workPos = pos;
return PLANTATION_PLANT;
}
}
return START_WORKING;
}
use of com.minecolonies.api.entity.ai.statemachine.states.IAIState in project minecolonies by Minecolonies.
the class AbstractEntityAIRequestSmelter method getRecipe.
@Override
protected IAIState getRecipe() {
final IRequest<? extends PublicCrafting> currentTask = job.getCurrentTask();
if (currentTask == null) {
worker.setItemInHand(Hand.MAIN_HAND, ItemStackUtils.EMPTY);
return START_WORKING;
}
job.setMaxCraftingCount(currentTask.getRequest().getCount());
final BlockPos furnacePosWithUsedFuel = getPositionOfOvenToRetrieveFuelFrom();
if (furnacePosWithUsedFuel != null) {
currentRequest = currentTask;
walkTo = furnacePosWithUsedFuel;
return RETRIEVING_USED_FUEL_FROM_FURNACE;
}
final BlockPos furnacePos = getPositionOfOvenToRetrieveFrom();
if (furnacePos != null) {
currentRequest = currentTask;
walkTo = furnacePos;
return RETRIEVING_END_PRODUCT_FROM_FURNACE;
}
if (currentRecipeStorage != null && currentRecipeStorage.getIntermediate() == Blocks.FURNACE) {
for (final BlockPos pos : getOwnBuilding().getFirstModuleOccurance(FurnaceUserModule.class).getFurnaces()) {
final TileEntity entity = world.getBlockEntity(pos);
if (entity instanceof FurnaceTileEntity) {
final FurnaceTileEntity furnace = (FurnaceTileEntity) entity;
if (furnace.isLit() || !isEmpty(furnace.getItem(RESULT_SLOT)) || !isEmpty(furnace.getItem(SMELTABLE_SLOT))) {
if (furnace.isLit()) {
setDelay(TICKS_20);
}
return CRAFT;
}
}
}
}
final IAIState newState = super.getRecipe();
final ItemListModule module = getOwnBuilding().getModuleMatching(ItemListModule.class, m -> m.getId().equals(FUEL_LIST));
// This should only happen in the stonesmelter, but it could potentially happen with multiple fuels.
if (newState == QUERY_ITEMS && currentRecipeStorage != null && module.isItemInList(new ItemStorage(currentRecipeStorage.getPrimaryOutput()))) {
job.setCraftCounter(0);
}
return newState;
}
use of com.minecolonies.api.entity.ai.statemachine.states.IAIState in project minecolonies by Minecolonies.
the class AbstractEntityAIRequestSmelter method checkForItems.
@Override
protected IAIState checkForItems(@NotNull final IRecipeStorage storage) {
if (storage.getIntermediate() != Blocks.FURNACE) {
return super.checkForItems(storage);
}
final List<ItemStorage> input = storage.getCleanedInput();
final int countInFurnaces = getExtendedCount(storage.getPrimaryOutput());
int outputInInv = InventoryUtils.getItemCountInItemHandler(worker.getInventoryCitizen(), stack -> ItemStackUtils.compareItemStacksIgnoreStackSize(stack, storage.getPrimaryOutput()));
for (final ItemStorage inputStorage : input) {
final Predicate<ItemStack> predicate = stack -> !ItemStackUtils.isEmpty(stack) && ItemStackUtils.compareItemStacksIgnoreStackSize(stack, inputStorage.getItemStack());
int inputInFurnace = getExtendedCount(inputStorage.getItemStack());
int inputInInv = InventoryUtils.getItemCountInItemHandler(worker.getInventoryCitizen(), predicate);
if (countInFurnaces + inputInFurnace + inputInInv + outputInInv < inputStorage.getAmount() * job.getMaxCraftingCount()) {
if (InventoryUtils.hasItemInProvider(getOwnBuilding(), predicate)) {
needsCurrently = new Tuple<>(predicate, inputStorage.getAmount() * (job.getMaxCraftingCount() - countInFurnaces - inputInFurnace));
return GATHERING_REQUIRED_MATERIALS;
}
}
// if we don't have enough at all, cancel
int countOfInput = inputInInv + InventoryUtils.getCountFromBuilding(getOwnBuilding(), predicate) + countInFurnaces + inputInFurnace + outputInInv;
if (countOfInput < inputStorage.getAmount() * job.getMaxCraftingCount()) {
job.finishRequest(false);
resetValues();
}
}
return CRAFT;
}
use of com.minecolonies.api.entity.ai.statemachine.states.IAIState 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 = getOwnBuilding().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(getOwnBuilding(), 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;
}
Aggregations