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;
}
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);
}
}
}
}
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;
}
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.");
}
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);
}
}
}
Aggregations