Search in sources :

Example 16 with CraftingRecipe

use of net.minecraft.world.item.crafting.CraftingRecipe in project TinkersConstruct by SlimeKnights.

the class CraftingStationBlockEntity method getResultForPlayer.

/**
 * Gets the player sensitive crafting result, also validating the player has access to this recipe
 * @param player  Player
 * @return  Player sensitive result
 */
public ItemStack getResultForPlayer(Player player) {
    ForgeHooks.setCraftingPlayer(player);
    // local variable just to prevent race conditions if the field changes, though that is unlikely
    CraftingRecipe recipe = this.lastRecipe;
    // try matches again now that we have player access
    if (recipe == null || this.level == null || !recipe.matches(craftingInventory, level)) {
        ForgeHooks.setCraftingPlayer(null);
        return ItemStack.EMPTY;
    }
    // check if the player has access to the recipe, if not give up
    // Disabled because this is an absolute mess of logic, and the gain is rather small, treating this like a furnace instead
    // note the gamerule is client side only anyways, so you would have to sync it, such as in the container
    // if you want limited crafting, disable the crafting station, the design of the station is incompatible with the game rule and vanilla syncing
    // if (!recipe.isDynamic() && world.getGameRules().getBoolean(GameRules.DO_LIMITED_CRAFTING)) {
    // // mojang, why can't PlayerEntity just have a RecipeBook getter, why must I go through the sided classes? grr
    // boolean locked;
    // if (!world.isRemote) {
    // locked = player instanceof ServerPlayerEntity && !((ServerPlayerEntity) player).getRecipeBook().isUnlocked(recipe);
    // } else {
    // locked = DistExecutor.unsafeCallWhenOn(Dist.CLIENT, () -> () -> player instanceof ClientPlayerEntity && !((ClientPlayerEntity) player).getRecipeBook().isUnlocked(recipe));
    // }
    // // if the player cannot craft this, block crafting
    // if (locked) {
    // ForgeHooks.setCraftingPlayer(null);
    // return ItemStack.EMPTY;
    // }
    // }
    ItemStack result = recipe.assemble(craftingInventory);
    ForgeHooks.setCraftingPlayer(null);
    return result;
}
Also used : CraftingRecipe(net.minecraft.world.item.crafting.CraftingRecipe) ItemStack(net.minecraft.world.item.ItemStack)

Example 17 with CraftingRecipe

use of net.minecraft.world.item.crafting.CraftingRecipe in project TinkersConstruct by SlimeKnights.

the class CraftingStationBlockEntity method takeResult.

/**
 * Removes the result from this inventory, updating inputs and triggering recipe hooks
 * @param player  Player taking result
 * @param result  Result removed
 * @param amount  Number of times crafted
 */
public void takeResult(Player player, ItemStack result, int amount) {
    // local variable just to prevent race conditions if the field changes, though that is unlikely
    CraftingRecipe recipe = this.lastRecipe;
    if (recipe == null || this.level == null) {
        return;
    }
    // fire crafting events
    if (!recipe.isSpecial()) {
        // unlock the recipe if it was not unlocked, so it shows in the recipe book
        player.awardRecipes(Collections.singleton(recipe));
    }
    result.onCraftedBy(this.level, player, amount);
    ForgeEventFactory.firePlayerCraftingEvent(player, result, this.craftingInventory);
    // update all slots in the inventory
    // remove remaining items
    ForgeHooks.setCraftingPlayer(player);
    NonNullList<ItemStack> remaining = recipe.getRemainingItems(craftingInventory);
    ForgeHooks.setCraftingPlayer(null);
    for (int i = 0; i < remaining.size(); ++i) {
        ItemStack original = this.getItem(i);
        ItemStack newStack = remaining.get(i);
        // if empty or size 1, set directly (decreases by 1)
        if (original.isEmpty() || original.getCount() == 1) {
            this.setItem(i, newStack);
        } else if (ItemStack.isSame(original, newStack) && ItemStack.tagMatches(original, newStack)) {
            // if matching, merge (decreasing by 1
            newStack.grow(original.getCount() - 1);
            this.setItem(i, newStack);
        } else {
            // directly update the slot
            this.setItem(i, ItemHandlerHelper.copyStackWithSize(original, original.getCount() - 1));
            // otherwise, drop the item as the player
            if (!newStack.isEmpty() && !player.getInventory().add(newStack)) {
                player.drop(newStack, false);
            }
        }
    }
}
Also used : CraftingRecipe(net.minecraft.world.item.crafting.CraftingRecipe) ItemStack(net.minecraft.world.item.ItemStack)

Example 18 with CraftingRecipe

use of net.minecraft.world.item.crafting.CraftingRecipe in project TinkersConstruct by SlimeKnights.

the class CraftingStationBlockEntity method calcResult.

/* Crafting */
@Override
public ItemStack calcResult(@Nullable Player player) {
    if (this.level == null || isEmpty()) {
        return ItemStack.EMPTY;
    }
    // assume empty unless we learn otherwise
    ItemStack result = ItemStack.EMPTY;
    if (!this.level.isClientSide && this.level.getServer() != null) {
        RecipeManager manager = this.level.getServer().getRecipeManager();
        // first, try the cached recipe
        CraftingRecipe recipe = lastRecipe;
        // note we intentionally have no player access during matches, that could lead to an unstable recipe
        if (recipe == null || !recipe.matches(this.craftingInventory, this.level)) {
            recipe = manager.getRecipeFor(RecipeType.CRAFTING, this.craftingInventory, this.level).orElse(null);
        }
        // if we have a recipe, fetch its result
        if (recipe != null) {
            ForgeHooks.setCraftingPlayer(player);
            result = recipe.assemble(this.craftingInventory);
            ForgeHooks.setCraftingPlayer(null);
            // sync if the recipe is different
            if (recipe != lastRecipe) {
                this.lastRecipe = recipe;
                this.syncToRelevantPlayers(this::syncRecipe);
            }
        }
    } else if (this.lastRecipe != null && this.lastRecipe.matches(this.craftingInventory, this.level)) {
        ForgeHooks.setCraftingPlayer(player);
        result = this.lastRecipe.assemble(this.craftingInventory);
        ForgeHooks.setCraftingPlayer(null);
    }
    return result;
}
Also used : RecipeManager(net.minecraft.world.item.crafting.RecipeManager) CraftingRecipe(net.minecraft.world.item.crafting.CraftingRecipe) ItemStack(net.minecraft.world.item.ItemStack)

Example 19 with CraftingRecipe

use of net.minecraft.world.item.crafting.CraftingRecipe in project just-vertical-slabs by Nyphet.

the class ServerAboutToStartEventHandler method onServerAboutToStartEvent.

/**
 * Handles the event {@link ServerAboutToStartEvent} to load the maps of slabs-blocks.
 * Searches through all {@link Item Items} with the {@link ItemTags#SLABS slabs} tag and associates them to the block they're made from.
 *
 * @param event - {@link ServerAboutToStartEvent}.
 */
@SubscribeEvent(priority = EventPriority.LOWEST)
public void onServerAboutToStartEvent(ServerAboutToStartEvent event) {
    Map<Item, Item> slabMap = new LinkedHashMap<Item, Item>(), blockMap = new HashMap<Item, Item>(), waxingMap = new HashMap<Item, Item>(), stonecuttingMap = new HashMap<Item, Item>();
    RecipeManager recipeManager = event.getServer().getRecipeManager();
    for (Item slab : ForgeRegistries.ITEMS.tags().getTag(ItemTags.SLABS)) {
        JustVerticalSlabsLoader.LOGGER.debug("Adding " + slab + " to " + JustVerticalSlabsLoader.MODID + " mod maps...");
        for (CraftingRecipe recipe : recipeManager.getAllRecipesFor(RecipeType.CRAFTING)) {
            if (recipe.getResultItem().is(slab) && !(recipe instanceof VerticalSlabCraftingRecipe)) {
                NonNullList<Ingredient> ingredients = recipe.getIngredients();
                // A slab can be connected to its block only if there exists a crafting recipe that uses at least one block and, if more, the blocks used are all the same.
                List<Ingredient> blockIngredients = getBlockIngredients(ingredients);
                if (sameIngredients(blockIngredients)) {
                    blockIngredients.stream().findFirst().ifPresent(ingredient -> {
                        for (ItemStack itemStack : ingredient.getItems()) {
                            if (isPlain(itemStack)) {
                                slabMap.put(slab, itemStack.getItem());
                            }
                            blockMap.put(itemStack.getItem(), slab);
                        }
                        // If no plain block is connected to this slab that means the slab is not plain either, so add the first (and theoretically only) block item.
                        if (!slabMap.containsKey(slab)) {
                            slabMap.put(slab, ingredient.getItems()[0].getItem());
                        }
                    });
                } else if (ingredients.stream().anyMatch(ingredient -> ingredient.test(Items.HONEYCOMB.getDefaultInstance()))) {
                    List<Ingredient> notHoneyIngredients = ingredients.stream().filter(ingredient -> !ingredient.test(Items.HONEYCOMB.getDefaultInstance())).toList();
                    if (notHoneyIngredients.size() == 1) {
                        ItemStack oxidizableSlab = notHoneyIngredients.get(0).getItems()[0];
                        if (oxidizableSlab.is(ItemTags.SLABS)) {
                            waxingMap.put(oxidizableSlab.getItem(), slab);
                        }
                    }
                }
            }
        }
        for (StonecutterRecipe recipe : recipeManager.getAllRecipesFor(RecipeType.STONECUTTING)) {
            if (recipe.getResultItem().is(slab) && !(recipe instanceof VerticalSlabStonecutterRecipe)) {
                Ingredient ingredient = recipe.getIngredients().get(0);
                for (ItemStack itemStack : ingredient.getItems()) {
                    Item block = itemStack.getItem();
                    if (!stonecuttingMap.containsKey(block)) {
                        // Put the block in the map if it's the first one that can be stonecut in the slab.
                        stonecuttingMap.put(block, slab);
                    } else if (slabMap.get(slab) == block) {
                        // If another block was associated to the slab in the stonecuttingMap, but the slabMap has this block associated to the slab,
                        // that means this block is the plain one for the slab so overwrite the block in the stonecuttingMap.
                        stonecuttingMap.put(block, slab);
                    }
                }
            }
        }
    }
    VerticalSlabUtils.slabMap = ImmutableMap.copyOf(slabMap);
    VerticalSlabUtils.blockMap = ImmutableMap.copyOf(blockMap);
    VerticalSlabUtils.stonecuttingMap = ImmutableMap.copyOf(stonecuttingMap);
    VerticalSlabUtils.waxingMap = ImmutableMap.copyOf(waxingMap);
    JustVerticalSlabsLoader.LOGGER.debug(JustVerticalSlabsLoader.MODID + " mod maps generated.");
}
Also used : Arrays(java.util.Arrays) Items(net.minecraft.world.item.Items) Item(net.minecraft.world.item.Item) HashMap(java.util.HashMap) Ingredient(net.minecraft.world.item.crafting.Ingredient) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) EventPriority(net.minecraftforge.eventbus.api.EventPriority) NonNullList(net.minecraft.core.NonNullList) VerticalSlabCraftingRecipe(crystalspider.justverticalslabs.recipes.crafting.VerticalSlabCraftingRecipe) SubscribeEvent(net.minecraftforge.eventbus.api.SubscribeEvent) ServerAboutToStartEvent(net.minecraftforge.event.server.ServerAboutToStartEvent) RecipeType(net.minecraft.world.item.crafting.RecipeType) VerticalSlabUtils(crystalspider.justverticalslabs.utils.VerticalSlabUtils) BlockItem(net.minecraft.world.item.BlockItem) CraftingRecipe(net.minecraft.world.item.crafting.CraftingRecipe) ImmutableMap(com.google.common.collect.ImmutableMap) ItemTags(net.minecraft.tags.ItemTags) StonecutterRecipe(net.minecraft.world.item.crafting.StonecutterRecipe) List(java.util.List) JustVerticalSlabsLoader(crystalspider.justverticalslabs.JustVerticalSlabsLoader) RecipeManager(net.minecraft.world.item.crafting.RecipeManager) ItemStack(net.minecraft.world.item.ItemStack) ForgeRegistries(net.minecraftforge.registries.ForgeRegistries) VerticalSlabStonecutterRecipe(crystalspider.justverticalslabs.recipes.stonecutter.VerticalSlabStonecutterRecipe) VerticalSlabCraftingRecipe(crystalspider.justverticalslabs.recipes.crafting.VerticalSlabCraftingRecipe) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) StonecutterRecipe(net.minecraft.world.item.crafting.StonecutterRecipe) VerticalSlabStonecutterRecipe(crystalspider.justverticalslabs.recipes.stonecutter.VerticalSlabStonecutterRecipe) VerticalSlabCraftingRecipe(crystalspider.justverticalslabs.recipes.crafting.VerticalSlabCraftingRecipe) CraftingRecipe(net.minecraft.world.item.crafting.CraftingRecipe) LinkedHashMap(java.util.LinkedHashMap) Item(net.minecraft.world.item.Item) BlockItem(net.minecraft.world.item.BlockItem) Ingredient(net.minecraft.world.item.crafting.Ingredient) RecipeManager(net.minecraft.world.item.crafting.RecipeManager) NonNullList(net.minecraft.core.NonNullList) List(java.util.List) ItemStack(net.minecraft.world.item.ItemStack) VerticalSlabStonecutterRecipe(crystalspider.justverticalslabs.recipes.stonecutter.VerticalSlabStonecutterRecipe) SubscribeEvent(net.minecraftforge.eventbus.api.SubscribeEvent)

Example 20 with CraftingRecipe

use of net.minecraft.world.item.crafting.CraftingRecipe in project Cyclic by Lothrazar.

the class TilePackager method tryDoPackage.

private void tryDoPackage() {
    if (POWERCONF.get() > 0 && energy.getEnergyStored() < POWERCONF.get()) {
        // not enough pow
        return;
    }
    setLitProperty(true);
    // pull in new fuel
    ItemStack stack = inputSlots.getStackInSlot(0);
    // shapeless recipes / shaped check either
    List<CraftingRecipe> recipes = level.getRecipeManager().getAllRecipesFor(RecipeType.CRAFTING);
    for (CraftingRecipe rec : recipes) {
        if (!isRecipeValid(rec)) {
            continue;
        }
        // test matching recipe and its size
        int total = getCostIfMatched(stack, rec);
        if (total > 0 && outputSlots.insertItem(0, rec.getResultItem().copy(), true).isEmpty()) {
            // consume items, produce output
            inputSlots.extractItem(0, total, false);
            outputSlots.insertItem(0, rec.getResultItem().copy(), false);
            energy.extractEnergy(POWERCONF.get(), false);
        }
    }
}
Also used : CraftingRecipe(net.minecraft.world.item.crafting.CraftingRecipe) ItemStack(net.minecraft.world.item.ItemStack)

Aggregations

CraftingRecipe (net.minecraft.world.item.crafting.CraftingRecipe)25 ItemStack (net.minecraft.world.item.ItemStack)22 ServerPlayer (net.minecraft.server.level.ServerPlayer)10 ClientboundContainerSetSlotPacket (net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket)9 Ingredient (net.minecraft.world.item.crafting.Ingredient)7 NonNullList (net.minecraft.core.NonNullList)4 ResourceLocation (net.minecraft.resources.ResourceLocation)4 CraftingContainer (net.minecraft.world.inventory.CraftingContainer)4 Item (net.minecraft.world.item.Item)4 ShapelessRecipe (net.minecraft.world.item.crafting.ShapelessRecipe)4 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 Map (java.util.Map)3 RecipeManager (net.minecraft.world.item.crafting.RecipeManager)3 AllItems (com.simibubi.create.AllItems)2 Create (com.simibubi.create.Create)2 FilterItem (com.simibubi.create.content.logistics.item.filter.FilterItem)2 Arrays (java.util.Arrays)2 List (java.util.List)2 ItemTags (net.minecraft.tags.ItemTags)2