From 3bb07828c7a68c3fba34ea51866a17359a44316f Mon Sep 17 00:00:00 2001 From: MartinSVK12 <37455793+MartinSVK12@users.noreply.github.com> Date: Sun, 20 Jul 2025 15:36:41 +0200 Subject: [PATCH 1/6] Favourites and recipe trees. --- build.gradle | 3 +- gradle.properties | 2 +- .../java/turing/tmb/InfoRecipeCategory.java | 7 +- src/main/java/turing/tmb/RecipeIndex.java | 5 + .../java/turing/tmb/RecipeIngredient.java | 20 + .../java/turing/tmb/RecipeTreeIngredient.java | 21 + src/main/java/turing/tmb/TMB.java | 4 + src/main/java/turing/tmb/TMBRuntime.java | 17 +- src/main/java/turing/tmb/TypedIngredient.java | 33 +- .../java/turing/tmb/api/VanillaTypes.java | 23 + .../IIngredientTypeWithSubtypes.java | 8 + .../tmb/api/ingredient/ITypedIngredient.java | 8 + .../tmb/api/recipe/IRecipeCategory.java | 2 + .../turing/tmb/api/recipe/IRecipeIndex.java | 3 + .../turing/tmb/api/recipe/IRecipeSlot.java | 8 + .../turing/tmb/api/runtime/ITMBRuntime.java | 11 + .../turing/tmb/client/RecipeTreePage.java | 299 +++++ .../turing/tmb/client/ScreenRecipeTree.java | 1046 +++++++++++++++++ .../turing/tmb/client/ScreenTMBRecipe.java | 96 +- .../java/turing/tmb/client/TMBRenderer.java | 151 ++- .../java/turing/tmb/mixin/LevelDataMixin.java | 97 ++ .../tmb/mixin/client/GameSettingsMixin.java | 24 + .../client/ScreenContainerAbstractMixin.java | 2 + .../turing/tmb/mixin/client/ScreenMixin.java | 2 + src/main/java/turing/tmb/util/IKeybinds.java | 7 + .../AbstractCraftingRecipeCategory.java | 11 +- .../tmb/vanilla/FurnaceRecipeCategory.java | 9 +- .../turing/tmb/vanilla/MobInfoCategory.java | 15 +- .../tmb/vanilla/TrommelRecipeCategory.java | 11 +- src/main/resources/lang/tmb/en_US.lang | 7 + src/main/resources/tmb.mixins.json | 1 + 31 files changed, 1927 insertions(+), 26 deletions(-) create mode 100644 src/main/java/turing/tmb/RecipeIngredient.java create mode 100644 src/main/java/turing/tmb/RecipeTreeIngredient.java create mode 100644 src/main/java/turing/tmb/client/RecipeTreePage.java create mode 100644 src/main/java/turing/tmb/client/ScreenRecipeTree.java create mode 100644 src/main/java/turing/tmb/mixin/LevelDataMixin.java diff --git a/build.gradle b/build.gradle index 3e9b035..bfda671 100644 --- a/build.gradle +++ b/build.gradle @@ -160,7 +160,7 @@ remapJar { archiveVersion.set(archiveVersion.get()+"-${bta_version}") } -publishing { +/*publishing { if(checkVersion(project.mod_group,project.mod_name,project.mod_version)) { repositories { maven { @@ -198,3 +198,4 @@ static boolean checkVersion(String group, String name, String version) { return true } } +*/ diff --git a/gradle.properties b/gradle.properties index 5358f64..1c9491e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,6 +15,6 @@ mod_menu_version=3.0.0 halplibe_version=5.2.4 # Mod -mod_version=1.1.2 +mod_version=1.2.0 mod_group=turing mod_name=tmb diff --git a/src/main/java/turing/tmb/InfoRecipeCategory.java b/src/main/java/turing/tmb/InfoRecipeCategory.java index 28f2a69..c66c76c 100644 --- a/src/main/java/turing/tmb/InfoRecipeCategory.java +++ b/src/main/java/turing/tmb/InfoRecipeCategory.java @@ -45,13 +45,18 @@ public IDrawable getBackground() { @Override public void drawRecipe(ITMBRuntime runtime, InfoRecipeTranslator recipe, IRecipeLayout layout, List ingredients, ILookupContext context) { - ingredients.add(0, new IngredientList(recipe.getOriginal().getIngredient())); + getIngredients(recipe, layout, context, ingredients); String text = recipe.getOriginal().getInfoTranslated(); runtime.getGuiHelper().getMinecraft().font.drawStringIntoConstrainedBlock(text, 3, 21, background.getWidth() - 5, 0xFFFFFF, true); runtime.getGuiHelper().getMinecraft().font.drawStringIntoConstrainedBlock(text, 2, 20, background.getWidth() - 4, 0xFFFFFF); } + @Override + public void getIngredients(InfoRecipeTranslator recipe, IRecipeLayout layout, ILookupContext context, List ingredients) { + ingredients.add(0, new IngredientList(recipe.getOriginal().getIngredient())); + } + @Override public IRecipeLayout getRecipeLayout() { return new RecipeLayoutBuilder() diff --git a/src/main/java/turing/tmb/RecipeIndex.java b/src/main/java/turing/tmb/RecipeIndex.java index f4cc2c1..cde9af7 100644 --- a/src/main/java/turing/tmb/RecipeIndex.java +++ b/src/main/java/turing/tmb/RecipeIndex.java @@ -116,6 +116,11 @@ public List> getAllCategories() { return Collections.unmodifiableList(categories); } + @Override + public Map, List>> getRecipeLists() { + return recipeLists; + } + @Override public void registerCatalyst(IRecipeCategory category, ITypedIngredient catalyst) { catalysts.get(category).add(catalyst); diff --git a/src/main/java/turing/tmb/RecipeIngredient.java b/src/main/java/turing/tmb/RecipeIngredient.java new file mode 100644 index 0000000..9b4f8ca --- /dev/null +++ b/src/main/java/turing/tmb/RecipeIngredient.java @@ -0,0 +1,20 @@ +package turing.tmb; + +import turing.tmb.api.ingredient.ITypedIngredient; +import turing.tmb.api.recipe.IRecipeCategory; +import turing.tmb.api.recipe.IRecipeTranslator; +import turing.tmb.api.recipe.RecipeIngredientRole; + +public class RecipeIngredient { + public final ITypedIngredient ingredient; + public final IRecipeTranslator recipe; + public final IRecipeCategory> category; + public final RecipeIngredientRole role; + + public RecipeIngredient(ITypedIngredient ingredient, IRecipeTranslator recipe, IRecipeCategory category, RecipeIngredientRole role) { + this.ingredient = ingredient; + this.recipe = recipe; + this.category = (IRecipeCategory>) category; + this.role = role; + } +} diff --git a/src/main/java/turing/tmb/RecipeTreeIngredient.java b/src/main/java/turing/tmb/RecipeTreeIngredient.java new file mode 100644 index 0000000..d81eca5 --- /dev/null +++ b/src/main/java/turing/tmb/RecipeTreeIngredient.java @@ -0,0 +1,21 @@ +package turing.tmb; + +public class RecipeTreeIngredient { + public final RecipeIngredient ingredient; + public int x; + public int y; + + public RecipeTreeIngredient(RecipeIngredient ingredient, int x, int y) { + this.ingredient = ingredient; + this.x = x; + this.y = y; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } +} diff --git a/src/main/java/turing/tmb/TMB.java b/src/main/java/turing/tmb/TMB.java index 6e6ddef..bc1cee3 100644 --- a/src/main/java/turing/tmb/TMB.java +++ b/src/main/java/turing/tmb/TMB.java @@ -8,6 +8,7 @@ import net.minecraft.client.gui.options.components.OptionsCategory; import net.minecraft.client.gui.options.data.OptionsPages; import net.minecraft.client.option.GameSettings; +import net.minecraft.core.item.ItemStack; import net.minecraft.core.net.command.CommandManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,6 +50,9 @@ public static void onClientStart() { GameSettings settings = Minecraft.getMinecraft().gameSettings; OptionsCategory category = new OptionsCategory("gui.options.page.controls.category.tmb"); category.withComponent(new KeyBindingComponent(((IKeybinds) settings).toomanyblocks$getKeyHideTMB())); + category.withComponent(new KeyBindingComponent(((IKeybinds) settings).toomanyblocks$getKeyAddFavourite())); + category.withComponent(new KeyBindingComponent(((IKeybinds) settings).toomanyblocks$getKeySetDefaultRecipe())); + category.withComponent(new KeyBindingComponent(((IKeybinds) settings).toomanyblocks$getKeyShowRecipeTree())); OptionsPages.CONTROLS.withComponent(category); OptionsCategory category1 = new OptionsCategory("gui.options.page.general.category.tmb"); category1.withComponent(new BooleanOptionComponent(((IKeybinds) settings).toomanyblocks$getIsRecipeViewEnabled())); diff --git a/src/main/java/turing/tmb/TMBRuntime.java b/src/main/java/turing/tmb/TMBRuntime.java index 7d36190..f6563a5 100644 --- a/src/main/java/turing/tmb/TMBRuntime.java +++ b/src/main/java/turing/tmb/TMBRuntime.java @@ -4,7 +4,6 @@ import net.minecraft.client.gui.TooltipElement; import net.minecraft.core.item.ItemStack; import net.minecraft.core.util.collection.Pair; -import org.jetbrains.annotations.Nullable; import turing.tmb.api.ingredient.IIngredientRegistry; import turing.tmb.api.ingredient.IIngredientType; import turing.tmb.api.ingredient.IIngredientTypeRegistry; @@ -31,6 +30,8 @@ public class TMBRuntime implements ITMBRuntime { protected final RecipeIndex recipeIndex = new RecipeIndex(this); protected static final TooltipElement tooltipElement = new TooltipElement(Minecraft.getMinecraft()); protected final GuiHelper guiHelper = new GuiHelper(this); + public final List> favourites = new ArrayList<>(); + protected final Map> defaultRecipes = new HashMap<>(); protected boolean isReady; protected TMBRuntime() { @@ -56,6 +57,10 @@ public void showRecipe(ILookupContext lookup) { } } } + if(results.size() == 1 && lookup.getRole() == RecipeIngredientRole.OUTPUT){ + Pair, IRecipeTranslator> pair = results.get(0); + defaultRecipes.put(new RecipeIngredient(lookup.getIngredient(),pair.getRight(),pair.getLeft(),RecipeIngredientRole.OUTPUT),pair.getRight()); + } if (!results.isEmpty()) { ScreenTMBRecipe.show(results, lookup, null); } @@ -107,6 +112,16 @@ public RecipeIndex getRecipeIndex() { return recipeIndex; } + @Override + public Map> getDefaultRecipes() { + return defaultRecipes; + } + + @Override + public List> getFavourites() { + return favourites; + } + public static String getTooltipText(ItemStack stack, boolean showDescription) { return tooltipElement.getTooltipText(stack, showDescription); } diff --git a/src/main/java/turing/tmb/TypedIngredient.java b/src/main/java/turing/tmb/TypedIngredient.java index e805391..c7c71e6 100644 --- a/src/main/java/turing/tmb/TypedIngredient.java +++ b/src/main/java/turing/tmb/TypedIngredient.java @@ -3,6 +3,7 @@ import net.minecraft.core.item.ItemStack; import turing.tmb.api.VanillaTypes; import turing.tmb.api.ingredient.IIngredientType; +import turing.tmb.api.ingredient.IIngredientTypeWithSubtypes; import turing.tmb.api.ingredient.ITypedIngredient; import turing.tmb.util.ModIDHelper; @@ -20,7 +21,7 @@ public TypedIngredient(String namespace, String name, IIngredientType type, T } public static TypedIngredient itemStackIngredient(ItemStack stack) { - return new TypedIngredient<>(ModIDHelper.getModIDForItem(stack), stack.getDisplayName(), VanillaTypes.ITEM_STACK, stack); + return new TypedIngredient<>(ModIDHelper.getModIDForItem(stack), stack.getDisplayName(), VanillaTypes.ITEM_STACK, stack.copy()); } @Override @@ -43,6 +44,36 @@ public String getUid() { return name; } + @Override + public String getName() { + if(getType() instanceof IIngredientTypeWithSubtypes){ + return ((IIngredientTypeWithSubtypes) getType()).getName(ingredient); + } + return ""; + } + + @Override + public void addAmount(int amount) { + if(getType() instanceof IIngredientTypeWithSubtypes){ + ((IIngredientTypeWithSubtypes) getType()).add(ingredient, amount); + } + } + + @Override + public int getAmount() { + if(getType() instanceof IIngredientTypeWithSubtypes){ + return ((IIngredientTypeWithSubtypes) getType()).getAmount(ingredient); + } + return 1; + } + + public boolean matches(Object ingredient){ + if(getType() instanceof IIngredientTypeWithSubtypes){ + return ((IIngredientTypeWithSubtypes) getType()).matches(this.ingredient, ingredient); + } + return false; + } + @Override public int hashCode() { return getUid().hashCode() + getNamespace().hashCode(); diff --git a/src/main/java/turing/tmb/api/VanillaTypes.java b/src/main/java/turing/tmb/api/VanillaTypes.java index 24688eb..62783bd 100644 --- a/src/main/java/turing/tmb/api/VanillaTypes.java +++ b/src/main/java/turing/tmb/api/VanillaTypes.java @@ -3,6 +3,7 @@ import net.minecraft.core.WeightedRandomLootObject; import net.minecraft.core.item.Item; import net.minecraft.core.item.ItemStack; +import turing.tmb.TypedIngredient; import turing.tmb.api.ingredient.IIngredientType; import turing.tmb.api.ingredient.IIngredientTypeWithSubtypes; @@ -32,6 +33,28 @@ public Item getBase(ItemStack ingredient) { public ItemStack getDefaultIngredient(Item base) { return base.getDefaultStack(); } + + @Override + public String getName(ItemStack ingredient) { + return ingredient.getDisplayName(); + } + + @Override + public void add(ItemStack ingredient, int amount) { + ingredient.stackSize += amount; + } + + @Override + public int getAmount(ItemStack ingredient) { + return ingredient.stackSize; + } + + @Override + public boolean matches(ItemStack ingredient, Object otherIngredient) { + if(otherIngredient instanceof TypedIngredient) throw new IllegalArgumentException("Received TypedIngredient instead of actual ingredient class, use .getIngredient() when calling this method."); + if(!(otherIngredient instanceof ItemStack)) return false; + return ingredient.isItemEqual((ItemStack) otherIngredient); + } }; public static final IIngredientType LOOT_OBJECT = new IIngredientType() { diff --git a/src/main/java/turing/tmb/api/ingredient/IIngredientTypeWithSubtypes.java b/src/main/java/turing/tmb/api/ingredient/IIngredientTypeWithSubtypes.java index 7bca121..92f2383 100644 --- a/src/main/java/turing/tmb/api/ingredient/IIngredientTypeWithSubtypes.java +++ b/src/main/java/turing/tmb/api/ingredient/IIngredientTypeWithSubtypes.java @@ -11,4 +11,12 @@ public interface IIngredientTypeWithSubtypes extends IIngredientType { default T getDefaultIngredient(B base) { throw new UnsupportedOperationException(); } + + String getName(T ingredient); + + void add(T ingredient, int amount); + + int getAmount(T ingredient); + + boolean matches(T ingredient, Object otherIngredient); } diff --git a/src/main/java/turing/tmb/api/ingredient/ITypedIngredient.java b/src/main/java/turing/tmb/api/ingredient/ITypedIngredient.java index b6c1c6f..1cf16e1 100644 --- a/src/main/java/turing/tmb/api/ingredient/ITypedIngredient.java +++ b/src/main/java/turing/tmb/api/ingredient/ITypedIngredient.java @@ -17,6 +17,14 @@ public interface ITypedIngredient { String getUid(); + String getName(); + + void addAmount(int amount); + + int getAmount(); + + boolean matches(Object ingredient); + default Optional getIngredient(IIngredientType ingredientType) { return ingredientType.castIngredient(getIngredient()); } diff --git a/src/main/java/turing/tmb/api/recipe/IRecipeCategory.java b/src/main/java/turing/tmb/api/recipe/IRecipeCategory.java index 985507f..07fabee 100644 --- a/src/main/java/turing/tmb/api/recipe/IRecipeCategory.java +++ b/src/main/java/turing/tmb/api/recipe/IRecipeCategory.java @@ -23,6 +23,8 @@ default IDrawable getIcon() { void drawRecipe(ITMBRuntime runtime, R recipe, IRecipeLayout layout, List ingredients, ILookupContext context); + void getIngredients(R recipe, IRecipeLayout layout, ILookupContext context, List ingredients); + IRecipeLayout getRecipeLayout(); default > List getTooltips(R recipe, IRecipeSlot slot, int mouseX, int mouseY) { diff --git a/src/main/java/turing/tmb/api/recipe/IRecipeIndex.java b/src/main/java/turing/tmb/api/recipe/IRecipeIndex.java index a9d49f6..4bfde65 100644 --- a/src/main/java/turing/tmb/api/recipe/IRecipeIndex.java +++ b/src/main/java/turing/tmb/api/recipe/IRecipeIndex.java @@ -5,11 +5,14 @@ import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.function.Function; public interface IRecipeIndex { List> getCategoriesForCatalyst(ITypedIngredient ingredient); + Map, List>> getRecipeLists(); + void registerCatalyst(IRecipeCategory category, ITypedIngredient catalyst); void hideCategory(String name); diff --git a/src/main/java/turing/tmb/api/recipe/IRecipeSlot.java b/src/main/java/turing/tmb/api/recipe/IRecipeSlot.java index ed2aa1b..1bae74d 100644 --- a/src/main/java/turing/tmb/api/recipe/IRecipeSlot.java +++ b/src/main/java/turing/tmb/api/recipe/IRecipeSlot.java @@ -28,6 +28,14 @@ default void draw(IGuiHelper helper) { GL11.glPopMatrix(); } + default void draw(IGuiHelper helper, float r, float g, float b, float a) { + GL11.glPushMatrix(); + GL11.glColor4f(r,g,b,a); + helper.getMinecraft().textureManager.loadTexture("/assets/minecraft/textures/gui/container/crafting.png").bind(); + helper.drawTexturedModalRect(0, 0, 7, 83, 18, 18); + GL11.glPopMatrix(); + } + @Override default int getHeight() { return 16; diff --git a/src/main/java/turing/tmb/api/runtime/ITMBRuntime.java b/src/main/java/turing/tmb/api/runtime/ITMBRuntime.java index c70eae9..f6d340f 100644 --- a/src/main/java/turing/tmb/api/runtime/ITMBRuntime.java +++ b/src/main/java/turing/tmb/api/runtime/ITMBRuntime.java @@ -1,5 +1,6 @@ package turing.tmb.api.runtime; +import turing.tmb.RecipeIngredient; import turing.tmb.api.drawable.gui.IGuiHelper; import turing.tmb.api.ingredient.IIngredientRegistry; import turing.tmb.api.ingredient.IIngredientType; @@ -7,8 +8,12 @@ import turing.tmb.api.ingredient.ITypedIngredient; import turing.tmb.api.recipe.ILookupContext; import turing.tmb.api.recipe.IRecipeIndex; +import turing.tmb.api.recipe.IRecipeTranslator; import turing.tmb.api.recipe.RecipeIngredientRole; +import java.util.List; +import java.util.Map; + public interface ITMBRuntime { IIngredientTypeRegistry getIngredientTypeRegistry(); @@ -20,9 +25,15 @@ public interface ITMBRuntime { IRecipeIndex getRecipeIndex(); + + void showRecipe(ILookupContext lookup); void showRecipe(ITypedIngredient ingredient, RecipeIngredientRole role); void showAllRecipes(); + + Map> getDefaultRecipes(); + + List> getFavourites(); } diff --git a/src/main/java/turing/tmb/client/RecipeTreePage.java b/src/main/java/turing/tmb/client/RecipeTreePage.java new file mode 100644 index 0000000..83b73c9 --- /dev/null +++ b/src/main/java/turing/tmb/client/RecipeTreePage.java @@ -0,0 +1,299 @@ +package turing.tmb.client; + +import net.minecraft.client.render.block.model.BlockModelDispatcher; +import net.minecraft.client.render.texture.stitcher.IconCoordinate; +import net.minecraft.client.render.texture.stitcher.TextureRegistry; +import net.minecraft.core.achievement.Achievement; +import net.minecraft.core.block.Block; +import net.minecraft.core.block.Blocks; +import net.minecraft.core.item.ItemStack; +import net.minecraft.core.util.helper.Side; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import turing.tmb.RecipeIngredient; +import turing.tmb.RecipeTreeIngredient; +import turing.tmb.TMB; +import turing.tmb.api.drawable.IIngredientList; +import turing.tmb.api.ingredient.ITypedIngredient; +import turing.tmb.api.recipe.IRecipeCategory; +import turing.tmb.api.recipe.IRecipeTranslator; +import turing.tmb.api.recipe.RecipeIngredientRole; + +import java.util.*; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; + +public class RecipeTreePage { + protected final Map entryMap = new HashMap<>(); + protected final List ingredientList = new ArrayList<>(); + + protected final String id; + protected final RecipeIngredient ingredient; + protected final RecipeTreeIngredient root; + + protected int currentX = 1; + protected int currentY = 1; + + protected final List allRequired = new ArrayList<>(); + protected final List usedRecipes = new ArrayList<>(); + + public @NotNull String getName() { + if (ingredient.ingredient.getItemStack().isPresent()) { + return ingredient.ingredient.getItemStack().get().getDisplayName(); + } + return ""; + } + + public @NotNull String getDescription() { + return ""; + } + + public RecipeTreePage(@NotNull RecipeIngredient rootIngredient){ + this.ingredient = rootIngredient; + this.root = new RecipeTreeIngredient(rootIngredient, currentX, currentY); + addIngredient(rootIngredient, currentX, currentY); + + this.id = rootIngredient.recipe.toString(); + + currentX += 1; + addRecipe(rootIngredient, true); + usedRecipes.clear(); + addRequirements(rootIngredient, true); + + int j = currentY + 2; + int k = 0; + for (RecipeIngredient recipeIngredient : allRequired) { + addIngredient(recipeIngredient, k+1, j); + k += 2; + if (k % 10 == 0) { + j++; + k = 0; + } + } + + } + + public void addRequirements(RecipeIngredient result, boolean root){ + List ingredients = new ArrayList<>(); + AtomicReference>> currentCategory = new AtomicReference<>(); + AtomicReference> currentRecipe = new AtomicReference<>(); + if(root){ + result.category.getIngredients(result.recipe, result.category.getRecipeLayout(), null, ingredients); + currentCategory.set(result.category); + currentRecipe.set(result.recipe); + } else { + Optional>> optional = TMB.getRuntime().getDefaultRecipes().entrySet().stream().filter(E -> E.getKey().ingredient.matches(result.ingredient.getIngredient())).findFirst(); + optional.ifPresent(entry -> { + entry.getKey().category.getIngredients(entry.getValue(), entry.getKey().category.getRecipeLayout(), null, ingredients); + currentCategory.set(entry.getKey().category); + currentRecipe.set(entry.getValue()); + }); + if (!optional.isPresent()) { + return; + } + } + if(usedRecipes.contains(currentRecipe.get().getOriginal().toString())){ + return; + } + usedRecipes.add(currentRecipe.get().getOriginal().toString()); + + for (int i = 0; i < ingredients.size(); i++) { + IIngredientList list = ingredients.get(i); + if (list.getSize() <= 0) continue; + ITypedIngredient typedIngredient = list.getIngredients().get(0); + RecipeIngredient ingredient = new RecipeIngredient(typedIngredient, null, null, RecipeIngredientRole.INPUT); + if (currentCategory.get().getRecipeLayout().getSlots().get(i).getRole() != RecipeIngredientRole.INPUT) continue; + if(allRequired + .stream() + .anyMatch(it -> + it.ingredient.matches(typedIngredient.getIngredient()) + ) + ){ + RecipeIngredient alreadyAdded = allRequired.stream().filter(it -> it.ingredient.matches(typedIngredient.getIngredient())).collect(Collectors.toList()).get(0); + alreadyAdded.ingredient.addAmount(typedIngredient.getAmount()); + addRequirements(ingredient,false); + continue; + } + addRequirements(ingredient,false); + allRequired.add(ingredient); + } + usedRecipes.remove(currentRecipe.get().getOriginal().toString()); + + } + + public void addRecipe(RecipeIngredient result, boolean root){ + int x = currentX; + int y = currentY; + List ingredients = new ArrayList<>(); + + AtomicReference>> currentCategory = new AtomicReference<>(); + AtomicReference> currentRecipe = new AtomicReference<>(); + + List alreadyUsed = new ArrayList<>(); + + if(root){ + result.category.getIngredients(result.recipe, result.category.getRecipeLayout(), null, ingredients); + currentCategory.set(result.category); + currentRecipe.set(result.recipe); + currentX += 1; + } else { + Optional>> optional = TMB.getRuntime().getDefaultRecipes().entrySet().stream().filter(E -> E.getKey().ingredient.matches(result.ingredient.getIngredient())).findFirst(); + optional.ifPresent(entry -> { + entry.getKey().category.getIngredients(entry.getValue(), entry.getKey().category.getRecipeLayout(), null, ingredients); + currentCategory.set(entry.getKey().category); + currentRecipe.set(entry.getValue()); + currentX += 1; + }); + if (!optional.isPresent()) { + return; + } + } + + TMB.LOGGER.info(result.recipe.getOriginal().toString()); + TMB.LOGGER.info(currentRecipe.get().getOriginal().toString()); + + if(usedRecipes.contains(currentRecipe.get().getOriginal().toString())){ + return; + } + usedRecipes.add(currentRecipe.get().getOriginal().toString()); + + int uniqueIngredients = 0; + for (int i = 0; i < ingredients.size(); i++) { + IIngredientList list = ingredients.get(i); + if (list.getSize() <= 0) continue; + ITypedIngredient typedIngredient = list.getIngredients().get(0); + if (currentCategory.get().getRecipeLayout().getSlots().get(i).getRole() != RecipeIngredientRole.INPUT) continue; + if(alreadyUsed + .stream() + .anyMatch(it -> + it.ingredient + .matches(typedIngredient.getIngredient()) + ) + ){ + RecipeIngredient alreadyAdded = alreadyUsed.stream().filter(it -> it.ingredient.matches(typedIngredient.getIngredient())).collect(Collectors.toList()).get(0); + alreadyAdded.ingredient.addAmount(typedIngredient.getAmount()); + continue; + } + RecipeIngredient ingredient = new RecipeIngredient(typedIngredient, currentRecipe.get(), currentCategory.get(), RecipeIngredientRole.INPUT); + if(currentCategory.get().getRecipeLayout().getSlots().stream().filter(it->it.getRole() == RecipeIngredientRole.INPUT).count() > 0){ + currentY++; + } + addIngredient(ingredient, x, currentY); + addRecipe(ingredient, false); + alreadyUsed.add(ingredient); + currentX = x+1; + uniqueIngredients++; + } + usedRecipes.remove(currentRecipe.get().getOriginal().toString()); + //if(ingredients.size() > 1){ + + //} + } + + public void addIngredient(@NotNull RecipeIngredient ingredient, int x, int y) { + RecipeTreeIngredient entry = new RecipeTreeIngredient(ingredient, x,y); + ingredientList.add(entry); + entryMap.put(ingredient, entry); + } + + /*public void loadQuests(List quests){ + questList.clear(); + entryMap.clear(); + for (Quest quest : quests) { + if(quest.getPage() == this){ + questList.add(quest); + entryMap.put(quest.getTemplate(), quest); + } + } + } + + public void reset(){ + Set quests = new HashSet<>(entryMap.keySet()); + questList.clear(); + entryMap.clear(); + for (QuestTemplate quest : quests) { + addQuest(quest); + } + for (Quest quest : getQuests()) { + quest.setupPrerequisites(); + } + }*/ + + public @Nullable IconCoordinate getBackgroundTile(ScreenRecipeTree screen, int layer, Random random, int tileX, int tileY) { + return getTextureFromBlock(Blocks.DIRT); + } + + public void postProcessBackground(ScreenRecipeTree screen, Random random, ScreenRecipeTree.BGLayer layerCache, int orgX, int orgY) { + + } + + public ItemStack getIcon() { + return ingredient.ingredient.getItemStack().orElse(null); + } + + public @NotNull Set getIngredients() { + return entryMap.keySet(); + } + + public @NotNull List getTreeIngredients() { + return ingredientList; + } + + public @Nullable RecipeTreeIngredient getTreeIngredient(RecipeIngredient ingredient) { + return entryMap.get(ingredient); + } + + public double getCompletionFraction() { + /*int completed = 0; + for (Quest q : questList) { + if (q.isCompleted()) { + completed++; + } + } + return completed / (double) questList.size();*/ + return 0; + } + + public int backgroundLayers() { + return 1; + } + + public int backgroundColor() { + return 0; + } + + public boolean hasIngredient(RecipeIngredient ingredient) { + return entryMap.containsKey(ingredient); + } + + public RecipeTreeIngredient getTreeRoot() { + return root; + } + + public IconCoordinate drawIngredientBackground(RecipeIngredient ingredient) { + if(ingredient == root.ingredient){ + return TextureRegistry.getTexture(Achievement.TYPE_SPECIAL.texture); + } + return TextureRegistry.getTexture(Achievement.TYPE_NORMAL.texture); + } + + public int lineColorLocked(boolean isHovered) { + return 0x808080; + } + + public int lineColorUnlocked(boolean isHovered) { + return 0x00ff00; + } + + public int lineColorCanUnlock(boolean isHovered) { + return 0x707070; + } + + public static IconCoordinate getTextureFromBlock(Block block) { + return BlockModelDispatcher.getInstance().getDispatch(block).getBlockTextureFromSideAndMetadata(Side.TOP, 0); + } + + public String getId() { + return id; + } +} diff --git a/src/main/java/turing/tmb/client/ScreenRecipeTree.java b/src/main/java/turing/tmb/client/ScreenRecipeTree.java new file mode 100644 index 0000000..79e162b --- /dev/null +++ b/src/main/java/turing/tmb/client/ScreenRecipeTree.java @@ -0,0 +1,1046 @@ +package turing.tmb.client; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.ButtonElement; +import net.minecraft.client.gui.ItemElement; +import net.minecraft.client.gui.Screen; +import net.minecraft.client.gui.TooltipElement; +import net.minecraft.client.gui.options.OptionsButtonElement; +import net.minecraft.client.render.Lighting; +import net.minecraft.client.render.Scissor; +import net.minecraft.client.render.item.model.ItemModelDispatcher; +import net.minecraft.client.render.tessellator.Tessellator; +import net.minecraft.client.render.texture.stitcher.IconCoordinate; +import net.minecraft.client.render.texture.stitcher.TextureRegistry; +import net.minecraft.core.item.ItemStack; +import net.minecraft.core.lang.I18n; +import net.minecraft.core.net.command.TextFormatting; +import net.minecraft.core.util.collection.Pair; +import net.minecraft.core.util.helper.Color; +import net.minecraft.core.util.helper.MathHelper; +import org.jetbrains.annotations.Nullable; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; +import turing.tmb.RecipeIngredient; +import turing.tmb.RecipeTreeIngredient; +import turing.tmb.TMB; +import turing.tmb.api.drawable.IIngredientList; +import turing.tmb.api.ingredient.IIngredientRenderer; +import turing.tmb.api.ingredient.IIngredientType; +import turing.tmb.api.ingredient.ITypedIngredient; +import turing.tmb.api.recipe.RecipeIngredientRole; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Random; +import java.util.stream.Collectors; + +import static org.lwjgl.opengl.GL11.*; + +public class ScreenRecipeTree extends Screen +{ + private static final int TOP_SPACING = 24; + private static final int BUTTON_SPACING = 4; + private static final int SEPARATOR_WIDTH = 8; + private static final int PADDING = 8; + private static final int PAGE_BUTTON_HEIGHT = 20; + + private static final int ACHIEVEMENT_CELL_WIDTH = 24; + private static final int ACHIEVEMENT_CELL_HEIGHT = 24; + + private static final int ACHIEVEMENT_ICON_WIDTH = 26; + private static final int ACHIEVEMENT_ICON_HEIGHT = 26; + + private static final int TOOLTIP_BOX_WIDTH_MIN = 120; + private static final int TOOLTIP_OFF_X = 8; + private static final int TOOLTIP_OFF_Y = -4; + + protected int mouseXOld; + protected int mouseYOld; + protected double oldShiftX; + protected double oldShiftY; + protected double targetShiftX; + protected double targetShiftY; + protected double currentShiftX; + protected double currentShiftY; + private boolean draggingViewport; + private final TooltipElement tooltip; + private ItemElement renderItem = null; + Screen parent; + + private int top; + private int bottom; + + private int viewportLeft; + private int viewportTop; + private int viewportRight; + private int viewportBottom; + private int viewportWidth; + private int viewportHeight; + + private double viewportZoom = 1; + + private double shiftMinX; + private double shiftMinY; + private double shiftMaxX; + private double shiftMaxY; + + private int pageListLeft; + private int pageListRight; + + private float pageListScrollAmount = 0.0f; + private Float oldPagesListScrollAmount; + private int pagesListScrollRegionHeight; + + private Integer clickX, clickY; + + private final RecipeIngredient mainRecipeResult; + private RecipeTreePage hoveredPage = null; + private RecipeTreeIngredient hoveredTreeIngredient = null; + + private RecipeTreePage currentPage; + + private BGLayer[] layers; + + public ScreenRecipeTree(Screen parent, RecipeTreePage page, RecipeIngredient ingredient) + { + mouseXOld = 0; + mouseYOld = 0; + draggingViewport = false; + currentPage = page; + mainRecipeResult = ingredient; + + this.parent = parent; + this.mc = Minecraft.getMinecraft(); + this.tooltip = new TooltipElement(mc); + this.renderItem = new ItemElement(mc); + + layers = new BGLayer[currentPage.backgroundLayers()]; + for (int i = 0; i < layers.length; i++) { + layers[i] = new BGLayer(i); + } + } + + @Override + public void init() + { + buttons.clear(); + buttons.add(new OptionsButtonElement(1, width / 2 - 100, height - 20 - BUTTON_SPACING, 200, 20, I18n.getInstance().translateKey("gui.achievements.button.done"))); + + lastTileX = Integer.MIN_VALUE; + lastTileY = Integer.MIN_VALUE; + + top = TOP_SPACING; + bottom = height - (BUTTON_SPACING + 20 + BUTTON_SPACING); + + pagesListScrollRegionHeight = bottom - top; + pageListLeft = 0; + pageListRight = width/4; + + viewportZoom = 1; + + viewportLeft = drawSidebar() ? pageListRight + SEPARATOR_WIDTH : 0; + viewportTop = top; + viewportBottom = bottom; + viewportRight = width; + + viewportWidth = viewportRight - viewportLeft; + viewportHeight = viewportBottom - viewportTop; + + int achMinX = Integer.MAX_VALUE; + int achMinY = Integer.MAX_VALUE; + int achMaxX = Integer.MIN_VALUE; + int achMaxY = Integer.MIN_VALUE; + + for (RecipeTreeIngredient q : currentPage.getTreeIngredients()){ + if (q.getX() < achMinX){ + achMinX = q.getX(); + } + if (q.getY() < achMinY){ + achMinY = q.getY(); + } + if (q.getX() > achMaxX){ + achMaxX = q.getX(); + } + if (q.getY() > achMaxY){ + achMaxY = q.getY(); + } + } + + shiftMinX = achMinX * ACHIEVEMENT_CELL_WIDTH ; + shiftMinY = achMinY * ACHIEVEMENT_CELL_HEIGHT; + shiftMaxX = achMaxX * ACHIEVEMENT_CELL_WIDTH + ACHIEVEMENT_CELL_WIDTH; + shiftMaxY = achMaxY * ACHIEVEMENT_CELL_HEIGHT + ACHIEVEMENT_CELL_HEIGHT; + + shiftMinX -= (int) (viewportWidth /4d); + shiftMinY -= (int) (viewportHeight/4d); + shiftMaxX += (int) (viewportWidth /4d); + shiftMaxY += (int) (viewportHeight/4d); + + // Centers the screen on the Open ContainerInventory achievement + RecipeTreeIngredient root = currentPage.getTreeRoot(); + oldShiftX = targetShiftX = currentShiftX = root.getX() * ACHIEVEMENT_CELL_WIDTH + ACHIEVEMENT_CELL_WIDTH/2d; + oldShiftY = targetShiftY = currentShiftY = root.getY() * ACHIEVEMENT_CELL_HEIGHT + ACHIEVEMENT_CELL_HEIGHT/2d; + } + + @Override + protected void buttonClicked(ButtonElement button) { + if(button.id == 1) { + mc.displayScreen(parent); + //mc.setIngameFocus(); + } + super.buttonClicked(button); + } + + @Override + public void keyPressed(char eventCharacter, int eventKey, int mx, int my) + { + if (eventKey == Keyboard.KEY_ESCAPE) { + mc.displayScreen(parent); + } else { + super.keyPressed(eventCharacter, eventKey, mx, my); + } + + if (eventKey == mc.gameSettings.keyShowRecipe.getKeyCode() || eventKey == mc.gameSettings.keyShowUsage.getKeyCode()) { + if(hoveredTreeIngredient != null){ + if (eventKey == mc.gameSettings.keyShowUsage.getKeyCode()) { + TMB.getRuntime().showRecipe(hoveredTreeIngredient.ingredient.ingredient, RecipeIngredientRole.INPUT); + } else { + TMB.getRuntime().showRecipe(hoveredTreeIngredient.ingredient.ingredient, RecipeIngredientRole.OUTPUT); + } + } + } + } + @Override + public void mouseClicked(int mx, int my, int buttonNum) { + if (drawSidebar() && mx >= pageListLeft && mx <= (pageListRight - 6) && my >= top && my <= bottom) { + int pagesListHeight = getTotalPagesListHeight(); + int pagesListY = top - (int) pageListScrollAmount; + if (pagesListHeight < bottom - top) { + pagesListY = top + (bottom - top - pagesListHeight) / 2; + } + /*for(QuestChapterPage page : VintageQuesting.CHAPTERS) { + if (mx >= pageListLeft && mx <= (pageListRight - 6) && my >= pagesListY && my <= pagesListY + PAGE_BUTTON_HEIGHT) { + currentPage = page; + mc.sndManager.playSound("random.click", SoundCategory.GUI_SOUNDS, 1.0F, 1.0F); + + layers = new BGLayer[currentPage.backgroundLayers()]; + for (int i = 0; i < layers.length; i++) { + layers[i] = new BGLayer(i); + } + + init(); + break; + } + pagesListY += PAGE_BUTTON_HEIGHT; + }*/ + } + + /*if(hoveredQuest != null){ + mc.displayScreen(new ScreenQuestInfo(this,hoveredQuest)); + }*/ + + super.mouseClicked(mx, my, buttonNum); + + clickX = mx; + clickY = my; + } + + @Override + public void render(int mx, int my, float partialTick) + { + if(Mouse.isButtonDown(0)) { + if(mx >= viewportLeft && mx < viewportRight && my >= viewportTop && my < viewportBottom) { + if(!draggingViewport) { + draggingViewport = true; + } else { + targetShiftX -= (mx - mouseXOld) / viewportZoom; + targetShiftY -= (my - mouseYOld) / viewportZoom; + currentShiftX = oldShiftX = targetShiftX; + currentShiftY = oldShiftY = targetShiftY; + } + mouseXOld = mx; + mouseYOld = my; + } + currentShiftX = MathHelper.clamp(currentShiftX, shiftMinX, shiftMaxX); + currentShiftY = MathHelper.clamp(currentShiftY, shiftMinY, shiftMaxY); + } else if (mc.controllerInput != null) { + targetShiftX += mc.controllerInput.joyRight.getX() / viewportZoom * 4; + targetShiftY += mc.controllerInput.joyRight.getY() / viewportZoom * 4; + currentShiftX = oldShiftX = targetShiftX; + currentShiftY = oldShiftY = targetShiftY; + currentShiftX = MathHelper.clamp(currentShiftX, shiftMinX, shiftMaxX); + currentShiftY = MathHelper.clamp(currentShiftY, shiftMinY, shiftMaxY); + + if (mc.controllerInput.buttonLeftTrigger.isPressed()) { + viewportZoom -= 0.01d; + } else if (mc.controllerInput.buttonRightTrigger.isPressed()) { + viewportZoom += 0.01f; + } + viewportZoom = MathHelper.clamp(viewportZoom, 0.5d, 2d); + + } else { + clickX = clickY = null; + oldPagesListScrollAmount = null; + draggingViewport = false; + } + + /*if (drawSidebar() && mx >= pageListLeft && mx <= pageListRight) { + if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL)) { + scrollPagesList(Mouse.getDWheel() / -0.01f); + } else { + scrollPagesList(Mouse.getDWheel() / -0.05f); + } + onScrollPagesList(); + } else*/ if (mx >= viewportLeft && mx <= viewportRight && my >= viewportTop && my <= viewportBottom){ + final double change = (Mouse.getDWheel()/10d); + viewportZoom = MathHelper.clamp(viewportZoom + change, 0.5d, 2); + + // Make zoom notch onto integer multiples + if (change != 0) { + final double[] notches = new double[]{0.25, 0.5, 1, 2, 4}; + for (double notch : notches){ + if (Math.abs(viewportZoom - notch) < 0.05){ + viewportZoom = notch; + break; + } + } + } + } + Mouse.getDWheel(); + + renderBackground(); + + /*if (drawSidebar()){ + overlayBackground(0, pageListRight, top, bottom, 0x202020); + }*/ + + renderAchievementsPanel(mx, my, partialTick); + + overlayBackground(0, width, 0, top, 0x404040); + overlayBackground(0, width, bottom, height, 0x404040); + //overlayBackground(pageListRight, viewportLeft, top, bottom, 0x404040); + + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glDisable(GL11.GL_ALPHA_TEST); + GL11.glShadeModel(GL11.GL_SMOOTH); + GL11.glEnable(GL11.GL_TEXTURE_2D); + + super.render(mx, my, partialTick); // Draw Buttons + GL11.glEnable(GL11.GL_DEPTH_TEST); + GL11.glEnable(GL11.GL_LIGHTING); + Lighting.disable(); + + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_DEPTH_TEST); + GL11.glEnable(GL11.GL_TEXTURE_2D); + GL11.glShadeModel(GL11.GL_FLAT); + GL11.glEnable(GL11.GL_ALPHA_TEST); + + /* if (drawSidebar()){ + Scissor.enable(pageListLeft, top, pageListRight - pageListLeft, bottom - top); + int pagesListHeight = getTotalPagesListHeight(); + int pagesListY = top - (int) pageListScrollAmount; + if (pagesListHeight < bottom - top) { + pagesListY = top + (bottom - top - pagesListHeight) / 2; + } + if (my >= top && my <= bottom) { + hoveredPage = drawPagesListItems(pageListLeft + PADDING - 4, pagesListY, pageListRight - PADDING, mx, my); + } else { + hoveredPage = drawPagesListItems(pageListLeft + PADDING - 4, pagesListY, pageListRight - PADDING, -1, -1); + } + Scissor.disable(); + }*/ + + { + GL11.glDisable(GL11.GL_TEXTURE_2D); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glDisable(GL11.GL_ALPHA_TEST); + GL11.glShadeModel(GL11.GL_SMOOTH); + + byte fadeDist = 4; + Tessellator tessellator = Tessellator.instance; + /*if (drawSidebar()) { + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_I(0, 0); + tessellator.addVertexWithUV(pageListLeft, top + fadeDist, 0.0D, 0.0D, 1.0D); + tessellator.addVertexWithUV(pageListRight, top + fadeDist, 0.0D, 1.0D, 1.0D); + tessellator.setColorRGBA_I(0, 255); + tessellator.addVertexWithUV(pageListRight, top, 0.0D, 1.0D, 0.0D); + tessellator.addVertexWithUV(pageListLeft, top, 0.0D, 0.0D, 0.0D); + tessellator.draw(); + + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_I(0, 255); + tessellator.addVertexWithUV(pageListLeft, bottom, 0.0D, 0.0D, 1.0D); + tessellator.addVertexWithUV(pageListRight, bottom, 0.0D, 1.0D, 1.0D); + tessellator.setColorRGBA_I(0, 0); + tessellator.addVertexWithUV(pageListRight, bottom - fadeDist, 0.0D, 1.0D, 0.0D); + tessellator.addVertexWithUV(pageListLeft, bottom - fadeDist, 0.0D, 0.0D, 0.0D); + tessellator.draw(); + + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_I(0, 0); + tessellator.addVertexWithUV(viewportLeft, top + fadeDist, 0.0D, 0.0D, 1.0D); + tessellator.addVertexWithUV(viewportRight, top + fadeDist, 0.0D, 1.0D, 1.0D); + tessellator.setColorRGBA_I(0, 255); + tessellator.addVertexWithUV(viewportRight, top, 0.0D, 1.0D, 0.0D); + tessellator.addVertexWithUV(viewportLeft, top, 0.0D, 0.0D, 0.0D); + tessellator.draw(); + + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_I(0, 255); + tessellator.addVertexWithUV(viewportLeft, bottom, 0.0D, 0.0D, 1.0D); + tessellator.addVertexWithUV(viewportRight, bottom, 0.0D, 1.0D, 1.0D); + tessellator.setColorRGBA_I(0, 0); + tessellator.addVertexWithUV(viewportRight, bottom - fadeDist, 0.0D, 1.0D, 0.0D); + tessellator.addVertexWithUV(viewportLeft, bottom - fadeDist, 0.0D, 0.0D, 0.0D); + tessellator.draw(); + } else {*/ + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_I(0, 0); + tessellator.addVertexWithUV(0, top + fadeDist, 0.0D, 0.0D, 1.0D); + tessellator.addVertexWithUV(width, top + fadeDist, 0.0D, 1.0D, 1.0D); + tessellator.setColorRGBA_I(0, 255); + tessellator.addVertexWithUV(width, top, 0.0D, 1.0D, 0.0D); + tessellator.addVertexWithUV(0, top, 0.0D, 0.0D, 0.0D); + tessellator.draw(); + + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_I(0, 255); + tessellator.addVertexWithUV(0, bottom, 0.0D, 0.0D, 1.0D); + tessellator.addVertexWithUV(width, bottom, 0.0D, 1.0D, 1.0D); + tessellator.setColorRGBA_I(0, 0); + tessellator.addVertexWithUV(width, bottom - fadeDist, 0.0D, 1.0D, 0.0D); + tessellator.addVertexWithUV(0, bottom - fadeDist, 0.0D, 0.0D, 0.0D); + tessellator.draw(); + //} + GL11.glEnable(GL_TEXTURE_2D); + GL11.glEnable(GL11.GL_ALPHA_TEST); + } + + if (hoveredTreeIngredient != null){ + drawAchievementToolTip(hoveredTreeIngredient, mx, my); + } + + /*if (drawSidebar()) { + drawPagesListScrollBar(mx, my); + + if (hoveredPage != null){ + String msg = font.wrapFormattedStringToWidth(hoveredPage.getDescription(), TOOLTIP_BOX_WIDTH_MIN); + msg += "\n" + TextFormatting.LIGHT_GRAY + I18n.getInstance().translateKeyAndFormat("gui.achievements.label.completion", Math.round(hoveredPage.getCompletionFraction() * 100) + "%"); + tooltip.render(msg, mx, my, TOOLTIP_OFF_X, TOOLTIP_OFF_Y); + } + }*/ + + renderLabels(); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_DEPTH_TEST); + + hoveredPage = null; + } + + @Override + public void tick() { + oldShiftX = targetShiftX; + oldShiftY = targetShiftY; + double xDiff = currentShiftX - targetShiftX; + double yDiff = currentShiftY - targetShiftY; + if(xDiff * xDiff + yDiff * yDiff < 4D) { + targetShiftX += xDiff; + targetShiftY += yDiff; + } else { + targetShiftX += xDiff * 0.85D; + targetShiftY += yDiff * 0.85D; + } + } + + protected void renderLabels() { + font.drawCenteredString(I18n.getInstance().translateKey("gui.tmb.recipeTree.label.title")/* + " " + viewportZoom + " X:" + currentShiftX + ", Y:" + currentShiftY*/, width/2, 5 , 0xFFFFFF); + } + + + protected void renderAchievementsPanel(int mouseX, int mouseY, float partialTick){ + double shiftX = MathHelper.lerp(oldShiftX, targetShiftX, partialTick); + double shiftY = MathHelper.lerp(oldShiftY, targetShiftY, partialTick); + shiftX = MathHelper.clamp(shiftX, shiftMinX, shiftMaxX); + shiftY = MathHelper.clamp(shiftY, shiftMinY, shiftMaxY); + + zLevel = 0.0F; + + GL11.glDepthFunc(GL11.GL_GEQUAL); + GL11.glPushMatrix(); + GL11.glTranslatef(0, 0, -200F); + Scissor.enable(viewportLeft, viewportTop, viewportWidth, viewportHeight); + GL11.glEnable(GL11.GL_TEXTURE_2D); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + GL11.glEnable(GL11.GL_COLOR_MATERIAL); + drawRectDouble(viewportLeft, viewportTop, viewportRight, viewportBottom, 0xFF000000 | currentPage.backgroundColor()); // Ensures that the viewport always has a background of some kind + + GL11.glPushMatrix(); + drawBackgroundTiles(shiftX, shiftY); + + GL11.glEnable(GL11.GL_DEPTH_TEST); + GL11.glDepthFunc(GL11.GL_LEQUAL); // Responsible for culling the overdraw later on + drawConnectingLines(mouseX, mouseY,shiftX, shiftY); + + Lighting.enableInventoryLight(); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + GL11.glEnable(GL11.GL_COLOR_MATERIAL); + hoveredTreeIngredient = drawAchievementIcons(mouseX, mouseY, shiftX, shiftY); + + GL11.glPopMatrix(); + + GL11.glDisable(GL11.GL_DEPTH_TEST); + GL11.glEnable(GL11.GL_BLEND); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + Scissor.disable(); + + // drawRectDouble(viewportLeft + viewportWidth/2d - 2.5, viewportTop + viewportHeight/2d - 2.5, viewportLeft + viewportWidth/2d + 2.5, viewportTop + viewportHeight/2d + 2.5, 0xFFA0A0A0); // Debug cross-hair + + GL11.glPopMatrix(); + + zLevel = 0.0F; + GL11.glDepthFunc(GL11.GL_LEQUAL); + GL11.glDisable(GL11.GL_DEPTH_TEST); + GL11.glEnable(GL11.GL_TEXTURE_2D); + } + + private static final int TILE_WIDTH = 16; + private static final int TILE_HEIGHT = 16; + + public int lastTileX = Integer.MIN_VALUE; + public int lastTileY = Integer.MIN_VALUE; + public int lastTilesWide = Integer.MIN_VALUE; + public int lastTilesTall = Integer.MIN_VALUE; + private void drawBackgroundTiles(double shiftX, double shiftY){ + double zoom = viewportZoom/* * 0.85*/; + + TextureRegistry.blockAtlas.bind(); + final int offset = 18 * TILE_WIDTH; + int viewTileX = (MathHelper.floor(shiftX) + offset) / TILE_WIDTH; + int viewTileY = (MathHelper.floor(shiftY) + offset) / TILE_HEIGHT; + double remainderX = (shiftX + offset) % TILE_WIDTH; + double remainderY = (shiftY + offset) % TILE_HEIGHT; + Random random = new Random(); + + int tilesWide = (int) (viewportWidth/(TILE_WIDTH * zoom) + 2); + int tilesTall = (int) (viewportHeight/(TILE_HEIGHT * zoom) + 2); + + int orgX = -tilesWide/2 - 1; + int orgY = -tilesTall/2 - 1; + int endX = tilesWide/2 + 1; + int endY = tilesTall/2 + 1; + + tilesWide = endX - orgX; + tilesTall = endY - orgY; + + // Cache background, saves some render time which is nice + if (viewTileX != lastTileX || viewTileY != lastTileY || tilesWide != lastTilesWide || tilesTall != lastTilesTall) { + lastTileX = viewTileX; + lastTileY = viewTileY; + lastTilesWide = tilesWide; + lastTilesTall = tilesTall; + + for (BGLayer layer : layers){ + layer.resize(tilesWide, tilesTall); + } + + long worldSeed = mc.currentWorld == null ? 0 : mc.currentWorld.getRandomSeed(); + for (int _y = 0; _y < tilesTall; _y++){ + for (int _x = 0; _x < tilesWide; _x++) { + int tileX = orgX + _x + viewTileX; + int tileY = orgY + _y + viewTileY; + // Hopefully this is actually random enough :) + random.setSeed(worldSeed); + long l1 = random.nextLong(); + random.setSeed(tileX); + long l2 = random.nextLong(); + random.setSeed(tileY); + long l3 = random.nextLong(); + + long seed = Objects.hash(l1, l2, ~l3); + + for (BGLayer layer : layers) { + random.setSeed(seed); + IconCoordinate fore = currentPage.getBackgroundTile(this, layer.id, random, tileX, tileY); + layer.put(fore, _x, _y); + } + } + } + + +// long l1 = random.nextLong(); +// random.setSeed(viewTileX); +// long l2 = random.nextLong(); +// random.setSeed(viewTileY); +// long l3 = random.nextLong(); +// +// long seed = Objects.hash(l1, l2, ~l3); +// random.setSeed(seed); + + for (BGLayer layer : layers) { + random.setSeed(worldSeed); + currentPage.postProcessBackground(this, random, layer, orgX + viewTileX, orgY + viewTileY); + } + } + + + + for(int _y = 0; _y < tilesTall; _y++) { + int tileY = orgY + _y + viewTileY; + float brightness = 0.3F; //- ((float)(tileY) / 25F) * 0.3F; + for(int _x = 0; _x < tilesWide; _x++) { + int tileX = orgX + _x + viewTileX; + + for (int i = layers.length - 1; i >= 0; i--) { + BGLayer topLayer = getLayer(i); + IconCoordinate fore = topLayer.get(_x, _y); + + IconCoordinate next = null; + if (i - 1 >= 0) { + BGLayer nextLayer = getLayer(i - 1); + next = nextLayer.get(_x, _y); + } + + + boolean bottom = false; + boolean top = false; + boolean left = false; + boolean right = false; + boolean topLeft = false; + boolean topRight = false; + boolean bottomLeft = false; + boolean bottomRight = false; + + + if (fore != null && next == null && i - 1 >= 0) { + BGLayer nextLayer = getLayer(i - 1); + top = nextLayer.get(_x, _y - 1) != null; + left = nextLayer.get(_x - 1, _y) != null; + right = nextLayer.get(_x + 1, _y) != null; + bottom = nextLayer.get(_x, _y + 1) != null; + topLeft = nextLayer.get(_x - 1, _y - 1) != null; + topRight = nextLayer.get(_x + 1, _y - 1) != null; + bottomLeft = nextLayer.get(_x - 1, _y + 1) != null; + bottomRight = nextLayer.get(_x + 1, _y + 1) != null; + } + + double iconLeft = (viewportLeft + viewportWidth / 2d) + zoom * (((orgX + _x) * TILE_WIDTH) - remainderX); + double iconTop = (viewportTop + viewportHeight / 2d) + zoom * (((orgY + _y) * TILE_HEIGHT) - remainderY); + double iconWidth = TILE_WIDTH * zoom; + double iconHeight = TILE_HEIGHT * zoom; + + if (fore != null) { + float shadowScale = (float) Math.pow(0.65f, i); + if (next != null) { + shadowScale *= 0.5f; + } + GL11.glColor4f(brightness, brightness, brightness, 1.0F); + final double epsilon = 0.05; + drawGuiIconDouble(iconLeft - epsilon, iconTop - epsilon, iconWidth + epsilon * 2, iconHeight + epsilon * 2, fore); + } + + /*GL11.glDisable(GL11.GL_TEXTURE_2D); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glDisable(GL11.GL_ALPHA_TEST); + GL11.glShadeModel(GL11.GL_SMOOTH); + Tessellator t = Tessellator.instance; + final double off = 0.05d; + double fadeDist = 6 * zoom; + short shadowDarkness = 128; + if (top) { + t.startDrawingQuads(); + t.setColorRGBA_I(0, 0); + t.addVertexWithUV(iconLeft - off, iconTop + fadeDist + off, 0.0D, 0.0D, 1.0D); + t.addVertexWithUV(iconLeft + iconWidth + off, iconTop + fadeDist + off, 0.0D, 1.0D, 1.0D); + t.setColorRGBA_I(0, shadowDarkness); + t.addVertexWithUV(iconLeft + iconWidth + off, iconTop - off, 0.0D, 1.0D, 0.0D); + t.addVertexWithUV(iconLeft - off, iconTop - off, 0.0D, 0.0D, 0.0D); + t.draw(); + } + if (left) { + t.startDrawingQuads(); + t.setColorRGBA_I(0, 0); + t.addVertexWithUV(iconLeft + fadeDist + off, iconTop + iconHeight + off, 0.0D, 1.0D, 1.0D); + t.addVertexWithUV(iconLeft + fadeDist + off, iconTop - off, 0.0D, 0.0D, 1.0D); + t.setColorRGBA_I(0, shadowDarkness); + t.addVertexWithUV(iconLeft - off, iconTop - off, 0.0D, 0.0D, 0.0D); + t.addVertexWithUV(iconLeft - off, iconTop + iconHeight + off, 0.0D, 1.0D, 0.0D); + t.draw(); + } + if (bottom) { + t.startDrawingQuads(); + t.setColorRGBA_I(0, 0); + t.addVertexWithUV(iconLeft + iconWidth + off, iconTop + iconHeight - fadeDist + off, 0.0D, 1.0D, 1.0D); + t.addVertexWithUV(iconLeft - off, iconTop + iconHeight - fadeDist + off, 0.0D, 0.0D, 1.0D); + t.setColorRGBA_I(0, shadowDarkness); + t.addVertexWithUV(iconLeft - off, iconTop + iconHeight - off, 0.0D, 0.0D, 0.0D); + t.addVertexWithUV(iconLeft + iconWidth + off, iconTop + iconHeight - off, 0.0D, 1.0D, 0.0D); + t.draw(); + } + if (right) { + t.startDrawingQuads(); + t.setColorRGBA_I(0, 0); + t.addVertexWithUV(iconLeft + iconWidth - fadeDist + off, iconTop - off, 0.0D, 0.0D, 1.0D); + t.addVertexWithUV(iconLeft + iconWidth - fadeDist + off, iconTop + iconHeight + off, 0.0D, 1.0D, 1.0D); + t.setColorRGBA_I(0, shadowDarkness); + t.addVertexWithUV(iconLeft + iconWidth - off, iconTop + iconHeight + off, 0.0D, 1.0D, 0.0D); + t.addVertexWithUV(iconLeft + iconWidth - off, iconTop - off, 0.0D, 0.0D, 0.0D); + t.draw(); + } + if (topLeft && !(left || top)) { + t.startDrawing(GL11.GL_TRIANGLES); + t.setColorRGBA_I(0, 0); + t.addVertexWithUV(iconLeft - off, iconTop + fadeDist + off, 0.0D, 1.0D, 0.0D); + t.addVertexWithUV(iconLeft + fadeDist + off, iconTop - off, 0.0D, 0.0D, 0.0D); + t.setColorRGBA_I(0, shadowDarkness); + t.addVertexWithUV(iconLeft - off, iconTop - off, 0.0D, 0.0D, 1.0D); + t.draw(); + } + if (topRight && !(right || top)) { + t.startDrawing(GL11.GL_TRIANGLES); + t.setColorRGBA_I(0, 0); + t.addVertexWithUV(iconLeft + iconWidth - fadeDist + off, iconTop - off, 0.0D, 0.0D, 0.0D); + t.addVertexWithUV(iconLeft + iconWidth - off, iconTop + fadeDist + off, 0.0D, 1.0D, 0.0D); + t.setColorRGBA_I(0, shadowDarkness); + t.addVertexWithUV(iconLeft + iconWidth - off, iconTop - off, 0.0D, 0.0D, 1.0D); + t.draw(); + } + if (bottomLeft && !(left || bottom)) { + t.startDrawing(GL11.GL_TRIANGLES); + t.setColorRGBA_I(0, 0); + t.addVertexWithUV(iconLeft + fadeDist + off, iconTop + iconHeight - off, 0.0D, 0.0D, 0.0D); + t.addVertexWithUV(iconLeft - off, iconTop + iconHeight - fadeDist + off, 0.0D, 1.0D, 0.0D); + t.setColorRGBA_I(0, shadowDarkness); + t.addVertexWithUV(iconLeft - off, iconTop + iconHeight - off, 0.0D, 0.0D, 1.0D); + t.draw(); + } + if (bottomRight && !(right || bottom)) { + t.startDrawing(GL11.GL_TRIANGLES); + t.setColorRGBA_I(0, 0); + t.addVertexWithUV(iconLeft + iconWidth - off, iconTop + iconHeight - fadeDist + off, 0.0D, 1.0D, 0.0D); + t.addVertexWithUV(iconLeft + iconWidth - fadeDist + off, iconTop + iconHeight - off, 0.0D, 0.0D, 0.0D); + t.setColorRGBA_I(0, shadowDarkness); + t.addVertexWithUV(iconLeft + iconWidth - off, iconTop + iconHeight - off, 0.0D, 0.0D, 1.0D); + t.draw(); + } + GL11.glEnable(GL_TEXTURE_2D); + GL11.glEnable(GL11.GL_ALPHA_TEST);*/ + } + } + } + } + + public BGLayer getLayer(int layer){ + if (layer < 0 || layer >= layers.length) return null; + return layers[layer]; + } + + private double timeSin(double amplitude, long period){ + return Math.sin(((double)(System.currentTimeMillis() % period) / period) * Math.PI * 2D) * amplitude; + } + private void drawConnectingLines(int mouseX, int mouseY, double shiftX, double shiftY){ + double zoom = viewportZoom; + + for(RecipeTreeIngredient entry : currentPage.getTreeIngredients()) { + RecipeIngredient ingredient = entry.ingredient; + List list = new ArrayList<>(); + if(ingredient.recipe == null || ingredient.category == null) continue; + ingredient.category.getIngredients(ingredient.recipe,ingredient.category.getRecipeLayout(), null, list); + List inputs = currentPage.getTreeIngredients();/*list + .stream() + .filter(it -> !it.getIngredients().isEmpty()) + .map(it -> it.getIngredients().get(0)) + .map(it -> currentPage.getTreeIngredients().stream().filter(it2 -> it.matches(it2.ingredient.ingredient.getIngredient())).findFirst().orElse(null)) + .filter(Objects::nonNull) + .collect(Collectors.toList());*/ + //List list = currentPage.getTreeIngredients().stream().filter(r -> r.ingredient.recipe == entry.ingredient.recipe).collect(Collectors.toList()); + for (RecipeTreeIngredient child : inputs) { + if(child == entry) continue; + if(child.ingredient.recipe == null || child.ingredient.category == null) continue; + double childX = (viewportLeft + viewportWidth/2d) + ((entry.getX() * ACHIEVEMENT_CELL_WIDTH - shiftX) + 11) * zoom; + double childY = (viewportTop + viewportHeight/2d) + ((entry.getY() * ACHIEVEMENT_CELL_HEIGHT - shiftY) + 11) * zoom; + double parentX = (viewportLeft + viewportWidth/2d) + ((child.getX() * ACHIEVEMENT_CELL_WIDTH - shiftX) + 11) * zoom; + double parentY = (viewportTop + viewportHeight/2d) + ((child.getY() * ACHIEVEMENT_CELL_HEIGHT - shiftY) + 11) * zoom; + boolean unlocked = false;//entry.isCompleted(); + boolean canUnlock = false;//entry.preRequisitesCompleted(); + + final double zoomOff = 11 * zoom; +// if ( +// (((childX + zoomOff) <= viewportLeft || (childX - zoomOff) >= viewportRight || (childY - zoomOff) >= viewportBottom || (childY + zoomOff) <= viewportTop) && +// (((parentX + zoomOff) <= viewportLeft || (parentX - zoomOff) >= viewportRight || (parentY - zoomOff) >= viewportBottom || (parentY + zoomOff) <= viewportTop)))) { +// continue; +// } + + boolean isHovered = false; + { + double x = parentX - zoomOff; + double y = parentY - zoomOff; + if ((mouseX >= 0 && mouseY >= viewportTop && mouseX < width && mouseY < viewportBottom) && // In viewport and + (mouseX >= x && mouseX <= x + 22 * zoom && mouseY >= y && mouseY <= y + 22 * zoom)) { // Hovering over achievement + isHovered = true; + } + + x = childX - zoomOff; + y = childY - zoomOff; + if ((mouseX >= 0 && mouseY >= viewportTop && mouseX < width && mouseY < viewportBottom) && // In viewport and + (mouseX >= x && mouseX <= x + 22 * zoom && mouseY >= y && mouseY <= y + 22 * zoom)) { // Hovering over achievement + isHovered = true; + } + } + + int color; + if(unlocked) { + color = 0xff << Color.SHIFT_ALPHA | (currentPage.lineColorUnlocked(isHovered) & 0xffffff); + } else if (canUnlock) { + int alpha = timeSin(1, 600) >= 0.6 ? 0x82 : 0xff; + color = (alpha << Color.SHIFT_ALPHA) | (currentPage.lineColorCanUnlock(isHovered) & 0xffffff); + } else { + color = 0xff << Color.SHIFT_ALPHA | (currentPage.lineColorLocked(isHovered) & 0xffffff); + } + + drawLineHorizontalDouble(childX, parentX, childY, color); + drawLineVerticalDouble(parentX, childY, parentY, color); + } + } + } + + private RecipeTreeIngredient drawAchievementIcons(int mouseX, int mouseY, double shiftX, double shiftY){ + double zoom = viewportZoom; + + RecipeTreeIngredient hoveredAchievment = null; + for(RecipeTreeIngredient recipeTreeIngredient : currentPage.getTreeIngredients()) { + RecipeIngredient ingredient = recipeTreeIngredient.ingredient; + double achViewX = (viewportLeft + viewportWidth/2d) + (recipeTreeIngredient.getX() * ACHIEVEMENT_CELL_WIDTH - shiftX ) * zoom; + double achViewY = (viewportTop + viewportHeight/2d) + (recipeTreeIngredient.getY() * ACHIEVEMENT_CELL_HEIGHT - shiftY) * zoom; + if(achViewX < viewportLeft - ACHIEVEMENT_CELL_WIDTH * zoom || achViewY < viewportTop - ACHIEVEMENT_CELL_HEIGHT * zoom || achViewX > viewportRight || achViewY > viewportBottom) { // Continue if outside viewport + continue; + } + float brightness = 0.50F; + GL11.glColor4f(brightness, brightness, brightness, 1.0F); + /*if(recipeTreeIngredient.isCompleted()) { + float brightness = 1.0F; + GL11.glColor4f(brightness, brightness, brightness, 1.0F); + } else if(recipeTreeIngredient.preRequisitesCompleted()) { + // Flicker if can unlock + float brightness = timeSin(1, 600) >= 0.6 ? 0.6F : 0.8F; + GL11.glColor4f(brightness, brightness, brightness, 1.0F); + } else { + // Darken if not unlock-able + float brightness = 0.3F; + GL11.glColor4f(brightness, brightness, brightness, 1.0F); + }*/ + + drawGuiIconDouble(achViewX - (ACHIEVEMENT_ICON_WIDTH - ACHIEVEMENT_CELL_WIDTH) * zoom, achViewY - (ACHIEVEMENT_ICON_HEIGHT - ACHIEVEMENT_CELL_HEIGHT) * zoom, ACHIEVEMENT_ICON_WIDTH * zoom, ACHIEVEMENT_ICON_HEIGHT * zoom, currentPage.drawIngredientBackground(ingredient)); + + /*if(!recipeTreeIngredient.preRequisitesCompleted()) { + float brightness = 0.1F; + GL11.glColor4f(brightness, brightness, brightness, 1.0F); + }*/ + + GL11.glPushMatrix(); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_CULL_FACE); + ItemStack achievementItem = ingredient.ingredient.getItemStack().orElse(null); + + GL11.glTranslated(achViewX + 3 * zoom, achViewY + 3 * zoom, 0); + GL11.glScaled(zoom, zoom, 1); + /*ItemModelDispatcher.getInstance().getDispatch(achievementItem) + .renderItemIntoGui(Tessellator.instance, mc.font, mc.textureManager, achievementItem, 0, 0, 1.0f); + ItemModelDispatcher.getInstance().getDispatch(achievementItem) + .renderItemOverlayIntoGUI(Tessellator.instance, mc.font, mc.textureManager, achievementItem, 0, 0, 1.0f);*/ + IIngredientType type = ingredient.ingredient.getType(); + IIngredientRenderer renderer = (IIngredientRenderer) type.getRenderer(TMB.getRuntime()); + new DrawableIngredient<>(ingredient.ingredient.getIngredient(), renderer).draw(TMB.getRuntime().getGuiHelper()); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glPopMatrix(); + + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + if((mouseX >= 0 && mouseY >= viewportTop && mouseX < width && mouseY < viewportBottom) && // In viewport and + (mouseX >= achViewX && mouseX <= achViewX + 22 * zoom && mouseY >= achViewY && mouseY <= achViewY + 22 * zoom)) { // Hovering over achievement + hoveredAchievment = recipeTreeIngredient; + } + } + return hoveredAchievment; + } + private void drawAchievementToolTip(RecipeTreeIngredient treeIngredient, int mouseX, int mouseY){ + StringBuilder s = new StringBuilder(treeIngredient.ingredient.ingredient.getName()); + /*if(quest.getPreRequisites().isEmpty() || quest.preRequisitesCompleted()){ + if(quest.isCompleted()){ + s.append("\n").append(TextFormatting.LIME).append("Completed!"); + if(!quest.areAllRewardsRedeemed()){ + s.append("\n").append(TextFormatting.LIGHT_BLUE).append("Unclaimed rewards!"); + } + } else { + s.append("\n").append(TextFormatting.LIGHT_GRAY).append(quest.numberOfCompletedTasks()).append("/").append(quest.getTasks().size()).append(" tasks."); + } + } else { + s.append("\n").append(TextFormatting.RED).append("Requires ").append("(").append(quest.getQuestLogic()).append("):"); + for (Quest preRequisite : quest.getPreRequisites()) { + s.append("\n").append(TextFormatting.RED).append("- ").append(preRequisite.getTranslatedName()); + } + s.append(TextFormatting.WHITE); + }*/ + tooltip.render(s.toString(),mouseX,mouseY,8,-8); + } + public boolean drawSidebar(){ + return /*VintageQuesting.CHAPTERS.size()*/0 > 1; + } + private void scrollPagesList(float amount) { + if(amount == 0.0f) return; + + pageListScrollAmount += amount; + onScrollPagesList(); + } + + private void onScrollPagesList() { + int totalPagesListHeight = getTotalPagesListHeight(); + if (pageListScrollAmount < 0 || pagesListScrollRegionHeight > totalPagesListHeight) pageListScrollAmount = 0; + else if (pageListScrollAmount > totalPagesListHeight - pagesListScrollRegionHeight) pageListScrollAmount = totalPagesListHeight - pagesListScrollRegionHeight; + } + private int getTotalPagesListHeight() { + return PAGE_BUTTON_HEIGHT * 0;//VintageQuesting.CHAPTERS.size(); + } + + @Nullable + private RecipeTreePage drawPagesListItems(int x, int y, int width, int mouseX, int mouseY) { + int y2 = y; + RecipeTreePage pageHovered = null; + /*for (QuestChapterPage page : VintageQuesting.CHAPTERS) { + String name = page.getName(); + int textColor = 0xFF7F7F7F; + if (page == currentPage) { + textColor = 0xFFFFFFFF; + } + if (mouseX >= x && mouseX < x + width && mouseY >= y2 && mouseY < y2 + PAGE_BUTTON_HEIGHT) { + textColor = 0xFFFFFFA0; + pageHovered = page; + } + renderItem.render(page.getIcon(), x, y2 + (PAGE_BUTTON_HEIGHT / 2) - 9); + if (page.getCompletionFraction() >= 1) { + GL11.glColor4f(1f, 1f, 1f, 1f); + drawGuiIcon(x + 8, y2 + (PAGE_BUTTON_HEIGHT / 2) - 9 + 8, 11, 11, TextureRegistry.getTexture("minecraft:gui/screen/achievement/star")); + } + mc.font.drawStringWithShadow(name, x + 19, y2 + (PAGE_BUTTON_HEIGHT / 2) - 4, textColor); + y2 += PAGE_BUTTON_HEIGHT; + }*/ + + return pageHovered; + } + protected void drawPagesListScrollBar(int mouseX, int mouseY) { + float totalPagesListHeight = getTotalPagesListHeight(); + float scrollBarHeightPercent = pagesListScrollRegionHeight / totalPagesListHeight; + + if(scrollBarHeightPercent > 1.0f) return; + + glDisable(GL_TEXTURE_2D); + + int scrollBarX = pageListRight - 6; + + int scrollBarHeightPx = (int) (scrollBarHeightPercent * pagesListScrollRegionHeight); + if(scrollBarHeightPx < 32) { + scrollBarHeightPx = 32; + } + + float scrollPercent = pageListScrollAmount / (totalPagesListHeight - pagesListScrollRegionHeight); + + int scrollBarY = (int) (top + (pagesListScrollRegionHeight - scrollBarHeightPx) * scrollPercent); + + Tessellator t = Tessellator.instance; + + t.startDrawingQuads(); + t.setColorOpaque(0, 0, 0); + t.drawRectangle(scrollBarX, top, 6, pagesListScrollRegionHeight); + t.setColorRGBA_I(0x808080, 255); + t.drawRectangle(scrollBarX, scrollBarY, 6, scrollBarHeightPx); + t.setColorRGBA_I(0xc0c0c0, 255); + t.drawRectangle(scrollBarX + 1, scrollBarY, 5, scrollBarHeightPx - 1); + t.draw(); + + glEnable(GL_TEXTURE_2D); + + if(clickX != null && clickY != null) { + if(clickX >= scrollBarX && clickY >= top && clickX <= scrollBarX + 6 && clickY < bottom) { + if(oldPagesListScrollAmount == null) { + oldPagesListScrollAmount = pageListScrollAmount; + } + pageListScrollAmount = oldPagesListScrollAmount + (clickY - mouseY) * (1.0f / scrollBarHeightPercent) * -1.0f; + onScrollPagesList(); + } + }else { + oldPagesListScrollAmount = null; + } + } + + private void overlayBackground(int minX, int maxX, int minY, int maxY, int color) + { + Tessellator tessellator = Tessellator.instance; + mc.textureManager.loadTexture("/assets/minecraft/textures/gui/background.png").bind(); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + float scale = 32F; + tessellator.startDrawingQuads(); + tessellator.setColorOpaque_I(color); + tessellator.addVertexWithUV(minX, maxY, 0.0D, (float) minX / scale, (float) maxY / scale); + tessellator.addVertexWithUV(maxX, maxY, 0.0D, (float) maxX / scale, (float) maxY / scale); + tessellator.setColorOpaque_I(color); + tessellator.addVertexWithUV(maxX, minY, 0.0D, (float) maxX / scale, (float) minY / scale); + tessellator.addVertexWithUV(minX, minY, 0.0D, (float) minX / scale, (float) minY / scale); + tessellator.draw(); + } + + public static class BGLayer { + private IconCoordinate[] data; + private int width; + private int height; + public final int id; + public BGLayer(int id) { + this.id = id; + data = new IconCoordinate[0]; + width = 0; + height = 0; + } + public int getWidth() { + return width; + } + public int getHeight() { + return height; + } + public IconCoordinate[] getData() { + return data; + } + protected void resize(int width, int height) { + this.width = width; + this.height = height; + data = new IconCoordinate[width * height]; + } + public void put(IconCoordinate coordinate, int x, int y){ + if (x < 0) return; + if (y < 0) return; + if (x >= width) return; + if (y >= height) return; + data[makeIndex(x, y)] = coordinate; + } + + public IconCoordinate get(int x, int y){ + if (x < 0) return null; + if (y < 0) return null; + if (x >= width) return null; + if (y >= height) return null; + return data[makeIndex(x, y)]; + } + + private int makeIndex(int x, int y){ + return x % width + y * width; + } + } +} diff --git a/src/main/java/turing/tmb/client/ScreenTMBRecipe.java b/src/main/java/turing/tmb/client/ScreenTMBRecipe.java index ca98342..da2d955 100644 --- a/src/main/java/turing/tmb/client/ScreenTMBRecipe.java +++ b/src/main/java/turing/tmb/client/ScreenTMBRecipe.java @@ -6,7 +6,6 @@ import net.minecraft.client.gui.ButtonElement; import net.minecraft.client.gui.Screen; import net.minecraft.client.gui.TooltipElement; -import net.minecraft.core.item.ItemStack; import net.minecraft.core.lang.I18n; import net.minecraft.core.net.command.TextFormatting; import net.minecraft.core.sound.SoundCategory; @@ -15,21 +14,18 @@ import org.jetbrains.annotations.Nullable; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; -import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GL11; +import turing.tmb.RecipeIngredient; import turing.tmb.TMB; import turing.tmb.TooltipBuilder; -import turing.tmb.api.ItemStackIngredientRenderer; -import turing.tmb.api.VanillaTypes; -import turing.tmb.api.drawable.IDrawable; import turing.tmb.api.drawable.IIngredientList; import turing.tmb.api.drawable.builder.ITooltipBuilder; import turing.tmb.api.ingredient.IIngredientRenderer; import turing.tmb.api.ingredient.IIngredientType; import turing.tmb.api.ingredient.ITypedIngredient; import turing.tmb.api.recipe.*; +import turing.tmb.util.IKeybinds; import turing.tmb.util.IngredientList; -import turing.tmb.util.LookupContext; import turing.tmb.util.RenderUtil; import java.util.*; @@ -51,6 +47,7 @@ public class ScreenTMBRecipe extends Screen { private int tabsPerPage = 7; private final List> tabList = new ArrayList<>(); private final List, Pair>> drawnIngredients = new ArrayList<>(); + private final List recipeIngredients = new ArrayList<>(); private final ButtonElement rightButton = new ButtonElement(0, 0, 0, ">"); private final ButtonElement leftButton = new ButtonElement(1, 0, 0, "<"); private final ButtonElement tabLeftButton = new ButtonElement(2, 0, 0, "<"); @@ -229,6 +226,7 @@ public void render(int mx, int my, float partialTick) { TMB.getRuntime().getGuiHelper().getCycleTimer().onDraw(); drawnIngredients.clear(); + recipeIngredients.clear(); tooltip = ""; TooltipBuilder tooltipBuilder = new TooltipBuilder(); @@ -263,6 +261,7 @@ public void render(int mx, int my, float partialTick) { renderCatalysts(category, mx, my, tooltipBuilder, isCtrl, isShift); int X = x + 4; int Y = y + 14; + GL11.glPushMatrix(); GL11.glTranslatef(x + 4, y + 14, 0); IRecipeLayout layout = category.getRecipeLayout(); @@ -279,13 +278,33 @@ public void render(int mx, int my, float partialTick) { GL11.glTranslatef(slot.getX(), slot.getY(), 0); X += slot.getX(); Y += slot.getY(); - slot.draw(TMB.getRuntime().getGuiHelper()); + boolean defaultRecipe = false; + if(slot.getRole() == RecipeIngredientRole.OUTPUT){ + if (ingredients.size() > I) { + IIngredientList list = ingredients.get(I); + ITypedIngredient ingredient = TMB.getRuntime().getGuiHelper().getCycleTimer().getCycledItem(list.getIngredients()); + if(ingredient != null){ + if(TMB.getRuntime().getDefaultRecipes().entrySet().stream().anyMatch((E)->E.getKey().ingredient.matches(ingredient.getIngredient()))){ + Map.Entry> entry = TMB.getRuntime().getDefaultRecipes().entrySet().stream().filter((E) -> E.getKey().ingredient.matches(ingredient.getIngredient())).collect(Collectors.toList()).get(0); + if(entry.getValue() == recipe){ + defaultRecipe = true; + } + } + } + } + } + if(defaultRecipe){ + slot.draw(TMB.getRuntime().getGuiHelper(),1,1,0,1); + } else { + slot.draw(TMB.getRuntime().getGuiHelper()); + } if (ingredients.size() > I) { GL11.glTranslatef(1, 1, 0); X++; Y++; IIngredientList list = ingredients.get(I); ITypedIngredient ingredient = TMB.getRuntime().getGuiHelper().getCycleTimer().getCycledItem(list.getIngredients()); + if (lookupContext != null) { Optional> found = list.getIngredients().stream().filter((t) -> t.hashCode() == lookupContext.getIngredient().hashCode()).findFirst(); if (found.isPresent()) { @@ -297,6 +316,7 @@ public void render(int mx, int my, float partialTick) { IIngredientRenderer renderer = (IIngredientRenderer) type.getRenderer(TMB.getRuntime()); new DrawableIngredient<>(ingredient.getIngredient(), renderer).draw(TMB.getRuntime().getGuiHelper()); drawnIngredients.add(Pair.of(ingredient, Pair.of(X, Y))); + recipeIngredients.add(new RecipeIngredient(ingredient, recipe, category, slot.getRole())); if (mx >= X && mx < X + 18 && my >= Y && my < Y + 18) { int mouseX = mx - ((this.width - this.xSize) / 2) - 4; int mouseY = my - ((this.height - this.ySize) / 2) - 14 - ((category.getBackground().getHeight() + 4) * i); @@ -373,6 +393,7 @@ public void render(int mx, int my, float partialTick) { tooltipElement.render(tooltip, mx, my, 8, -8); GL11.glPopMatrix(); } + super.render(mx,my,partialTick); } @SuppressWarnings("unchecked") @@ -393,6 +414,7 @@ private void renderCatalysts(IRecipeCategory category, int mx, int my, IToolt new DrawableIngredient<>(ingredient.getIngredient(), ingredient.getType().getRenderer(TMB.getRuntime())).draw(TMB.getRuntime().getGuiHelper(), x + 3, y + 3); drawnIngredients.add(Pair.of(ingredient, Pair.of(x + 3, y + 3))); + recipeIngredients.add(new RecipeIngredient(ingredient,null, null, RecipeIngredientRole.CATALYST)); if (mx >= x && mx < x + 22 && my >= y && my < y + 22) { ingredient.getType().getRenderer(TMB.getRuntime()).getTooltip(tooltipBuilder, ingredient.getIngredient(), isCtrl, isShift); @@ -427,8 +449,66 @@ public void keyPressed(char eventCharacter, int eventKey, int mx, int my) { } mc.displayScreen(s); } + + if (eventKey == ((IKeybinds)mc.gameSettings).toomanyblocks$getKeyShowRecipeTree().getKeyCode()){ + for (int i = 0; i < drawnIngredients.size(); i++) { + Pair, Pair> drawn = drawnIngredients.get(i); + RecipeIngredient recipeIngredient = recipeIngredients.get(i); + if (mx >= drawn.getRight().getLeft() && my >= drawn.getRight().getRight() && mx < drawn.getRight().getLeft() + 16 && my < drawn.getRight().getRight() + 16) { + if (recipeIngredient.recipe != null) { + mc.displayScreen(new ScreenRecipeTree(this,new RecipeTreePage(recipeIngredient),recipeIngredient)); + } + break; + } + } + } + + if (eventKey == ((IKeybinds)mc.gameSettings).toomanyblocks$getKeyAddFavourite().getKeyCode()){ + for (int i = 0; i < drawnIngredients.size(); i++) { + Pair, Pair> drawn = drawnIngredients.get(i); + RecipeIngredient recipeIngredient = recipeIngredients.get(i); + if (mx >= drawn.getRight().getLeft() && my >= drawn.getRight().getRight() && mx < drawn.getRight().getLeft() + 16 && my < drawn.getRight().getRight() + 16) { + if (recipeIngredient.recipe != null) { + if (TMB.getRuntime().getFavourites().stream().anyMatch(it -> it.matches(recipeIngredient.ingredient.getIngredient()))) { + TMB.getRuntime().getFavourites().removeIf(ingredient -> recipeIngredient.ingredient.matches(ingredient.getIngredient())); + } else { + TMB.getRuntime().getFavourites().add(recipeIngredient.ingredient); + } + } + break; + } + } + } + + if (eventKey == ((IKeybinds)mc.gameSettings).toomanyblocks$getKeySetDefaultRecipe().getKeyCode()){ + loop: for (int i = 0; i < drawnIngredients.size(); i++) { + Pair, Pair> drawn = drawnIngredients.get(i); + RecipeIngredient recipeIngredient = recipeIngredients.get(i); + if (mx >= drawn.getRight().getLeft() && my >= drawn.getRight().getRight() && mx < drawn.getRight().getLeft() + 16 && my < drawn.getRight().getRight() + 16) { + if (recipeIngredient.recipe != null && recipeIngredient.role == RecipeIngredientRole.OUTPUT) { + Iterator>> iterator = TMB.getRuntime().getDefaultRecipes().entrySet().iterator(); + while (iterator.hasNext()) { + RecipeIngredient ingredient = iterator.next().getKey(); + if(ingredient.ingredient.matches(recipeIngredient.ingredient.getIngredient())){ + iterator.remove(); + if(Objects.equals(recipeIngredient.recipe.getOriginal().toString(), ingredient.recipe.getOriginal().toString())){ + mc.hudIngame.addChatMessage(String.format(I18n.getInstance().translateKey("message.tmb.removeDefaultRecipe"),recipeIngredient.ingredient.getName())); + break loop; + } + } + } + TMB.getRuntime().getDefaultRecipes().put(recipeIngredient, recipeIngredient.recipe); + mc.hudIngame.addChatMessage(String.format(I18n.getInstance().translateKey("message.tmb.setDefaultRecipe"), recipeIngredient.ingredient.getName(), recipeIngredient.recipe.getOriginal().toString())); + //mc.displayScreen(new ScreenRecipeTree(this,new RecipeTreePage(recipeIngredient),recipeIngredient)); + } + break; + } + } + } + if (eventKey == mc.gameSettings.keyShowRecipe.getKeyCode() || eventKey == mc.gameSettings.keyShowUsage.getKeyCode()) { - for (Pair, Pair> drawn : drawnIngredients) { + for (int i = 0; i < drawnIngredients.size(); i++) { + Pair, Pair> drawn = drawnIngredients.get(i); if (mx >= drawn.getRight().getLeft() && my >= drawn.getRight().getRight() && mx < drawn.getRight().getLeft() + 16 && my < drawn.getRight().getRight() + 16) { if (eventKey == mc.gameSettings.keyShowUsage.getKeyCode()) { TMB.getRuntime().showRecipe(drawn.getLeft(), RecipeIngredientRole.INPUT); diff --git a/src/main/java/turing/tmb/client/TMBRenderer.java b/src/main/java/turing/tmb/client/TMBRenderer.java index 33066a8..b6a0caf 100644 --- a/src/main/java/turing/tmb/client/TMBRenderer.java +++ b/src/main/java/turing/tmb/client/TMBRenderer.java @@ -8,6 +8,7 @@ import net.minecraft.client.gui.TextFieldElement; import net.minecraft.client.gui.TooltipElement; import net.minecraft.client.gui.container.ScreenContainerAbstract; +import net.minecraft.core.item.ItemStack; import net.minecraft.core.sound.SoundCategory; import net.minecraft.core.util.helper.MathHelper; import org.jetbrains.annotations.Nullable; @@ -34,13 +35,19 @@ public class TMBRenderer { public static int currentPage = 0; public static int pages = 0; + public static int currentFavouritePage = 0; + public static int favouritePages = 0; public static boolean show = true; public static boolean enabledRecipes = true; protected static boolean initialized; protected static final ButtonElement leftButton = new ButtonElement(0, 0, 0, 16, 16, "<"); protected static final ButtonElement rightButton = new ButtonElement(1, 0, 0, 16, 16, ">"); + protected static final ButtonElement leftButton2 = new ButtonElement(0, 0, 0, 16, 16, "<"); + protected static final ButtonElement rightButton2 = new ButtonElement(1, 0, 0, 16, 16, ">"); public static TextFieldElement search; protected static TooltipElement tooltip; + private static ITypedIngredient hoveredItem = null; + private static int debounce = 0; public static void init(Minecraft mc) { initialized = true; @@ -77,6 +84,28 @@ public static void renderHeader(int mouseX, int mouseY, int width, int height, M search.drawTextBox(); } + public static void renderHeader2(int mouseX, int mouseY, int width, int height, Minecraft mc, float pt, @Nullable IGuiProperties properties) { + if (!show || !initialized) return; + int w = (int) (width / 3.5F); + Screen currentScreen = mc.currentScreen; + if (currentScreen instanceof ScreenContainerAbstract) { + w = Math.min(((width / 2) - ((ScreenContainerAbstract) (currentScreen)).xSize / 2) - 16, w); + } else if (properties != null) { + w = Math.min(((width / 2) - properties.guiXSize() / 2) - 16, w); + } + int startX = 0;//width - w; + int startY = 4; + String str = "Page " + (currentFavouritePage + 1) + " / " + (favouritePages + 1); + + leftButton2.xPosition = startX; + leftButton2.yPosition = startY; + rightButton2.xPosition = Math.min(startX + (18 * (w / 18)), width - 18); + rightButton2.yPosition = startY; + mc.font.renderString(str, ((((leftButton2.xPosition + leftButton2.width) + (rightButton2.xPosition + rightButton2.width)) / 2) - mc.font.getStringWidth(str) / 2) - 4, startY + 4, 0xFFFFFF, false); + leftButton2.drawButton(mc, mouseX, mouseY); + rightButton2.drawButton(mc, mouseX, mouseY); + } + public static void onTick() { if (!show) return; if(search == null) return; @@ -100,6 +129,25 @@ public static void mouseClicked(int mouseX, int mouseY, int width, int height, M if (currentPage < 0) currentPage = pages; if (currentPage > pages) currentPage = 0; } + + boolean left2 = leftButton2.mouseClicked(mc, mouseX, mouseY); + boolean right2 = rightButton2.mouseClicked(mc, mouseX, mouseY); + if (left2 || right2) { + mc.sndManager.playSound("random.click", SoundCategory.GUI_SOUNDS, 1.0F, 1.0F); + int change = 1; + if (left2) { + change = -1; + } + currentFavouritePage += change; + if (currentFavouritePage < 0) currentFavouritePage = favouritePages; + if (currentFavouritePage > favouritePages) currentFavouritePage = 0; + } + + + if(hoveredItem != null && hoveredItem.getIngredient() instanceof ItemStack && mc.thePlayer.inventory.getHeldItemStack() == null) { + //mc.thePlayer.sendChatMessage("/give @p "+((ItemStack) hoveredItem.getIngredient()).getItem().namespaceID.toString()+" 64"); + } + search.mouseClicked(mouseX, mouseY, 1); } @@ -151,11 +199,11 @@ public static void renderItems(int mouseX, int mouseY, int width, int height, Mi List> pageList = toDisplay.stream().skip((long) itemsPerPage * currentPage).limit(itemsPerPage).collect(Collectors.toList()); - ITypedIngredient hoveredItem = null; TooltipBuilder tooltipBuilder = new TooltipBuilder(); boolean isCtrl = Keyboard.isKeyDown(29) || Keyboard.isKeyDown(157); boolean isShift = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT); + hoveredItem = null; int i = 0; loop: for (int y = 0; y < itemsY; y++) { for (int x = 0; x < itemsX; x++) { @@ -197,6 +245,107 @@ public static void renderItems(int mouseX, int mouseY, int width, int height, Mi runtime.showRecipe(hoveredItem, RecipeIngredientRole.INPUT); } } + + if (((IKeybinds) mc.gameSettings).toomanyblocks$getKeyAddFavourite().isPressed()) { + if (runtime.getFavourites().stream().noneMatch(it -> it.matches(hoveredItem.getIngredient()))) { + runtime.getFavourites().add(hoveredItem); + } + } + } + } + + public static void renderItems2(int mouseX, int mouseY, int width, int height, Minecraft mc, float pt, @Nullable IGuiProperties properties) { + if (!initialized) { + init(mc); + return; + } + if (!show) { + return; + } + if(debounce > 0) debounce--; + + Screen currentScreen = mc.currentScreen; + ITMBRuntime runtime = TMB.getRuntime(); + Collection> toDisplay = runtime.getFavourites(); + + int startX = (int) (width / 3.5F); + + if (currentScreen instanceof ScreenContainerAbstract) { + startX = Math.min(((width / 2) - ((ScreenContainerAbstract) (currentScreen)).xSize / 2) - 18, startX); + } else if (properties != null) { + startX = Math.min(((width / 2) - properties.guiXSize() / 2) - 18, startX); + } + + int itemsX = (startX / 18); + int itemsY = Math.min((height / 18) - 1, ((height - 28) / 18)); + int xOffset = 0; + int yOffset = 1; + + startX = 0; + + int itemsPerPage = itemsX * itemsY; + if (itemsPerPage <= 0) return; + favouritePages = toDisplay.size() / itemsPerPage; + + if (currentFavouritePage > favouritePages) currentFavouritePage = favouritePages; + + List> pageList = toDisplay.stream().skip((long) itemsPerPage * currentFavouritePage).limit(itemsPerPage).collect(Collectors.toList()); + + TooltipBuilder tooltipBuilder = new TooltipBuilder(); + boolean isCtrl = Keyboard.isKeyDown(29) || Keyboard.isKeyDown(157); + boolean isShift = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT); + + hoveredItem = null; + int i = 0; + loop: for (int y = 0; y < itemsY; y++) { + for (int x = 0; x < itemsX; x++) { + if (i >= pageList.size()) break loop; + ITypedIngredient ingredient = (ITypedIngredient) pageList.get(i); + int xOff = /*width -*/ startX + (xOffset * 16) + (2 * xOffset); + int yOff = 8 + (yOffset * 16) + (2 * yOffset); + + ingredient.getType().getRenderer(runtime).render(runtime.getGuiHelper(), ingredient.getIngredient(), xOff, yOff); + + if (mouseX >= xOff && mouseX < xOff + 16 && mouseY >= yOff && mouseY < yOff + 16) { + hoveredItem = ingredient; + ingredient.getType().getRenderer(runtime).getTooltip(tooltipBuilder, hoveredItem.getIngredient(), isCtrl, isShift); + RenderUtil.renderItemSelected(runtime.getGuiHelper(), xOff, yOff); + } + + i++; + xOffset++; + if (xOffset >= itemsX) { + xOffset = 0; + } + } + yOffset++; + } + + if (hoveredItem != null) { + if (!tooltipBuilder.getLines().isEmpty()) { + StringBuilder builder = new StringBuilder(); + tooltipBuilder.getLines().forEach(str -> builder.append(str).append("\n")); + GL11.glPushMatrix(); + tooltip.render(builder.toString(), mouseX, mouseY, 8, -8); + GL11.glPopMatrix(); + } + + if (enabledRecipes) { + if (mc.gameSettings.keyShowRecipe.isPressed()) { + runtime.showRecipe(hoveredItem, RecipeIngredientRole.OUTPUT); + } else if (mc.gameSettings.keyShowUsage.isPressed()) { + runtime.showRecipe(hoveredItem, RecipeIngredientRole.INPUT); + } + } + + if (((IKeybinds) mc.gameSettings).toomanyblocks$getKeyAddFavourite().isPressed() && debounce <= 0) { + debounce = 10; + if (runtime.getFavourites().stream().anyMatch(it -> it.matches(hoveredItem.getIngredient()))) { + runtime.getFavourites().removeIf(it -> it.matches(hoveredItem.getIngredient())); + } else { + runtime.getFavourites().add(hoveredItem); + } + } } } diff --git a/src/main/java/turing/tmb/mixin/LevelDataMixin.java b/src/main/java/turing/tmb/mixin/LevelDataMixin.java new file mode 100644 index 0000000..0006acd --- /dev/null +++ b/src/main/java/turing/tmb/mixin/LevelDataMixin.java @@ -0,0 +1,97 @@ +package turing.tmb.mixin; + +import com.mojang.nbt.tags.CompoundTag; +import com.mojang.nbt.tags.Tag; +import net.minecraft.core.world.save.LevelData; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import turing.tmb.RecipeIngredient; +import turing.tmb.TMB; +import turing.tmb.api.ingredient.ITypedIngredient; +import turing.tmb.api.recipe.IRecipeCategory; +import turing.tmb.api.recipe.IRecipeTranslator; +import turing.tmb.api.recipe.RecipeIngredientRole; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicReference; + +@Mixin(value = LevelData.class,remap = false) +public class LevelDataMixin { + + @Inject(method = "updateTagCompound", at = @At("HEAD")) + private void updateTagCompound(CompoundTag levelTag, CompoundTag playerTag, CallbackInfo ci) { + CompoundTag favourites = new CompoundTag(); + List> iTypedIngredients = TMB.getRuntime().getFavourites(); + for (int j = 0; j < iTypedIngredients.size(); j++) { + ITypedIngredient favourite = iTypedIngredients.get(j); + CompoundTag favouriteTag = new CompoundTag(); + favouriteTag.putString("namespace", favourite.getNamespace()); + favouriteTag.putString("uid", favourite.getUid()); + favourites.put(String.valueOf(j), favouriteTag); + } + levelTag.putCompound("Favourites", favourites); + + CompoundTag defaultRecipes = new CompoundTag(); + int i = 0; + for (Map.Entry> entry : TMB.getRuntime().getDefaultRecipes().entrySet()) { + RecipeIngredient key = entry.getKey(); + IRecipeTranslator value = entry.getValue(); + CompoundTag defaultRecipeTag = new CompoundTag(); + CompoundTag ingredientTag = new CompoundTag(); + CompoundTag categoryTag = new CompoundTag(); + + defaultRecipeTag.putString("recipe", value.getOriginal().toString()); + ingredientTag.putString("namespace", key.ingredient.getNamespace()); + ingredientTag.putString("uid", key.ingredient.getUid()); + defaultRecipeTag.put("ingredient", ingredientTag); + categoryTag.putString("namespace", key.category.getNamespace()); + categoryTag.putString("name", key.category.getName()); + defaultRecipeTag.put("category", categoryTag); + defaultRecipes.put(String.valueOf(i), defaultRecipeTag); + i++; + } + levelTag.putCompound("DefaultRecipes", defaultRecipes); + } + + + @Inject(method = "readFromCompoundTag", at = @At("HEAD")) + private void readFromCompoundTag(CompoundTag tag, CallbackInfo ci) { + TMB.getRuntime().getFavourites().clear(); + for (Tag compoundTag : tag.getCompound("Favourites").getValues()) { + CompoundTag favouriteTag = (CompoundTag) compoundTag; + TMB.getRuntime().getIngredientIndex() + .getIngredient(favouriteTag.getString("namespace"), favouriteTag.getString("uid")) + .ifPresent(TMB.getRuntime().getFavourites()::add); + } + + for (Tag compoundTag : tag.getCompound("DefaultRecipes").getValues()) { + CompoundTag defaultRecipeTag = (CompoundTag) compoundTag; + CompoundTag ingredientTag = defaultRecipeTag.getCompound("ingredient"); + CompoundTag categoryTag = defaultRecipeTag.getCompound("category"); + String recipeId = defaultRecipeTag.getString("recipe"); + + Optional> category = TMB.getRuntime().getRecipeIndex().getAllCategories().stream() + .filter(it -> + it.getName().equals(categoryTag.getString("name")) + && it.getNamespace().equals(categoryTag.getString("namespace"))).findFirst(); + + Optional> recipe = category + .flatMap(it -> TMB.getRuntime().getRecipeIndex().getRecipeLists().get(it).stream() + .filter(it2 -> it2.getOriginal().toString().equals(recipeId)).findFirst()); + + Optional> ingredient = recipe + .flatMap(it -> TMB.getRuntime().getIngredientIndex() + .getIngredient(ingredientTag.getString("namespace"), ingredientTag.getString("uid"))); + + ingredient + .ifPresent(it -> { + RecipeIngredient recipeIngredient = new RecipeIngredient(it, recipe.get(), category.get(), RecipeIngredientRole.OUTPUT); + TMB.getRuntime().getDefaultRecipes().put(recipeIngredient, recipe.get()); + }); + } + } +} diff --git a/src/main/java/turing/tmb/mixin/client/GameSettingsMixin.java b/src/main/java/turing/tmb/mixin/client/GameSettingsMixin.java index 87e6688..2318ced 100644 --- a/src/main/java/turing/tmb/mixin/client/GameSettingsMixin.java +++ b/src/main/java/turing/tmb/mixin/client/GameSettingsMixin.java @@ -19,6 +19,15 @@ public class GameSettingsMixin implements IKeybinds { @Unique public KeyBinding keyHideTMB = new KeyBinding("key.tmb.hide").bind(InputDevice.keyboard, Keyboard.KEY_O); + @Unique + public KeyBinding keyShowRecipeTree = new KeyBinding("key.tmb.showRecipeTree").bind(InputDevice.keyboard, Keyboard.KEY_T); + + @Unique + public KeyBinding keySetDefaultRecipe = new KeyBinding("key.tmb.setDefaultRecipe").bind(InputDevice.keyboard, Keyboard.KEY_D); + + @Unique + public KeyBinding keyAddFavourite = new KeyBinding("key.tmb.keyAddFavourite").bind(InputDevice.keyboard, Keyboard.KEY_A); + @Unique public OptionBoolean isTMBHidden = new OptionBoolean((GameSettings) ((Object) this), "isTMBHidden", false); @@ -48,6 +57,21 @@ public class GameSettingsMixin implements IKeybinds { return lastTMBSearch; } + @Override + public KeyBinding toomanyblocks$getKeyShowRecipeTree() { + return keyShowRecipeTree; + } + + @Override + public KeyBinding toomanyblocks$getKeySetDefaultRecipe() { + return keySetDefaultRecipe; + } + + @Override + public KeyBinding toomanyblocks$getKeyAddFavourite() { + return keyAddFavourite; + } + @Inject(method = "saveOptions", at = @At("HEAD")) public void saveTMBState(CallbackInfo ci) { if (TMBRenderer.search != null) { diff --git a/src/main/java/turing/tmb/mixin/client/ScreenContainerAbstractMixin.java b/src/main/java/turing/tmb/mixin/client/ScreenContainerAbstractMixin.java index f51d109..593aaa4 100644 --- a/src/main/java/turing/tmb/mixin/client/ScreenContainerAbstractMixin.java +++ b/src/main/java/turing/tmb/mixin/client/ScreenContainerAbstractMixin.java @@ -30,6 +30,8 @@ public ScreenContainerAbstractMixin() { public void render(int mouseX, int mouseY, float pt, CallbackInfo ci) { TMBRenderer.renderHeader(mouseX, mouseY, width, height, mc, pt, null); TMBRenderer.renderItems(mouseX, mouseY, width, height, mc, pt, null); + TMBRenderer.renderHeader2(mouseX, mouseY, width, height, mc, pt, null); + TMBRenderer.renderItems2(mouseX, mouseY, width, height, mc, pt, null); } @Inject(method = "tick", at = @At("HEAD")) diff --git a/src/main/java/turing/tmb/mixin/client/ScreenMixin.java b/src/main/java/turing/tmb/mixin/client/ScreenMixin.java index 1371b7e..a8c224b 100644 --- a/src/main/java/turing/tmb/mixin/client/ScreenMixin.java +++ b/src/main/java/turing/tmb/mixin/client/ScreenMixin.java @@ -30,6 +30,8 @@ public void render(int mouseX, int mouseY, float partialTick, CallbackInfo ci) { IGuiProperties properties = GuiHelper.extraScreens.get(t.getClass().getCanonicalName()).apply(t); TMBRenderer.renderHeader(mouseX, mouseY, width, height, mc, partialTick, properties); TMBRenderer.renderItems(mouseX, mouseY, width, height, mc, partialTick, properties); + TMBRenderer.renderHeader2(mouseX, mouseY, width, height, mc, partialTick, properties); + TMBRenderer.renderItems2(mouseX, mouseY, width, height, mc, partialTick, properties); } } diff --git a/src/main/java/turing/tmb/util/IKeybinds.java b/src/main/java/turing/tmb/util/IKeybinds.java index 16546c7..6e326c1 100644 --- a/src/main/java/turing/tmb/util/IKeybinds.java +++ b/src/main/java/turing/tmb/util/IKeybinds.java @@ -12,4 +12,11 @@ public interface IKeybinds { OptionBoolean toomanyblocks$getIsRecipeViewEnabled(); OptionString toomanyblocks$getLastTMBSearch(); + + + KeyBinding toomanyblocks$getKeyShowRecipeTree(); + + KeyBinding toomanyblocks$getKeySetDefaultRecipe(); + + KeyBinding toomanyblocks$getKeyAddFavourite(); } diff --git a/src/main/java/turing/tmb/vanilla/AbstractCraftingRecipeCategory.java b/src/main/java/turing/tmb/vanilla/AbstractCraftingRecipeCategory.java index 4f6c99c..1fdb192 100644 --- a/src/main/java/turing/tmb/vanilla/AbstractCraftingRecipeCategory.java +++ b/src/main/java/turing/tmb/vanilla/AbstractCraftingRecipeCategory.java @@ -7,6 +7,7 @@ import org.jetbrains.annotations.Nullable; import turing.tmb.RecipeLayoutBuilder; import turing.tmb.RecipeTranslator; +import turing.tmb.TMB; import turing.tmb.TypedIngredient; import turing.tmb.api.ItemStackIngredientRenderer; import turing.tmb.api.VanillaTypes; @@ -52,15 +53,19 @@ public IDrawable getBackground() { @Override public void drawRecipe(ITMBRuntime runtime, T recipe, IRecipeLayout layout, List ingredients, ILookupContext context) { - ingredients.add(0, new IngredientList(TypedIngredient.itemStackIngredient(recipe.getOriginal().getOutput()))); - - addInputs(runtime, recipe, layout, ingredients, context); + getIngredients(recipe, layout, context, ingredients); arrow.draw(runtime.getGuiHelper(), x + 62, (background.getHeight() / 2) + 6); } abstract void addInputs(ITMBRuntime runtime, T recipe, IRecipeLayout layout, List ingredients, ILookupContext context); + @Override + public void getIngredients(T recipe, IRecipeLayout layout, ILookupContext context, List ingredients) { + ingredients.add(0, new IngredientList(TypedIngredient.itemStackIngredient(recipe.getOriginal().getOutput()))); + addInputs(TMB.getRuntime(), recipe, layout, ingredients, context); + } + @Override public IRecipeLayout getRecipeLayout() { return new RecipeLayoutBuilder() diff --git a/src/main/java/turing/tmb/vanilla/FurnaceRecipeCategory.java b/src/main/java/turing/tmb/vanilla/FurnaceRecipeCategory.java index be927bb..9909153 100644 --- a/src/main/java/turing/tmb/vanilla/FurnaceRecipeCategory.java +++ b/src/main/java/turing/tmb/vanilla/FurnaceRecipeCategory.java @@ -65,8 +65,7 @@ public IDrawable getBackground() { @Override public void drawRecipe(ITMBRuntime runtime, T recipe, IRecipeLayout layout, List ingredients, ILookupContext context) { - ingredients.add(0, IngredientList.fromRecipeSymbol(recipe.getOriginal().getInput())); - ingredients.add(1, new IngredientList(TypedIngredient.itemStackIngredient(recipe.getOriginal().getOutput()))); + getIngredients(recipe, layout, context, ingredients); arrowBack.draw(runtime.getGuiHelper(), x + 26, (background.getHeight() / 2) - 5); arrow.draw(runtime.getGuiHelper(), x + 26, (background.getHeight() / 2) - 5); @@ -74,6 +73,12 @@ public void drawRecipe(ITMBRuntime runtime, T recipe, IRecipeLayout layout, List flame.draw(runtime.getGuiHelper(), x + 2, (background.getHeight() / 2) + 13); } + @Override + public void getIngredients(T recipe, IRecipeLayout layout, ILookupContext context, List ingredients) { + ingredients.add(0, IngredientList.fromRecipeSymbol(recipe.getOriginal().getInput())); + ingredients.add(1, new IngredientList(TypedIngredient.itemStackIngredient(recipe.getOriginal().getOutput()))); + } + @Override public IRecipeLayout getRecipeLayout() { return new RecipeLayoutBuilder() diff --git a/src/main/java/turing/tmb/vanilla/MobInfoCategory.java b/src/main/java/turing/tmb/vanilla/MobInfoCategory.java index a51b034..ac8ae99 100644 --- a/src/main/java/turing/tmb/vanilla/MobInfoCategory.java +++ b/src/main/java/turing/tmb/vanilla/MobInfoCategory.java @@ -152,11 +152,7 @@ public void drawRecipe(ITMBRuntime runtime, MobInfoRecipeTranslator recipe, IRec yOffset += 10; } - if (recipe.getOriginal().getDrops() != null && recipe.getOriginal().getDrops().length > 0) { - for (int i = 0; i < recipe.getOriginal().getDrops().length; i++) { - ingredients.add(new IngredientList(TypedIngredient.itemStackIngredient(recipe.getOriginal().getDrops()[i].getStack()))); - } - } + getIngredients(recipe, layout, context, ingredients); if (mob == null && !giveUp) { Class mobClass = recipe.getOriginal().getEntityClass(); @@ -174,6 +170,15 @@ public void drawRecipe(ITMBRuntime runtime, MobInfoRecipeTranslator recipe, IRec } } + @Override + public void getIngredients(MobInfoRecipeTranslator recipe, IRecipeLayout layout, ILookupContext context, List ingredients) { + if (recipe.getOriginal().getDrops() != null && recipe.getOriginal().getDrops().length > 0) { + for (int i = 0; i < recipe.getOriginal().getDrops().length; i++) { + ingredients.add(new IngredientList(TypedIngredient.itemStackIngredient(recipe.getOriginal().getDrops()[i].getStack()))); + } + } + } + @Override public > List getTooltips(MobInfoRecipeTranslator recipe, IRecipeSlot slot, int mouseX, int mouseY) { if (recipe.getOriginal().getDrops() != null && recipe.getOriginal().getDrops().length > 0) { diff --git a/src/main/java/turing/tmb/vanilla/TrommelRecipeCategory.java b/src/main/java/turing/tmb/vanilla/TrommelRecipeCategory.java index 8b351f2..485609f 100644 --- a/src/main/java/turing/tmb/vanilla/TrommelRecipeCategory.java +++ b/src/main/java/turing/tmb/vanilla/TrommelRecipeCategory.java @@ -63,6 +63,15 @@ public IDrawable getBackground() { @Override public void drawRecipe(ITMBRuntime runtime, TrommelRecipeTranslator recipe, IRecipeLayout layout, List ingredients, ILookupContext context) { + + getIngredients(recipe, layout, context, ingredients); + + arrowBack.draw(runtime.getGuiHelper(), x + 26, (background.getHeight() / 2) + 7); + arrow.draw(runtime.getGuiHelper(), x + 26, (background.getHeight() / 2) + 7); + } + + @Override + public void getIngredients(TrommelRecipeTranslator recipe, IRecipeLayout layout, ILookupContext context, List ingredients) { ingredients.add(0, IngredientList.fromRecipeSymbol(recipe.getOriginal().getInput())); for (int i = 0; i < 9; i++) { @@ -74,8 +83,6 @@ public void drawRecipe(ITMBRuntime runtime, TrommelRecipeTranslator recipe, IRec } } - arrowBack.draw(runtime.getGuiHelper(), x + 26, (background.getHeight() / 2) + 7); - arrow.draw(runtime.getGuiHelper(), x + 26, (background.getHeight() / 2) + 7); } @Override diff --git a/src/main/resources/lang/tmb/en_US.lang b/src/main/resources/lang/tmb/en_US.lang index e90d12c..38d382f 100644 --- a/src/main/resources/lang/tmb/en_US.lang +++ b/src/main/resources/lang/tmb/en_US.lang @@ -7,6 +7,13 @@ tmb.tooltip.allCategories=Click to see all categories gui.options.page.controls.category.tmb=Too Many Blocks gui.options.page.general.category.tmb=Too Many Blocks +gui.tmb.recipeTree.label.title=Recipe Tree key.tmb.hide=Hide TMB +key.tmb.keyAddFavourite=Add/Remove Favourite +key.tmb.setDefaultRecipe=Set/Remove Default Recipe +key.tmb.showRecipeTree=Show Recipe Tree options.isRecipeViewEnabled=Enable Recipe Viewing options.isTMBHidden=Hide TMB + +message.tmb.setDefaultRecipe=Set default recipe for '%s' to '%s'! +message.tmb.removeDefaultRecipe=Removed default recipe for '%s'. diff --git a/src/main/resources/tmb.mixins.json b/src/main/resources/tmb.mixins.json index 0483afa..594787e 100644 --- a/src/main/resources/tmb.mixins.json +++ b/src/main/resources/tmb.mixins.json @@ -4,6 +4,7 @@ "package": "turing.tmb.mixin", "compatibilityLevel": "JAVA_8", "mixins": [ + "LevelDataMixin" ], "client": [ "client.GameSettingsMixin", From 7f04fad7d48aeb98f03e66d4c54455963e110f79 Mon Sep 17 00:00:00 2001 From: MartinSVK12 <37455793+MartinSVK12@users.noreply.github.com> Date: Sun, 20 Jul 2025 15:40:10 +0200 Subject: [PATCH 2/6] Cleanup. --- .../turing/tmb/client/RecipeTreePage.java | 35 +- .../turing/tmb/client/ScreenRecipeTree.java | 355 ++---------------- 2 files changed, 23 insertions(+), 367 deletions(-) diff --git a/src/main/java/turing/tmb/client/RecipeTreePage.java b/src/main/java/turing/tmb/client/RecipeTreePage.java index 83b73c9..3c1a397 100644 --- a/src/main/java/turing/tmb/client/RecipeTreePage.java +++ b/src/main/java/turing/tmb/client/RecipeTreePage.java @@ -185,9 +185,6 @@ public void addRecipe(RecipeIngredient result, boolean root){ uniqueIngredients++; } usedRecipes.remove(currentRecipe.get().getOriginal().toString()); - //if(ingredients.size() > 1){ - - //} } public void addIngredient(@NotNull RecipeIngredient ingredient, int x, int y) { @@ -196,29 +193,6 @@ public void addIngredient(@NotNull RecipeIngredient ingredient, int x, int y) { entryMap.put(ingredient, entry); } - /*public void loadQuests(List quests){ - questList.clear(); - entryMap.clear(); - for (Quest quest : quests) { - if(quest.getPage() == this){ - questList.add(quest); - entryMap.put(quest.getTemplate(), quest); - } - } - } - - public void reset(){ - Set quests = new HashSet<>(entryMap.keySet()); - questList.clear(); - entryMap.clear(); - for (QuestTemplate quest : quests) { - addQuest(quest); - } - for (Quest quest : getQuests()) { - quest.setupPrerequisites(); - } - }*/ - public @Nullable IconCoordinate getBackgroundTile(ScreenRecipeTree screen, int layer, Random random, int tileX, int tileY) { return getTextureFromBlock(Blocks.DIRT); } @@ -244,14 +218,7 @@ public ItemStack getIcon() { } public double getCompletionFraction() { - /*int completed = 0; - for (Quest q : questList) { - if (q.isCompleted()) { - completed++; - } - } - return completed / (double) questList.size();*/ - return 0; + return 1; } public int backgroundLayers() { diff --git a/src/main/java/turing/tmb/client/ScreenRecipeTree.java b/src/main/java/turing/tmb/client/ScreenRecipeTree.java index 79e162b..8fd7ed7 100644 --- a/src/main/java/turing/tmb/client/ScreenRecipeTree.java +++ b/src/main/java/turing/tmb/client/ScreenRecipeTree.java @@ -190,7 +190,6 @@ public void init() protected void buttonClicked(ButtonElement button) { if(button.id == 1) { mc.displayScreen(parent); - //mc.setIngameFocus(); } super.buttonClicked(button); } @@ -222,26 +221,8 @@ public void mouseClicked(int mx, int my, int buttonNum) { if (pagesListHeight < bottom - top) { pagesListY = top + (bottom - top - pagesListHeight) / 2; } - /*for(QuestChapterPage page : VintageQuesting.CHAPTERS) { - if (mx >= pageListLeft && mx <= (pageListRight - 6) && my >= pagesListY && my <= pagesListY + PAGE_BUTTON_HEIGHT) { - currentPage = page; - mc.sndManager.playSound("random.click", SoundCategory.GUI_SOUNDS, 1.0F, 1.0F); - - layers = new BGLayer[currentPage.backgroundLayers()]; - for (int i = 0; i < layers.length; i++) { - layers[i] = new BGLayer(i); - } - - init(); - break; - } - pagesListY += PAGE_BUTTON_HEIGHT; - }*/ } - /*if(hoveredQuest != null){ - mc.displayScreen(new ScreenQuestInfo(this,hoveredQuest)); - }*/ super.mouseClicked(mx, my, buttonNum); @@ -288,14 +269,7 @@ public void render(int mx, int my, float partialTick) draggingViewport = false; } - /*if (drawSidebar() && mx >= pageListLeft && mx <= pageListRight) { - if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL)) { - scrollPagesList(Mouse.getDWheel() / -0.01f); - } else { - scrollPagesList(Mouse.getDWheel() / -0.05f); - } - onScrollPagesList(); - } else*/ if (mx >= viewportLeft && mx <= viewportRight && my >= viewportTop && my <= viewportBottom){ + if (mx >= viewportLeft && mx <= viewportRight && my >= viewportTop && my <= viewportBottom){ final double change = (Mouse.getDWheel()/10d); viewportZoom = MathHelper.clamp(viewportZoom + change, 0.5d, 2); @@ -314,15 +288,10 @@ public void render(int mx, int my, float partialTick) renderBackground(); - /*if (drawSidebar()){ - overlayBackground(0, pageListRight, top, bottom, 0x202020); - }*/ - renderAchievementsPanel(mx, my, partialTick); overlayBackground(0, width, 0, top, 0x404040); overlayBackground(0, width, bottom, height, 0x404040); - //overlayBackground(pageListRight, viewportLeft, top, bottom, 0x404040); GL11.glEnable(GL11.GL_BLEND); GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); @@ -341,21 +310,6 @@ public void render(int mx, int my, float partialTick) GL11.glShadeModel(GL11.GL_FLAT); GL11.glEnable(GL11.GL_ALPHA_TEST); - /* if (drawSidebar()){ - Scissor.enable(pageListLeft, top, pageListRight - pageListLeft, bottom - top); - int pagesListHeight = getTotalPagesListHeight(); - int pagesListY = top - (int) pageListScrollAmount; - if (pagesListHeight < bottom - top) { - pagesListY = top + (bottom - top - pagesListHeight) / 2; - } - if (my >= top && my <= bottom) { - hoveredPage = drawPagesListItems(pageListLeft + PADDING - 4, pagesListY, pageListRight - PADDING, mx, my); - } else { - hoveredPage = drawPagesListItems(pageListLeft + PADDING - 4, pagesListY, pageListRight - PADDING, -1, -1); - } - Scissor.disable(); - }*/ - { GL11.glDisable(GL11.GL_TEXTURE_2D); GL11.glEnable(GL11.GL_BLEND); @@ -365,61 +319,23 @@ public void render(int mx, int my, float partialTick) byte fadeDist = 4; Tessellator tessellator = Tessellator.instance; - /*if (drawSidebar()) { - tessellator.startDrawingQuads(); - tessellator.setColorRGBA_I(0, 0); - tessellator.addVertexWithUV(pageListLeft, top + fadeDist, 0.0D, 0.0D, 1.0D); - tessellator.addVertexWithUV(pageListRight, top + fadeDist, 0.0D, 1.0D, 1.0D); - tessellator.setColorRGBA_I(0, 255); - tessellator.addVertexWithUV(pageListRight, top, 0.0D, 1.0D, 0.0D); - tessellator.addVertexWithUV(pageListLeft, top, 0.0D, 0.0D, 0.0D); - tessellator.draw(); - - tessellator.startDrawingQuads(); - tessellator.setColorRGBA_I(0, 255); - tessellator.addVertexWithUV(pageListLeft, bottom, 0.0D, 0.0D, 1.0D); - tessellator.addVertexWithUV(pageListRight, bottom, 0.0D, 1.0D, 1.0D); - tessellator.setColorRGBA_I(0, 0); - tessellator.addVertexWithUV(pageListRight, bottom - fadeDist, 0.0D, 1.0D, 0.0D); - tessellator.addVertexWithUV(pageListLeft, bottom - fadeDist, 0.0D, 0.0D, 0.0D); - tessellator.draw(); - - tessellator.startDrawingQuads(); - tessellator.setColorRGBA_I(0, 0); - tessellator.addVertexWithUV(viewportLeft, top + fadeDist, 0.0D, 0.0D, 1.0D); - tessellator.addVertexWithUV(viewportRight, top + fadeDist, 0.0D, 1.0D, 1.0D); - tessellator.setColorRGBA_I(0, 255); - tessellator.addVertexWithUV(viewportRight, top, 0.0D, 1.0D, 0.0D); - tessellator.addVertexWithUV(viewportLeft, top, 0.0D, 0.0D, 0.0D); - tessellator.draw(); - - tessellator.startDrawingQuads(); - tessellator.setColorRGBA_I(0, 255); - tessellator.addVertexWithUV(viewportLeft, bottom, 0.0D, 0.0D, 1.0D); - tessellator.addVertexWithUV(viewportRight, bottom, 0.0D, 1.0D, 1.0D); - tessellator.setColorRGBA_I(0, 0); - tessellator.addVertexWithUV(viewportRight, bottom - fadeDist, 0.0D, 1.0D, 0.0D); - tessellator.addVertexWithUV(viewportLeft, bottom - fadeDist, 0.0D, 0.0D, 0.0D); - tessellator.draw(); - } else {*/ - tessellator.startDrawingQuads(); - tessellator.setColorRGBA_I(0, 0); - tessellator.addVertexWithUV(0, top + fadeDist, 0.0D, 0.0D, 1.0D); - tessellator.addVertexWithUV(width, top + fadeDist, 0.0D, 1.0D, 1.0D); - tessellator.setColorRGBA_I(0, 255); - tessellator.addVertexWithUV(width, top, 0.0D, 1.0D, 0.0D); - tessellator.addVertexWithUV(0, top, 0.0D, 0.0D, 0.0D); - tessellator.draw(); - - tessellator.startDrawingQuads(); - tessellator.setColorRGBA_I(0, 255); - tessellator.addVertexWithUV(0, bottom, 0.0D, 0.0D, 1.0D); - tessellator.addVertexWithUV(width, bottom, 0.0D, 1.0D, 1.0D); - tessellator.setColorRGBA_I(0, 0); - tessellator.addVertexWithUV(width, bottom - fadeDist, 0.0D, 1.0D, 0.0D); - tessellator.addVertexWithUV(0, bottom - fadeDist, 0.0D, 0.0D, 0.0D); - tessellator.draw(); - //} + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_I(0, 0); + tessellator.addVertexWithUV(0, top + fadeDist, 0.0D, 0.0D, 1.0D); + tessellator.addVertexWithUV(width, top + fadeDist, 0.0D, 1.0D, 1.0D); + tessellator.setColorRGBA_I(0, 255); + tessellator.addVertexWithUV(width, top, 0.0D, 1.0D, 0.0D); + tessellator.addVertexWithUV(0, top, 0.0D, 0.0D, 0.0D); + tessellator.draw(); + + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_I(0, 255); + tessellator.addVertexWithUV(0, bottom, 0.0D, 0.0D, 1.0D); + tessellator.addVertexWithUV(width, bottom, 0.0D, 1.0D, 1.0D); + tessellator.setColorRGBA_I(0, 0); + tessellator.addVertexWithUV(width, bottom - fadeDist, 0.0D, 1.0D, 0.0D); + tessellator.addVertexWithUV(0, bottom - fadeDist, 0.0D, 0.0D, 0.0D); + tessellator.draw(); GL11.glEnable(GL_TEXTURE_2D); GL11.glEnable(GL11.GL_ALPHA_TEST); } @@ -428,16 +344,6 @@ public void render(int mx, int my, float partialTick) drawAchievementToolTip(hoveredTreeIngredient, mx, my); } - /*if (drawSidebar()) { - drawPagesListScrollBar(mx, my); - - if (hoveredPage != null){ - String msg = font.wrapFormattedStringToWidth(hoveredPage.getDescription(), TOOLTIP_BOX_WIDTH_MIN); - msg += "\n" + TextFormatting.LIGHT_GRAY + I18n.getInstance().translateKeyAndFormat("gui.achievements.label.completion", Math.round(hoveredPage.getCompletionFraction() * 100) + "%"); - tooltip.render(msg, mx, my, TOOLTIP_OFF_X, TOOLTIP_OFF_Y); - } - }*/ - renderLabels(); GL11.glEnable(GL11.GL_LIGHTING); GL11.glEnable(GL11.GL_DEPTH_TEST); @@ -576,16 +482,6 @@ private void drawBackgroundTiles(double shiftX, double shiftY){ } } - -// long l1 = random.nextLong(); -// random.setSeed(viewTileX); -// long l2 = random.nextLong(); -// random.setSeed(viewTileY); -// long l3 = random.nextLong(); -// -// long seed = Objects.hash(l1, l2, ~l3); -// random.setSeed(seed); - for (BGLayer layer : layers) { random.setSeed(worldSeed); currentPage.postProcessBackground(this, random, layer, orgX + viewTileX, orgY + viewTileY); @@ -647,94 +543,6 @@ private void drawBackgroundTiles(double shiftX, double shiftY){ final double epsilon = 0.05; drawGuiIconDouble(iconLeft - epsilon, iconTop - epsilon, iconWidth + epsilon * 2, iconHeight + epsilon * 2, fore); } - - /*GL11.glDisable(GL11.GL_TEXTURE_2D); - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - GL11.glDisable(GL11.GL_ALPHA_TEST); - GL11.glShadeModel(GL11.GL_SMOOTH); - Tessellator t = Tessellator.instance; - final double off = 0.05d; - double fadeDist = 6 * zoom; - short shadowDarkness = 128; - if (top) { - t.startDrawingQuads(); - t.setColorRGBA_I(0, 0); - t.addVertexWithUV(iconLeft - off, iconTop + fadeDist + off, 0.0D, 0.0D, 1.0D); - t.addVertexWithUV(iconLeft + iconWidth + off, iconTop + fadeDist + off, 0.0D, 1.0D, 1.0D); - t.setColorRGBA_I(0, shadowDarkness); - t.addVertexWithUV(iconLeft + iconWidth + off, iconTop - off, 0.0D, 1.0D, 0.0D); - t.addVertexWithUV(iconLeft - off, iconTop - off, 0.0D, 0.0D, 0.0D); - t.draw(); - } - if (left) { - t.startDrawingQuads(); - t.setColorRGBA_I(0, 0); - t.addVertexWithUV(iconLeft + fadeDist + off, iconTop + iconHeight + off, 0.0D, 1.0D, 1.0D); - t.addVertexWithUV(iconLeft + fadeDist + off, iconTop - off, 0.0D, 0.0D, 1.0D); - t.setColorRGBA_I(0, shadowDarkness); - t.addVertexWithUV(iconLeft - off, iconTop - off, 0.0D, 0.0D, 0.0D); - t.addVertexWithUV(iconLeft - off, iconTop + iconHeight + off, 0.0D, 1.0D, 0.0D); - t.draw(); - } - if (bottom) { - t.startDrawingQuads(); - t.setColorRGBA_I(0, 0); - t.addVertexWithUV(iconLeft + iconWidth + off, iconTop + iconHeight - fadeDist + off, 0.0D, 1.0D, 1.0D); - t.addVertexWithUV(iconLeft - off, iconTop + iconHeight - fadeDist + off, 0.0D, 0.0D, 1.0D); - t.setColorRGBA_I(0, shadowDarkness); - t.addVertexWithUV(iconLeft - off, iconTop + iconHeight - off, 0.0D, 0.0D, 0.0D); - t.addVertexWithUV(iconLeft + iconWidth + off, iconTop + iconHeight - off, 0.0D, 1.0D, 0.0D); - t.draw(); - } - if (right) { - t.startDrawingQuads(); - t.setColorRGBA_I(0, 0); - t.addVertexWithUV(iconLeft + iconWidth - fadeDist + off, iconTop - off, 0.0D, 0.0D, 1.0D); - t.addVertexWithUV(iconLeft + iconWidth - fadeDist + off, iconTop + iconHeight + off, 0.0D, 1.0D, 1.0D); - t.setColorRGBA_I(0, shadowDarkness); - t.addVertexWithUV(iconLeft + iconWidth - off, iconTop + iconHeight + off, 0.0D, 1.0D, 0.0D); - t.addVertexWithUV(iconLeft + iconWidth - off, iconTop - off, 0.0D, 0.0D, 0.0D); - t.draw(); - } - if (topLeft && !(left || top)) { - t.startDrawing(GL11.GL_TRIANGLES); - t.setColorRGBA_I(0, 0); - t.addVertexWithUV(iconLeft - off, iconTop + fadeDist + off, 0.0D, 1.0D, 0.0D); - t.addVertexWithUV(iconLeft + fadeDist + off, iconTop - off, 0.0D, 0.0D, 0.0D); - t.setColorRGBA_I(0, shadowDarkness); - t.addVertexWithUV(iconLeft - off, iconTop - off, 0.0D, 0.0D, 1.0D); - t.draw(); - } - if (topRight && !(right || top)) { - t.startDrawing(GL11.GL_TRIANGLES); - t.setColorRGBA_I(0, 0); - t.addVertexWithUV(iconLeft + iconWidth - fadeDist + off, iconTop - off, 0.0D, 0.0D, 0.0D); - t.addVertexWithUV(iconLeft + iconWidth - off, iconTop + fadeDist + off, 0.0D, 1.0D, 0.0D); - t.setColorRGBA_I(0, shadowDarkness); - t.addVertexWithUV(iconLeft + iconWidth - off, iconTop - off, 0.0D, 0.0D, 1.0D); - t.draw(); - } - if (bottomLeft && !(left || bottom)) { - t.startDrawing(GL11.GL_TRIANGLES); - t.setColorRGBA_I(0, 0); - t.addVertexWithUV(iconLeft + fadeDist + off, iconTop + iconHeight - off, 0.0D, 0.0D, 0.0D); - t.addVertexWithUV(iconLeft - off, iconTop + iconHeight - fadeDist + off, 0.0D, 1.0D, 0.0D); - t.setColorRGBA_I(0, shadowDarkness); - t.addVertexWithUV(iconLeft - off, iconTop + iconHeight - off, 0.0D, 0.0D, 1.0D); - t.draw(); - } - if (bottomRight && !(right || bottom)) { - t.startDrawing(GL11.GL_TRIANGLES); - t.setColorRGBA_I(0, 0); - t.addVertexWithUV(iconLeft + iconWidth - off, iconTop + iconHeight - fadeDist + off, 0.0D, 1.0D, 0.0D); - t.addVertexWithUV(iconLeft + iconWidth - fadeDist + off, iconTop + iconHeight - off, 0.0D, 0.0D, 0.0D); - t.setColorRGBA_I(0, shadowDarkness); - t.addVertexWithUV(iconLeft + iconWidth - off, iconTop + iconHeight - off, 0.0D, 0.0D, 1.0D); - t.draw(); - } - GL11.glEnable(GL_TEXTURE_2D); - GL11.glEnable(GL11.GL_ALPHA_TEST);*/ } } } @@ -756,14 +564,7 @@ private void drawConnectingLines(int mouseX, int mouseY, double shiftX, double s List list = new ArrayList<>(); if(ingredient.recipe == null || ingredient.category == null) continue; ingredient.category.getIngredients(ingredient.recipe,ingredient.category.getRecipeLayout(), null, list); - List inputs = currentPage.getTreeIngredients();/*list - .stream() - .filter(it -> !it.getIngredients().isEmpty()) - .map(it -> it.getIngredients().get(0)) - .map(it -> currentPage.getTreeIngredients().stream().filter(it2 -> it.matches(it2.ingredient.ingredient.getIngredient())).findFirst().orElse(null)) - .filter(Objects::nonNull) - .collect(Collectors.toList());*/ - //List list = currentPage.getTreeIngredients().stream().filter(r -> r.ingredient.recipe == entry.ingredient.recipe).collect(Collectors.toList()); + List inputs = currentPage.getTreeIngredients(); for (RecipeTreeIngredient child : inputs) { if(child == entry) continue; if(child.ingredient.recipe == null || child.ingredient.category == null) continue; @@ -771,15 +572,10 @@ private void drawConnectingLines(int mouseX, int mouseY, double shiftX, double s double childY = (viewportTop + viewportHeight/2d) + ((entry.getY() * ACHIEVEMENT_CELL_HEIGHT - shiftY) + 11) * zoom; double parentX = (viewportLeft + viewportWidth/2d) + ((child.getX() * ACHIEVEMENT_CELL_WIDTH - shiftX) + 11) * zoom; double parentY = (viewportTop + viewportHeight/2d) + ((child.getY() * ACHIEVEMENT_CELL_HEIGHT - shiftY) + 11) * zoom; - boolean unlocked = false;//entry.isCompleted(); - boolean canUnlock = false;//entry.preRequisitesCompleted(); + boolean unlocked = false; + boolean canUnlock = false; final double zoomOff = 11 * zoom; -// if ( -// (((childX + zoomOff) <= viewportLeft || (childX - zoomOff) >= viewportRight || (childY - zoomOff) >= viewportBottom || (childY + zoomOff) <= viewportTop) && -// (((parentX + zoomOff) <= viewportLeft || (parentX - zoomOff) >= viewportRight || (parentY - zoomOff) >= viewportBottom || (parentY + zoomOff) <= viewportTop)))) { -// continue; -// } boolean isHovered = false; { @@ -827,26 +623,9 @@ private RecipeTreeIngredient drawAchievementIcons(int mouseX, int mouseY, double } float brightness = 0.50F; GL11.glColor4f(brightness, brightness, brightness, 1.0F); - /*if(recipeTreeIngredient.isCompleted()) { - float brightness = 1.0F; - GL11.glColor4f(brightness, brightness, brightness, 1.0F); - } else if(recipeTreeIngredient.preRequisitesCompleted()) { - // Flicker if can unlock - float brightness = timeSin(1, 600) >= 0.6 ? 0.6F : 0.8F; - GL11.glColor4f(brightness, brightness, brightness, 1.0F); - } else { - // Darken if not unlock-able - float brightness = 0.3F; - GL11.glColor4f(brightness, brightness, brightness, 1.0F); - }*/ drawGuiIconDouble(achViewX - (ACHIEVEMENT_ICON_WIDTH - ACHIEVEMENT_CELL_WIDTH) * zoom, achViewY - (ACHIEVEMENT_ICON_HEIGHT - ACHIEVEMENT_CELL_HEIGHT) * zoom, ACHIEVEMENT_ICON_WIDTH * zoom, ACHIEVEMENT_ICON_HEIGHT * zoom, currentPage.drawIngredientBackground(ingredient)); - /*if(!recipeTreeIngredient.preRequisitesCompleted()) { - float brightness = 0.1F; - GL11.glColor4f(brightness, brightness, brightness, 1.0F); - }*/ - GL11.glPushMatrix(); GL11.glEnable(GL11.GL_LIGHTING); GL11.glEnable(GL11.GL_CULL_FACE); @@ -854,10 +633,6 @@ private RecipeTreeIngredient drawAchievementIcons(int mouseX, int mouseY, double GL11.glTranslated(achViewX + 3 * zoom, achViewY + 3 * zoom, 0); GL11.glScaled(zoom, zoom, 1); - /*ItemModelDispatcher.getInstance().getDispatch(achievementItem) - .renderItemIntoGui(Tessellator.instance, mc.font, mc.textureManager, achievementItem, 0, 0, 1.0f); - ItemModelDispatcher.getInstance().getDispatch(achievementItem) - .renderItemOverlayIntoGUI(Tessellator.instance, mc.font, mc.textureManager, achievementItem, 0, 0, 1.0f);*/ IIngredientType type = ingredient.ingredient.getType(); IIngredientRenderer renderer = (IIngredientRenderer) type.getRenderer(TMB.getRuntime()); new DrawableIngredient<>(ingredient.ingredient.getIngredient(), renderer).draw(TMB.getRuntime().getGuiHelper()); @@ -875,26 +650,10 @@ private RecipeTreeIngredient drawAchievementIcons(int mouseX, int mouseY, double } private void drawAchievementToolTip(RecipeTreeIngredient treeIngredient, int mouseX, int mouseY){ StringBuilder s = new StringBuilder(treeIngredient.ingredient.ingredient.getName()); - /*if(quest.getPreRequisites().isEmpty() || quest.preRequisitesCompleted()){ - if(quest.isCompleted()){ - s.append("\n").append(TextFormatting.LIME).append("Completed!"); - if(!quest.areAllRewardsRedeemed()){ - s.append("\n").append(TextFormatting.LIGHT_BLUE).append("Unclaimed rewards!"); - } - } else { - s.append("\n").append(TextFormatting.LIGHT_GRAY).append(quest.numberOfCompletedTasks()).append("/").append(quest.getTasks().size()).append(" tasks."); - } - } else { - s.append("\n").append(TextFormatting.RED).append("Requires ").append("(").append(quest.getQuestLogic()).append("):"); - for (Quest preRequisite : quest.getPreRequisites()) { - s.append("\n").append(TextFormatting.RED).append("- ").append(preRequisite.getTranslatedName()); - } - s.append(TextFormatting.WHITE); - }*/ tooltip.render(s.toString(),mouseX,mouseY,8,-8); } public boolean drawSidebar(){ - return /*VintageQuesting.CHAPTERS.size()*/0 > 1; + return false; } private void scrollPagesList(float amount) { if(amount == 0.0f) return; @@ -912,76 +671,6 @@ private int getTotalPagesListHeight() { return PAGE_BUTTON_HEIGHT * 0;//VintageQuesting.CHAPTERS.size(); } - @Nullable - private RecipeTreePage drawPagesListItems(int x, int y, int width, int mouseX, int mouseY) { - int y2 = y; - RecipeTreePage pageHovered = null; - /*for (QuestChapterPage page : VintageQuesting.CHAPTERS) { - String name = page.getName(); - int textColor = 0xFF7F7F7F; - if (page == currentPage) { - textColor = 0xFFFFFFFF; - } - if (mouseX >= x && mouseX < x + width && mouseY >= y2 && mouseY < y2 + PAGE_BUTTON_HEIGHT) { - textColor = 0xFFFFFFA0; - pageHovered = page; - } - renderItem.render(page.getIcon(), x, y2 + (PAGE_BUTTON_HEIGHT / 2) - 9); - if (page.getCompletionFraction() >= 1) { - GL11.glColor4f(1f, 1f, 1f, 1f); - drawGuiIcon(x + 8, y2 + (PAGE_BUTTON_HEIGHT / 2) - 9 + 8, 11, 11, TextureRegistry.getTexture("minecraft:gui/screen/achievement/star")); - } - mc.font.drawStringWithShadow(name, x + 19, y2 + (PAGE_BUTTON_HEIGHT / 2) - 4, textColor); - y2 += PAGE_BUTTON_HEIGHT; - }*/ - - return pageHovered; - } - protected void drawPagesListScrollBar(int mouseX, int mouseY) { - float totalPagesListHeight = getTotalPagesListHeight(); - float scrollBarHeightPercent = pagesListScrollRegionHeight / totalPagesListHeight; - - if(scrollBarHeightPercent > 1.0f) return; - - glDisable(GL_TEXTURE_2D); - - int scrollBarX = pageListRight - 6; - - int scrollBarHeightPx = (int) (scrollBarHeightPercent * pagesListScrollRegionHeight); - if(scrollBarHeightPx < 32) { - scrollBarHeightPx = 32; - } - - float scrollPercent = pageListScrollAmount / (totalPagesListHeight - pagesListScrollRegionHeight); - - int scrollBarY = (int) (top + (pagesListScrollRegionHeight - scrollBarHeightPx) * scrollPercent); - - Tessellator t = Tessellator.instance; - - t.startDrawingQuads(); - t.setColorOpaque(0, 0, 0); - t.drawRectangle(scrollBarX, top, 6, pagesListScrollRegionHeight); - t.setColorRGBA_I(0x808080, 255); - t.drawRectangle(scrollBarX, scrollBarY, 6, scrollBarHeightPx); - t.setColorRGBA_I(0xc0c0c0, 255); - t.drawRectangle(scrollBarX + 1, scrollBarY, 5, scrollBarHeightPx - 1); - t.draw(); - - glEnable(GL_TEXTURE_2D); - - if(clickX != null && clickY != null) { - if(clickX >= scrollBarX && clickY >= top && clickX <= scrollBarX + 6 && clickY < bottom) { - if(oldPagesListScrollAmount == null) { - oldPagesListScrollAmount = pageListScrollAmount; - } - pageListScrollAmount = oldPagesListScrollAmount + (clickY - mouseY) * (1.0f / scrollBarHeightPercent) * -1.0f; - onScrollPagesList(); - } - }else { - oldPagesListScrollAmount = null; - } - } - private void overlayBackground(int minX, int maxX, int minY, int maxY, int color) { Tessellator tessellator = Tessellator.instance; From ccefef1bb0d91d4503eb26bd1120b50125b60e2c Mon Sep 17 00:00:00 2001 From: MartinSVK12 <37455793+MartinSVK12@users.noreply.github.com> Date: Sun, 20 Jul 2025 15:42:53 +0200 Subject: [PATCH 3/6] Cleanup 2. --- build.gradle | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index bfda671..1fb20e7 100644 --- a/build.gradle +++ b/build.gradle @@ -160,7 +160,7 @@ remapJar { archiveVersion.set(archiveVersion.get()+"-${bta_version}") } -/*publishing { +publishing { if(checkVersion(project.mod_group,project.mod_name,project.mod_version)) { repositories { maven { @@ -177,7 +177,7 @@ remapJar { maven(MavenPublication) { groupId = project.mod_group artifactId = project.mod_name - version = project.mod_version + "-" + project.bta_version + version = project.mod_version from components.java } } @@ -198,4 +198,3 @@ static boolean checkVersion(String group, String name, String version) { return true } } -*/ From 4eecb9bf43ca351f80907512005345ca0831c958 Mon Sep 17 00:00:00 2001 From: MartinSVK12 <37455793+MartinSVK12@users.noreply.github.com> Date: Sun, 20 Jul 2025 18:53:14 +0200 Subject: [PATCH 4/6] Changed the way data is saved. --- src/main/java/turing/tmb/TMB.java | 118 +++++++++++++++++- .../java/turing/tmb/mixin/LevelDataMixin.java | 97 -------------- .../tmb/mixin/client/ScreenPauseMixin.java | 19 +++ src/main/resources/tmb.mixins.json | 4 +- 4 files changed, 137 insertions(+), 101 deletions(-) delete mode 100644 src/main/java/turing/tmb/mixin/LevelDataMixin.java create mode 100644 src/main/java/turing/tmb/mixin/client/ScreenPauseMixin.java diff --git a/src/main/java/turing/tmb/TMB.java b/src/main/java/turing/tmb/TMB.java index bc1cee3..48c9b6a 100644 --- a/src/main/java/turing/tmb/TMB.java +++ b/src/main/java/turing/tmb/TMB.java @@ -1,5 +1,8 @@ package turing.tmb; +import com.mojang.nbt.NbtIo; +import com.mojang.nbt.tags.CompoundTag; +import com.mojang.nbt.tags.Tag; import net.fabricmc.api.ModInitializer; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.Minecraft; @@ -14,14 +17,23 @@ import org.slf4j.LoggerFactory; import turing.tmb.api.ITMBPlugin; import turing.tmb.api.TMBEntrypoint; +import turing.tmb.api.ingredient.ITypedIngredient; +import turing.tmb.api.recipe.IRecipeCategory; +import turing.tmb.api.recipe.IRecipeTranslator; +import turing.tmb.api.recipe.RecipeIngredientRole; import turing.tmb.api.runtime.ITMBRuntime; import turing.tmb.plugin.BTATweaker; import turing.tmb.util.IKeybinds; import turing.tmb.vanilla.VanillaPlugin; import turniplabs.halplibe.util.ClientStartEntrypoint; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Optional; public class TMB implements ModInitializer, ClientStartEntrypoint, TMBEntrypoint { public static final String MOD_ID = "tmb"; @@ -71,7 +83,7 @@ public void beforeClientStart() { @Override public void afterClientStart() { - + loadData(); } private static void loadTMB() { @@ -88,9 +100,111 @@ private static void loadTMB() { plugin.registerRecipeCatalysts(runtime); plugin.registerRecipes(runtime); } + runtime.isReady = true; long timeTook = System.currentTimeMillis() - time; LOGGER.info("TMB loaded in {}ms!", timeTook); - runtime.isReady = true; + } + + public static void saveData() { + File dataFolder = new File(Minecraft.getMinecraft().getMinecraftDir()+"/config/tmb/"); + dataFolder.mkdirs(); + + File dataFile = new File(Minecraft.getMinecraft().getMinecraftDir()+"/config/tmb/", "data.dat"); + + CompoundTag dataTag = new CompoundTag(); + + CompoundTag favourites = new CompoundTag(); + List> iTypedIngredients = TMB.getRuntime().getFavourites(); + for (int j = 0; j < iTypedIngredients.size(); j++) { + ITypedIngredient favourite = iTypedIngredients.get(j); + CompoundTag favouriteTag = new CompoundTag(); + favouriteTag.putString("namespace", favourite.getNamespace()); + favouriteTag.putString("uid", favourite.getUid()); + favourites.put(String.valueOf(j), favouriteTag); + } + dataTag.putCompound("Favourites", favourites); + + CompoundTag defaultRecipes = new CompoundTag(); + int i = 0; + for (Map.Entry> entry : TMB.getRuntime().getDefaultRecipes().entrySet()) { + RecipeIngredient key = entry.getKey(); + IRecipeTranslator value = entry.getValue(); + CompoundTag defaultRecipeTag = new CompoundTag(); + CompoundTag ingredientTag = new CompoundTag(); + CompoundTag categoryTag = new CompoundTag(); + + defaultRecipeTag.putString("recipe", value.getOriginal().toString()); + ingredientTag.putString("namespace", key.ingredient.getNamespace()); + ingredientTag.putString("uid", key.ingredient.getUid()); + defaultRecipeTag.put("ingredient", ingredientTag); + categoryTag.putString("namespace", key.category.getNamespace()); + categoryTag.putString("name", key.category.getName()); + defaultRecipeTag.put("category", categoryTag); + defaultRecipes.put(String.valueOf(i), defaultRecipeTag); + i++; + } + dataTag.putCompound("DefaultRecipes", defaultRecipes); + + try { + if(!dataFile.exists()) { + if (!dataFile.createNewFile()) { + return; + } + } + NbtIo.writeCompressed(dataTag, Files.newOutputStream(dataFile.toPath())); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static void loadData() { + + File dataFolder = new File(Minecraft.getMinecraft().getMinecraftDir()+"/config/tmb/"); + dataFolder.mkdirs(); + + File dataFile = new File(Minecraft.getMinecraft().getMinecraftDir()+"/config/tmb/", "data.dat"); + try { + if(!dataFile.exists()) { + return; + } + CompoundTag tag = NbtIo.readCompressed(Files.newInputStream(dataFile.toPath())); + + TMB.getRuntime().getFavourites().clear(); + for (Tag compoundTag : tag.getCompound("Favourites").getValues()) { + CompoundTag favouriteTag = (CompoundTag) compoundTag; + TMB.getRuntime().getIngredientIndex() + .getIngredient(favouriteTag.getString("namespace"), favouriteTag.getString("uid")) + .ifPresent(TMB.getRuntime().getFavourites()::add); + } + + for (Tag compoundTag : tag.getCompound("DefaultRecipes").getValues()) { + CompoundTag defaultRecipeTag = (CompoundTag) compoundTag; + CompoundTag ingredientTag = defaultRecipeTag.getCompound("ingredient"); + CompoundTag categoryTag = defaultRecipeTag.getCompound("category"); + String recipeId = defaultRecipeTag.getString("recipe"); + + Optional> category = TMB.getRuntime().getRecipeIndex().getAllCategories().stream() + .filter(it -> + it.getName().equals(categoryTag.getString("name")) + && it.getNamespace().equals(categoryTag.getString("namespace"))).findFirst(); + + Optional> recipe = category + .flatMap(it -> TMB.getRuntime().getRecipeIndex().getRecipeLists().get(it).stream() + .filter(it2 -> it2.getOriginal().toString().equals(recipeId)).findFirst()); + + Optional> ingredient = recipe + .flatMap(it -> TMB.getRuntime().getIngredientIndex() + .getIngredient(ingredientTag.getString("namespace"), ingredientTag.getString("uid"))); + + ingredient + .ifPresent(it -> { + RecipeIngredient recipeIngredient = new RecipeIngredient(it, recipe.get(), category.get(), RecipeIngredientRole.OUTPUT); + TMB.getRuntime().getDefaultRecipes().put(recipeIngredient, recipe.get()); + }); + } + } catch (IOException e) { + throw new RuntimeException(e); + } } private static void clear() { diff --git a/src/main/java/turing/tmb/mixin/LevelDataMixin.java b/src/main/java/turing/tmb/mixin/LevelDataMixin.java deleted file mode 100644 index 0006acd..0000000 --- a/src/main/java/turing/tmb/mixin/LevelDataMixin.java +++ /dev/null @@ -1,97 +0,0 @@ -package turing.tmb.mixin; - -import com.mojang.nbt.tags.CompoundTag; -import com.mojang.nbt.tags.Tag; -import net.minecraft.core.world.save.LevelData; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import turing.tmb.RecipeIngredient; -import turing.tmb.TMB; -import turing.tmb.api.ingredient.ITypedIngredient; -import turing.tmb.api.recipe.IRecipeCategory; -import turing.tmb.api.recipe.IRecipeTranslator; -import turing.tmb.api.recipe.RecipeIngredientRole; - -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicReference; - -@Mixin(value = LevelData.class,remap = false) -public class LevelDataMixin { - - @Inject(method = "updateTagCompound", at = @At("HEAD")) - private void updateTagCompound(CompoundTag levelTag, CompoundTag playerTag, CallbackInfo ci) { - CompoundTag favourites = new CompoundTag(); - List> iTypedIngredients = TMB.getRuntime().getFavourites(); - for (int j = 0; j < iTypedIngredients.size(); j++) { - ITypedIngredient favourite = iTypedIngredients.get(j); - CompoundTag favouriteTag = new CompoundTag(); - favouriteTag.putString("namespace", favourite.getNamespace()); - favouriteTag.putString("uid", favourite.getUid()); - favourites.put(String.valueOf(j), favouriteTag); - } - levelTag.putCompound("Favourites", favourites); - - CompoundTag defaultRecipes = new CompoundTag(); - int i = 0; - for (Map.Entry> entry : TMB.getRuntime().getDefaultRecipes().entrySet()) { - RecipeIngredient key = entry.getKey(); - IRecipeTranslator value = entry.getValue(); - CompoundTag defaultRecipeTag = new CompoundTag(); - CompoundTag ingredientTag = new CompoundTag(); - CompoundTag categoryTag = new CompoundTag(); - - defaultRecipeTag.putString("recipe", value.getOriginal().toString()); - ingredientTag.putString("namespace", key.ingredient.getNamespace()); - ingredientTag.putString("uid", key.ingredient.getUid()); - defaultRecipeTag.put("ingredient", ingredientTag); - categoryTag.putString("namespace", key.category.getNamespace()); - categoryTag.putString("name", key.category.getName()); - defaultRecipeTag.put("category", categoryTag); - defaultRecipes.put(String.valueOf(i), defaultRecipeTag); - i++; - } - levelTag.putCompound("DefaultRecipes", defaultRecipes); - } - - - @Inject(method = "readFromCompoundTag", at = @At("HEAD")) - private void readFromCompoundTag(CompoundTag tag, CallbackInfo ci) { - TMB.getRuntime().getFavourites().clear(); - for (Tag compoundTag : tag.getCompound("Favourites").getValues()) { - CompoundTag favouriteTag = (CompoundTag) compoundTag; - TMB.getRuntime().getIngredientIndex() - .getIngredient(favouriteTag.getString("namespace"), favouriteTag.getString("uid")) - .ifPresent(TMB.getRuntime().getFavourites()::add); - } - - for (Tag compoundTag : tag.getCompound("DefaultRecipes").getValues()) { - CompoundTag defaultRecipeTag = (CompoundTag) compoundTag; - CompoundTag ingredientTag = defaultRecipeTag.getCompound("ingredient"); - CompoundTag categoryTag = defaultRecipeTag.getCompound("category"); - String recipeId = defaultRecipeTag.getString("recipe"); - - Optional> category = TMB.getRuntime().getRecipeIndex().getAllCategories().stream() - .filter(it -> - it.getName().equals(categoryTag.getString("name")) - && it.getNamespace().equals(categoryTag.getString("namespace"))).findFirst(); - - Optional> recipe = category - .flatMap(it -> TMB.getRuntime().getRecipeIndex().getRecipeLists().get(it).stream() - .filter(it2 -> it2.getOriginal().toString().equals(recipeId)).findFirst()); - - Optional> ingredient = recipe - .flatMap(it -> TMB.getRuntime().getIngredientIndex() - .getIngredient(ingredientTag.getString("namespace"), ingredientTag.getString("uid"))); - - ingredient - .ifPresent(it -> { - RecipeIngredient recipeIngredient = new RecipeIngredient(it, recipe.get(), category.get(), RecipeIngredientRole.OUTPUT); - TMB.getRuntime().getDefaultRecipes().put(recipeIngredient, recipe.get()); - }); - } - } -} diff --git a/src/main/java/turing/tmb/mixin/client/ScreenPauseMixin.java b/src/main/java/turing/tmb/mixin/client/ScreenPauseMixin.java new file mode 100644 index 0000000..70b2f50 --- /dev/null +++ b/src/main/java/turing/tmb/mixin/client/ScreenPauseMixin.java @@ -0,0 +1,19 @@ +package turing.tmb.mixin.client; + +import net.minecraft.client.gui.ButtonElement; +import net.minecraft.client.gui.ScreenPause; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import turing.tmb.TMB; + +@Mixin(value = ScreenPause.class,remap = false) +public class ScreenPauseMixin { + + @Inject(method = "buttonClicked", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;changeWorld(Lnet/minecraft/client/world/WorldClient;)V")) + protected void buttonClicked(ButtonElement button, CallbackInfo ci) { + TMB.saveData(); + } + +} diff --git a/src/main/resources/tmb.mixins.json b/src/main/resources/tmb.mixins.json index 594787e..2a324a8 100644 --- a/src/main/resources/tmb.mixins.json +++ b/src/main/resources/tmb.mixins.json @@ -4,7 +4,6 @@ "package": "turing.tmb.mixin", "compatibilityLevel": "JAVA_8", "mixins": [ - "LevelDataMixin" ], "client": [ "client.GameSettingsMixin", @@ -14,7 +13,8 @@ "client.ScreenContainerAbstractMixin", "client.ScreenInventoryCreativeAccessor", "client.ScreenInventoryCreativeMixin", - "client.ScreenMixin" + "client.ScreenMixin", + "client.ScreenPauseMixin" ], "injectors": { "defaultRequire": 1 From 01cabff2ae08324d3fde9169378b07169f029930 Mon Sep 17 00:00:00 2001 From: MartinSVK12 <37455793+MartinSVK12@users.noreply.github.com> Date: Sun, 20 Jul 2025 20:57:07 +0200 Subject: [PATCH 5/6] Removed unfinished stuff. --- src/main/java/turing/tmb/client/TMBRenderer.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/turing/tmb/client/TMBRenderer.java b/src/main/java/turing/tmb/client/TMBRenderer.java index b6a0caf..9b6f5f4 100644 --- a/src/main/java/turing/tmb/client/TMBRenderer.java +++ b/src/main/java/turing/tmb/client/TMBRenderer.java @@ -143,11 +143,6 @@ public static void mouseClicked(int mouseX, int mouseY, int width, int height, M if (currentFavouritePage > favouritePages) currentFavouritePage = 0; } - - if(hoveredItem != null && hoveredItem.getIngredient() instanceof ItemStack && mc.thePlayer.inventory.getHeldItemStack() == null) { - //mc.thePlayer.sendChatMessage("/give @p "+((ItemStack) hoveredItem.getIngredient()).getItem().namespaceID.toString()+" 64"); - } - search.mouseClicked(mouseX, mouseY, 1); } From e0eeee00e66d8a5232e0c7937fdfc0c52acbe898 Mon Sep 17 00:00:00 2001 From: MartinSVK12 <37455793+MartinSVK12@users.noreply.github.com> Date: Sun, 20 Jul 2025 21:02:25 +0200 Subject: [PATCH 6/6] Set version to 2.0.0 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 1c9491e..b62d8e8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,6 +15,6 @@ mod_menu_version=3.0.0 halplibe_version=5.2.4 # Mod -mod_version=1.2.0 +mod_version=2.0.0 mod_group=turing mod_name=tmb