Fixed Fluid recipe NBT write

Wow, forge overrides equals() and hashCode() in FluidStack but did not
int Fluid. It cause fluid has different hash after restart of JVM. Fixed
by adding custom hashCode in GT_Utility. Works fine. Closes #74.
This commit is contained in:
TheDarkDnKTv 2021-03-09 03:22:54 +02:00
parent 3c52821fbc
commit 17fe25bef7
3 changed files with 66 additions and 20 deletions

View file

@ -2,7 +2,6 @@ package gregtechmod.api.recipe;
import gregtechmod.api.util.GT_Log; import gregtechmod.api.util.GT_Log;
import gregtechmod.api.util.GT_Utility; import gregtechmod.api.util.GT_Utility;
import gregtechmod.common.recipe.RecipeEntry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -16,7 +15,6 @@ import java.util.stream.Collectors;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagList;
@ -332,16 +330,18 @@ public class Recipe {
//////////////////// ////////////////////
public void writeToNBT(NBTTagCompound data) { public void writeToNBT(NBTTagCompound data) {
NBTTagList outputs = new NBTTagList(); NBTTagList itemOut = new NBTTagList();
for (ItemStack out : this.getResults(new Random())) { NBTTagList fluidOut = new NBTTagList();
NBTTagCompound stack = out.writeToNBT(new NBTTagCompound()); for (ItemStack out : this.getResults(new Random()))
outputs.appendTag(stack); itemOut.appendTag(out.writeToNBT(new NBTTagCompound()));
} for (FluidStack out : this.getFluidOutputs())
fluidOut.appendTag(out.writeToNBT(new NBTTagCompound()));
data.setInteger("recipeHash", this.hashCode()); data.setInteger("recipeHash", this.hashCode());
data.setTag("recipeOutput", outputs); data.setTag("recipeItemOutput", itemOut);
data.setTag("recipeFluidOutput", fluidOut);
} }
// TODO still does not support fluid output saves
public static Recipe loadFromNBT(RecipeMap<?> recipeMap, NBTTagCompound data) { public static Recipe loadFromNBT(RecipeMap<?> recipeMap, NBTTagCompound data) {
if (recipeMap != null && data.hasKey("recipeHash")) { if (recipeMap != null && data.hasKey("recipeHash")) {
int hash = data.getInteger("recipeHash"); int hash = data.getInteger("recipeHash");
@ -352,21 +352,41 @@ public class Recipe {
} }
} }
if (data.hasKey("recipeOutput")) { if (data.hasKey("recipeItemOutput") || data.hasKey("recipeFluidOutput")) {
NBTTagList recipe = data.getTagList("recipeOutput", 10); NBTTagList itemOut = data.getTagList("recipeItemOutput", 10);
NBTTagList fluidOut = data.getTagList("recipeFluidOutput", 10);
List<ItemStack> stacks = new ArrayList<>(); List<ItemStack> stacks = new ArrayList<>();
for (int i = 0; i < recipe.tagCount(); i++) { List<FluidStack> fluids = new ArrayList<>();
NBTTagCompound stackData = recipe.getCompoundTagAt(i);
for (int i = 0; itemOut != null && i < itemOut.tagCount(); i++) {
NBTTagCompound stackData = itemOut.getCompoundTagAt(i);
ItemStack stack = ItemStack.loadItemStackFromNBT(stackData); ItemStack stack = ItemStack.loadItemStackFromNBT(stackData);
if (stack != null) { if (stack != null) {
stacks.add(stack); stacks.add(stack);
} else GT_Log.log.error("Unable to load stack from tag: " + stackData); } else GT_Log.log.error("Unable to load item stack from tag: " + stackData);
}
for (int i = 0; fluidOut != null && i < fluidOut.tagCount(); i++) {
NBTTagCompound stackData = fluidOut.getCompoundTagAt(i);
FluidStack stack = FluidStack.loadFluidStackFromNBT(stackData);
if (stack != null) {
fluids.add(stack);
} else GT_Log.log.error("Unable to load fluid stack from tag: " + stackData);
} }
return new Recipe(0, 0, 0, false, return new Recipe(0, 0, 0, false,
Collections.singleton(RecipeEntry.singleton(new ItemStack(Blocks.bedrock))), Collections.emptyList(),
stacks, stacks,
Collections.emptyList()); Collections.emptyList(),
Collections.emptyList(),
fluids,
Collections.emptyMap()) {
@Override
public boolean matches(boolean decrease, List<ItemStack> input, List<FluidStack> fluidInputs) {
return false;
}
};
} }
return null; return null;
@ -378,13 +398,16 @@ public class Recipe {
@Override @Override
public int hashCode() { public int hashCode() {
return (startEU * EUt * duration) + (shaped ? 1 : 0) int hash = (3 * startEU) + (3 * EUt) + (3 * duration) + (shaped ? 1 : 0)
+ itemInputs.hashCode() + itemInputs.hashCode()
+ itemOutputs.hashCode() + itemOutputs.hashCode()
+ chancedOutputs.hashCode() + chancedOutputs.hashCode()
+ fluidInputs.hashCode()
+ fluidOutputs.hashCode()
+ metadata.hashCode(); + metadata.hashCode();
for (FluidStack fluid : fluidInputs)
hash += GT_Utility.hashFluidStack(fluid);
for (FluidStack fluid : fluidOutputs)
hash += GT_Utility.hashFluidStack(fluid);
return hash;
} }
@Override @Override

View file

@ -71,6 +71,29 @@ public class GT_Utility {
public static final DecimalFormat sFormat = new DecimalFormat("###,###.##", new DecimalFormatSymbols(Locale.ENGLISH)); public static final DecimalFormat sFormat = new DecimalFormat("###,###.##", new DecimalFormatSymbols(Locale.ENGLISH));
public static int hashFluidStack(FluidStack stack) {
int code = 1;
code = 31*code + hashFluid(stack.getFluid());
code = 31*code + stack.amount;
if (stack.tag != null)
code = 31*code + stack.tag.hashCode();
return code;
}
public static int hashFluid(Fluid fluid) {
int code = 1;
code = 31*code + fluid.getName().hashCode();
if (fluid.getUnlocalizedName() != null)
code = 31*code + fluid.getUnlocalizedName().hashCode();
code = 31*code + fluid.getColor();
code += fluid.getDensity() +
fluid.getLuminosity() +
fluid.getTemperature() +
fluid.getViscosity() +
(fluid.isGaseous() ? 1 : 0);
return code;
}
public static String toIndexNumbers(String string) { public static String toIndexNumbers(String string) {
char[] charArray = string.toCharArray(); char[] charArray = string.toCharArray();
for (int i = 0; i < charArray.length; i++) { for (int i = 0; i < charArray.length; i++) {

View file

@ -85,7 +85,7 @@ public class GeneratorRecipeLogic extends RecipeLogic {
if (getMachine().spaceForOutput(recipe)) { if (getMachine().spaceForOutput(recipe)) {
previousRecipe = recipe; previousRecipe = recipe;
progressTime = 1; progressTime = 1;
leftEU = (int) (recipe.getDuration() * recipe.getEUt() * (efficiency.getAsInt() / 100.0D)); leftEU = (long) (recipe.getDuration() * recipe.getEUt() * (efficiency.getAsInt() / 100.0D));
maxProgressTime = (int) Math.ceil(leftEU * 1.0D / ((MetaTileEntity) getMachine()).maxEUOutput()); maxProgressTime = (int) Math.ceil(leftEU * 1.0D / ((MetaTileEntity) getMachine()).maxEUOutput());
if (consumeInputs(recipe)) { if (consumeInputs(recipe)) {
triggerMachine(true); triggerMachine(true);