Clean up NEI handlers (#131)

This commit is contained in:
koolkrafter5 authored and GitHub committed 2026-06-04 19:06:36 +02:00
1 parent 3fa2240e61
commit ffdce1834c
16 files changed
+797 -711

No files matched your search

+2 -2
View File
@@ -44,7 +44,7 @@ developmentEnvironmentUserName = Developer
# - jabel: Jabel syntax-only support, compiles to J8 bytecode # - jabel: Jabel syntax-only support, compiles to J8 bytecode
# - jvmDowngrader: Full modern Java via JVM Downgrader (syntax + stdlib APIs) # - jvmDowngrader: Full modern Java via JVM Downgrader (syntax + stdlib APIs)
# - modern: Native modern Java bytecode, no downgrading # - modern: Native modern Java bytecode, no downgrading
enableModernJavaSyntax = jabel enableModernJavaSyntax = jvmDowngrader
# If set, ignores the above setting and compiles with the given toolchain. This may cause unexpected issues, # If set, ignores the above setting and compiles with the given toolchain. This may cause unexpected issues,
# and should *not* be used in most situations. -1 disables this. # and should *not* be used in most situations. -1 disables this.
@@ -65,7 +65,7 @@ enableModernJavaSyntax = jabel
# - external: Another dependency provides stubs (no constraint, no warning) # - external: Another dependency provides stubs (no constraint, no warning)
# - (empty): Warning reminding you to configure stubs # - (empty): Warning reminding you to configure stubs
# Note: 'shade' option requires you to verify license compliance, see: https://github.com/unimined/JvmDowngrader/blob/main/LICENSE.md # Note: 'shade' option requires you to verify license compliance, see: https://github.com/unimined/JvmDowngrader/blob/main/LICENSE.md
# jvmDowngraderStubsProvider = jvmDowngraderStubsProvider = gtnhlib
# Enables injecting missing generics into the decompiled source code for a better coding experience. # Enables injecting missing generics into the decompiled source code for a better coding experience.
# Turns most publicly visible List, Map, etc. into proper List<E>, Map<K, V> types. # Turns most publicly visible List, Map, etc. into proper List<E>, Map<K, V> types.
@@ -0,0 +1,22 @@
package vazkii.botania.client.integration.nei;
import cpw.mods.fml.common.event.FMLInterModComms;
import net.minecraft.nbt.NBTTagCompound;
import vazkii.botania.client.integration.nei.recipe.RecipeHandlerBrewery;
public class IMCForNEI {
public static void IMCSender() {
sendCatalyst(RecipeHandlerBrewery.OVERLAY, "Botania:vial", -1);
sendCatalyst(RecipeHandlerBrewery.OVERLAY, "Botania:vial:1", -1);
sendCatalyst(RecipeHandlerBrewery.OVERLAY, "Botania:incenseStick", -1);
sendCatalyst(RecipeHandlerBrewery.OVERLAY, "Botania:bloodPendant", -1);
}
private static void sendCatalyst(String handlerName, String stack, int priority) {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setString("handlerID", handlerName);
nbt.setString("itemName", stack);
nbt.setInteger("priority", priority);
FMLInterModComms.sendMessage("NotEnoughItems", "registerCatalystInfo", nbt);
}
}
@@ -0,0 +1,18 @@
package vazkii.botania.client.integration.nei;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.item.ItemStack;
public class NEIHelper {
public static final RenderItem renderItem = new RenderItem();
public static final Minecraft mc = Minecraft.getMinecraft();
public static final TextureManager textureManager = mc.getTextureManager();
public static final FontRenderer font = mc.fontRenderer;
public static void renderItemIntoGUI(ItemStack stack, int x, int y) {
renderItem.renderItemIntoGUI(font, textureManager, stack, x, y);
}
}
@@ -23,118 +23,123 @@ import codechicken.nei.recipe.TemplateRecipeHandler;
public class RecipeHandlerBrewery extends TemplateRecipeHandler { public class RecipeHandlerBrewery extends TemplateRecipeHandler {
public class CachedBreweryRecipe extends CachedRecipe { public static final String OVERLAY = "botania.brewery";
public List<PositionedStack> inputs = new ArrayList<>(); public class CachedBreweryRecipe extends CachedRecipe {
public PositionedStack output;
public int mana;
public CachedBreweryRecipe(RecipeBrew recipe, ItemStack vial) { public List<PositionedStack> inputs = new ArrayList<>();
if(recipe == null) public PositionedStack output;
return; public int mana;
setIngredients(recipe.getInputs()); public CachedBreweryRecipe(RecipeBrew recipe, ItemStack vial) {
ItemStack toVial; if (recipe == null) return;
if (vial == null)
toVial = new ItemStack(ModItems.vial);
else
toVial = vial.copy();
toVial.stackSize = 1;
inputs.add(new PositionedStack(toVial, 39, 42));
output = new PositionedStack(recipe.getOutput(toVial), 87, 42); setIngredients(recipe.getInputs());
} ItemStack toVial;
if (vial == null) {
toVial = new ItemStack(ModItems.vial);
} else {
toVial = vial.copy();
toVial.stackSize = 1;
}
inputs.add(new PositionedStack(toVial, 39, 42));
public CachedBreweryRecipe(RecipeBrew recipe) { output = new PositionedStack(recipe.getOutput(toVial), 87, 42);
this(recipe, null); }
}
public void setIngredients(List<Object> inputs) { public CachedBreweryRecipe(RecipeBrew recipe) {
int left = 96 - inputs.size() * 18 / 2; this(recipe, null);
}
int i = 0; public void setIngredients(List<Object> inputs) {
for (Object o : inputs) { int left = 96 - inputs.size() * 18 / 2;
if (o instanceof String)
this.inputs.add(new PositionedStack(OreDictionary.getOres((String) o), left + i * 18, 6));
else
this.inputs.add(new PositionedStack(o, left + i * 18, 6));
i++; for (int i = 0; i < inputs.size(); i++) {
} Object o = inputs.get(i);
} if (o instanceof String oreName) {
o = OreDictionary.getOres(oreName);
}
this.inputs.add(new PositionedStack(o, left + i * 18, 6));
}
}
@Override @Override
public List<PositionedStack> getIngredients() { public List<PositionedStack> getIngredients() {
return getCycledIngredients(cycleticks / 20, inputs); return inputs;
} }
@Override @Override
public PositionedStack getResult() { public PositionedStack getResult() {
return output; return output;
} }
} }
@Override @Override
public String getRecipeName() { public String getRecipeName() {
return StatCollector.translateToLocal("botania.nei.brewery"); return StatCollector.translateToLocal("botania.nei.brewery");
} }
@Override @Override
public String getGuiTexture() { public String getOverlayIdentifier() {
return LibResources.GUI_NEI_BREWERY; return OVERLAY;
} }
@Override @Override
public void loadTransferRects() { public String getGuiTexture() {
transferRects.add(new RecipeTransferRect(new Rectangle(87, 25, 15, 14), "botania.brewery")); return LibResources.GUI_NEI_BREWERY;
} }
@Override @Override
public void drawBackground(int recipe) { public void loadTransferRects() {
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); transferRects.add(new RecipeTransferRect(new Rectangle(87, 25, 15, 14), getOverlayIdentifier()));
GuiDraw.changeTexture(getGuiTexture()); }
GuiDraw.drawTexturedModalRect(0, 0, 0, 0, 166, 65);
}
@Override @Override
public void loadCraftingRecipes(String outputId, Object... results) { public void drawBackground(int recipe) {
if(outputId.equals("botania.brewery")) GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
for(RecipeBrew recipe : BotaniaAPI.brewRecipes) GuiDraw.changeTexture(getGuiTexture());
arecipes.add(new CachedBreweryRecipe(recipe)); GuiDraw.drawTexturedModalRect(0, 0, 0, 0, 166, 65);
else super.loadCraftingRecipes(outputId, results); }
}
@Override @Override
public void loadCraftingRecipes(ItemStack result) { public void loadCraftingRecipes(String outputId, Object... results) {
if(result.getItem() instanceof IBrewItem) if (outputId.equals(getOverlayIdentifier())) {
for(RecipeBrew recipe : BotaniaAPI.brewRecipes) { for (RecipeBrew recipe : BotaniaAPI.brewRecipes) {
if(recipe == null) arecipes.add(new CachedBreweryRecipe(recipe));
continue; }
} else {
super.loadCraftingRecipes(outputId, results);
}
}
if(((IBrewItem) result.getItem()).getBrew(result) == recipe.getBrew()) @Override
arecipes.add(new CachedBreweryRecipe(recipe)); public void loadCraftingRecipes(ItemStack result) {
} if (!(result.getItem() instanceof IBrewItem brew)) return;
} for (RecipeBrew recipe : BotaniaAPI.brewRecipes) {
if (recipe != null && brew.getBrew(result) == recipe.getBrew()) {
arecipes.add(new CachedBreweryRecipe(recipe));
}
}
}
@Override @Override
public void loadUsageRecipes(ItemStack ingredient) { public void loadUsageRecipes(ItemStack ingredient) {
if(ingredient.getItem() instanceof IBrewContainer) { if (ingredient.getItem() instanceof IBrewContainer) {
for(RecipeBrew recipe : BotaniaAPI.brewRecipes) { for (RecipeBrew recipe : BotaniaAPI.brewRecipes) {
if(recipe == null) if (recipe != null && recipe.getOutput(ingredient) != null) {
continue; arecipes.add(new CachedBreweryRecipe(recipe, ingredient));
}
if(recipe.getOutput(ingredient) != null) }
arecipes.add(new CachedBreweryRecipe(recipe, ingredient)); } else {
} for (RecipeBrew recipe : BotaniaAPI.brewRecipes) {
} else for(RecipeBrew recipe : BotaniaAPI.brewRecipes) { if (recipe == null) continue;
if(recipe == null) CachedBreweryRecipe crecipe = new CachedBreweryRecipe(recipe);
continue; if (ItemNBTHelper.cachedRecipeContainsWithNBT(crecipe.inputs, ingredient)) {
arecipes.add(crecipe);
CachedBreweryRecipe crecipe = new CachedBreweryRecipe(recipe); }
if(ItemNBTHelper.cachedRecipeContainsWithNBT(crecipe.inputs, ingredient)) }
arecipes.add(crecipe); }
} }
}
} }
@@ -4,8 +4,8 @@ import java.awt.Rectangle;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import com.google.common.collect.Iterables;
import net.minecraft.client.renderer.entity.RenderItem; import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@@ -26,144 +26,122 @@ import vazkii.botania.common.core.helper.ItemNBTHelper;
public class RecipeHandlerElvenTrade extends TemplateRecipeHandler { public class RecipeHandlerElvenTrade extends TemplateRecipeHandler {
public class CachedElvenTradeRecipe extends CachedRecipe { public static final String OVERLAY = "botania.elvenTrade";
public List<PositionedStack> inputs = new ArrayList<>(); public class CachedElvenTradeRecipe extends CachedRecipe {
public PositionedStack output;
public CachedElvenTradeRecipe(RecipeElvenTrade recipe) { public List<PositionedStack> inputs = new ArrayList<>();
if(recipe == null) public PositionedStack output;
return;
setIngredients(recipe.getInputs()); public CachedElvenTradeRecipe(RecipeElvenTrade recipe) {
output = new PositionedStack(recipe.getOutput(), 107, 46); if (recipe == null) return;
} setIngredients(recipe.getInputs());
output = new PositionedStack(recipe.getOutput(), 107, 46);
}
public void setIngredients(List<Object> inputs) { public void setIngredients(List<Object> inputs) {
int i = 0; for (int i = 0; i < inputs.size(); i++) {
for(Object o : inputs) { Object o = inputs.get(i);
if(o instanceof String) if (o instanceof String oreName) {
this.inputs.add(new PositionedStack(OreDictionary.getOres((String) o), 60 + i * 18, 6)); o = OreDictionary.getOres(oreName);
else this.inputs.add(new PositionedStack(o, 60 + i * 18, 6)); }
this.inputs.add(new PositionedStack(o, 60 + i * 18, 6));
}
}
i++; @Override
} public List<PositionedStack> getIngredients() {
} return inputs;
}
@Override @Override
public List<PositionedStack> getIngredients() { public PositionedStack getResult() {
return getCycledIngredients(cycleticks / 20, inputs); return output;
} }
}
@Override @Override
public PositionedStack getResult() { public String getRecipeName() {
return output; return StatCollector.translateToLocal("botania.nei.elvenTrade");
} }
} @Override
public String getOverlayIdentifier() {
return OVERLAY;
}
@Override @Override
public String getRecipeName() { public String getGuiTexture() {
return StatCollector.translateToLocal("botania.nei.elvenTrade"); return LibResources.GUI_NEI_BLANK;
} }
@Override @Override
public String getGuiTexture() { public void loadTransferRects() {
return LibResources.GUI_NEI_BLANK; transferRects.add(new RecipeTransferRect(new Rectangle(35, 30, 48, 48), getOverlayIdentifier()));
} }
@Override @Override
public void loadTransferRects() { public void drawBackground(int recipe) {
transferRects.add(new RecipeTransferRect(new Rectangle(35, 30, 48, 48), "botania.elvenTrade")); super.drawBackground(recipe);
} GL11.glEnable(GL11.GL_BLEND);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.7F);
GuiDraw.changeTexture(LibResources.GUI_ELVEN_TRADE_OVERLAY);
GuiDraw.drawTexturedModalRect(30, 10, 17, 17, 100, 80);
GL11.glDisable(GL11.GL_BLEND);
GuiDraw.changeTexture(TextureMap.locationBlocksTexture);
RenderItem.getInstance().renderIcon(35, 29, BlockAlfPortal.portalTex, 48, 48);
}
@Override @Override
public int recipiesPerPage() { public void loadCraftingRecipes(String outputId, Object... results) {
return 1; if (outputId.equals(getOverlayIdentifier())) {
} for (RecipeElvenTrade recipe : filteredElvenTradeRecipes()) {
arecipes.add(new CachedElvenTradeRecipe(recipe));
}
} else {
super.loadCraftingRecipes(outputId, results);
}
}
@Override @Override
public void drawBackground(int recipe) { public void loadCraftingRecipes(ItemStack result) {
super.drawBackground(recipe); for (RecipeElvenTrade recipe : filteredElvenTradeRecipes()) {
GL11.glEnable(GL11.GL_BLEND); if (NEIServerUtils.areStacksSameTypeCrafting(recipe.getOutput(), result)) {
GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.7F); arecipes.add(new CachedElvenTradeRecipe(recipe));
GuiDraw.changeTexture(LibResources.GUI_ELVEN_TRADE_OVERLAY); }
GuiDraw.drawTexturedModalRect(30, 10, 17, 17, 100, 80); }
GL11.glDisable(GL11.GL_BLEND); }
GuiDraw.changeTexture(TextureMap.locationBlocksTexture);
RenderItem.getInstance().renderIcon(35, 29, BlockAlfPortal.portalTex, 48, 48);
}
private static boolean hasElvenKnowledge() { @Override
/*EntityPlayer player = Minecraft.getMinecraft().thePlayer; public void loadUsageRecipes(ItemStack ingredient) {
if (player != null) { for (RecipeElvenTrade recipe : filteredElvenTradeRecipes()) {
for (ItemStack stack : player.inventory.mainInventory) { CachedElvenTradeRecipe crecipe = new CachedElvenTradeRecipe(recipe);
if (stack != null && stack.getItem() instanceof ILexicon) { if (crecipe.contains(crecipe.inputs, ingredient)) {
ILexicon lexicon = (ILexicon) stack.getItem(); arecipes.add(crecipe);
if (lexicon.isKnowledgeUnlocked(stack, BotaniaAPI.elvenKnowledge)) { }
return true; }
} }
}
}
}
return false;*/
return true;
}
@Override private Iterable<RecipeElvenTrade> filteredElvenTradeRecipes() {
public void loadCraftingRecipes(String outputId, Object... results) { return Iterables.filter(
if(outputId.equals("botania.elvenTrade") && hasElvenKnowledge()) { BotaniaAPI.elvenTradeRecipes,
if(hasElvenKnowledge()) { recipe -> recipe != null
for(RecipeElvenTrade recipe : filteredElvenTradeRecipes()) { && (recipe.getInputs().size() != 1
arecipes.add(new CachedElvenTradeRecipe(recipe)); || !stackSame(recipe.getOutput(), recipe.getInputs().getFirst())));
} }
}
} else super.loadCraftingRecipes(outputId, results);
}
@Override private boolean stackSame(ItemStack stack, Object obj) {
public void loadCraftingRecipes(ItemStack result) { if (obj instanceof String oreName) {
if(hasElvenKnowledge()) { return Iterables.any(
for(RecipeElvenTrade recipe : filteredElvenTradeRecipes()) { OreDictionary.getOres(oreName),
if(NEIServerUtils.areStacksSameTypeCrafting(recipe.getOutput(), result)) s -> ItemNBTHelper.areStacksSameTypeCraftingWithNBT(stack, s)
arecipes.add(new CachedElvenTradeRecipe(recipe)); );
} } else {
} return Iterables.any(
} Arrays.asList(NEIServerUtils.extractRecipeItems(obj)),
s -> ItemNBTHelper.areStacksSameTypeCraftingWithNBT(stack, s)
@Override );
public void loadUsageRecipes(ItemStack ingredient) { }
if(hasElvenKnowledge()) { }
for(RecipeElvenTrade recipe : filteredElvenTradeRecipes()) {
CachedElvenTradeRecipe crecipe = new CachedElvenTradeRecipe(recipe);
if(crecipe.contains(crecipe.inputs, ingredient))
arecipes.add(crecipe);
}
}
}
// hide dummy recipes
private List<RecipeElvenTrade> filteredElvenTradeRecipes() {
return BotaniaAPI.elvenTradeRecipes
.stream()
.filter(recipe -> {
if (recipe == null) {
return false;
}
if (recipe.getInputs().size() == 1) {
return !stackSame(recipe.getOutput(), recipe.getInputs().get(0));
}
return true;
})
.collect(Collectors.toList());
}
private boolean stackSame(ItemStack stack, Object obj) {
if (obj instanceof String) {
return OreDictionary.getOres((String) obj).stream().anyMatch(s -> ItemNBTHelper.areStacksSameTypeCraftingWithNBT(stack, s));
} else {
return Arrays.stream(NEIServerUtils.extractRecipeItems(obj)).anyMatch(s -> ItemNBTHelper.areStacksSameTypeCraftingWithNBT(stack, s));
}
}
} }
@@ -17,65 +17,70 @@ import codechicken.nei.recipe.TemplateRecipeHandler;
public class RecipeHandlerFloatingFlowers extends TemplateRecipeHandler { public class RecipeHandlerFloatingFlowers extends TemplateRecipeHandler {
public class CachedFloatingFlowerRecipe extends CachedRecipe { public class CachedFloatingFlowerRecipe extends CachedRecipe {
public List<PositionedStack> inputs = new ArrayList<>(); public List<PositionedStack> inputs = new ArrayList<>();
public PositionedStack output; public PositionedStack output;
public CachedFloatingFlowerRecipe(ItemStack floatingFlower, ItemStack specialFlower, ItemStack output) { public CachedFloatingFlowerRecipe(ItemStack floatingFlower, ItemStack specialFlower, ItemStack output) {
inputs.add(new PositionedStack(floatingFlower, 25, 6)); inputs.add(new PositionedStack(floatingFlower, 25, 6));
inputs.add(new PositionedStack(specialFlower, 43, 6)); inputs.add(new PositionedStack(specialFlower, 43, 6));
this.output = new PositionedStack(output, 119, 24); this.output = new PositionedStack(output, 119, 24);
this.output.setMaxSize(1); this.output.setMaxSize(1);
} }
@Override @Override
public List<PositionedStack> getIngredients() { public List<PositionedStack> getIngredients() {
return getCycledIngredients(cycleticks / 20, inputs); return inputs;
} }
@Override @Override
public PositionedStack getResult() { public PositionedStack getResult() {
return output; return output;
} }
} }
@Override
public String getRecipeName() {
return StatCollector.translateToLocal("botania.nei.floatingFlowers");
}
@Override @Override
public String getRecipeName() { public String getOverlayIdentifier() {
return StatCollector.translateToLocal("botania.nei.floatingFlowers"); return "crafting2x2";
} }
@Override @Override
public void loadTransferRects() { public void loadTransferRects() {
transferRects.add(new RecipeTransferRect(new Rectangle(84, 23, 24, 18), "crafting")); transferRects.add(new RecipeTransferRect(new Rectangle(84, 23, 24, 18), "crafting"));
} }
@Override @Override
public String getGuiTexture() { public String getGuiTexture() {
return "textures/gui/container/crafting_table.png"; return "textures/gui/container/crafting_table.png";
} }
@Override @Override
public void loadCraftingRecipes(ItemStack result) { public void loadCraftingRecipes(ItemStack result) {
if(Block.getBlockFromItem(result.getItem()) instanceof BlockFloatingSpecialFlower) { if (Block.getBlockFromItem(result.getItem()) instanceof BlockFloatingSpecialFlower) {
ItemStack floatingFlower = new ItemStack(ModBlocks.floatingFlower, 1, OreDictionary.WILDCARD_VALUE); ItemStack floatingFlower = new ItemStack(ModBlocks.floatingFlower, 1, OreDictionary.WILDCARD_VALUE);
ItemStack specialFlower = new ItemStack(ModBlocks.specialFlower); ItemStack specialFlower = new ItemStack(ModBlocks.specialFlower);
specialFlower.setTagCompound((NBTTagCompound) result.getTagCompound().copy()); specialFlower.setTagCompound((NBTTagCompound) result.getTagCompound().copy());
arecipes.add(new CachedFloatingFlowerRecipe(floatingFlower, specialFlower, result.copy())); arecipes.add(new CachedFloatingFlowerRecipe(floatingFlower, specialFlower, result.copy()));
} }
} }
@Override @Override
public void loadUsageRecipes(ItemStack ingredient) { public void loadUsageRecipes(ItemStack ingredient) {
if(Block.getBlockFromItem(ingredient.getItem()) instanceof BlockSpecialFlower) { if (Block.getBlockFromItem(ingredient.getItem()) instanceof BlockSpecialFlower) {
ItemStack floatingFlower = new ItemStack(ModBlocks.floatingFlower, 1, OreDictionary.WILDCARD_VALUE); ItemStack floatingFlower = new ItemStack(ModBlocks.floatingFlower, 1, OreDictionary.WILDCARD_VALUE);
ItemStack result = new ItemStack(ModBlocks.floatingSpecialFlower); ItemStack result = new ItemStack(ModBlocks.floatingSpecialFlower);
result.setTagCompound((NBTTagCompound) ingredient.getTagCompound().copy()); result.setTagCompound((NBTTagCompound) ingredient.getTagCompound().copy());
arecipes.add(new CachedFloatingFlowerRecipe(floatingFlower, ingredient.copy(), result)); arecipes.add(new CachedFloatingFlowerRecipe(floatingFlower, ingredient.copy(), result));
} }
} }
} }
@@ -2,21 +2,19 @@
* This class was created by <Vazkii>. It's distributed as * This class was created by <Vazkii>. It's distributed as
* part of the Botania Mod. Get the Source Code in github: * part of the Botania Mod. Get the Source Code in github:
* https://github.com/Vazkii/Botania * https://github.com/Vazkii/Botania
* * <p>
* Botania is Open Source and distributed under the * Botania is Open Source and distributed under the
* Botania License: http://botaniamod.net/license.php * Botania License: http://botaniamod.net/license.php
* * <p>
* File Created @ [12/12/2015, 23:25:47 (GMT)] * File Created @ [12/12/2015, 23:25:47 (GMT)]
*/ */
package vazkii.botania.client.integration.nei.recipe; package vazkii.botania.client.integration.nei.recipe;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiScreen;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.EnumChatFormatting;
@@ -26,129 +24,146 @@ import vazkii.botania.api.BotaniaAPI;
import vazkii.botania.api.lexicon.KnowledgeType; import vazkii.botania.api.lexicon.KnowledgeType;
import vazkii.botania.api.lexicon.LexiconEntry; import vazkii.botania.api.lexicon.LexiconEntry;
import vazkii.botania.api.lexicon.LexiconRecipeMappings; import vazkii.botania.api.lexicon.LexiconRecipeMappings;
import vazkii.botania.client.integration.nei.NEIHelper;
import vazkii.botania.client.lib.LibResources; import vazkii.botania.client.lib.LibResources;
import vazkii.botania.common.item.ModItems; import vazkii.botania.common.item.ModItems;
import vazkii.botania.common.lexicon.page.PageText; import vazkii.botania.common.lexicon.page.PageText;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.PositionedStack; import codechicken.nei.PositionedStack;
import codechicken.nei.recipe.TemplateRecipeHandler; import codechicken.nei.recipe.TemplateRecipeHandler;
public class RecipeHandlerLexicaBotania extends TemplateRecipeHandler { public class RecipeHandlerLexicaBotania extends TemplateRecipeHandler {
private static final ItemStack LEXICA = new ItemStack(ModItems.lexicon);
public class CachedLexicaBotaniaRecipe extends CachedRecipe { public class CachedLexicaBotaniaRecipe extends CachedRecipe {
public LexiconEntry entry; public LexiconEntry entry;
public PositionedStack item; public PositionedStack item;
public List<PositionedStack> otherStacks = new ArrayList<>();
public CachedLexicaBotaniaRecipe(ItemStack stack, LexiconEntry entry) { public CachedLexicaBotaniaRecipe(ItemStack stack, LexiconEntry entry) {
otherStacks.add(new PositionedStack(new ItemStack(ModItems.lexicon), 51, 5)); item = new PositionedStack(stack, 91, 5);
item = new PositionedStack(stack, 91, 5); this.entry = entry;
this.entry = entry; }
}
@Override @Override
public List<PositionedStack> getIngredients() { public PositionedStack getResult() {
return otherStacks; return item;
} }
@Override @Override
public PositionedStack getResult() { public boolean contains(Collection<PositionedStack> ingredients, ItemStack ingredient) {
return item; return ingredient.getItem() == ModItems.lexicon;
} }
@Override }
public List<PositionedStack> getOtherStacks() {
return otherStacks;
}
@Override @Override
public boolean contains(Collection<PositionedStack> ingredients, ItemStack ingredient) { public String getRecipeName() {
return ingredient.getItem() == ModItems.lexicon; return StatCollector.translateToLocal("botania.nei.lexica");
} }
} @Override
public String getOverlayIdentifier() {
return "botania.lexica";
}
@Override @Override
public String getRecipeName() { public String getGuiTexture() {
return StatCollector.translateToLocal("botania.nei.lexica"); return LibResources.GUI_NEI_BLANK;
} }
@Override @Override
public String getGuiTexture() { public void loadTransferRects() {
return LibResources.GUI_NEI_BLANK; transferRects.add(new RecipeTransferRect(new Rectangle(50, 4, 18, 18), getOverlayIdentifier()));
} }
@Override @Override
public int recipiesPerPage() { public void drawBackground(int recipe) {
return 1; super.drawBackground(recipe);
}
@Override
public void loadTransferRects() {
transferRects.add(new RecipeTransferRect(new Rectangle(50, 4, 18, 18), "botania.lexica"));
}
@Override
public void drawBackground(int recipe) {
super.drawBackground(recipe);
FontRenderer font = Minecraft.getMinecraft().fontRenderer;
CachedLexicaBotaniaRecipe recipeObj = ((CachedLexicaBotaniaRecipe) arecipes.get(recipe));
String s = EnumChatFormatting.UNDERLINE + StatCollector.translateToLocal(recipeObj.entry.getUnlocalizedName()); CachedLexicaBotaniaRecipe recipeObj = ((CachedLexicaBotaniaRecipe) arecipes.get(recipe));
font.drawString(s, 82 - font.getStringWidth(s) / 2, 30, 4210752);
KnowledgeType type = recipeObj.entry.getKnowledgeType();
s = type.color + StatCollector.translateToLocal(type.getUnlocalizedName()).replaceAll("\\&.", "");
font.drawString(s, 82 - font.getStringWidth(s) / 2, 42, 4210752);
s = "\"" + StatCollector.translateToLocal(recipeObj.entry.getTagline()) + "\"";
PageText.renderText(5, 42, 160, 200, s);
String key = LexiconRecipeMappings.stackToString(recipeObj.item.item);
String quickInfo = "botania.nei.quickInfo:" + key;
String quickInfoLocal = StatCollector.translateToLocal(quickInfo);
if(GuiScreen.isShiftKeyDown() && GuiScreen.isCtrlKeyDown() && Minecraft.getMinecraft().gameSettings.advancedItemTooltips)
s = "name: " + key;
else if(quickInfo.equals(quickInfoLocal))
s = StatCollector.translateToLocal("botania.nei.lexicaNoInfo");
else {
s = StatCollector.translateToLocal("botania.nei.lexicaSeparator");
font.drawString(s, 82 - font.getStringWidth(s) / 2, 80, 4210752);
s = quickInfoLocal;
}
PageText.renderText(5, 80, 160, 200, s);
}
@Override NEIHelper.renderItemIntoGUI(LEXICA, 51, 5);
public void loadCraftingRecipes(String outputId, Object... results) {
if(outputId.equals("botania.lexica")) {
for(LexiconEntry entry : BotaniaAPI.getAllEntries()) {
List<ItemStack> stacks = entry.getDisplayedRecipes();
for(ItemStack stack : stacks)
arecipes.add(new CachedLexicaBotaniaRecipe(stack, entry));
}
} else super.loadCraftingRecipes(outputId, results);
}
@Override GuiDraw.drawStringC(
public void loadCraftingRecipes(ItemStack result) { EnumChatFormatting.UNDERLINE + StatCollector.translateToLocal(recipeObj.entry.getUnlocalizedName()),
for(LexiconEntry entry : BotaniaAPI.getAllEntries()) { 82,
List<ItemStack> stacks = entry.getDisplayedRecipes(); 30,
for(ItemStack stack : stacks) { 0x404040,
String key1 = LexiconRecipeMappings.stackToString(stack); false);
String key2 = LexiconRecipeMappings.stackToString(result);
if(key1.equals(key2))
arecipes.add(new CachedLexicaBotaniaRecipe(stack, entry));
}
}
}
@Override KnowledgeType type = recipeObj.entry.getKnowledgeType();
public void loadUsageRecipes(ItemStack ingredient) { GuiDraw.drawStringC(
// NO-OP type.color + StatCollector.translateToLocal(type.getUnlocalizedName()).replaceAll("&[0-9a-fklmnor]", ""),
} 82,
42,
0x404040,
false);
PageText.renderText(
5,
42,
160,
200,
"\"" + StatCollector.translateToLocal(recipeObj.entry.getTagline()) + "\"");
String key = LexiconRecipeMappings.stackToString(recipeObj.item.item);
String quickInfo = "botania.nei.quickInfo:" + key;
String quickInfoLocal = StatCollector.translateToLocal(quickInfo);
String s;
if (GuiScreen.isShiftKeyDown() && GuiScreen.isCtrlKeyDown() && Minecraft.getMinecraft().gameSettings.advancedItemTooltips)
s = "name: " + key;
else if (quickInfo.equals(quickInfoLocal))
s = StatCollector.translateToLocal("botania.nei.lexicaNoInfo");
else {
GuiDraw.drawStringC(
StatCollector.translateToLocal("botania.nei.lexicaSeparator"),
82,
80,
0x404040,
false);
s = quickInfoLocal;
}
PageText.renderText(5, 80, 160, 200, s);
}
@Override
public void loadCraftingRecipes(String outputId, Object... results) {
if (outputId.equals(getOverlayIdentifier())) {
for (LexiconEntry entry : BotaniaAPI.getAllEntries()) {
List<ItemStack> stacks = entry.getDisplayedRecipes();
for (ItemStack stack : stacks)
arecipes.add(new CachedLexicaBotaniaRecipe(stack, entry));
}
} else {
super.loadCraftingRecipes(outputId, results);
}
}
@Override
public void loadCraftingRecipes(ItemStack result) {
for (LexiconEntry entry : BotaniaAPI.getAllEntries()) {
List<ItemStack> stacks = entry.getDisplayedRecipes();
for (ItemStack stack : stacks) {
String key1 = LexiconRecipeMappings.stackToString(stack);
String key2 = LexiconRecipeMappings.stackToString(result);
if (key1.equals(key2)) {
arecipes.add(new CachedLexicaBotaniaRecipe(stack, entry));
}
}
}
}
@Override
public void loadUsageRecipes(String outputId, Object... ingredients) {
loadCraftingRecipes(outputId, ingredients);
}
@Override
public void loadUsageRecipes(ItemStack ingredient) {
loadCraftingRecipes(ingredient);
}
} }
@@ -1,13 +1,9 @@
package vazkii.botania.client.integration.nei.recipe; package vazkii.botania.client.integration.nei.recipe;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiScreen;
import net.minecraft.item.Item; import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.StatCollector; import net.minecraft.util.StatCollector;
import net.minecraftforge.oredict.OreDictionary; import net.minecraftforge.oredict.OreDictionary;
@@ -17,6 +13,7 @@ import org.lwjgl.opengl.GL11;
import vazkii.botania.api.BotaniaAPI; import vazkii.botania.api.BotaniaAPI;
import vazkii.botania.api.recipe.RecipeManaInfusion; import vazkii.botania.api.recipe.RecipeManaInfusion;
import vazkii.botania.client.core.handler.HUDHandler; import vazkii.botania.client.core.handler.HUDHandler;
import vazkii.botania.client.integration.nei.NEIHelper;
import vazkii.botania.client.lib.LibResources; import vazkii.botania.client.lib.LibResources;
import vazkii.botania.client.render.tile.RenderTilePool; import vazkii.botania.client.render.tile.RenderTilePool;
import vazkii.botania.common.block.ModBlocks; import vazkii.botania.common.block.ModBlocks;
@@ -28,120 +25,138 @@ import vazkii.botania.common.core.helper.ItemNBTHelper;
public class RecipeHandlerManaPool extends TemplateRecipeHandler { public class RecipeHandlerManaPool extends TemplateRecipeHandler {
public class CachedManaPoolRecipe extends CachedRecipe { private static final ItemStack POOL = new ItemStack(ModBlocks.pool);
public List<PositionedStack> inputs = new ArrayList<>(); public class CachedManaPoolRecipe extends CachedRecipe {
public PositionedStack output;
public List<PositionedStack> otherStacks = new ArrayList<>();
public int mana;
public CachedManaPoolRecipe(RecipeManaInfusion recipe) { private static final PositionedStack ALCHEMY = new PositionedStack(new ItemStack(ModBlocks.alchemyCatalyst), 10, 37);
if(recipe == null) private static final PositionedStack CONJURATION = new PositionedStack(new ItemStack(ModBlocks.conjurationCatalyst), 10, 37);
return; public PositionedStack input;
inputs.add(new PositionedStack(new ItemStack(ModBlocks.pool, 1, recipe.getOutput().getItem() == Item.getItemFromBlock(ModBlocks.pool) ? 2 : 0), 71, 37)); public PositionedStack output;
public PositionedStack catalyst;
public int mana;
if(recipe.getInput() instanceof String) public CachedManaPoolRecipe(RecipeManaInfusion recipe) {
inputs.add(new PositionedStack(OreDictionary.getOres((String) recipe.getInput()), 42, 37)); if (recipe == null) return;
else inputs.add(new PositionedStack(recipe.getInput(), 42, 37));
if(recipe.isAlchemy()) Object o = recipe.getInput();
otherStacks.add(new PositionedStack(new ItemStack(ModBlocks.alchemyCatalyst), 10, 37)); if (o instanceof String oreName) {
else if (recipe.isConjuration()) o = OreDictionary.getOres(oreName);
otherStacks.add(new PositionedStack(new ItemStack(ModBlocks.conjurationCatalyst), 10, 37)); }
input = new PositionedStack(o, 42, 37);
output = new PositionedStack(recipe.getOutput(), 101, 37); if (recipe.isAlchemy()) {
// This value is where the mana bar is stored initially catalyst = ALCHEMY;
mana = recipe.getManaToConsume(); } else if (recipe.isConjuration()) {
} catalyst = CONJURATION;
}
@Override output = new PositionedStack(recipe.getOutput(), 101, 37);
public List<PositionedStack> getIngredients() { mana = recipe.getManaToConsume();
return getCycledIngredients(cycleticks / 20, inputs); }
}
@Override @Override
public PositionedStack getResult() { public PositionedStack getIngredient() {
return output; return input;
} }
@Override @Override
public List<PositionedStack> getOtherStacks() { public PositionedStack getResult() {
return otherStacks; return output;
} }
} @Override
public PositionedStack getOtherStack() {
return catalyst;
}
@Override }
public String getRecipeName() {
return StatCollector.translateToLocal("botania.nei.manaPool");
}
@Override @Override
public String getGuiTexture() { public String getRecipeName() {
return LibResources.GUI_NEI_BLANK; return StatCollector.translateToLocal("botania.nei.manaPool");
} }
@Override @Override
public int recipiesPerPage() { public String getOverlayIdentifier() {
return 1; return "botania.manaPool";
} }
@Override @Override
public void loadTransferRects() { public String getGuiTexture() {
transferRects.add(new RecipeTransferRect(new Rectangle(70, 36, 18, 18), "botania.manaPool")); return LibResources.GUI_NEI_BLANK;
} }
@Override @Override
public void drawBackground(int recipe) { public void loadTransferRects() {
super.drawBackground(recipe); transferRects.add(new RecipeTransferRect(new Rectangle(70, 36, 18, 18), getOverlayIdentifier()));
GL11.glEnable(GL11.GL_BLEND); }
GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.5F);
// Mana infusion is the mana pool, super weird.
GuiDraw.changeTexture(LibResources.GUI_MANA_INFUSION_OVERLAY);
GuiDraw.drawTexturedModalRect(45, 20, 38, 35, 92, 50);
// Below is where the mana bar actually drawn.
int tempMana = ((CachedManaPoolRecipe) arecipes.get(recipe)).mana;
HUDHandler.renderManaBar(32, 80, 0x0000FF, 0.75F, GuiScreen.isShiftKeyDown() ? tempMana : tempMana * 10, TilePool.MAX_MANA / 10);
FontRenderer font = Minecraft.getMinecraft().fontRenderer;
String size = GuiScreen.isShiftKeyDown() ? "1x" : "10x";
String localized = StatCollector.translateToLocalFormatted("botaniamisc.neiratio", size);
font.drawString(localized, 84 - font.getStringWidth(localized) / 2, 71, 0x000000);
RenderTilePool.forceMana = true;
}
@Override @Override
public void loadCraftingRecipes(String outputId, Object... results) { public void drawBackground(int recipe) {
if(outputId.equals("botania.manaPool")) { super.drawBackground(recipe);
for(RecipeManaInfusion recipe : BotaniaAPI.manaInfusionRecipes) { GL11.glEnable(GL11.GL_BLEND);
if(recipe == null) GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.5F);
continue; // Arrows
GuiDraw.changeTexture(LibResources.GUI_MANA_INFUSION_OVERLAY);
GuiDraw.drawTexturedModalRect(45, 20, 38, 35, 92, 50);
// Mana bar
int tempMana = ((CachedManaPoolRecipe) arecipes.get(recipe)).mana;
HUDHandler.renderManaBar(
32,
80,
0x0000FF,
0.75F,
GuiScreen.isShiftKeyDown() ? tempMana : tempMana * 10,
TilePool.MAX_MANA / 10);
String size = GuiScreen.isShiftKeyDown() ? "1x" : "10x";
String localized = StatCollector.translateToLocalFormatted("botaniamisc.neiratio", size);
GuiDraw.drawStringC(localized, 84, 71, 0x000000, false);
GL11.glDisable(GL11.GL_BLEND);
// Mana pool item
RenderHelper.enableGUIStandardItemLighting();
GL11.glEnable(GL11.GL_DEPTH_TEST);
RenderTilePool.forceMana = true;
NEIHelper.renderItemIntoGUI(POOL, 71, 37);
GL11.glDisable(GL11.GL_DEPTH_TEST);
RenderHelper.disableStandardItemLighting();
}
arecipes.add(new CachedManaPoolRecipe(recipe)); @Override
} public void loadCraftingRecipes(String outputId, Object... results) {
} else super.loadCraftingRecipes(outputId, results); if (outputId.equals(getOverlayIdentifier())) {
} for (RecipeManaInfusion recipe : BotaniaAPI.manaInfusionRecipes) {
if (recipe == null) continue;
@Override arecipes.add(new CachedManaPoolRecipe(recipe));
public void loadCraftingRecipes(ItemStack result) { }
for(RecipeManaInfusion recipe : BotaniaAPI.manaInfusionRecipes) { } else {
if(recipe == null) super.loadCraftingRecipes(outputId, results);
continue; }
}
if(ItemNBTHelper.areStacksSameTypeCraftingWithNBT(recipe.getOutput(), result)) @Override
arecipes.add(new CachedManaPoolRecipe(recipe)); public void loadCraftingRecipes(ItemStack result) {
} for (RecipeManaInfusion recipe : BotaniaAPI.manaInfusionRecipes) {
} if (recipe == null) continue;
@Override if (ItemNBTHelper.areStacksSameTypeCraftingWithNBT(recipe.getOutput(), result)) {
public void loadUsageRecipes(ItemStack ingredient) { arecipes.add(new CachedManaPoolRecipe(recipe));
for(RecipeManaInfusion recipe : BotaniaAPI.manaInfusionRecipes) { }
if(recipe == null) }
continue; }
CachedManaPoolRecipe crecipe = new CachedManaPoolRecipe(recipe); @Override
if(ItemNBTHelper.cachedRecipeContainsWithNBT(crecipe.getIngredients(), ingredient) || ItemNBTHelper.cachedRecipeContainsWithNBT(crecipe.getOtherStacks(), ingredient)) public void loadUsageRecipes(ItemStack ingredient) {
arecipes.add(crecipe); for (RecipeManaInfusion recipe : BotaniaAPI.manaInfusionRecipes) {
} if (recipe == null) continue;
}
CachedManaPoolRecipe crecipe = new CachedManaPoolRecipe(recipe);
if (ItemNBTHelper.positionedStackContainsWithNBT(crecipe.input, ingredient) ||
ItemNBTHelper.positionedStackContainsWithNBT(crecipe.catalyst, ingredient)) {
arecipes.add(crecipe);
}
}
}
} }
@@ -4,6 +4,7 @@ import java.awt.Rectangle;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.init.Items; import net.minecraft.init.Items;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.StatCollector; import net.minecraft.util.StatCollector;
@@ -13,6 +14,7 @@ import org.lwjgl.opengl.GL11;
import vazkii.botania.api.BotaniaAPI; import vazkii.botania.api.BotaniaAPI;
import vazkii.botania.api.recipe.RecipePetals; import vazkii.botania.api.recipe.RecipePetals;
import vazkii.botania.client.integration.nei.NEIHelper;
import vazkii.botania.client.lib.LibResources; import vazkii.botania.client.lib.LibResources;
import vazkii.botania.common.block.ModBlocks; import vazkii.botania.common.block.ModBlocks;
import codechicken.lib.gui.GuiDraw; import codechicken.lib.gui.GuiDraw;
@@ -22,122 +24,137 @@ import codechicken.nei.recipe.TemplateRecipeHandler;
import vazkii.botania.common.core.helper.ItemNBTHelper; import vazkii.botania.common.core.helper.ItemNBTHelper;
public class RecipeHandlerPetalApothecary extends TemplateRecipeHandler { public class RecipeHandlerPetalApothecary extends TemplateRecipeHandler {
private static final ItemStack APOTHECARY = new ItemStack(ModBlocks.altar);
public class CachedPetalApothecaryRecipe extends CachedRecipe { public class CachedPetalApothecaryRecipe extends CachedRecipe {
public List<PositionedStack> inputs = new ArrayList<>();
public PositionedStack output;
public List<PositionedStack> inputs = new ArrayList<>(); public CachedPetalApothecaryRecipe(RecipePetals recipe, PositionedStack centerItem) {
public PositionedStack output; this(recipe);
inputs.add(centerItem);
}
public CachedPetalApothecaryRecipe(RecipePetals recipe, boolean addCenterItem) { public CachedPetalApothecaryRecipe(RecipePetals recipe) {
setIngredients(recipe.getInputs()); setIngredients(recipe.getInputs());
output = new PositionedStack(recipe.getOutput(), 111, 21); output = new PositionedStack(recipe.getOutput(), 111, 21);
if(addCenterItem) }
inputs.add(new PositionedStack(new ItemStack(ModBlocks.altar), 73, 55));
}
public CachedPetalApothecaryRecipe(RecipePetals recipe) { public void setIngredients(List<Object> inputs) {
this(recipe, true); float degreePerInput = 360F / inputs.size();
} float currentDegree = -90F;
public void setIngredients(List<Object> inputs) { for (Object o : inputs) {
float degreePerInput = 360F / inputs.size(); int posX = (int) Math.round(73 + Math.cos(currentDegree * Math.PI / 180D) * 32);
float currentDegree = -90F; int posY = (int) Math.round(55 + Math.sin(currentDegree * Math.PI / 180D) * 32);
for(Object o : inputs) { if (o instanceof String oreName) {
int posX = (int) Math.round(73 + Math.cos(currentDegree * Math.PI / 180D) * 32); o = OreDictionary.getOres(oreName);
int posY = (int) Math.round(55 + Math.sin(currentDegree * Math.PI / 180D) * 32); }
this.inputs.add(new PositionedStack(o, posX, posY));
currentDegree += degreePerInput;
}
}
if(o instanceof String) @Override
this.inputs.add(new PositionedStack(OreDictionary.getOres((String) o), posX, posY)); public List<PositionedStack> getIngredients() {
else this.inputs.add(new PositionedStack(o, posX, posY)); return inputs;
currentDegree += degreePerInput; }
}
}
@Override @Override
public List<PositionedStack> getIngredients() { public PositionedStack getResult() {
return getCycledIngredients(cycleticks / 20, inputs); return output;
} }
}
@Override @Override
public PositionedStack getResult() { public String getRecipeName() {
return output; return StatCollector.translateToLocal("botania.nei.petalApothecary");
} }
} @Override
public String getOverlayIdentifier() {
return "botania.petalApothecary";
}
@Override // Used by the Alfheim addon, identical to getOverlayIdentifier()
public String getRecipeName() { @Deprecated
return StatCollector.translateToLocal("botania.nei.petalApothecary"); public String getRecipeID() {
} return "botania.petalApothecary";
}
public String getRecipeID() { @Override
return "botania.petalApothecary"; public String getGuiTexture() {
} return LibResources.GUI_NEI_BLANK;
}
@Override @Override
public String getGuiTexture() { public void loadTransferRects() {
return LibResources.GUI_NEI_BLANK; transferRects.add(new RecipeTransferRect(new Rectangle(73, 56, 16, 16), getOverlayIdentifier()));
} }
@Override @Override
public void loadTransferRects() { public void drawBackground(int recipe) {
transferRects.add(new RecipeTransferRect(new Rectangle(72, 54, 18, 18), getRecipeID())); super.drawBackground(recipe);
} // Background circle graphic
GL11.glEnable(GL11.GL_BLEND);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.5F);
GuiDraw.changeTexture(LibResources.GUI_PETAL_OVERLAY);
GuiDraw.drawTexturedModalRect(45, 10, 38, 7, 92, 92);
// Item
RenderHelper.enableGUIStandardItemLighting();
GL11.glEnable(GL11.GL_DEPTH_TEST);
NEIHelper.renderItemIntoGUI(getRenderItem(), 73, 55);
GL11.glDisable(GL11.GL_DEPTH_TEST);
RenderHelper.disableStandardItemLighting();
}
@Override protected ItemStack getRenderItem() {
public int recipiesPerPage() { return APOTHECARY;
return 1; }
}
@Override public List<? extends RecipePetals> getRecipes() {
public void drawBackground(int recipe) { return BotaniaAPI.petalRecipes;
super.drawBackground(recipe); }
GL11.glEnable(GL11.GL_BLEND);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.5F);
GuiDraw.changeTexture(LibResources.GUI_PETAL_OVERLAY);
GuiDraw.drawTexturedModalRect(45, 10, 38, 7, 92, 92);
}
public List<? extends RecipePetals> getRecipes() { public CachedPetalApothecaryRecipe getCachedRecipe(RecipePetals recipe) {
return BotaniaAPI.petalRecipes; ItemStack seedStack = new ItemStack(Items.wheat_seeds);
} seedStack.setStackDisplayName(StatCollector.translateToLocal("botania.nei.anySeed"));
return new CachedPetalApothecaryRecipe(recipe, new PositionedStack(seedStack, 73, 39));
}
public CachedPetalApothecaryRecipe getCachedRecipe(RecipePetals recipe) { @Override
return new CachedPetalApothecaryRecipe(recipe); public void loadCraftingRecipes(String outputId, Object... results) {
} if (outputId.equals(getOverlayIdentifier())) {
for (RecipePetals recipe : getRecipes())
if (recipe.getOutput().getItem() != Items.skull)
arecipes.add(getCachedRecipe(recipe));
} else {
super.loadCraftingRecipes(outputId, results);
}
}
@Override @Override
public void loadCraftingRecipes(String outputId, Object... results) { public void loadCraftingRecipes(ItemStack result) {
if(outputId.equals(getRecipeID())) { for (RecipePetals recipe : getRecipes()) {
for(RecipePetals recipe : getRecipes()) if (recipe == null) continue;
if(recipe.getOutput().getItem() != Items.skull)
arecipes.add(getCachedRecipe(recipe));
} else super.loadCraftingRecipes(outputId, results);
}
@Override if (recipe.getOutput().stackTagCompound != null && ItemNBTHelper.areStacksSameTypeWithNBT(recipe.getOutput(), result) || recipe.getOutput().stackTagCompound == null && NEIServerUtils.areStacksSameTypeCrafting(recipe.getOutput(), result) && recipe.getOutput().getItem() != Items.skull) {
public void loadCraftingRecipes(ItemStack result) { arecipes.add(getCachedRecipe(recipe));
for(RecipePetals recipe : getRecipes()){ }
if(recipe == null) }
continue; }
if(recipe.getOutput().stackTagCompound != null && ItemNBTHelper.areStacksSameTypeWithNBT(recipe.getOutput(), result) || recipe.getOutput().stackTagCompound == null && NEIServerUtils.areStacksSameTypeCrafting(recipe.getOutput(), result) && recipe.getOutput().getItem() != Items.skull) @Override
arecipes.add(getCachedRecipe(recipe)); public void loadUsageRecipes(ItemStack ingredient) {
} for (RecipePetals recipe : getRecipes()) {
} if (recipe == null) continue;
@Override
public void loadUsageRecipes(ItemStack ingredient) {
for(RecipePetals recipe : getRecipes()) {
if(recipe == null)
continue;
CachedPetalApothecaryRecipe crecipe = getCachedRecipe(recipe);
if(ItemNBTHelper.cachedRecipeContainsWithNBT(crecipe.inputs, ingredient) && recipe.getOutput().getItem() != Items.skull)
arecipes.add(crecipe);
}
}
CachedPetalApothecaryRecipe crecipe = getCachedRecipe(recipe);
if (ItemNBTHelper.cachedRecipeContainsWithNBT(crecipe.inputs, ingredient) && recipe.getOutput().getItem() != Items.skull) {
arecipes.add(crecipe);
}
}
}
} }
@@ -1,8 +1,6 @@
package vazkii.botania.client.integration.nei.recipe; package vazkii.botania.client.integration.nei.recipe;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@@ -13,6 +11,7 @@ import org.lwjgl.opengl.GL11;
import vazkii.botania.api.BotaniaAPI; import vazkii.botania.api.BotaniaAPI;
import vazkii.botania.api.recipe.RecipePureDaisy; import vazkii.botania.api.recipe.RecipePureDaisy;
import vazkii.botania.client.integration.nei.NEIHelper;
import vazkii.botania.client.lib.LibResources; import vazkii.botania.client.lib.LibResources;
import vazkii.botania.common.core.helper.ItemNBTHelper; import vazkii.botania.common.core.helper.ItemNBTHelper;
import vazkii.botania.common.item.block.ItemBlockSpecialFlower; import vazkii.botania.common.item.block.ItemBlockSpecialFlower;
@@ -23,103 +22,102 @@ import codechicken.nei.recipe.TemplateRecipeHandler;
public class RecipeHandlerPureDaisy extends TemplateRecipeHandler { public class RecipeHandlerPureDaisy extends TemplateRecipeHandler {
public class CachedPureDaisyRecipe extends CachedRecipe { private static final ItemStack DAISY = ItemBlockSpecialFlower.ofType(LibBlockNames.SUBTILE_PUREDAISY);
public List<PositionedStack> inputs = new ArrayList<>(); public class CachedPureDaisyRecipe extends CachedRecipe {
public PositionedStack output;
public List<PositionedStack> otherStacks = new ArrayList<>();
public CachedPureDaisyRecipe(RecipePureDaisy recipe) { public PositionedStack inputs;
if(recipe == null) public PositionedStack output;
return;
inputs.add(new PositionedStack(ItemBlockSpecialFlower.ofType(LibBlockNames.SUBTILE_PUREDAISY), 71, 23));
if(recipe.getInput() instanceof String) public CachedPureDaisyRecipe(RecipePureDaisy recipe) {
inputs.add(new PositionedStack(OreDictionary.getOres((String) recipe.getInput()), 42, 23)); if (recipe == null) return;
else inputs.add(new PositionedStack(new ItemStack((Block) recipe.getInput()), 42, 23));
output = new PositionedStack(new ItemStack(recipe.getOutput()), 101, 23); Object o = recipe.getInput();
} if (o instanceof String oreName) {
o = OreDictionary.getOres(oreName);
} else {
o = new ItemStack((Block) o);
}
inputs = new PositionedStack(o, 42, 23);
output = new PositionedStack(new ItemStack(recipe.getOutput()), 101, 23);
}
@Override @Override
public List<PositionedStack> getIngredients() { public PositionedStack getIngredient() {
return getCycledIngredients(cycleticks / 20, inputs); return inputs;
} }
@Override @Override
public PositionedStack getResult() { public PositionedStack getResult() {
return output; return output;
} }
@Override }
public List<PositionedStack> getOtherStacks() {
return otherStacks;
}
} @Override
public String getRecipeName() {
return StatCollector.translateToLocal("botania.nei.pureDaisy");
}
@Override @Override
public String getRecipeName() { public String getOverlayIdentifier() {
return StatCollector.translateToLocal("botania.nei.pureDaisy"); return "botania.pureDaisy";
} }
@Override @Override
public String getGuiTexture() { public String getGuiTexture() {
return LibResources.GUI_NEI_BLANK; return LibResources.GUI_NEI_BLANK;
} }
@Override @Override
public int recipiesPerPage() { public void loadTransferRects() {
return 2; transferRects.add(new RecipeTransferRect(new Rectangle(70, 22, 18, 18), getOverlayIdentifier()));
} }
@Override @Override
public void loadTransferRects() { public void drawBackground(int recipe) {
transferRects.add(new RecipeTransferRect(new Rectangle(70, 22, 18, 18), "botania.pureDaisy")); super.drawBackground(recipe);
} // Arrows
GL11.glEnable(GL11.GL_BLEND);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.5F);
GuiDraw.changeTexture(LibResources.GUI_PURE_DAISY_OVERLAY);
GuiDraw.drawTexturedModalRect(48, 10, 0, 0, 65, 44);
// Flower item
NEIHelper.renderItemIntoGUI(DAISY, 71, 23);
}
@Override @Override
public void drawBackground(int recipe) { public void loadCraftingRecipes(String outputId, Object... results) {
super.drawBackground(recipe); if (outputId.equals(getOverlayIdentifier())) {
GL11.glEnable(GL11.GL_BLEND); for (RecipePureDaisy recipe : BotaniaAPI.pureDaisyRecipes) {
GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.5F); if (recipe != null) arecipes.add(new CachedPureDaisyRecipe(recipe));
GuiDraw.changeTexture(LibResources.GUI_PURE_DAISY_OVERLAY); }
GuiDraw.drawTexturedModalRect(45, 10, 0, 0, 65, 44); } else {
} super.loadCraftingRecipes(outputId, results);
}
}
@Override @Override
public void loadCraftingRecipes(String outputId, Object... results) { public void loadCraftingRecipes(ItemStack result) {
if(outputId.equals("botania.pureDaisy")) { for (RecipePureDaisy recipe : BotaniaAPI.pureDaisyRecipes) {
for(RecipePureDaisy recipe : BotaniaAPI.pureDaisyRecipes) { if (recipe == null) continue;
if(recipe == null)
continue;
arecipes.add(new CachedPureDaisyRecipe(recipe)); if (ItemNBTHelper.areStacksSameTypeCraftingWithNBT(new ItemStack(recipe.getOutput()), result)) {
} arecipes.add(new CachedPureDaisyRecipe(recipe));
} else super.loadCraftingRecipes(outputId, results); }
} }
}
@Override @Override
public void loadCraftingRecipes(ItemStack result) { public void loadUsageRecipes(ItemStack ingredient) {
for(RecipePureDaisy recipe : BotaniaAPI.pureDaisyRecipes) { for (RecipePureDaisy recipe : BotaniaAPI.pureDaisyRecipes) {
if(recipe == null) if (recipe == null) continue;
continue;
if(ItemNBTHelper.areStacksSameTypeCraftingWithNBT(new ItemStack(recipe.getOutput()), result)) CachedPureDaisyRecipe crecipe = new CachedPureDaisyRecipe(recipe);
arecipes.add(new CachedPureDaisyRecipe(recipe)); if (ItemNBTHelper.cachedRecipeContainsWithNBT(crecipe.getIngredients(), ingredient) || ItemNBTHelper.cachedRecipeContainsWithNBT(crecipe.getOtherStacks(), ingredient)) {
} arecipes.add(crecipe);
} }
}
@Override }
public void loadUsageRecipes(ItemStack ingredient) {
for(RecipePureDaisy recipe : BotaniaAPI.pureDaisyRecipes) {
if(recipe == null)
continue;
CachedPureDaisyRecipe crecipe = new CachedPureDaisyRecipe(recipe);
if(ItemNBTHelper.cachedRecipeContainsWithNBT(crecipe.getIngredients(), ingredient) || ItemNBTHelper.cachedRecipeContainsWithNBT(crecipe.getOtherStacks(), ingredient))
arecipes.add(crecipe);
}
}
} }
@@ -14,44 +14,48 @@ import codechicken.nei.PositionedStack;
public class RecipeHandlerRunicAltar extends RecipeHandlerPetalApothecary { public class RecipeHandlerRunicAltar extends RecipeHandlerPetalApothecary {
public class CachedRunicAltarRecipe extends CachedPetalApothecaryRecipe { private static final ItemStack ALTAR = new ItemStack(ModBlocks.runeAltar);
private static final PositionedStack LIVINGROCK = new PositionedStack(new ItemStack(ModBlocks.livingrock), 73, 39);
public int manaUsage; public class CachedRunicAltarRecipe extends CachedPetalApothecaryRecipe {
public CachedRunicAltarRecipe(RecipeRuneAltar recipe) { public int manaUsage;
super(recipe, false);
if(recipe == null)
return;
manaUsage = recipe.getManaUsage();
inputs.add(new PositionedStack(new ItemStack(ModBlocks.runeAltar), 73, 55));
}
} public CachedRunicAltarRecipe(RecipeRuneAltar recipe, PositionedStack centerItem) {
super(recipe, centerItem);
manaUsage = recipe.getManaUsage();
}
}
@Override
public String getRecipeName() {
return StatCollector.translateToLocal("botania.nei.runicAltar");
}
@Override
public String getOverlayIdentifier() {
return "botania.runicAltar";
}
@Override
public void drawBackground(int recipe) {
super.drawBackground(recipe);
HUDHandler.renderManaBar(32, 113, 0x0000FF, 0.75F, ((CachedRunicAltarRecipe) arecipes.get(recipe)).manaUsage, TilePool.MAX_MANA / 10);
}
@Override
public List<? extends RecipePetals> getRecipes() {
return BotaniaAPI.runeAltarRecipes;
}
@Override
public CachedPetalApothecaryRecipe getCachedRecipe(RecipePetals recipe) {
return new CachedRunicAltarRecipe((RecipeRuneAltar) recipe, LIVINGROCK);
}
@Override @Override
public String getRecipeName() { protected ItemStack getRenderItem() {
return StatCollector.translateToLocal("botania.nei.runicAltar"); return ALTAR;
} }
@Override
public String getRecipeID() {
return "botania.runicAltar";
}
@Override
public void drawBackground(int recipe) {
super.drawBackground(recipe);
HUDHandler.renderManaBar(32, 113, 0x0000FF, 0.75F, ((CachedRunicAltarRecipe) arecipes.get(recipe)).manaUsage, TilePool.MAX_MANA / 10);
}
@Override
public List<? extends RecipePetals> getRecipes() {
return BotaniaAPI.runeAltarRecipes;
}
@Override
public CachedPetalApothecaryRecipe getCachedRecipe(RecipePetals recipe) {
return new CachedRunicAltarRecipe((RecipeRuneAltar) recipe);
}
} }
@@ -43,6 +43,7 @@ public class Botania {
public static boolean etFuturumLoaded = false; public static boolean etFuturumLoaded = false;
public static boolean storageDrawersLoaded = false; public static boolean storageDrawersLoaded = false;
public static boolean structureLibLoaded = false; public static boolean structureLibLoaded = false;
public static boolean neiLoaded = false;
public static ILightHelper lightHelper; public static ILightHelper lightHelper;
@@ -63,6 +64,7 @@ public class Botania {
etFuturumLoaded = Loader.isModLoaded("etfuturum"); etFuturumLoaded = Loader.isModLoaded("etfuturum");
storageDrawersLoaded = Loader.isModLoaded("StorageDrawers"); storageDrawersLoaded = Loader.isModLoaded("StorageDrawers");
structureLibLoaded = Loader.isModLoaded("structurelib"); structureLibLoaded = Loader.isModLoaded("structurelib");
neiLoaded = Loader.isModLoaded("NotEnoughItems");
lightHelper = coloredLightsLoaded ? new LightHelperColored() : new LightHelperVanilla(); lightHelper = coloredLightsLoaded ? new LightHelperColored() : new LightHelperVanilla();
proxy.preInit(event); proxy.preInit(event);
@@ -22,7 +22,6 @@ import net.minecraftforge.oredict.OreDictionary;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Collection; import java.util.Collection;
import java.util.Set;
public final class ItemNBTHelper { public final class ItemNBTHelper {
@@ -221,6 +220,7 @@ public final class ItemNBTHelper {
* NBT-friendly version of {@link codechicken.nei.recipe.TemplateRecipeHandler.CachedRecipe#contains(Collection, ItemStack)} * NBT-friendly version of {@link codechicken.nei.recipe.TemplateRecipeHandler.CachedRecipe#contains(Collection, ItemStack)}
*/ */
public static boolean cachedRecipeContainsWithNBT(Collection<PositionedStack> ingredients, ItemStack ingredient) { public static boolean cachedRecipeContainsWithNBT(Collection<PositionedStack> ingredients, ItemStack ingredient) {
if (ingredients == null) return false;
for (PositionedStack stack : ingredients) for (PositionedStack stack : ingredients)
if (positionedStackContainsWithNBT(stack, ingredient)) if (positionedStackContainsWithNBT(stack, ingredient))
return true; return true;
@@ -232,6 +232,7 @@ public final class ItemNBTHelper {
* NBT-friendly version of {@link codechicken.nei.PositionedStack#contains(ItemStack)} * NBT-friendly version of {@link codechicken.nei.PositionedStack#contains(ItemStack)}
*/ */
public static boolean positionedStackContainsWithNBT(PositionedStack stack, ItemStack ingredient) { public static boolean positionedStackContainsWithNBT(PositionedStack stack, ItemStack ingredient) {
if (stack == null) return false;
for(ItemStack item : stack.items) for(ItemStack item : stack.items)
if(areStacksSameTypeCraftingWithNBT(item, ingredient)) if(areStacksSameTypeCraftingWithNBT(item, ingredient))
return true; return true;
@@ -33,6 +33,7 @@ import vazkii.botania.api.BotaniaAPI;
import vazkii.botania.api.lexicon.ITwoNamedPage; import vazkii.botania.api.lexicon.ITwoNamedPage;
import vazkii.botania.api.lexicon.LexiconEntry; import vazkii.botania.api.lexicon.LexiconEntry;
import vazkii.botania.api.lexicon.LexiconPage; import vazkii.botania.api.lexicon.LexiconPage;
import vazkii.botania.client.integration.nei.IMCForNEI;
import vazkii.botania.common.Botania; import vazkii.botania.common.Botania;
import vazkii.botania.common.achievement.ModAchievements; import vazkii.botania.common.achievement.ModAchievements;
import vazkii.botania.common.block.ModBlocks; import vazkii.botania.common.block.ModBlocks;
@@ -152,6 +153,10 @@ public class CommonProxy {
new StatementAPIPlugin(); new StatementAPIPlugin();
LexiconData.init(); LexiconData.init();
if (Botania.neiLoaded) {
IMCForNEI.IMCSender();
}
} }
public void postInit(FMLPostInitializationEvent event) { public void postInit(FMLPostInitializationEvent event) {
@@ -10,14 +10,13 @@
*/ */
package vazkii.botania.common.item.equipment.bauble; package vazkii.botania.common.item.equipment.bauble;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HexFormat;
import java.util.List; import java.util.List;
import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.gui.ScaledResolution;
@@ -121,44 +120,44 @@ public class ItemFlightTiara extends ItemBauble implements IManaUsingItem, IBaub
infoList.add(StatCollector.translateToLocal("botania.wings" + stack.getItemDamage())); infoList.add(StatCollector.translateToLocal("botania.wings" + stack.getItemDamage()));
} }
/**
* The original solution for "16E1BDFD1D6AE1A954C9C5E1B2D9099780F3E1724541F1F2F77310B769CFFBAC" has been lost
* to time. It's supposed to be a 19 character long Matrix reference, but hash() is broken and gives
* inconsistent output, so it probably wouldn't even be recognized if you got it right. It was later
* replaced with the name of an Aqours single, but the name is too long for anvils in 1.7.10.
* It has been fixed to be consistent (and considerably simplified since doing weird random obfuscation before
* hashing is pointless at best), but it required replacing it with my own solution.
* If you have the original solution, I will gladly replace this one with it.
* Here are a few hints:
* It's the title of a song that aligns with Vazkii's interests.
* For authenticity, this song was released before this secret was originally added (2015).
* This song has a special segment only present in one of the single-member versions.
* -koolkrafter5
*/
@Override @Override
public void onEquipped(ItemStack stack, EntityLivingBase player) { public void onEquipped(ItemStack stack, EntityLivingBase player) {
super.onEquipped(stack, player); super.onEquipped(stack, player);
if(stack.getItemDamage() != WING_TYPES && hash(stack.getDisplayName()).equals("16E1BDFD1D6AE1A954C9C5E1B2D9099780F3E1724541F1F2F77310B769CFFBAC")) { if (stack.getItemDamage() != WING_TYPES &&
hash(stack.getDisplayName()).equals("04E789FA6BC538F7645606141A1CFECECF4E84C301CB892779E761FD3FFF6386")) {
stack.setItemDamage(WING_TYPES); stack.setItemDamage(WING_TYPES);
stack.getTagCompound().removeTag("display"); stack.getTagCompound().removeTag("display");
} }
} }
String hash(String str) { String hash(String str) {
if(str != null) try {
try { MessageDigest md = MessageDigest.getInstance("SHA-256");
MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] digest = md.digest(salt(str).getBytes(StandardCharsets.UTF_8));
return new HexBinaryAdapter().marshal(md.digest(salt(str).getBytes())); return HexFormat.of().withUpperCase().formatHex(digest);
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
e.printStackTrace(); e.printStackTrace();
} return "";
return ""; }
} }
// Might as well be called sugar given it's not secure at all :D // Might as well be called sugar given it's not secure at all :D
String salt(String str) { String salt(String str) {
str = str += "wowsuchsaltmuchsecurityverywow"; return str + "wowsuchsaltmuchsecurityverywow";
SecureRandom rand = new SecureRandom(str.getBytes());
int l = str.length();
int steps = rand.nextInt(l);
char[] chrs = str.toCharArray();
for(int i = 0; i < steps; i++) {
int indA = rand.nextInt(l);
int indB;
do {
indB = rand.nextInt(l);
} while(indB == indA);
char c = (char) (chrs[indA] ^ chrs[indB]);
chrs[indA] = c;
}
return String.copyValueOf(chrs);
} }
@Override @Override
@@ -184,6 +184,8 @@ botania.nei.pureDaisy=Pure Daisy
botania.nei.lexica=Lexica Botania botania.nei.lexica=Lexica Botania
nei.options.keys.gui.botania_corporea_request=Corporea Request nei.options.keys.gui.botania_corporea_request=Corporea Request
botania.nei.anySeed=Any Seed
botania.nei.lexicaSeparator=Extra Info: botania.nei.lexicaSeparator=Extra Info:
botania.nei.lexicaNoInfo=(there's no Extra Info for this entry, sorry!) botania.nei.lexicaNoInfo=(there's no Extra Info for this entry, sorry!)