use of com.minecolonies.api.entity.ai.statemachine.states.IAIState in project minecolonies by Minecolonies.
the class EntityAIConcreteMixer method mixConcrete.
/**
* Mix the concrete and mine it.
*
* @return next state.
*/
private IAIState mixConcrete() {
int slot = -1;
if (currentRequest != null && currentRecipeStorage != null) {
ItemStack inputStack = currentRecipeStorage.getCleanedInput().get(0).getItemStack();
if (CONCRETE.test(inputStack)) {
slot = InventoryUtils.findFirstSlotInItemHandlerWith(worker.getInventoryCitizen(), s -> ItemStackUtils.compareItemStacksIgnoreStackSize(s, inputStack));
} else {
return START_WORKING;
}
} else {
slot = InventoryUtils.findFirstSlotInItemHandlerWith(worker.getInventoryCitizen(), CONCRETE);
}
if (slot != -1) {
final ItemStack stack = worker.getInventoryCitizen().getStackInSlot(slot);
final Block block = ((BlockItem) stack.getItem()).getBlock();
final BlockPos posToPlace = building.getBlockToPlace();
if (posToPlace != null) {
if (walkToBlock(posToPlace)) {
walkTo = posToPlace;
return START_WORKING;
}
walkTo = null;
if (InventoryUtils.attemptReduceStackInItemHandler(worker.getInventoryCitizen(), stack, 1)) {
world.setBlock(posToPlace, block.defaultBlockState().updateShape(Direction.DOWN, block.defaultBlockState(), world, posToPlace, posToPlace), 0x03);
}
return START_WORKING;
}
}
final BlockPos pos = building.getBlockToMine();
if (pos != null) {
if (walkToBlock(pos)) {
walkTo = pos;
return START_WORKING;
}
walkTo = null;
if (mineBlock(pos)) {
this.resetActionsDone();
return CRAFT;
}
return START_WORKING;
}
if (InventoryUtils.hasItemInItemHandler(building.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElseGet(null), CONCRETE)) {
needsCurrently = new Tuple<>(CONCRETE, STACKSIZE);
return GATHERING_REQUIRED_MATERIALS;
} else {
incrementActionsDone();
}
return START_WORKING;
}
use of com.minecolonies.api.entity.ai.statemachine.states.IAIState in project minecolonies by Minecolonies.
the class EntityAIWorkCook method checkForImportantJobs.
/**
* Checks if the cook has anything important to do before going to the default furnace user jobs. First calculate the building range if not cached yet. Then check for citizens
* around the building. If no citizen around switch to default jobs. If citizens around check if food in inventory, if not, switch to gather job. If food in inventory switch to
* serve job.
*
* @return the next IAIState to transfer to.
*/
@Override
protected IAIState checkForImportantJobs() {
// Clear the cache of current pending work
this.reservedItemCache.clear();
citizenToServe.clear();
final List<AbstractEntityCitizen> citizenList = WorldUtil.getEntitiesWithinBuilding(world, AbstractEntityCitizen.class, building, null).stream().filter(cit -> !(cit.getCitizenJobHandler().getColonyJob() instanceof JobCook) && cit.shouldBeFed() && !InventoryUtils.hasItemInItemHandler(cit.getItemHandlerCitizen(), stack -> CAN_EAT.test(stack) && canEat(stack, cit))).sorted(Comparator.comparingInt(a -> (a.getCitizenJobHandler().getColonyJob() == null ? 1 : 0))).collect(Collectors.toList());
final List<PlayerEntity> playerList = WorldUtil.getEntitiesWithinBuilding(world, PlayerEntity.class, building, player -> player != null && player.getFoodData().getFoodLevel() < LEVEL_TO_FEED_PLAYER && building.getColony().getPermissions().hasPermission(player, Action.MANAGE_HUTS));
playerToServe.addAll(playerList);
boolean hasFoodInBuilding = false;
for (final AbstractEntityCitizen citizen : citizenList) {
final Predicate<ItemStack> foodPredicate = stack -> ItemStackUtils.CAN_EAT.test(stack) && !isItemStackForAssistant(stack) && canEat(stack, citizen);
if (InventoryUtils.hasItemInItemHandler(worker.getInventoryCitizen(), foodPredicate)) {
citizenToServe.add(citizen);
} else {
if (InventoryUtils.hasItemInProvider(building, foodPredicate)) {
hasFoodInBuilding = true;
needsCurrently = new Tuple<>(foodPredicate, STACKSIZE);
}
}
}
if (!citizenToServe.isEmpty()) {
return COOK_SERVE_FOOD_TO_CITIZEN;
}
if (hasFoodInBuilding) {
return GATHERING_REQUIRED_MATERIALS;
}
return START_WORKING;
}
use of com.minecolonies.api.entity.ai.statemachine.states.IAIState in project minecolonies by Minecolonies.
the class EntityAIWorkCook method serveFoodToCitizen.
/**
* Serve food to customer
* <p>
* If no customer, transition to START_WORKING. If we need to walk to the customer, repeat this state with tiny delay. If the customer has a full inventory, report and remove
* customer, delay and repeat this state. If we have food, then COOK_SERVE. If no food in the building, transition to START_WORKING. If we were able to get the stored food,
* then COOK_SERVE. If food is no longer available, delay and transition to START_WORKING. Otherwise, give the customer some food, then delay and repeat this state.
*
* @return next IAIState
*/
private IAIState serveFoodToCitizen() {
worker.getCitizenStatusHandler().setLatestStatus(new TranslationTextComponent(TranslationConstants.COM_MINECOLONIES_COREMOD_STATUS_SERVING));
if (citizenToServe.isEmpty() && playerToServe.isEmpty()) {
return START_WORKING;
}
worker.getCitizenData().setVisibleStatus(COOK);
final Entity living = citizenToServe.isEmpty() ? playerToServe.get(0) : citizenToServe.get(0);
if (!building.isInBuilding(living.blockPosition())) {
worker.getNavigation().stop();
removeFromQueue();
return START_WORKING;
}
if (walkToBlock(new BlockPos(living.position()))) {
return getState();
}
final IItemHandler handler = citizenToServe.isEmpty() ? new InvWrapper(playerToServe.get(0).inventory) : citizenToServe.get(0).getInventoryCitizen();
if (InventoryUtils.isItemHandlerFull(handler)) {
if (!citizenToServe.isEmpty()) {
final int foodSlot = InventoryUtils.findFirstSlotInItemHandlerWith(worker.getInventoryCitizen(), stack -> ItemStackUtils.CAN_EAT.test(stack) && canEat(stack, citizenToServe.isEmpty() ? null : citizenToServe.get(0)));
if (foodSlot != -1) {
final ItemStack stack = worker.getInventoryCitizen().extractItem(foodSlot, 1, false);
if (stack.getItem().isEdible()) {
citizenToServe.get(0).getCitizenData().increaseSaturation(stack.getItem().getFoodProperties().getNutrition() / 2.0);
}
}
}
removeFromQueue();
return getState();
} else if (InventoryUtils.hasItemInItemHandler(handler, stack -> CAN_EAT.test(stack) && canEat(stack, citizenToServe.isEmpty() ? null : citizenToServe.get(0)))) {
removeFromQueue();
return getState();
}
if (!InventoryUtils.transferFoodUpToSaturation(worker, handler, building.getBuildingLevel() * SATURATION_TO_SERVE, stack -> CAN_EAT.test(stack) && canEat(stack, citizenToServe.isEmpty() ? null : citizenToServe.get(0)))) {
removeFromQueue();
return getState();
}
if (!citizenToServe.isEmpty() && citizenToServe.get(0).getCitizenData() != null) {
citizenToServe.get(0).getCitizenData().setJustAte(true);
}
if (citizenToServe.isEmpty() && living instanceof PlayerEntity) {
MessageUtils.format(MESSAGE_INFO_CITIZEN_COOK_SERVE_PLAYER, worker.getName().getString()).sendTo((PlayerEntity) living);
}
removeFromQueue();
worker.getCitizenExperienceHandler().addExperience(BASE_XP_GAIN);
this.incrementActionsDoneAndDecSaturation();
return START_WORKING;
}
use of com.minecolonies.api.entity.ai.statemachine.states.IAIState in project minecolonies by Minecolonies.
the class EntityAIWorkNether method decide.
@Override
protected IAIState decide() {
if (job.isInNether()) {
if (!worker.isInvisible()) {
goToVault();
}
return NETHER_AWAY;
}
if (worker.isInvisible()) {
returnFromVault(true);
}
IAIState crafterState = super.decide();
if (crafterState != IDLE && crafterState != START_WORKING) {
return crafterState;
}
// Get Armor if available.
// This is async, so we could go to the nether without it.
checkAndRequestArmor();
// Check for materials needed to go to the Nether:
IRecipeStorage rs = building.getFirstModuleOccurance(BuildingNetherWorker.CraftingModule.class).getFirstRecipe(ItemStack::isEmpty);
boolean hasItemsAvailable = true;
if (rs != null) {
for (ItemStorage item : rs.getInput()) {
if (!checkIfRequestForItemExistOrCreateAsync(new ItemStack(item.getItem(), 1), item.getAmount(), item.getAmount())) {
hasItemsAvailable = false;
}
}
}
if (!hasItemsAvailable) {
return IDLE;
}
final BlockPos portal = building.getPortalLocation();
if (portal == null) {
Log.getLogger().warn("--- Missing Portal Tag In Nether Worker Building! Aborting Operation! ---");
return IDLE;
}
// Make sure we have a stash of some food
checkIfRequestForItemExistOrCreate(new StackList(getEdiblesList(), "Edible Food", 16));
// Get other adventuring supplies. These are required.
// Done this way to get all the requests in parallel
boolean missingAxe = checkForToolOrWeapon(ToolType.AXE);
boolean missingPick = checkForToolOrWeapon(ToolType.PICKAXE);
boolean missingShovel = checkForToolOrWeapon(ToolType.SHOVEL);
boolean missingSword = checkForToolOrWeapon(ToolType.SWORD);
boolean missingLighter = checkForToolOrWeapon(ToolType.FLINT_N_STEEL);
if (missingAxe || missingPick || missingShovel || missingSword || missingLighter) {
worker.getCitizenData().setIdleAtJob(true);
return IDLE;
}
if (currentRecipeStorage == null) {
final ICraftingBuildingModule module = building.getFirstModuleOccurance(BuildingNetherWorker.CraftingModule.class);
currentRecipeStorage = module.getFirstFulfillableRecipe(ItemStackUtils::isEmpty, 1, false);
if (building.isReadyForTrip()) {
worker.getCitizenData().setIdleAtJob(true);
}
if (currentRecipeStorage == null && building.shallClosePortalOnReturn()) {
final BlockState block = world.getBlockState(portal);
if (block.is(Blocks.NETHER_PORTAL)) {
return NETHER_CLOSEPORTAL;
}
}
return getState();
} else {
if (!building.isReadyForTrip()) {
worker.getCitizenData().setIdleAtJob(false);
return IDLE;
}
if (walkTo != null || walkToBuilding()) {
return getState();
}
if (InventoryUtils.isItemHandlerFull(worker.getInventoryCitizen())) {
return INVENTORY_FULL;
}
IAIState checkResult = checkForItems(currentRecipeStorage);
if (checkResult == GET_RECIPE) {
currentRecipeStorage = null;
worker.getCitizenData().setIdleAtJob(true);
return IDLE;
}
if (checkResult != CRAFT) {
return checkResult;
}
}
return NETHER_LEAVE;
}
use of com.minecolonies.api.entity.ai.statemachine.states.IAIState in project minecolonies by Minecolonies.
the class EntityAIWorkCowboy method decideWhatToDo.
@Override
public IAIState decideWhatToDo() {
final IAIState result = super.decideWhatToDo();
final boolean hasBucket = InventoryUtils.hasItemInItemHandler(worker.getInventoryCitizen(), Items.BUCKET);
if (building != null && building.getSetting(BuildingCowboy.MILKING).getValue() && result.equals(START_WORKING) && hasBucket) {
return COWBOY_MILK;
}
return result;
}
Aggregations