Skip to content

Commit

Permalink
build
Browse files Browse the repository at this point in the history
  • Loading branch information
MehVahdJukaar committed Jun 11, 2024
1 parent 5377407 commit 862b579
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 100 deletions.
4 changes: 2 additions & 2 deletions build.properties
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#Thu Apr 11 18:45:01 UTC 2024
#Tue Jun 11 12:51:09 UTC 2024
mapping_version=1.20.1
version=1.0
mod_name=Zeta
mc_version=1.20.1
mapping_channel=official
mod_id=zeta
build_number=17
build_number=18
dir_output=../Build Output/Zeta/
4 changes: 3 additions & 1 deletion changelog.txt
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
- Made some minor tweaks to the creative tab addition logic to try and fix whatever is going on with the sporadic tabs disappearing/crashing bug
- mass recipe get can now also get tags
- recipe crawl event will ignore catalyst items
- Recipe crawl digestion will only target vanilla recipe types as to noc cause problems with unknown recipe types that could have some different interpretation
99 changes: 78 additions & 21 deletions src/main/java/org/violetmoon/zeta/event/play/ZRecipeCrawl.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
package org.violetmoon.zeta.event.play;

import java.util.Collection;

import java.util.List;
import java.util.Set;
import java.util.function.Consumer;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.collect.Streams;
import net.minecraft.core.registries.BuiltInRegistries;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import org.violetmoon.zeta.event.bus.IZetaPlayEvent;

import com.google.common.collect.Multimap;
Expand All @@ -17,32 +26,13 @@
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.ShapedRecipe;
import net.minecraft.world.item.crafting.ShapelessRecipe;
import org.violetmoon.zeta.util.RegistryUtil;

public abstract class ZRecipeCrawl implements IZetaPlayEvent {

public static class Reset extends ZRecipeCrawl { }
public static class Starting extends ZRecipeCrawl { }

public static class Digest extends ZRecipeCrawl {

private final Multimap<Item, ItemStack> digestion;
private final Multimap<Item, ItemStack> backwardsDigestion;

public Digest(Multimap<Item, ItemStack> digestion, Multimap<Item, ItemStack> backwardsDigestion) {
this.digestion = digestion;
this.backwardsDigestion = backwardsDigestion;
}

public boolean has(Item item, boolean backwards) {
return (backwards ? backwardsDigestion : digestion).containsKey(item);
}

public Collection<ItemStack> get(Item item, boolean backwards) {
return (backwards ? backwardsDigestion : digestion).get(item);
}

}

public static abstract class Visit<T extends Recipe<?>> extends ZRecipeCrawl {

public final T recipe;
Expand Down Expand Up @@ -98,4 +88,71 @@ public Misc(Recipe<?> recipe, RegistryAccess access) {
}

}

/**
* Fired after all recipes have been digested
*/
public static class Digest extends ZRecipeCrawl {

private final Multimap<Item, ItemStack> digestion;
private final Multimap<Item, ItemStack> backwardsDigestion;

public Digest(Multimap<Item, ItemStack> digestion, Multimap<Item, ItemStack> backwardsDigestion) {
this.digestion = digestion;
this.backwardsDigestion = backwardsDigestion;
}

public boolean has(Item item, boolean backwards) {
return (backwards ? backwardsDigestion : digestion).containsKey(item);
}

public Collection<ItemStack> get(Item item, boolean backwards) {
return (backwards ? backwardsDigestion : digestion).get(item);
}

/*
* Derivation list -> items to add and then derive (raw materials)
* Whitelist -> items to add and not derive from
* Blacklist -> items to ignore
*/

public void recursivelyFindCraftedItemsFromStrings(@Nullable Collection<String> derivationList, @Nullable Collection<String> whitelist, @Nullable Collection<String> blacklist, Consumer<Item> callback) {
List<Item> parsedDerivationList = derivationList == null ? null : RegistryUtil.massRegistryGet(derivationList, BuiltInRegistries.ITEM);
List<Item> parsedWhitelist = whitelist == null ? null : RegistryUtil.massRegistryGet(whitelist, BuiltInRegistries.ITEM);
List<Item> parsedBlacklist = blacklist == null ? null : RegistryUtil.massRegistryGet(blacklist, BuiltInRegistries.ITEM);

recursivelyFindCraftedItems(parsedDerivationList, parsedWhitelist, parsedBlacklist, callback);
}

public void recursivelyFindCraftedItems(@Nullable Collection<Item> derivationList, @Nullable Collection<Item> whitelist, @Nullable Collection<Item> blacklist, Consumer<Item> callback) {
Collection<Item> trueDerivationList = derivationList == null ? Lists.newArrayList() : derivationList;
Collection<Item> trueWhitelist = whitelist == null ? Lists.newArrayList() : whitelist;
Collection<Item> trueBlacklist = blacklist == null ? Lists.newArrayList() : blacklist;

Streams.concat(trueDerivationList.stream(), trueWhitelist.stream()).forEach(callback);

Set<Item> scanned = Sets.newHashSet(trueDerivationList);
List<Item> toScan = Lists.newArrayList(trueDerivationList);

while(!toScan.isEmpty()) {
Item scan = toScan.remove(0);

if(digestion.containsKey(scan)) {
for(ItemStack digestedStack : digestion.get(scan)) {
Item candidate = digestedStack.getItem();

if(!scanned.contains(candidate)) {
scanned.add(candidate);
toScan.add(candidate);

if(!trueBlacklist.contains(candidate))
callback.accept(candidate);
}
}
}
}
}

}

}
123 changes: 47 additions & 76 deletions src/main/java/org/violetmoon/zeta/util/handler/RecipeCrawlHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import org.violetmoon.zeta.Zeta;
import org.violetmoon.zeta.event.bus.IZetaPlayEvent;
Expand All @@ -15,18 +15,13 @@
import org.violetmoon.zeta.event.load.ZTagsUpdated;
import org.violetmoon.zeta.event.play.ZRecipeCrawl;
import org.violetmoon.zeta.event.play.ZServerTick;
import org.violetmoon.zeta.util.RegistryUtil;
import org.violetmoon.zeta.util.zetalist.ZetaList;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.google.common.collect.Streams;

import net.minecraft.core.NonNullList;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.server.packs.resources.SimplePreparableReloadListener;
import net.minecraft.util.profiling.ProfilerFiller;
Expand All @@ -40,11 +35,13 @@
import net.minecraft.world.item.crafting.ShapedRecipe;
import net.minecraft.world.item.crafting.ShapelessRecipe;

@ApiStatus.Internal
public class RecipeCrawlHandler {

private static final List<Recipe<?>> recipesToLazyDigest = new ArrayList<>();
private static final Multimap<Item, ItemStack> recipeDigestion = HashMultimap.create();
private static final Multimap<Item, ItemStack> backwardsDigestion = HashMultimap.create();
// this just includes vanilla recipe types. Custom recipes could have some conversion scheme that we can't predict
private static final List<Recipe<?>> vanillaRecipesToLazyDigest = new ArrayList<>();
private static final Multimap<Item, ItemStack> vanillaRecipeDigestion = HashMultimap.create();
private static final Multimap<Item, ItemStack> backwardsVanillaDigestion = HashMultimap.create();

private static final Object mutex = new Object();
private static boolean needsCrawl = false;
Expand Down Expand Up @@ -75,45 +72,50 @@ private static void clear() {
mayCrawl = false;
fire(new ZRecipeCrawl.Reset());
}

private static void fire(IZetaPlayEvent event) {
ZetaList.INSTANCE.fireEvent(event);
}

@SuppressWarnings("ConstantValue") // some nullchecks on stuff that is ostensibly non-null, but you never know with mods
@SuppressWarnings("ConstantValue")
// some nullchecks on stuff that is ostensibly non-null, but you never know with mods
private static void load(RecipeManager manager, RegistryAccess access) {
if(!manager.getRecipes().isEmpty()) {
if (!manager.getRecipes().isEmpty()) {
fire(new ZRecipeCrawl.Starting());

recipesToLazyDigest.clear();
recipeDigestion.clear();
backwardsDigestion.clear();
vanillaRecipesToLazyDigest.clear();
vanillaRecipeDigestion.clear();
backwardsVanillaDigestion.clear();

for(Recipe<?> recipe : manager.getRecipes()) {
for (Recipe<?> recipe : manager.getRecipes()) {
try {
if(recipe == null)
if (recipe == null)
throw new IllegalStateException("Recipe is null");
if(recipe.getIngredients() == null)
if (recipe.getIngredients() == null)
throw new IllegalStateException("Recipe ingredients are null");
if(recipe.getResultItem(access) == null)
if (recipe.getResultItem(access) == null)
throw new IllegalStateException("Recipe getResultItem is null");

ZRecipeCrawl.Visit<?> event;
if(recipe instanceof ShapedRecipe sr)
if (recipe instanceof ShapedRecipe sr)
event = new ZRecipeCrawl.Visit.Shaped(sr, access);
else if(recipe instanceof ShapelessRecipe sr)
else if (recipe instanceof ShapelessRecipe sr)
event = new ZRecipeCrawl.Visit.Shapeless(sr, access);
else if(recipe instanceof CustomRecipe cr)
else if (recipe instanceof CustomRecipe cr)
event = new ZRecipeCrawl.Visit.Custom(cr, access);
else if(recipe instanceof AbstractCookingRecipe acr)
else if (recipe instanceof AbstractCookingRecipe acr)
event = new ZRecipeCrawl.Visit.Cooking(acr, access);
else
event = new ZRecipeCrawl.Visit.Misc(recipe, access);

recipesToLazyDigest.add(recipe);
//misc recipes could have custom logic that we cant make many assumptions on. For example FD cutting board recipes are lossy.
//for instance a hanging sign can be cut into a plank. A hanging sign is magnetic but this does not mean planks are
if(!(event instanceof ZRecipeCrawl.Visit.Misc)) {
vanillaRecipesToLazyDigest.add(recipe);
}
fire(event);
} catch (Exception e) {
if(recipe == null)
if (recipe == null)
Zeta.GLOBAL_LOG.error("Encountered null recipe in RecipeManager.getRecipes. This is not good");
else
Zeta.GLOBAL_LOG.error("Failed to scan recipe " + recipe.getId() + ". This should be reported to " + recipe.getId().getNamespace() + "!", e);
Expand All @@ -125,80 +127,49 @@ else if(recipe instanceof AbstractCookingRecipe acr)
@PlayEvent
public static void onTick(ZServerTick.Start tick) {
synchronized (mutex) {
if(mayCrawl && needsCrawl) {
if (mayCrawl && needsCrawl) {
RecipeManager manager = tick.getServer().getRecipeManager();
RegistryAccess access = tick.getServer().registryAccess();
load(manager, access);
needsCrawl = false;
}

if(!recipesToLazyDigest.isEmpty()) {
recipeDigestion.clear();
backwardsDigestion.clear();
if (!vanillaRecipesToLazyDigest.isEmpty()) {
vanillaRecipeDigestion.clear();
backwardsVanillaDigestion.clear();

for(Recipe<?> recipe : recipesToLazyDigest)
for (Recipe<?> recipe : vanillaRecipesToLazyDigest)
digest(recipe, tick.getServer().registryAccess());

recipesToLazyDigest.clear();
fire(new ZRecipeCrawl.Digest(recipeDigestion, backwardsDigestion));
vanillaRecipesToLazyDigest.clear();
fire(new ZRecipeCrawl.Digest(vanillaRecipeDigestion, backwardsVanillaDigestion));
}
}
}

private static void digest(Recipe<?> recipe, RegistryAccess access) {
// we only digest vanilla recipe types. Custom recipes could have some conversion scheme that we can't predict
ItemStack out = recipe.getResultItem(access);
Item outItem = out.getItem();

NonNullList<Ingredient> ingredients = recipe.getIngredients();
for(Ingredient ingredient : ingredients) {
for(ItemStack inStack : ingredient.getItems()) {
recipeDigestion.put(inStack.getItem(), out);
backwardsDigestion.put(outItem, inStack);
for (Ingredient ingredient : ingredients) {
for (ItemStack inStack : ingredient.getItems()) {
//don't include catalyst items. This includes partial ones like buckets and such
if (!inStack.getCraftingRemainingItem().isEmpty()) {
vanillaRecipeDigestion.put(inStack.getItem(), out);
backwardsVanillaDigestion.put(outItem, inStack);
}
}
}
}

/*
* Derivation list -> items to add and then derive (raw materials)
* Whitelist -> items to add and not derive from
* Blacklist -> items to ignore
*/

public static void recursivelyFindCraftedItemsFromStrings(@Nullable Collection<String> derivationList, @Nullable Collection<String> whitelist, @Nullable Collection<String> blacklist, Consumer<Item> callback) {
List<Item> parsedDerivationList = derivationList == null ? null : RegistryUtil.massRegistryGet(derivationList, BuiltInRegistries.ITEM);
List<Item> parsedWhitelist = whitelist == null ? null : RegistryUtil.massRegistryGet(whitelist, BuiltInRegistries.ITEM);
List<Item> parsedBlacklist = blacklist == null ? null : RegistryUtil.massRegistryGet(blacklist, BuiltInRegistries.ITEM);

recursivelyFindCraftedItems(parsedDerivationList, parsedWhitelist, parsedBlacklist, callback);
//delete this if you see it. Just here so this update doesnt crash with an old quark version
@Deprecated(forRemoval = true)
public void recursivelyFindCraftedItemsFromStrings(@Nullable Collection<String> derivationList, @Nullable Collection<String> whitelist, @Nullable Collection<String> blacklist, Consumer<Item> callback) {
}

public static void recursivelyFindCraftedItems(@Nullable Collection<Item> derivationList, @Nullable Collection<Item> whitelist, @Nullable Collection<Item> blacklist, Consumer<Item> callback) {
Collection<Item> trueDerivationList = derivationList == null ? Lists.newArrayList() : derivationList;
Collection<Item> trueWhitelist = whitelist == null ? Lists.newArrayList() : whitelist;
Collection<Item> trueBlacklist = blacklist == null ? Lists.newArrayList() : blacklist;

Streams.concat(trueDerivationList.stream(), trueWhitelist.stream()).forEach(callback);

Set<Item> scanned = Sets.newHashSet(trueDerivationList);
List<Item> toScan = Lists.newArrayList(trueDerivationList);

while(!toScan.isEmpty()) {
Item scan = toScan.remove(0);

if(recipeDigestion.containsKey(scan)) {
for(ItemStack digestedStack : recipeDigestion.get(scan)) {
Item candidate = digestedStack.getItem();

if(!scanned.contains(candidate)) {
scanned.add(candidate);
toScan.add(candidate);

if(!trueBlacklist.contains(candidate))
callback.accept(candidate);
}
}
}
}
@Deprecated(forRemoval = true)
public void recursivelyFindCraftedItems(@Nullable Collection<Item> derivationList, @Nullable Collection<Item> whitelist, @Nullable Collection<Item> blacklist, Consumer<Item> callback) {
}

}
Loading

0 comments on commit 862b579

Please sign in to comment.