use of com.minecolonies.api.entity.ai.statemachine.states.IAIState in project minecolonies by Minecolonies.
the class AbstractEntityAIStructure method structureStep.
/**
* The Structure step to execute the actual placement actions etc.
*
* @return the next step to go to.
*/
protected IAIState structureStep() {
if (structurePlacer.getB().getStage() == null) {
return PICK_UP_RESIDUALS;
}
if (InventoryUtils.isItemHandlerFull(worker.getInventoryCitizen())) {
return INVENTORY_FULL;
}
worker.getCitizenStatusHandler().setLatestStatus(new TranslationTextComponent("com.minecolonies.coremod.status.building"));
checkForExtraBuildingActions();
// some things to do first! then we go to the actual phase!
// Fill workFrom with the position from where the builder should build.
// also ensure we are at that position.
final BlockPos progress = getProgressPos() == null ? NULL_POS : getProgressPos().getA();
final BlockPos worldPos = structurePlacer.getB().getProgressPosInWorld(progress);
if (getProgressPos() != null) {
structurePlacer.getB().setStage(getProgressPos().getB());
}
if (!progress.equals(NULL_POS) && !limitReached && (blockToMine == null ? !walkToConstructionSite(worldPos) : !walkToConstructionSite(blockToMine))) {
return getState();
}
limitReached = false;
final StructurePhasePlacementResult result;
final StructurePlacer placer = structurePlacer.getA();
switch(structurePlacer.getB().getStage()) {
case BUILD_SOLID:
// structure
result = placer.executeStructureStep(world, null, progress, StructurePlacer.Operation.BLOCK_PLACEMENT, () -> placer.getIterator().increment(DONT_TOUCH_PREDICATE.or((info, pos, handler) -> !info.getBlockInfo().getState().getMaterial().isSolid() || isDecoItem(info.getBlockInfo().getState().getBlock()))), false);
break;
case CLEAR_WATER:
// water
result = placer.executeStructureStep(world, null, progress, StructurePlacer.Operation.WATER_REMOVAL, () -> placer.getIterator().decrement((info, pos, handler) -> handler.getWorld().getBlockState(pos).getFluidState().isEmpty()), false);
break;
case CLEAR_NON_SOLIDS:
// clear air
result = placer.executeStructureStep(world, null, progress, StructurePlacer.Operation.BLOCK_PLACEMENT, () -> placer.getIterator().decrement(DONT_TOUCH_PREDICATE.or((info, pos, handler) -> !(info.getBlockInfo().getState().getBlock() instanceof AirBlock) || (handler.getWorld().isEmptyBlock(pos)))), false);
break;
case DECORATE:
// not solid
result = placer.executeStructureStep(world, null, progress, StructurePlacer.Operation.BLOCK_PLACEMENT, () -> placer.getIterator().increment(DONT_TOUCH_PREDICATE.or((info, pos, handler) -> info.getBlockInfo().getState().getMaterial().isSolid() && !isDecoItem(info.getBlockInfo().getState().getBlock()))), false);
break;
case SPAWN:
// entities
result = placer.executeStructureStep(world, null, progress, StructurePlacer.Operation.BLOCK_PLACEMENT, () -> placer.getIterator().increment(DONT_TOUCH_PREDICATE.or((info, pos, handler) -> info.getEntities().length == 0)), true);
break;
case REMOVE_WATER:
// water
placer.getIterator().setRemoving();
result = placer.executeStructureStep(world, null, progress, StructurePlacer.Operation.WATER_REMOVAL, () -> placer.getIterator().decrement((info, pos, handler) -> info.getBlockInfo().getState().getFluidState().isEmpty()), false);
break;
case REMOVE:
placer.getIterator().setRemoving();
result = placer.executeStructureStep(world, null, progress, StructurePlacer.Operation.BLOCK_REMOVAL, () -> placer.getIterator().decrement((info, pos, handler) -> handler.getWorld().getBlockState(pos).getBlock() instanceof AirBlock || info.getBlockInfo().getState().getBlock() instanceof AirBlock || !handler.getWorld().getBlockState(pos).getFluidState().isEmpty() || info.getBlockInfo().getState().getBlock() == com.ldtteam.structurize.blocks.ModBlocks.blockSolidSubstitution.get() || info.getBlockInfo().getState().getBlock() == com.ldtteam.structurize.blocks.ModBlocks.blockSubstitution.get() || info.getBlockInfo().getState().getBlock() == com.ldtteam.structurize.blocks.ModBlocks.blockSubstitution.get() || handler.getWorld().getBlockState(pos).getBlock() instanceof IBuilderUndestroyable), true);
break;
case CLEAR:
default:
result = placer.executeStructureStep(world, null, progress, StructurePlacer.Operation.BLOCK_REMOVAL, () -> placer.getIterator().decrement((info, pos, handler) -> handler.getWorld().getBlockState(pos).getBlock() instanceof IBuilderUndestroyable || handler.getWorld().getBlockState(pos).getBlock() == Blocks.BEDROCK || handler.getWorld().getBlockState(pos).getBlock() instanceof AirBlock || info.getBlockInfo().getState().getBlock() == com.ldtteam.structurize.blocks.ModBlocks.blockFluidSubstitution.get() || !handler.getWorld().getBlockState(pos).getFluidState().isEmpty()), false);
if (result.getBlockResult().getResult() == BlockPlacementResult.Result.FINISHED) {
getOwnBuilding().checkOrRequestBucket(getOwnBuilding().getRequiredResources(), worker.getCitizenData(), true);
}
break;
}
if (result.getBlockResult().getResult() == BlockPlacementResult.Result.FINISHED) {
getOwnBuilding().nextStage();
if (!structurePlacer.getB().nextStage()) {
getOwnBuilding().setProgressPos(null, null);
return COMPLETE_BUILD;
}
} else if (result.getBlockResult().getResult() == BlockPlacementResult.Result.LIMIT_REACHED) {
this.limitReached = true;
}
this.storeProgressPos(result.getIteratorPos(), structurePlacer.getB().getStage());
if (result.getBlockResult().getResult() == BlockPlacementResult.Result.MISSING_ITEMS) {
if (hasListOfResInInvOrRequest(this, result.getBlockResult().getRequiredItems(), result.getBlockResult().getRequiredItems().size() > 1) == RECALC) {
job.getWorkOrder().setRequested(false);
return LOAD_STRUCTURE;
}
return NEEDS_ITEM;
}
if (result.getBlockResult().getResult() == BlockPlacementResult.Result.BREAK_BLOCK) {
blockToMine = result.getBlockResult().getWorldPos();
return MINE_BLOCK;
} else {
blockToMine = null;
}
if (MineColonies.getConfig().getServer().builderBuildBlockDelay.get() > 0) {
final double decrease = 1 - worker.getCitizenColonyHandler().getColony().getResearchManager().getResearchEffects().getEffectStrength(BLOCK_PLACE_SPEED);
setDelay((int) ((MineColonies.getConfig().getServer().builderBuildBlockDelay.get() * PROGRESS_MULTIPLIER / (getPlaceSpeedLevel() / 2 + PROGRESS_MULTIPLIER)) * decrease));
}
return getState();
}
use of com.minecolonies.api.entity.ai.statemachine.states.IAIState in project minecolonies by Minecolonies.
the class AbstractEntityAIStructure method pickUpMaterial.
/**
* State to pick up material before going back to work.
*
* @return the next state to go to.
*/
public IAIState pickUpMaterial() {
if (structurePlacer == null || !structurePlacer.getB().hasBluePrint()) {
return IDLE;
}
if (structurePlacer.getB().getStage() == null || structurePlacer.getB().getStage() == BuildingStructureHandler.Stage.CLEAR) {
pickUpCount = 0;
return START_WORKING;
}
final List<Tuple<Predicate<ItemStack>, Integer>> neededItemsList = new ArrayList<>();
final BuilderBucket neededRessourcesMap = getOwnBuilding().getRequiredResources();
final BuildingResourcesModule module = getOwnBuilding().getFirstModuleOccurance(BuildingResourcesModule.class);
if (neededRessourcesMap != null) {
for (final Map.Entry<String, Integer> entry : neededRessourcesMap.getResourceMap().entrySet()) {
final BuildingBuilderResource res = module.getResourceFromIdentifier(entry.getKey());
if (res != null) {
int amount = entry.getValue();
neededItemsList.add(new Tuple<>(itemstack -> ItemStackUtils.compareItemStacksIgnoreStackSize(res.getItemStack(), itemstack, true, true), amount));
}
}
}
if (neededItemsList.size() <= pickUpCount || InventoryUtils.openSlotCount(worker.getInventoryCitizen()) <= MIN_OPEN_SLOTS) {
getOwnBuilding().checkOrRequestBucket(getOwnBuilding().getRequiredResources(), worker.getCitizenData(), true);
getOwnBuilding().checkOrRequestBucket(getOwnBuilding().getNextBucket(), worker.getCitizenData(), false);
pickUpCount = 0;
return START_WORKING;
}
needsCurrently = neededItemsList.get(pickUpCount);
pickUpCount++;
if (InventoryUtils.hasItemInProvider(getOwnBuilding().getTileEntity(), needsCurrently.getA())) {
return GATHERING_REQUIRED_MATERIALS;
}
return pickUpMaterial();
}
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 (!getOwnBuilding().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));
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))) {
removeFromQueue();
return getState();
}
if (!InventoryUtils.transferFoodUpToSaturation(worker, handler, getOwnBuilding().getBuildingLevel() * SATURATION_TO_SERVE, stack -> CAN_EAT.test(stack) && canEat(stack))) {
removeFromQueue();
return getState();
}
if (!citizenToServe.isEmpty() && citizenToServe.get(0).getCitizenData() != null) {
citizenToServe.get(0).getCitizenData().setJustAte(true);
}
if (citizenToServe.isEmpty() && living instanceof PlayerEntity) {
LanguageHandler.sendPlayerMessage((PlayerEntity) living, "com.minecolonies.coremod.cook.serve.player", worker.getName().getString());
}
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 AbstractEntityAICrafting method checkForItems.
/**
* Check for all items of the required recipe.
*
* @param storage the recipe storage.
* @return the next state to go to.
*/
protected IAIState checkForItems(@NotNull final IRecipeStorage storage) {
final int inProgressCount = getExtendedCount(currentRecipeStorage.getPrimaryOutput());
final int countPerIteration = currentRecipeStorage.getPrimaryOutput().getCount();
final int progressOpsCount = inProgressCount / countPerIteration;
final List<ItemStorage> input = storage.getCleanedInput();
for (final ItemStorage inputStorage : input) {
final Predicate<ItemStack> predicate = stack -> !ItemStackUtils.isEmpty(stack) && new Stack(stack, false).matches(inputStorage.getItemStack());
final int invCount = InventoryUtils.getItemCountInItemHandler(worker.getInventoryCitizen(), predicate);
final ItemStack container = inputStorage.getItem().getContainerItem(inputStorage.getItemStack());
final int remaining;
if (!currentRecipeStorage.getCraftingToolsAndSecondaryOutputs().isEmpty() && ItemStackUtils.compareItemStackListIgnoreStackSize(currentRecipeStorage.getCraftingToolsAndSecondaryOutputs(), inputStorage.getItemStack(), false, true)) {
remaining = inputStorage.getAmount();
} else if (!ItemStackUtils.isEmpty(container) && ItemStackUtils.compareItemStacksIgnoreStackSize(inputStorage.getItemStack(), container, false, true)) {
remaining = inputStorage.getAmount();
} else {
remaining = inputStorage.getAmount() * job.getMaxCraftingCount();
}
if (invCount <= 0 || invCount + ((job.getCraftCounter() + progressOpsCount) * inputStorage.getAmount()) < remaining) {
if (InventoryUtils.hasItemInProvider(getOwnBuilding(), predicate)) {
needsCurrently = new Tuple<>(predicate, remaining);
return GATHERING_REQUIRED_MATERIALS;
}
currentRecipeStorage = null;
currentRequest = null;
return GET_RECIPE;
}
}
return CRAFT;
}
use of com.minecolonies.api.entity.ai.statemachine.states.IAIState in project minecolonies by Minecolonies.
the class AbstractEntityAICrafting method craft.
/**
* The actual crafting logic.
*
* @return the next state to go to.
*/
protected IAIState craft() {
if (currentRecipeStorage == null || job.getCurrentTask() == null) {
return START_WORKING;
}
if (currentRequest == null && job.getCurrentTask() != null) {
return GET_RECIPE;
}
if (walkToBuilding()) {
return getState();
}
job.setProgress(job.getProgress() + 1);
worker.setItemInHand(Hand.MAIN_HAND, currentRecipeStorage.getCleanedInput().get(worker.getRandom().nextInt(currentRecipeStorage.getCleanedInput().size())).getItemStack().copy());
worker.setItemInHand(Hand.OFF_HAND, currentRecipeStorage.getPrimaryOutput().copy());
worker.getCitizenItemHandler().hitBlockWithToolInHand(getOwnBuilding().getPosition());
currentRequest = job.getCurrentTask();
if (currentRequest != null && (currentRequest.getState() == RequestState.CANCELLED || currentRequest.getState() == RequestState.FAILED)) {
currentRequest = null;
incrementActionsDone(getActionRewardForCraftingSuccess());
currentRecipeStorage = null;
return START_WORKING;
}
if (job.getProgress() >= getRequiredProgressForMakingRawMaterial()) {
final IAIState check = checkForItems(currentRecipeStorage);
if (check == CRAFT) {
if (!currentRecipeStorage.fullfillRecipe(getLootContext(), ImmutableList.of(worker.getItemHandlerCitizen()))) {
currentRequest = null;
incrementActionsDone(getActionRewardForCraftingSuccess());
job.finishRequest(false);
resetValues();
return START_WORKING;
}
currentRequest.addDelivery(currentRecipeStorage.getPrimaryOutput());
job.setCraftCounter(job.getCraftCounter() + 1);
if (job.getCraftCounter() >= job.getMaxCraftingCount()) {
incrementActionsDone(getActionRewardForCraftingSuccess());
final ICraftingBuildingModule module = getOwnBuilding().getCraftingModuleForRecipe(currentRecipeStorage.getToken());
if (module != null) {
module.improveRecipe(currentRecipeStorage, job.getCraftCounter(), worker.getCitizenData());
}
currentRecipeStorage = null;
resetValues();
if (inventoryNeedsDump()) {
if (job.getMaxCraftingCount() == 0 && job.getProgress() == 0 && job.getCraftCounter() == 0 && currentRequest != null) {
job.finishRequest(true);
worker.getCitizenExperienceHandler().addExperience(currentRequest.getRequest().getCount() / 2.0);
}
}
} else {
job.setProgress(0);
return GET_RECIPE;
}
} else {
currentRequest = null;
job.finishRequest(false);
incrementActionsDoneAndDecSaturation();
resetValues();
}
return START_WORKING;
}
return getState();
}
Aggregations