Jump to content

[1.15.2] Recipe input doubles - custom crafting table + recipe [Solved]


Thorius

Recommended Posts

Hello,

i created a special crafting table and recipe. If i craft something, then the ingredients get decreased by one, but then they double themselves. For example: a stack has initally 3 items, then after a single craft it becomes 4, then 6, 10, 18 and so on.

If the recipeType is changed to the normal vanilla one in the container, then it functions properly. Consequently it is probably the custom recipe responsible for the error.

This, however, contradicts my findings, the CraftingResultSlot should be responsible for handling the ingredients slots. But as i said, the container class works fine with the vanilla recipes and i didn't find anything related in the classes responsible for the recipes.

 

Container class:

package com.thoriuslight.professionsmod.inventory.container;

import java.util.Optional;

import com.thoriuslight.professionsmod.init.BlockInit;
import com.thoriuslight.professionsmod.init.ModContainerTypes;
import com.thoriuslight.professionsmod.init.RecipeSerializerInit;
import com.thoriuslight.professionsmod.item.crafting.ISmithRecipe;

import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.CraftResultInventory;
import net.minecraft.inventory.CraftingInventory;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.container.CraftingResultSlot;
import net.minecraft.inventory.container.RecipeBookContainer;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.RecipeItemHelper;
import net.minecraft.network.PacketBuffer;
import net.minecraft.network.play.server.SSetSlotPacket;
import net.minecraft.util.IWorldPosCallable;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

public class SmithCraftingContainer extends RecipeBookContainer<CraftingInventory>{
	private final CraftingInventory craftMatrix = new CraftingInventory(this, 3, 3);
	private final CraftResultInventory craftResult = new CraftResultInventory();
	private final IWorldPosCallable canInteractWithCallable;
	private final PlayerEntity player;
	
	public SmithCraftingContainer(int windowId, final PlayerInventory playerInventory, final PacketBuffer data) {
		this(windowId, playerInventory, IWorldPosCallable.DUMMY);
	}
	
	public SmithCraftingContainer(int windowId, final PlayerInventory playerInventory) {
		this(windowId, playerInventory, IWorldPosCallable.DUMMY);
	}
	
	public SmithCraftingContainer(int windowId, final PlayerInventory playerInventory, IWorldPosCallable worldPosCallable) {
		super(ModContainerTypes.SMITH_CRAFTING.get(), windowId);
		this.canInteractWithCallable = worldPosCallable;
		this.player = playerInventory.player;
	    this.addSlot(new CraftingResultSlot(playerInventory.player, this.craftMatrix, this.craftResult, 0, 124, 35));
	    
	    for(int i = 0; i < 3; ++i) {
	    	for(int j = 0; j < 3; ++j) {
	    		this.addSlot(new Slot(this.craftMatrix, j + i * 3, 30 + j * 18, 17 + i * 18));
	    	}
	    }

	    for(int k = 0; k < 3; ++k) {
	    	for(int i1 = 0; i1 < 9; ++i1) {
	    		this.addSlot(new Slot(playerInventory, i1 + k * 9 + 9, 8 + i1 * 18, 84 + k * 18));
	    	}
	    }

	    for(int l = 0; l < 9; ++l) {
	    	this.addSlot(new Slot(playerInventory, l, 8 + l * 18, 142));
	    }
	}
	
	protected static void func_217066_a(int p_217066_0_, World world, PlayerEntity p_217066_2_, CraftingInventory craftInv, CraftResultInventory p_217066_4_) {
		if (!world.isRemote) {
			ServerPlayerEntity serverplayerentity = (ServerPlayerEntity)p_217066_2_;
			ItemStack itemstack = ItemStack.EMPTY;
			Optional<ISmithRecipe> optional = world.getServer().getRecipeManager().getRecipe(RecipeSerializerInit.SMITH_TYPE, craftInv, world);

			if (optional.isPresent()) {
				ISmithRecipe ismithrecipe = optional.get();

				if (p_217066_4_.canUseRecipe(world, serverplayerentity, ismithrecipe)) {
					itemstack = ismithrecipe.getCraftingResult(craftInv);
				}
			}

			p_217066_4_.setInventorySlotContents(0, itemstack);
			serverplayerentity.connection.sendPacket(new SSetSlotPacket(p_217066_0_, 0, itemstack));
		}
	}
	
	@Override
	public void onCraftMatrixChanged(IInventory inventoryIn) {
		this.canInteractWithCallable.consume((world, p_217069_2_) -> {
			func_217066_a(this.windowId, world, this.player, this.craftMatrix, this.craftResult);
		});
	}
	
	@Override
	public void fillStackedContents(RecipeItemHelper itemHelperIn) {
		this.craftMatrix.fillStackedContents(itemHelperIn);
	}

	@Override
	public void clear() {
		this.craftMatrix.clear();
		this.craftResult.clear();
	}

	@Override
	public boolean matches(IRecipe<? super CraftingInventory> recipeIn) {
		return recipeIn.matches(this.craftMatrix, this.player.world);
	}
	
	@Override
	public void onContainerClosed(PlayerEntity playerIn) {
		super.onContainerClosed(playerIn);
		this.canInteractWithCallable.consume((p_217068_2_, p_217068_3_) -> {
			this.clearContainer(playerIn, p_217068_2_, this.craftMatrix);
		});
	}

	@Override
	public boolean canInteractWith(PlayerEntity playerIn) {
		   return isWithinUsableDistance(this.canInteractWithCallable, playerIn, BlockInit.SMITHCRAFTINGTABLE_BLOCK.get());
	}
	
	@Override
	public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) {
		ItemStack itemstack = ItemStack.EMPTY;
		Slot slot = this.inventorySlots.get(index);
		if (slot != null && slot.getHasStack()) {
			ItemStack itemstack1 = slot.getStack();
			itemstack = itemstack1.copy();
			if (index == 0) {
				this.canInteractWithCallable.consume((p_217067_2_, p_217067_3_) -> {
					itemstack1.getItem().onCreated(itemstack1, p_217067_2_, playerIn);
				});
				if (!this.mergeItemStack(itemstack1, 10, 46, true)) {
					return ItemStack.EMPTY;
				}

				slot.onSlotChange(itemstack1, itemstack);
			} else if (index >= 10 && index < 46) {
				if (!this.mergeItemStack(itemstack1, 1, 10, false)) {
					if (index < 37) {
						if (!this.mergeItemStack(itemstack1, 37, 46, false)) {
							return ItemStack.EMPTY;
						}
					} else if (!this.mergeItemStack(itemstack1, 10, 37, false)) {
						return ItemStack.EMPTY;
					}
				}
			} else if (!this.mergeItemStack(itemstack1, 10, 46, false)) {
				return ItemStack.EMPTY;
			}

			if (itemstack1.isEmpty()) {
				slot.putStack(ItemStack.EMPTY);
			} else {
				slot.onSlotChanged();
			}

			if (itemstack1.getCount() == itemstack.getCount()) {
				return ItemStack.EMPTY;
			}

			ItemStack itemstack2 = slot.onTake(playerIn, itemstack1);
			if (index == 0) {
				playerIn.dropItem(itemstack2, false);
			}
		}

		return itemstack;
	}
	
	@Override
	public boolean canMergeSlot(ItemStack stack, Slot slotIn) {
		return slotIn.inventory != this.craftResult && super.canMergeSlot(stack, slotIn);
	}
	
	@Override
	public int getOutputSlot() {
		return 0;
	}
	
	@Override
	public int getWidth() {
		return this.craftMatrix.getWidth();
	}
	
	@Override
	public int getHeight() {
		return this.craftMatrix.getHeight();
	}
	
	@OnlyIn(Dist.CLIENT)
	@Override
	public int getSize() {
		return 10;
	}
}

 

Recipe class:

package com.thoriuslight.professionsmod.item.crafting;

import com.thoriuslight.professionsmod.init.RecipeSerializerInit;

import net.minecraft.inventory.CraftingInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipeSerializer;
import net.minecraft.item.crafting.Ingredient;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;

public class SmithRecipe implements ISmithRecipe{
	
	private final int recipeWidth;
	private final int recipeHeight;
	private final NonNullList<Ingredient> recipeItems;
	private final ItemStack recipeOutput;
	private final ResourceLocation id;
	
	public SmithRecipe(ResourceLocation id, int recipeWidthIn, int recipeHeightIn, NonNullList<Ingredient> recipeItemsIn, ItemStack output){
		this.recipeWidth = recipeWidthIn;
		this.recipeHeight = recipeHeightIn;
		this.id = id;
		this.recipeItems = recipeItemsIn;
		this.recipeOutput = output;
	}
	
	@Override
	public boolean matches(CraftingInventory inv, World worldIn) {
		//Horizontal shift
		for(int x = 0; x <= inv.getWidth() - this.recipeWidth; ++x) {
			//Vertical shift
			for(int y = 0; y <= inv.getHeight() - this.recipeHeight; ++y) {
				if (this.checkMatch(inv, x, y, true)) {
					return true;
				}
				if (this.checkMatch(inv, x, y, false)) {
					return true;
				}
			}
		}
		return false;
	}
	
	private boolean checkMatch(CraftingInventory craftingInventory, int p_77573_2_, int p_77573_3_, boolean p_77573_4_) {
		for(int i = 0; i < craftingInventory.getWidth(); ++i) {
			for(int j = 0; j < craftingInventory.getHeight(); ++j) {
				int k = i - p_77573_2_;
				int l = j - p_77573_3_;
				Ingredient ingredient = Ingredient.EMPTY;
				if (k >= 0 && l >= 0 && k < this.recipeWidth && l < this.recipeHeight) {
					if (p_77573_4_) {
						ingredient = this.recipeItems.get(this.recipeWidth - k - 1 + l * this.recipeWidth);
					} else {
						ingredient = this.recipeItems.get(k + l * this.recipeWidth);
					}
				}
				if (!ingredient.test(craftingInventory.getStackInSlot(i + j * craftingInventory.getWidth()))) {
					return false;
				}
			}
		}
		return true;
	}
	
	@Override
	public ItemStack getCraftingResult(CraftingInventory inv) {
		return this.recipeOutput.copy();
	}

	@Override
	public boolean canFit(int width, int height) {
		return width >= this.recipeWidth && height >= this.recipeHeight;
	}

	@Override
	public ItemStack getRecipeOutput() {
		return this.recipeOutput;
	}

	@Override
	public ResourceLocation getId() {
		return this.id;
	}

	@Override
	public IRecipeSerializer<?> getSerializer() {
		return RecipeSerializerInit.SMITH_SERIALIZER.get();
	}

	@Override
	public Ingredient getInput() {
		return null;
	}
	
	public int getRecipeHeight() {
		return this.recipeHeight;
	}
	
	public int getRecipeWidth() {
		return this.recipeWidth;
	}
	@Override
	public NonNullList<Ingredient> getIngredients() {
		return this.recipeItems;
	}
}

 

IRecipe class:

package com.thoriuslight.professionsmod.item.crafting;

import javax.annotation.Nonnull;

import com.thoriuslight.professionsmod.ProfessionsMod;

import net.minecraft.inventory.CraftingInventory;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.IRecipeType;
import net.minecraft.item.crafting.Ingredient;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.registry.Registry;

public interface ISmithRecipe extends IRecipe<CraftingInventory>{
	ResourceLocation RECIPE_TYPE_ID = new ResourceLocation(ProfessionsMod.MODID, "smith");
	
	@Nonnull
	@Override
	default IRecipeType<?> getType() {
		return Registry.RECIPE_TYPE.getValue(RECIPE_TYPE_ID).get();
	}
	
	@Override
	default boolean canFit(int width, int height) {
		return false;
	}
	
	Ingredient getInput();
}

 

RecipeSerializer class:

package com.thoriuslight.professionsmod.item.crafting;

import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;

import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipeSerializer;
import net.minecraft.item.crafting.Ingredient;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.JSONUtils;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.crafting.CraftingHelper;
import net.minecraftforge.registries.ForgeRegistryEntry;

public class SmithRecipeSerializer extends ForgeRegistryEntry<IRecipeSerializer<?>> implements IRecipeSerializer<SmithRecipe>{

	@Override
	public SmithRecipe read(ResourceLocation recipeId, JsonObject json) {
        Map<String, Ingredient> map = SmithRecipeSerializer.deserializeKey(JSONUtils.getJsonObject(json, "key"));
        String[] astring = SmithRecipeSerializer.shrink(SmithRecipeSerializer.patternFromJson(JSONUtils.getJsonArray(json, "pattern")));
        int i = astring[0].length();
        int j = astring.length;
		NonNullList<Ingredient> input = deserializeIngredients(astring, map, i, j);
		ItemStack ouput = CraftingHelper.getItemStack(JSONUtils.getJsonObject(json, "result"), true);
		return new SmithRecipe(recipeId, i, j, input, ouput);
	}
	
	private static NonNullList<Ingredient> deserializeIngredients(String[] pattern, Map<String, Ingredient> keys, int patternWidth, int patternHeight) {
		NonNullList<Ingredient> nonnulllist = NonNullList.withSize(patternWidth * patternHeight, Ingredient.EMPTY);
		Set<String> set = Sets.newHashSet(keys.keySet());
		set.remove(" ");
		for(int i = 0; i < pattern.length; ++i) {
			for(int j = 0; j < pattern[i].length(); ++j) {
				String s = pattern[i].substring(j, j + 1);
				Ingredient ingredient = keys.get(s);
				if (ingredient == null) {
					throw new JsonSyntaxException("Pattern references symbol '" + s + "' but it's not defined in the key");
				}
				set.remove(s);
				nonnulllist.set(j + patternWidth * i, ingredient);
			}
		}
		if (!set.isEmpty()) {
			throw new JsonSyntaxException("Key defines symbols that aren't used in pattern: " + set);
		} else {
			return nonnulllist;
		}
	}
	
	private static Map<String, Ingredient> deserializeKey(JsonObject json) {
		Map<String, Ingredient> map = Maps.newHashMap();
		for(Entry<String, JsonElement> entry : json.entrySet()) {
			if (entry.getKey().length() != 1) {
				throw new JsonSyntaxException("Invalid key entry: '" + (String)entry.getKey() + "' is an invalid symbol (must be 1 character only).");
			}
			if (" ".equals(entry.getKey())) {
				throw new JsonSyntaxException("Invalid key entry: ' ' is a reserved symbol.");
			}
			map.put(entry.getKey(), Ingredient.deserialize(entry.getValue()));
		}
		map.put(" ", Ingredient.EMPTY);
		return map;
	}
	
	@VisibleForTesting
	static String[] shrink(String... toShrink) {
		int i = Integer.MAX_VALUE;
		int j = 0;
		int k = 0;
		int l = 0;
		for(int i1 = 0; i1 < toShrink.length; ++i1) {
			String s = toShrink[i1];
			i = Math.min(i, firstNonSpace(s));
			int j1 = lastNonSpace(s);
			j = Math.max(j, j1);
			if (j1 < 0) {
				if (k == i1) {
					++k;
				}
				++l;
			} else {
				l = 0;
			}
		}
		if (toShrink.length == l) {
			return new String[0];
		} else {
			String[] astring = new String[toShrink.length - l - k];
			for(int k1 = 0; k1 < astring.length; ++k1) {
				astring[k1] = toShrink[k1 + k].substring(i, j + 1);
			}
	        return astring;
		}
	}
	
	private static int firstNonSpace(String str) {
		int i;
		for(i = 0; i < str.length() && str.charAt(i) == ' '; ++i) {
			;
		}
		return i;
	}

	private static int lastNonSpace(String str) {
		int i;
		for(i = str.length() - 1; i >= 0 && str.charAt(i) == ' '; --i) {
			;
		}
		return i;
	}
	
	private static String[] patternFromJson(JsonArray jsonArr) {
		String[] astring = new String[jsonArr.size()];
		if (astring.length > 3) {
			throw new JsonSyntaxException("Invalid pattern: too many rows, " + 3 + " is maximum");
		} else if (astring.length == 0) {
			throw new JsonSyntaxException("Invalid pattern: empty pattern not allowed");
		} else {
			for(int i = 0; i < astring.length; ++i) {
				String s = JSONUtils.getString(jsonArr.get(i), "pattern[" + i + "]");
				if (s.length() > 3) {
					throw new JsonSyntaxException("Invalid pattern: too many columns, " + 3 + " is maximum");
				}
				if (i > 0 && astring[0].length() != s.length()) {
					throw new JsonSyntaxException("Invalid pattern: each row must be the same width");
				}
				astring[i] = s;
			}
			return astring;
		}
	}
	
	@Override
	public SmithRecipe read(ResourceLocation recipeId, PacketBuffer buffer) {
		int i = buffer.readVarInt();
        int j = buffer.readVarInt();
        NonNullList<Ingredient> nonnulllist = NonNullList.withSize(i * j, Ingredient.EMPTY);
        for(int k = 0; k < nonnulllist.size(); ++k) {
           nonnulllist.set(k, Ingredient.read(buffer));
        }
        ItemStack itemstack = buffer.readItemStack();
        return new SmithRecipe(recipeId, i, j, nonnulllist, itemstack);
	}

	@Override
	public void write(PacketBuffer buffer, SmithRecipe recipe) {
        buffer.writeVarInt(recipe.getRecipeWidth());
        buffer.writeVarInt(recipe.getRecipeHeight());

        for(Ingredient ingredient : recipe.getIngredients()) {
        	ingredient.write(buffer);
        }

        buffer.writeItemStack(recipe.getRecipeOutput());
	}

}

 

Recipe Init class:

package com.thoriuslight.professionsmod.init;

import com.thoriuslight.professionsmod.ProfessionsMod;
import com.thoriuslight.professionsmod.item.crafting.ISmithRecipe;
import com.thoriuslight.professionsmod.item.crafting.SmithRecipe;
import com.thoriuslight.professionsmod.item.crafting.SmithRecipeSerializer;

import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.IRecipeSerializer;
import net.minecraft.item.crafting.IRecipeType;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.registry.Registry;
import net.minecraftforge.fml.RegistryObject;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;

public class RecipeSerializerInit {
	
	public static final IRecipeSerializer<SmithRecipe> SMITH_RECIPE_SERIALIZER = new SmithRecipeSerializer();
	public static final IRecipeType<ISmithRecipe> SMITH_TYPE = registerType(ISmithRecipe.RECIPE_TYPE_ID);
	
	public static final DeferredRegister<IRecipeSerializer<?>> RECIPE_SERIALIZERS = new DeferredRegister<>(ForgeRegistries.RECIPE_SERIALIZERS, ProfessionsMod.MODID);
	
	public static final RegistryObject<IRecipeSerializer<?>> SMITH_SERIALIZER = RECIPE_SERIALIZERS.register("smith", () -> SMITH_RECIPE_SERIALIZER);

	private static IRecipeType<ISmithRecipe> registerType(ResourceLocation recipeTypeId) {
		return Registry.register(Registry.RECIPE_TYPE, recipeTypeId, new RecipeType<>());
	}
	
	private static class RecipeType<T extends IRecipe<?>> implements IRecipeType<T> {
		@Override
		public String toString() {
			return Registry.RECIPE_TYPE.getKey(this).toString();
		}
	}
}

 

Thank you for taking your time to help. I really appreciate it.

Edited by Thorius
Link to comment
Share on other sites

5 hours ago, Thorius said:

If i craft something, then the ingredients get decreased by one, but then they double themselves.

Then that's probably a desynchronisation across what you are changing. You are probably handling something that is not isolated and directly affects a field directly. As for what, I can't tell as most of this code seems to be from the shaped crafting recipe. You should rehandle your code such that it extends directly from the shaped crafting recipe if you are going to do it this way. Quite literally, I see no different between crafting tables other than a different recipe type. Therefore, you could reuse everything except the container and screen which could just be simply transferred as needed. This is not to mention a little bit of problematic logic during synchronization and how containers are handled.

 

Just so I understand, are you saying the output is duplicating or the input?

Link to comment
Share on other sites

The input gets duplicated.

However i found the problem. I extended the CraftResultSlot for debug reasons and i noticed that it uses IRecipeType.CRAFTING to get the ingredients. After changing it to my type it works fine.

Thanks for the help anyways.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Minecraft java and forge seem to have it out for me, any ideas? I have had issues with exit code 1 while loading forge -fabric was having the same issues, but I seemed to fix it in these repairs? (tried different versions upwards from 1.19 to 1.20.2 for forge, nothing worked and I'm confident older versions wouldn't either) -The launcher itself loads fine, it will load the game within the launcher, and then crash the moment it tries to load outside of the launcher. I have tried the default launcher, legacy launcher, and the curse forge launcher, none have worked! (all have had the same problem) I think this started when I took a break and upgraded to windows 11 and wonder if that changed anything? I have tried the following: uninstalled & reinstalled java, (I have having issues where I download jdk 17 but only 8 would show up (would not show up anywhere but the control panel, not even the official uninstaller, I *think* I got that fixed) tried jarfix uninstalled & reinstalled minecraft tried alternate launchers -forge & legacy, & repaired them too. tried without mods updated game drivers uninstalled and reinstalled forge -including completely wiping it from my system changed java excutable path followed everything in the error code 1 post completely reset my pc I tried to change the launch path but couldn't seem to get it to work -the default launcher wont let me even see properties as an option, i have yet to try with the other two (i did try on legacy but it was being weird) I want to include my debug log; but its over the max size? sorry my brains gone numb from trying to fix this for the past 2 days
    • I personally create registries using DataPackRegistryEvent.NewRegistry. It's pretty powerful as long as you know how to make codecs. In some class, make a registry key like so: public static final ResourceKey<Registry<MyDataType>> MY_REGISTRY = ResourceKey.createRegistryKey(new ResourceLocation(MyMod.MOD_ID, "registry_name")); This will make a registry that holds objects of type "MyDataType". JSON files stored in data/<datapack_namespace>/modid/registryname/ will be parsed and put into this registry. Note that the directory structure has a folder named after your mod inside your datapack directory, so the actual path would look like: data/my_mod/my_mod/registry_name (or if another mod uses your registry: data/their_mod/my_mod/registry_name. To register this registry, subscribe to the DataPackRegistryEvent.NewRegistry event on the MOD event bus and call event.dataPackRegistry() for every registry you have. An example of what I'm doing for my mod (this is in the constructor for the main mod file): IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); bus.addListener((DataPackRegistryEvent.NewRegistry event) -> { event.dataPackRegistry(ModRegistries.INSULATOR_DATA, InsulatorData.CODEC); }); CODEC is a public static field inside the class for the custom data type I am registering. It holds a Codec<InsulatorData> that tells Minecraft how to serialize/deserialize the data. Most of my data so far can be represented by records, so I use RecordCodecBuilder.create() to do this: public static final Codec<InsulatorData> CODEC = RecordCodecBuilder.create(instance -> instance.group( // Yadda yadda ).apply(instance, InsulatorData::new)); What exactly to put here depends on what you're trying to do, so that's up to you. But basically you're just defining a list of codecs that correspond to the parameters of the record (data type). Most primitive data types have records in the Codec class (ex. Codec.INT) that you can use, and other classes like ResourceLocation have their own codecs as a static field (ex. ResourceLocation.CODEC). Hopefully this is what you're looking for, and that this helps.
    • Good days  I finnaly manage to fix and get a working gui from BlockItem and from BlockEntity the next issues i have to fix is this the block Entity model for some reason is moved to the south west  this briefcase model must be centered but is moved to a side, i have nothing weird in the code but this is happening // ########## ########## ########## ########## @Override public RenderShape getRenderShape(BlockState blkstate) {     return RenderShape.MODEL; } the block model is out of place However The hitBox of the block is right in place   ########################################################################################################### This next issue  Mi gui also adds the 5 slots from the player equipment the thing is theres no filter to determine whats can be put in an armor slot and what not      i have this method that draws the slots for the armor, the part i dont get i slike wheres the code that responds when you set an item in a item slot to do checks and allow the item to be set or not  //########## ########## ########## //Draw Player Armor private void addPlayerArmorSlots(Inventory playerInventory) { // 36 this.addSlot(new Slot(playerInventory, 39, 8, 8)); this.addSlot(new Slot(playerInventory, 38, 8, 26)); this.addSlot(new Slot(playerInventory, 37, 8, 44)); this.addSlot(new Slot(playerInventory, 36, 8, 62)); this.addSlot(new Slot(playerInventory, 40, 26, 53)); }   theres must be a method that triggers when you set a itemstack inside an slot and allows to do a check if its a valid item for that slot                                             
    • No like how do I use my new PreperableReloadListener, I know how to set it up now and register it, I just need to know how to use it in other classes.
    • Completely out of the blue my forge loader is lagging, although at 120 fps. Like when I turn it lags, or hit mobs it lags, or run sometimes although staying at 120 fps. I found another person having a similar problem:  But there was no solution I dont think. I tried everything from: 1. Updating my computer 2. Updating/reinstalling forge 3. Testing if allocated memory was problem (if it was low or high or mid nothing changed) 4. Adding various performance mods 5. Deleting most of my profiles if storage was a problem.   Really not sure what to do next or if forge is just broken for ever for me now.  
  • Topics

×
×
  • Create New...

Important Information

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