use of com.minecolonies.api.colony.buildings.modules.ICraftingBuildingModule in project minecolonies by Minecolonies.
the class RecipeAnalyzer method findRecipes.
/**
* Find all recipes for a given crafter.
*
* @param vanilla vanilla recipes map.
* @param crafting crafting module.
* @return list of recipes
*/
@NotNull
public static List<IGenericRecipe> findRecipes(@NotNull final Map<CraftingType, List<IGenericRecipe>> vanilla, @NotNull final ICraftingBuildingModule crafting) {
final List<IGenericRecipe> recipes = new ArrayList<>();
// all vanilla teachable recipes
for (final Map.Entry<CraftingType, List<IGenericRecipe>> entry : vanilla.entrySet()) {
if (crafting.canLearn(entry.getKey())) {
for (final IGenericRecipe recipe : entry.getValue()) {
final IGenericRecipe safeRecipe = GenericRecipeUtils.filterInputs(recipe, crafting.getIngredientValidator());
if (crafting.isRecipeCompatible(safeRecipe)) {
recipes.add(safeRecipe);
}
}
}
}
// custom MineColonies additional recipes
for (final CustomRecipe customRecipe : CustomRecipeManager.getInstance().getRecipes(crafting.getCustomRecipeKey())) {
final IRecipeStorage recipeStorage = customRecipe.getRecipeStorage();
if (!recipeStorage.getAlternateOutputs().isEmpty()) {
// this is a multi-output recipe; assume it replaces a bunch of vanilla
// recipes we already added above
recipes.removeIf(r -> ItemStackUtils.compareItemStacksIgnoreStackSize(recipeStorage.getPrimaryOutput(), r.getPrimaryOutput()));
recipes.removeIf(r -> recipeStorage.getAlternateOutputs().stream().anyMatch(s -> ItemStackUtils.compareItemStacksIgnoreStackSize(s, r.getPrimaryOutput())));
}
recipes.add(GenericRecipeUtils.create(customRecipe, recipeStorage));
}
// and even more recipes that can't be taught, but are just inherent in the worker AI
recipes.addAll(crafting.getAdditionalRecipesForDisplayPurposesOnly());
return recipes;
}
use of com.minecolonies.api.colony.buildings.modules.ICraftingBuildingModule 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.colony.buildings.modules.ICraftingBuildingModule in project minecolonies by Minecolonies.
the class EntityAIWorkSifter method sift.
/**
* The sifting process.
*
* @return the next AiState to go to.
*/
protected IAIState sift() {
final BuildingSifter sifterBuilding = building;
// 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 = building.getFirstModuleOccurance(BuildingSifter.CraftingModule.class);
currentRecipeStorage = module.getFirstFulfillableRecipe(ItemStackUtils::isEmpty, 1, false);
}
if (currentRecipeStorage == null) {
if (InventoryUtils.hasBuildingEnoughElseCount(sifterBuilding, i -> ModTags.meshes.contains(i.getItem()), 1) == 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(building.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, building.getID(), SoundEvents.LEASH_KNOT_BREAK);
return getState();
}
use of com.minecolonies.api.colony.buildings.modules.ICraftingBuildingModule in project minecolonies by Minecolonies.
the class RecipeSetting method getValue.
@Override
public IRecipeStorage getValue(final IBuilding building) {
final ICraftingBuildingModule craftingModule = building.getModuleMatching(ICraftingBuildingModule.class, m -> m.getId().equals(craftingModuleId));
for (final IToken<?> token : craftingModule.getRecipes()) {
if (token.equals(currentIndex)) {
return IColonyManager.getInstance().getRecipeManager().getRecipe(currentIndex);
}
}
currentIndex = building.getFirstModuleOccurance(ICraftingBuildingModule.class).getRecipes().get(0);
return IColonyManager.getInstance().getRecipeManager().getRecipe(currentIndex);
}
use of com.minecolonies.api.colony.buildings.modules.ICraftingBuildingModule in project minecolonies by Minecolonies.
the class AbstractEntityAICrafting method getRecipe.
/**
* Query the IRecipeStorage of the first request in the queue.
*
* @return the next state to go to.
*/
protected IAIState getRecipe() {
final IRequest<? extends PublicCrafting> currentTask = job.getCurrentTask();
if (currentTask == null) {
return START_WORKING;
}
final ICraftingBuildingModule module = building.getCraftingModuleForRecipe(currentTask.getRequest().getRecipeID());
if (module == null) {
job.finishRequest(false);
incrementActionsDone(getActionRewardForCraftingSuccess());
return START_WORKING;
}
currentRecipeStorage = module.getFirstFulfillableRecipe(stack -> ItemStackUtils.compareItemStacksIgnoreStackSize(stack, currentTask.getRequest().getStack()), 1, false);
if (currentRecipeStorage == null) {
job.finishRequest(false);
incrementActionsDone(getActionRewardForCraftingSuccess());
return START_WORKING;
}
currentRequest = currentTask;
job.setMaxCraftingCount(currentRequest.getRequest().getCount());
final int currentCount = InventoryUtils.getItemCountInItemHandler(worker.getInventoryCitizen(), stack -> ItemStackUtils.compareItemStacksIgnoreStackSize(stack, currentRecipeStorage.getPrimaryOutput()));
final int inProgressCount = getExtendedCount(currentRecipeStorage.getPrimaryOutput());
final int countPerIteration = currentRecipeStorage.getPrimaryOutput().getCount();
final int doneOpsCount = currentCount / countPerIteration;
final int progressOpsCount = inProgressCount / countPerIteration;
final int remainingOpsCount = currentRequest.getRequest().getCount() - doneOpsCount - progressOpsCount;
final List<ItemStorage> input = currentRecipeStorage.getCleanedInput();
for (final ItemStorage inputStorage : input) {
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() * remainingOpsCount;
}
if (InventoryUtils.getCountFromBuilding(building, itemStack -> ItemStackUtils.compareItemStacksIgnoreStackSize(itemStack, inputStorage.getItemStack(), false, true)) + InventoryUtils.getItemCountInItemHandler(worker.getInventoryCitizen(), itemStack -> ItemStackUtils.compareItemStacksIgnoreStackSize(itemStack, inputStorage.getItemStack(), false, true)) + getExtendedCount(inputStorage.getItemStack()) < remaining) {
job.finishRequest(false);
incrementActionsDone(getActionRewardForCraftingSuccess());
return START_WORKING;
}
}
job.setCraftCounter(doneOpsCount);
return QUERY_ITEMS;
}
Aggregations