Jump to content

DoctorC

Members
  • Posts

    39
  • Joined

  • Last visited

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

DoctorC's Achievements

Tree Puncher

Tree Puncher (2/8)

0

Reputation

  1. Hello! I am wondering whether you can log in to Minecraft using a Microsoft account in the development environment? I found a thread on this from October that says that it isn't possible, but it also says that it may be possible in 1.18.
  2. Okay, thanks! I've been trying out Mixins, but can't figure out how Surface Rules work, so I'll probably just wait.
  3. Hello! I have implemented a custom biome, but am not sure how to change the surface of it. In the past, I used a surfacebuilder to have red sand as my top layer, but I'm not sure how to do this in 1.18. Currently, I am looking at Mixins in SurfaceRuleData (I think this is how Fabric does it). Unfortunately, this doesn't work well with Forge Registry items. How should I go about changing the surface of my biome?
  4. Hmm, okay. Yeah I need to do recipes, but I'll probably just have to hard code in this specific case and have recipes as overrides. Thanks!
  5. Yes, I've used the method before. Are you suggesting that I loop through every single registered block and see if it is burnable? That seems pretty laggy and I'm not even sure how to get a list of all blocks. I could yeah, but I'm not sure what you'd need to see.
  6. So I would like to create a custom recipe where one of the items can be any furnace fuel. I tried using AbstractFurnaceTileEntity.getFuel() and creating an Ingredient from its keys. Unfortunately, there are a few issues with this: this method is deprecated it came up with this error on runData: "Tag minecraft:non_flammable_wood used before it was bound" it doesn't support custom furnace fuels added by other mods (I think) What would the correct way to generate a list of all furnace fuels be?
  7. It works! I'm not sure about your final point about Ingredient.fromJson working already, as I used a different JSON key ('ingredientWithout' instead of 'ingredient') - so I didn't change this. Sorry to bother you again but what did you mean by 'forge:compound' earlier as a method of removing both bricks and nether bricks. I can easily do this with a custom tag, just wondering if that would be an easier way? Thanks!
  8. Yep, thanks - I've fixed this. Now that I have fixed up the getItems() method, JEI has all the ingots except brick - so that respect is working great! I've done this - but unfortunately the recipe still works with brick. Here are my new files: IngredientWithout.java: package my.mod.crafting; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.Ingredient; import net.minecraft.tags.ITag; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.Arrays; import java.util.stream.Collectors; import java.util.stream.Stream; public class IngredientWithout extends Ingredient { private final Ingredient of; private final Ingredient without; protected IngredientWithout(@Nonnull ITag<Item> of, ITag<Item> without) { super(Stream.of(new Ingredient.TagList(of))); this.of = Ingredient.of(of); this.without = Ingredient.of(without); } protected IngredientWithout(@Nonnull Ingredient of, Ingredient without) { super(Arrays.stream(of.getItems()).filter((item) -> !item.isEmpty()).map(SingleItemList::new)); this.of = of; this.without = without; } public static IngredientWithout of(ITag<Item> of, ITag<Item> without) { return new IngredientWithout(of, without); } public static IngredientWithout fromJson(JsonElement jsonElement) { return new IngredientWithout(Ingredient.fromJson(jsonElement.getAsJsonObject().get("of")), Ingredient.fromJson(jsonElement.getAsJsonObject().get("without"))); } @Override public ItemStack[] getItems() { return Arrays.stream(this.of.getItems()).filter( ofItemStack -> !Arrays.stream(this.without.getItems()) .map(ItemStack::getItem) .collect(Collectors.toList()).contains(ofItemStack.getItem())) .toArray(ItemStack[]::new); } @Override public boolean test(@Nullable ItemStack p_test_1_) { if (super.test(p_test_1_)) { for (ItemStack itemStack : this.of.getItems()) { if (!this.without.test(itemStack)) return true; } } return false; } @Override public JsonElement toJson() { JsonObject jsonObject = new JsonObject(); jsonObject.add("of", this.of.toJson()); jsonObject.add("without", this.without.toJson()); return jsonObject; } } PressingRecipe.java: package my.mod.crafting.recipe; import com.google.gson.JsonObject; import my.mod.crafting.IngredientWithout; import my.mod.setup.ModRecipes; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipeSerializer; import net.minecraft.item.crafting.Ingredient; import net.minecraft.item.crafting.SingleItemRecipe; import net.minecraft.network.PacketBuffer; import net.minecraft.util.JSONUtils; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistryEntry; import javax.annotation.Nullable; public class PressingRecipe extends SingleItemRecipe { public PressingRecipe(ResourceLocation recipeId, Ingredient ingredient, ItemStack result) { super(ModRecipes.Types.PRESSING, ModRecipes.Serialisers.PRESSING.get(), recipeId, "", ingredient, result); } @Override public boolean matches(IInventory inv, World world) { return this.ingredient.test(inv.getItem(0)); } public static class Serialiser extends ForgeRegistryEntry<IRecipeSerializer<?>> implements IRecipeSerializer<PressingRecipe> { @Override public PressingRecipe fromJson(ResourceLocation recipeId, JsonObject json) { ResourceLocation itemId = new ResourceLocation(JSONUtils.getAsString(json, "result")); int count = JSONUtils.getAsInt(json, "count", 1); ItemStack result = new ItemStack(ForgeRegistries.ITEMS.getValue(itemId), count); if (json.has("ingredientWithout")) { IngredientWithout ingredient = IngredientWithout.fromJson(json.get("ingredientWithout")); return new PressingRecipe(recipeId, ingredient, result); } else { Ingredient ingredient = Ingredient.fromJson(json.get("ingredient")); return new PressingRecipe(recipeId, ingredient, result); } } @Nullable @Override public PressingRecipe fromNetwork(ResourceLocation recipeId, PacketBuffer buffer) { Ingredient ingredient = Ingredient.fromNetwork(buffer); ItemStack result = buffer.readItem(); return new PressingRecipe(recipeId, ingredient, result); } @Override public void toNetwork(PacketBuffer buffer, PressingRecipe recipe) { recipe.ingredient.toNetwork(buffer); buffer.writeItem(recipe.result); } } }
  9. Okay, so I've tried to implement this: IngredientWithout.java package my.mod.crafting; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.Ingredient; import net.minecraft.tags.ITag; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.Arrays; import java.util.stream.Collectors; import java.util.stream.Stream; public class IngredientWithout extends Ingredient { private final Ingredient of; private final Ingredient without; protected IngredientWithout(@Nonnull ITag<Item> of, ITag<Item> without) { super(Stream.of(new Ingredient.TagList(of))); this.of = Ingredient.of(of); this.without = Ingredient.of(without); } protected IngredientWithout(@Nonnull Ingredient of, Ingredient without) { super(Arrays.stream(of.getItems()).filter((item) -> !item.isEmpty()).map(SingleItemList::new)); this.of = of; this.without = without; } public static IngredientWithout of(ITag<Item> of, ITag<Item> without) { return new IngredientWithout(of, without); } public static IngredientWithout of(Ingredient of, Ingredient without) { return new IngredientWithout(of, without); } public static IngredientWithout fromJson(JsonElement jsonElement) { return new IngredientWithout(Ingredient.fromJson(jsonElement.getAsJsonObject().get("of")), Ingredient.fromJson(jsonElement.getAsJsonObject().get("without"))); } public Ingredient of() { return this.of; } public Ingredient without() { return this.without; } @Override public ItemStack[] getItems() { return Arrays.stream(this.of.getItems()).filter( item -> Arrays.asList(this.without.getItems()).contains(item)) .toArray(ItemStack[]::new); } @Override public boolean test(@Nullable ItemStack p_test_1_) { if (super.test(p_test_1_)) { for (ItemStack itemStack : this.of.getItems()) { if (!this.without.test(itemStack)) return true; } } return false; } @Override public JsonElement toJson() { JsonObject jsonObject = new JsonObject(); jsonObject.add("of", this.of.toJson()); jsonObject.add("without", this.without.toJson()); return jsonObject; } } I already have a Serialiser (as the recipe is for a custom Tile Entity), and have successfully implemented fromJson, but I'm not sure how to do fromNetwork and toNetwork as there are two ingredients: PressingRecipe.java package my.mod.crafting.recipe; import com.google.gson.JsonObject; import my.mod.crafting.IngredientWithout; import my.mod.setup.ModRecipes; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipeSerializer; import net.minecraft.item.crafting.Ingredient; import net.minecraft.item.crafting.SingleItemRecipe; import net.minecraft.network.PacketBuffer; import net.minecraft.util.JSONUtils; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistryEntry; import javax.annotation.Nullable; public class PressingRecipe extends SingleItemRecipe { public PressingRecipe(ResourceLocation recipeId, Ingredient ingredient, ItemStack result) { super(ModRecipes.Types.PRESSING, ModRecipes.Serialisers.PRESSING.get(), recipeId, "", ingredient, result); } @Override public boolean matches(IInventory inv, World world) { return this.ingredient.test(inv.getItem(0)); } public static class Serialiser extends ForgeRegistryEntry<IRecipeSerializer<?>> implements IRecipeSerializer<PressingRecipe> { @Override public PressingRecipe fromJson(ResourceLocation recipeId, JsonObject json) { ResourceLocation itemId = new ResourceLocation(JSONUtils.getAsString(json, "result")); int count = JSONUtils.getAsInt(json, "count", 1); ItemStack result = new ItemStack(ForgeRegistries.ITEMS.getValue(itemId), count); if (json.has("ingredientWithout")) { IngredientWithout ingredient = IngredientWithout.fromJson(json.get("ingredientWithout")); return new PressingRecipe(recipeId, ingredient, result); } else { Ingredient ingredient = Ingredient.fromJson(json.get("ingredient")); return new PressingRecipe(recipeId, ingredient, result); } } @Nullable @Override public PressingRecipe fromNetwork(ResourceLocation recipeId, PacketBuffer buffer) { Ingredient of = Ingredient.fromNetwork(buffer); Ingredient without = Ingredient.fromNetwork(buffer); ItemStack result = buffer.readItem(); return new PressingRecipe(recipeId, IngredientWithout.of(of, without), result); } @Override public void toNetwork(PacketBuffer buffer, PressingRecipe recipe) { if (recipe.ingredient instanceof IngredientWithout) { ((IngredientWithout) recipe.ingredient).of().toNetwork(buffer); ((IngredientWithout) recipe.ingredient).without().toNetwork(buffer); } else { recipe.ingredient.toNetwork(buffer); } buffer.writeItem(recipe.result); } } } And this is how I implemented the recipe: PressingRecipeBuilder.builder(IngredientWithout.of(Tags.Items.INGOTS, Tags.Items.INGOTS_BRICK), ModItems.SHEET_METAL.get()) .unlockedBy("has_item", has(Tags.Items.INGOTS)) .save(consumer, mod("sheet_metal_pressing")); Unfortunately, anything from the forge:ingots tag seems to still work. This has also messed up my JEI integration (the input is blank in the JEI screen).
  10. Okay, I implemented this (without the forge:compound, no idea how to do this): package my.mod.crafting; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.Ingredient; import java.util.Arrays; import java.util.stream.Stream; public class IngredientWithout extends Ingredient { protected IngredientWithout(Stream<? extends IItemList> p_i49381_1_) { super(p_i49381_1_); } public static IngredientWithout of(Ingredient of, Ingredient without) { Stream<ItemStack> withoutItems = Arrays.stream(of.getItems()).filter(without); IngredientWithout ing = new IngredientWithout(withoutItems.filter((item) -> !item.isEmpty()).map(SingleItemList::new)); return ing.getItems().length == 0 ? new IngredientWithout(Stream.empty()) : ing; } } But it produced the same issue:
  11. Sorry, I'm still not sure what you mean? I have a RegistryObject<IRecipeSerializer<PressingRecipe>> which is used for my custom recipe type. I have tried creating an Ingredient from a list of ItemStacks, generated using Tags.Items.INGOTS and removing the brick and nether brick tags (similar to as seen above) - but this produced the same error as in my original post.
  12. It uses a custom recipe builder, but it's pretty similar to the furnace builders: PressingRecipeBuilder.builder(Ingredient.of(ModTags.Items.INGOTS_METAL), ModItems.SHEET_METAL.get()) .unlockedBy("has_item", has(ModTags.Items.INGOTS_METAL)) .save(consumer, mod("sheet_metal_pressing"))
  13. Sorry. You said that 'I would just check at runtime if the item is in the ingots tag but not in the brick or nether brick tags'. How would I go about doing this?
  14. Okay, I guess that's the only option. I'd like to have multiple recipes, so is there a good way to remove the bricks for the specific recipe instead of completely removing any support for them as an input Ingredient?
  15. I think this is what you mean? ModItemTagsProvider.java package my.mod.data; import my.mod.Main; import my.mod.setup.ModTags; import net.minecraft.data.BlockTagsProvider; import net.minecraft.data.DataGenerator; import net.minecraft.data.ItemTagsProvider; import net.minecraft.item.Item; import net.minecraftforge.common.Tags; import net.minecraftforge.common.data.ExistingFileHelper; import java.util.List; public class ModItemTagsProvider extends ItemTagsProvider { public ModItemTagsProvider(DataGenerator dataGenerator, BlockTagsProvider blockTagsProvider, ExistingFileHelper existingFileHelper) { super(dataGenerator, blockTagsProvider, Main.MOD_ID, existingFileHelper); } @Override protected void addTags() { List<Item> metalIngots = Tags.Items.INGOTS.getValues(); metalIngots.removeAll(Tags.Items.INGOTS_BRICK.getValues()); metalIngots.removeAll(Tags.Items.INGOTS_NETHER_BRICK.getValues()); tag(ModTags.Items.INGOTS_METAL).add(metalIngots.toArray(new Item[0])); } } DataGenerators.java package my.mod.data; import my.mod.Main; import my.mod.data.ModBlockTagsProvider; import my.mod.data.ModItemTagsProvider; import net.minecraft.data.DataGenerator; import net.minecraftforge.common.data.ExistingFileHelper; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.event.lifecycle.GatherDataEvent; @EventBusSubscriber(modid = Main.MOD_ID, bus = EventBusSubscriber.Bus.MOD) public class DataGenerators { @SubscribeEvent public static void gatherData(GatherDataEvent event) { DataGenerator gen = event.getGenerator(); ExistingFileHelper fileHelper = event.getExistingFileHelper(); ModBlockTagsProvider blockTags = new ModBlockTagsProvider(gen, fileHelper); gen.addProvider(blockTags); gen.addProvider(new ModItemTagsProvider(gen, blockTags, fileHelper)); } } ModTags.java package my.mod.setup; import my.mod.Main; import net.minecraft.tags.ITag; import net.minecraft.util.ResourceLocation; import net.minecraft.item.Item; public class ModTags { public static final class Items { public static final ITag.INamedTag<Item> INGOTS_METAL = mod("metal_ingots"); private static ITag.INamedTag<Item> mod(String path) { return ItemTags.createOptional(new ResourceLocation(Main.MOD_ID, path)); } } }
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.