NEI Meteor Handler Revamp (#77)

Co-authored-by: Maya <10861407+serenibyss@users.noreply.github.com>
This commit is contained in:
koolkrafter5andMaya authored and GitHub committed 2025-05-13 18:49:06 -05:00
1 parent 097c0c62e4
commit a6f1919f52
17 files changed
+495 -119

No files matched your search

+1 -1
View File
@@ -24,7 +24,7 @@
dependencies {
api("com.github.GTNewHorizons:waila:1.8.4:dev")
api("com.github.GTNewHorizons:NotEnoughItems:2.7.40-GTNH:dev")
api("com.github.GTNewHorizons:NotEnoughItems:2.7.43-GTNH:dev")
compileOnly("com.github.GTNewHorizons:GT5-Unofficial:5.09.51.275:dev") {transitive = false }
@@ -7,8 +7,9 @@ import cpw.mods.fml.common.event.FMLInterModComms;
public class IMCForNEI {
public static void IMCSender() {
sendHandler("alchemicalwizardry.meteor", "AWWayofTime:masterStone", 130);
sendHandler("alchemicalwizardry.meteor", "AWWayofTime:masterStone", 181);
sendCatalyst("alchemicalwizardry.meteor", "AWWayofTime:masterStone");
sendCatalyst("alchemicalwizardry.bindingritual", "AWWayofTime:masterStone");
}
private static void sendHandler(String handlerName, String stack, int height) {
@@ -1,15 +1,16 @@
package WayofTime.alchemicalWizardry.client.nei;
import static WayofTime.alchemicalWizardry.client.ClientUtils.mc;
import static WayofTime.alchemicalWizardry.client.nei.NEIConfig.getBloodOrbs;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
@@ -28,28 +29,19 @@ public class NEIAlchemyRecipeHandler extends TemplateRecipeHandler {
public class CachedAlchemyRecipe extends CachedRecipe {
public class BloodOrbs {
public PositionedStack stack;
public BloodOrbs(ItemStack orb) {
this.stack = new PositionedStack(orb, 136, 47, false);
}
}
ArrayList<BloodOrbs> orbs;
ArrayList<ItemStack> orbs;
PositionedStack output;
List<PositionedStack> inputs;
int lp;
public CachedAlchemyRecipe(AlchemyRecipe recipe, ItemStack orb) {
this(recipe);
this.orbs = new ArrayList<BloodOrbs>();
orbs.add(new BloodOrbs(orb));
this.orbs = new ArrayList<>();
orbs.add(orb);
}
public CachedAlchemyRecipe(AlchemyRecipe recipe) {
List<PositionedStack> inputs = new ArrayList<PositionedStack>();
List<PositionedStack> inputs = new ArrayList<>();
ItemStack[] stacks = recipe.getRecipe();
if (stacks.length > 0) inputs.add(new PositionedStack(stacks[0], 76, 3));
if (stacks.length > 1) inputs.add(new PositionedStack(stacks[1], 51, 19));
@@ -59,10 +51,10 @@ public class NEIAlchemyRecipeHandler extends TemplateRecipeHandler {
this.inputs = inputs;
this.output = new PositionedStack(recipe.getResult(), 76, 25);
this.lp = recipe.getAmountNeeded() * 100;
this.orbs = new ArrayList<BloodOrbs>();
this.orbs = new ArrayList<>();
for (Item orb : getBloodOrbs()) {
if (((IBloodOrb) orb).getOrbLevel() >= recipe.getOrbLevel()) {
orbs.add(new BloodOrbs(new ItemStack(orb)));
orbs.add(new ItemStack(orb));
}
}
}
@@ -79,8 +71,11 @@ public class NEIAlchemyRecipeHandler extends TemplateRecipeHandler {
@Override
public PositionedStack getOtherStack() {
if (orbs == null || orbs.size() <= 0) return null;
return orbs.get((cycleticks / 48) % orbs.size()).stack;
if (orbs == null || orbs.isEmpty()) return null;
PositionedStack stack = new PositionedStack(orbs, 136, 47, false);
stack.setPermutationToRender((cycleticks / 48) % orbs.size());
stack.setMaxSize(1);
return stack;
}
}
@@ -122,10 +117,10 @@ public class NEIAlchemyRecipeHandler extends TemplateRecipeHandler {
@Override
public void loadUsageRecipes(ItemStack ingredient) {
if (ingredient.getItem() instanceof IBloodOrb) {
if (ingredient.getItem() instanceof IBloodOrb orb) {
for (AlchemyRecipe recipe : AlchemyRecipeRegistry.recipes) {
if (recipe == null) continue;
if (((IBloodOrb) ingredient.getItem()).getOrbLevel() >= recipe.getOrbLevel()) {
if (orb.getOrbLevel() >= recipe.getOrbLevel()) {
arecipes.add(new CachedAlchemyRecipe(recipe, ingredient));
}
}
@@ -145,17 +140,14 @@ public class NEIAlchemyRecipeHandler extends TemplateRecipeHandler {
@Override
public void drawExtras(int id) {
CachedAlchemyRecipe cache = (CachedAlchemyRecipe) arecipes.get(id);
Minecraft.getMinecraft().fontRenderer.drawString("\u00a77" + cache.lp + "LP", getLPX(cache.lp), 34, 0);
CachedAlchemyRecipe recipe = (CachedAlchemyRecipe) arecipes.get(id);
String text = EnumChatFormatting.GRAY.toString() + recipe.lp + "LP";
mc.fontRenderer.drawString(text, getLPX(text), 28, 0);
}
public int getLPX(int lp) {
if (lp < 10) return 122;
else if (lp < 100) return 122;
else if (lp < 1000) return 130;
else if (lp < 10000) return 127;
else if (lp < 100000) return 124;
return 122;
public int getLPX(String text) {
int textWidth = mc.fontRenderer.getStringWidth(text);
return 144 - (textWidth / 2);
}
@Override
@@ -6,6 +6,7 @@ import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
@@ -65,7 +66,7 @@ public class NEIAltarRecipeHandler extends TemplateRecipeHandler {
public void loadCraftingRecipes(ItemStack result) {
for (AltarRecipe recipe : AltarRecipeRegistry.altarRecipes) {
if (NEIServerUtils.areStacksSameTypeCraftingWithNBT(recipe.result, result)) {
if (recipe != null && recipe.result != null) arecipes.add(new CachedAltarRecipe(recipe));
if (recipe.result != null) arecipes.add(new CachedAltarRecipe(recipe));
}
}
}
@@ -74,7 +75,7 @@ public class NEIAltarRecipeHandler extends TemplateRecipeHandler {
public void loadUsageRecipes(ItemStack ingredient) {
for (AltarRecipe recipe : AltarRecipeRegistry.altarRecipes) {
if (NEIServerUtils.areStacksSameTypeCraftingWithNBT(recipe.requiredItem, ingredient)) {
if (recipe != null && recipe.result != null) arecipes.add(new CachedAltarRecipe(recipe));
if (recipe.result != null) arecipes.add(new CachedAltarRecipe(recipe));
}
}
}
@@ -83,21 +84,18 @@ public class NEIAltarRecipeHandler extends TemplateRecipeHandler {
public void drawExtras(int id) {
CachedAltarRecipe recipe = (CachedAltarRecipe) arecipes.get(id);
Minecraft.getMinecraft().fontRenderer.drawString(
"\u00a77" + StatCollector.translateToLocal("bm.string.tier") + ": " + recipe.tier,
EnumChatFormatting.GRAY + StatCollector.translateToLocal("bm.string.tier") + ": " + recipe.tier,
78,
5,
0);
Minecraft.getMinecraft().fontRenderer.drawString("\u00a77" + "LP: " + recipe.lp_amount, 78, 15, 0);
Minecraft.getMinecraft().fontRenderer
.drawString(EnumChatFormatting.GRAY + "LP: " + recipe.lp_amount, 78, 15, 0);
}
@Override
public List<String> handleTooltip(GuiRecipe<?> gui, List<String> currenttip, int id) {
super.handleTooltip(gui, currenttip, id);
Point mouse = GuiDraw.getMousePosition();
Point root = gui.getRecipePosition(id);
int offsetX = gui.guiLeft + root.x;
int offsetY = gui.guiTop + root.y;
if (mouse.x >= 14 + offsetX && mouse.x <= 75 + offsetX && mouse.y >= 22 + offsetY && mouse.y <= 56 + offsetY) {
if (altarRect(gui, id).contains(GuiDraw.getMousePosition())) {
CachedAltarRecipe recipe = (CachedAltarRecipe) arecipes.get(id);
currenttip.add(StatCollector.translateToLocal("bm.string.consume") + ": " + recipe.consumption + "LP/t");
currenttip.add(StatCollector.translateToLocal("bm.string.drain") + ": " + recipe.drain + "LP/t");
@@ -105,6 +103,13 @@ public class NEIAltarRecipeHandler extends TemplateRecipeHandler {
return currenttip;
}
public Rectangle altarRect(GuiRecipe<?> gui, int id) {
Point root = gui.getRecipePosition(id);
int offsetX = gui.guiLeft + root.x;
int offsetY = gui.guiTop + root.y;
return new Rectangle(14 + offsetX, 22 + offsetY, 62, 34);
}
@Override
public String getOverlayIdentifier() {
return "altarrecipes";
@@ -117,7 +122,7 @@ public class NEIAltarRecipeHandler extends TemplateRecipeHandler {
@Override
public String getRecipeName() {
return " " + StatCollector.translateToLocal("tile.bloodAltar.name");
return StatCollector.translateToLocal("tile.bloodAltar.name");
}
@Override
@@ -1,14 +1,22 @@
package WayofTime.alchemicalWizardry.client.nei;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.List;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import WayofTime.alchemicalWizardry.api.bindingRegistry.BindingRecipe;
import WayofTime.alchemicalWizardry.api.bindingRegistry.BindingRegistry;
import WayofTime.alchemicalWizardry.client.nei.widgets.ReagentInfo;
import WayofTime.alchemicalWizardry.client.nei.widgets.RitualInfo;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.NEIServerUtils;
import codechicken.nei.PositionedStack;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.recipe.GuiRecipe;
import codechicken.nei.recipe.TemplateRecipeHandler;
/**
@@ -16,6 +24,9 @@ import codechicken.nei.recipe.TemplateRecipeHandler;
*/
public class NEIBindingRitualHandler extends TemplateRecipeHandler {
private static final RitualInfo ritualInfo = new RitualInfo(1f, "AW006Binding");
private static final ReagentInfo reagentInfo = new ReagentInfo(1f);
public class CachedBindingRecipe extends CachedRecipe {
PositionedStack input, output;
@@ -53,7 +64,7 @@ public class NEIBindingRitualHandler extends TemplateRecipeHandler {
public void loadCraftingRecipes(ItemStack result) {
for (BindingRecipe recipe : BindingRegistry.bindingRecipes) {
if (NEIServerUtils.areStacksSameTypeCraftingWithNBT(recipe.outputItem, result)) {
if (recipe != null && recipe.outputItem != null) {
if (recipe.outputItem != null) {
arecipes.add(new CachedBindingRecipe(recipe));
}
}
@@ -64,13 +75,41 @@ public class NEIBindingRitualHandler extends TemplateRecipeHandler {
public void loadUsageRecipes(ItemStack ingredient) {
for (BindingRecipe recipe : BindingRegistry.bindingRecipes) {
if (NEIServerUtils.areStacksSameTypeCraftingWithNBT(recipe.requiredItem, ingredient)) {
if (recipe != null && recipe.outputItem != null) {
if (recipe.outputItem != null) {
arecipes.add(new CachedBindingRecipe(recipe));
}
}
}
}
@Override
public void drawExtras(int recipe) {
super.drawExtras(recipe);
// Only shows these for the first result
if (recipe == 0) {
ritualInfo.onDraw(0, 0);
reagentInfo.onDraw(150, 0);
}
}
@Override
public List<String> handleTooltip(GuiRecipe<?> gui, List<String> currenttip, int recipeIndex) {
if (GuiContainerManager.shouldShowTooltip(gui) && currenttip.isEmpty()) {
CachedRecipe cRecipe = arecipes.get(recipeIndex);
Point mousePos = GuiDraw.getMousePosition();
if (recipeIndex == 0 && cRecipe instanceof NEIBindingRitualHandler.CachedBindingRecipe) {
if (ritualInfo.getRect(gui).contains(mousePos)) {
ritualInfo.onHover(currenttip);
} else if (reagentInfo.getRect(gui).contains(mousePos)) {
currenttip.add(StatCollector.translateToLocal("nei.recipe.reagent.none"));
}
}
}
return super.handleTooltip(gui, currenttip, recipeIndex);
}
@Override
public String getOverlayIdentifier() {
return "alchemicalwizardry.bindingritual";
@@ -2,7 +2,6 @@ package WayofTime.alchemicalWizardry.client.nei;
import static WayofTime.alchemicalWizardry.client.nei.NEIConfig.getBloodOrbs;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
@@ -33,21 +32,17 @@ public class NEIBloodOrbShapedHandler extends ShapedRecipeHandler {
public void setIngredients(int width, int height, Object[] items) {
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
if (items[y * width + x] == null) continue;
Object o = items[y * width + x];
if (o == null) continue;
if (o instanceof ItemStack) {
PositionedStack stack = new PositionedStack(
items[y * width + x],
25 + x * 18,
6 + y * 18,
false);
PositionedStack stack = new PositionedStack(o, 25 + x * 18, 6 + y * 18, false);
stack.setMaxSize(1);
ingredients.add(stack);
} else if (o instanceof Integer) {
} else if (o instanceof Integer i) {
ArrayList<ItemStack> orbs = new ArrayList<>();
for (Item item : getBloodOrbs()) {
if (((IBloodOrb) item).getOrbLevel() >= (Integer) o) {
if (((IBloodOrb) item).getOrbLevel() >= i) {
orbs.add(new ItemStack(item));
}
}
@@ -64,13 +59,12 @@ public class NEIBloodOrbShapedHandler extends ShapedRecipeHandler {
}
}
@SuppressWarnings("unchecked")
@Override
public void loadCraftingRecipes(String outputId, Object... results) {
if (outputId.equals("crafting") && getClass() == NEIBloodOrbShapedHandler.class) {
for (IRecipe irecipe : (List<IRecipe>) CraftingManager.getInstance().getRecipeList()) {
if (irecipe instanceof ShapedBloodOrbRecipe) {
CachedBloodOrbRecipe recipe = forgeShapedRecipe((ShapedBloodOrbRecipe) irecipe);
for (IRecipe irecipe : CraftingManager.getInstance().getRecipeList()) {
if (irecipe instanceof ShapedBloodOrbRecipe orbRecipe) {
CachedBloodOrbRecipe recipe = forgeShapedRecipe(orbRecipe);
if (recipe == null) continue;
recipe.computeVisuals();
@@ -82,12 +76,11 @@ public class NEIBloodOrbShapedHandler extends ShapedRecipeHandler {
}
}
@SuppressWarnings("unchecked")
@Override
public void loadCraftingRecipes(ItemStack result) {
for (IRecipe irecipe : (List<IRecipe>) CraftingManager.getInstance().getRecipeList()) {
if (irecipe instanceof ShapedBloodOrbRecipe) {
CachedBloodOrbRecipe recipe = forgeShapedRecipe((ShapedBloodOrbRecipe) irecipe);
for (IRecipe irecipe : CraftingManager.getInstance().getRecipeList()) {
if (irecipe instanceof ShapedBloodOrbRecipe orbRecipe) {
CachedBloodOrbRecipe recipe = forgeShapedRecipe(orbRecipe);
if (recipe == null || !NEIServerUtils.areStacksSameTypeCraftingWithNBT(recipe.result.item, result))
continue;
@@ -97,12 +90,11 @@ public class NEIBloodOrbShapedHandler extends ShapedRecipeHandler {
}
}
@SuppressWarnings("unchecked")
@Override
public void loadUsageRecipes(ItemStack ingredient) {
for (IRecipe irecipe : (List<IRecipe>) CraftingManager.getInstance().getRecipeList()) {
for (IRecipe irecipe : CraftingManager.getInstance().getRecipeList()) {
CachedShapedRecipe recipe = null;
if (irecipe instanceof ShapedBloodOrbRecipe) recipe = forgeShapedRecipe((ShapedBloodOrbRecipe) irecipe);
if (irecipe instanceof ShapedBloodOrbRecipe orbRecipe) recipe = forgeShapedRecipe(orbRecipe);
if (recipe == null || !recipe.contains(recipe.ingredients, ingredient.getItem())) continue;
@@ -134,11 +126,6 @@ public class NEIBloodOrbShapedHandler extends ShapedRecipeHandler {
return new CachedBloodOrbRecipe(width, height, items, recipe.getRecipeOutput());
}
@Override
public void loadTransferRects() {
transferRects.add(new RecipeTransferRect(new Rectangle(84, 23, 24, 18), "crafting"));
}
@Override
public String getRecipeName() {
return StatCollector.translateToLocal("bm.string.crafting.orb.shaped");
@@ -1,6 +1,5 @@
package WayofTime.alchemicalWizardry.client.nei;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
@@ -39,10 +38,10 @@ public class NEIBloodOrbShapelessHandler extends ShapelessRecipeHandler {
6 + stackorder[ingred][1] * 18);
stack.setMaxSize(1);
ingredients.add(stack);
} else if (o instanceof Integer) {
} else if (o instanceof Integer i) {
ArrayList<ItemStack> orbs = new ArrayList<>();
for (Item item : NEIConfig.getBloodOrbs()) {
if (((IBloodOrb) item).getOrbLevel() >= (Integer) o) {
if (((IBloodOrb) item).getOrbLevel() >= i) {
orbs.add(new ItemStack(item));
}
}
@@ -65,15 +64,13 @@ public class NEIBloodOrbShapelessHandler extends ShapelessRecipeHandler {
}
}
@SuppressWarnings("unchecked")
@Override
public void loadCraftingRecipes(String outputId, Object... results) {
if (outputId.equals("crafting") && getClass() == NEIBloodOrbShapelessHandler.class) {
List<IRecipe> allrecipes = CraftingManager.getInstance().getRecipeList();
for (IRecipe irecipe : allrecipes) {
List<IRecipe> allRecipes = CraftingManager.getInstance().getRecipeList();
for (IRecipe irecipe : allRecipes) {
CachedBloodOrbRecipe recipe = null;
if (irecipe instanceof ShapelessBloodOrbRecipe)
recipe = forgeShapelessRecipe((ShapelessBloodOrbRecipe) irecipe);
if (irecipe instanceof ShapelessBloodOrbRecipe orbRecipe) recipe = forgeShapelessRecipe(orbRecipe);
if (recipe == null) continue;
@@ -84,15 +81,13 @@ public class NEIBloodOrbShapelessHandler extends ShapelessRecipeHandler {
}
}
@SuppressWarnings("unchecked")
@Override
public void loadCraftingRecipes(ItemStack result) {
List<IRecipe> allrecipes = CraftingManager.getInstance().getRecipeList();
for (IRecipe irecipe : allrecipes) {
List<IRecipe> allRecipes = CraftingManager.getInstance().getRecipeList();
for (IRecipe irecipe : allRecipes) {
if (NEIServerUtils.areStacksSameTypeCraftingWithNBT(irecipe.getRecipeOutput(), result)) {
CachedBloodOrbRecipe recipe = null;
if (irecipe instanceof ShapelessBloodOrbRecipe)
recipe = forgeShapelessRecipe((ShapelessBloodOrbRecipe) irecipe);
if (irecipe instanceof ShapelessBloodOrbRecipe orbRecipe) recipe = forgeShapelessRecipe(orbRecipe);
if (recipe == null) continue;
@@ -101,14 +96,12 @@ public class NEIBloodOrbShapelessHandler extends ShapelessRecipeHandler {
}
}
@SuppressWarnings("unchecked")
@Override
public void loadUsageRecipes(ItemStack ingredient) {
List<IRecipe> allrecipes = CraftingManager.getInstance().getRecipeList();
for (IRecipe irecipe : allrecipes) {
List<IRecipe> allRecipes = CraftingManager.getInstance().getRecipeList();
for (IRecipe irecipe : allRecipes) {
CachedBloodOrbRecipe recipe = null;
if (irecipe instanceof ShapelessBloodOrbRecipe)
recipe = forgeShapelessRecipe((ShapelessBloodOrbRecipe) irecipe);
if (irecipe instanceof ShapelessBloodOrbRecipe orbRecipe) recipe = forgeShapelessRecipe(orbRecipe);
if (recipe == null) continue;
@@ -128,16 +121,6 @@ public class NEIBloodOrbShapelessHandler extends ShapelessRecipeHandler {
return new CachedBloodOrbRecipe(items, recipe.getRecipeOutput());
}
@Override
public void loadTransferRects() {
transferRects.add(new RecipeTransferRect(new Rectangle(84, 23, 24, 18), "crafting"));
}
@Override
public String getOverlayIdentifier() {
return "crafting";
}
@Override
public String getRecipeName() {
return StatCollector.translateToLocal("bm.string.crafting.orb.shapeless");
@@ -13,6 +13,7 @@ import codechicken.nei.api.IConfigureNEI;
public class NEIConfig implements IConfigureNEI {
private static ArrayList<Item> bloodOrbs = null;
private static ArrayList<Item> byCapacity = null;
public static ArrayList<Item> getBloodOrbs() {
if (bloodOrbs == null) {
@@ -44,6 +45,19 @@ public class NEIConfig implements IConfigureNEI {
return bloodOrbsTemp;
}
public static ArrayList<Item> getOrbsByCapacity() {
if (byCapacity == null) {
byCapacity = new ArrayList<>(getBloodOrbs());
byCapacity.sort((a, b) -> {
if (a instanceof IBloodOrb && b instanceof IBloodOrb) {
return Integer.compare(((IBloodOrb) a).getMaxEssence(), ((IBloodOrb) b).getMaxEssence());
}
return 0;
});
}
return byCapacity;
}
@Override
public void loadConfig() {
API.registerRecipeHandler(new NEIAlchemyRecipeHandler());
@@ -1,51 +1,70 @@
package WayofTime.alchemicalWizardry.client.nei;
import static WayofTime.alchemicalWizardry.client.ClientUtils.mc;
import java.awt.Point;
import java.awt.Rectangle;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.I18n;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import net.minecraftforge.oredict.OreDictionary;
import org.lwjgl.opengl.GL11;
import com.google.common.base.Joiner;
import WayofTime.alchemicalWizardry.AlchemicalWizardry;
import WayofTime.alchemicalWizardry.api.alchemy.energy.Reagent;
import WayofTime.alchemicalWizardry.api.spell.APISpellHelper;
import WayofTime.alchemicalWizardry.client.nei.widgets.CostInfo;
import WayofTime.alchemicalWizardry.client.nei.widgets.RadiusInfo;
import WayofTime.alchemicalWizardry.client.nei.widgets.ReagentInfo;
import WayofTime.alchemicalWizardry.client.nei.widgets.RitualInfo;
import WayofTime.alchemicalWizardry.common.summoning.meteor.Meteor;
import WayofTime.alchemicalWizardry.common.summoning.meteor.MeteorComponent;
import WayofTime.alchemicalWizardry.common.summoning.meteor.MeteorReagent;
import WayofTime.alchemicalWizardry.common.summoning.meteor.MeteorReagentRegistry;
import WayofTime.alchemicalWizardry.common.summoning.meteor.MeteorRegistry;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.NEIServerUtils;
import codechicken.nei.PositionedStack;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.recipe.GuiRecipe;
import codechicken.nei.recipe.TemplateRecipeHandler;
public class NEIMeteorRecipeHandler extends TemplateRecipeHandler {
private static final RitualInfo ritualInfo = new RitualInfo(0.75f, "AW019FallingTower");
private static final ReagentInfo reagentInfo = new ReagentInfo(0.75f);
public class CachedMeteorRecipe extends CachedRecipe {
private final List<PositionedStack> input = new ArrayList<>();
private final List<PositionedStack> outputs = new ArrayList<>();
private final int cost;
private final int radius;
private final CostInfo costInfo;
private final RadiusInfo radiusInfo;
private Point focus;
public float fillerChance;
public CachedMeteorRecipe(Meteor meteor, ItemStack focusStack) {
this.input.add(new PositionedStack(meteor.focusItem, 74, 4));
this.input.add(new PositionedStack(meteor.focusItem, 75, 4));
int row = 0;
int col = 0;
float totalComponentWeight = MeteorComponent.getTotalListWeight(meteor.ores);
float fillerChance = meteor.fillerChance;
fillerChance = meteor.fillerChance;
List<MeteorComponent> sortedComponents = new ArrayList<>(meteor.ores);
sortedComponents.sort(Comparator.comparingInt(c -> -c.getWeight()));
@@ -115,8 +134,8 @@ public class NEIMeteorRecipeHandler extends TemplateRecipeHandler {
}
}
this.radius = meteor.radius;
this.cost = meteor.cost;
this.costInfo = new CostInfo(1.0f, meteor.cost);
this.radiusInfo = new RadiusInfo(1.0f, meteor.radius);
}
private String getReagentStrings(MeteorComponent component) {
@@ -144,11 +163,11 @@ public class NEIMeteorRecipeHandler extends TemplateRecipeHandler {
}
public int getCost() {
return cost;
return costInfo.getCost();
}
public int getRadius() {
return radius;
return radiusInfo.getRadius();
}
}
@@ -238,12 +257,10 @@ public class NEIMeteorRecipeHandler extends TemplateRecipeHandler {
@Override
public void drawExtras(int recipe) {
CachedMeteorRecipe meteorRecipe = (CachedMeteorRecipe) this.arecipes.get(recipe);
int cost = meteorRecipe.getCost();
int radius = meteorRecipe.getRadius();
Minecraft.getMinecraft().fontRenderer
.drawString(I18n.format("nei.recipe.meteor.cost", String.format("%,d", cost)), 2, 168, 0x000000);
Minecraft.getMinecraft().fontRenderer
.drawString(I18n.format("nei.recipe.meteor.radius", radius), 2, 179, 0x000000);
meteorRecipe.costInfo.onDraw(30, 4);
meteorRecipe.radiusInfo.onDraw(120, 4);
ritualInfo.onDraw(0, 0);
reagentInfo.onDraw(153, 0);
}
@Override
@@ -264,9 +281,8 @@ public class NEIMeteorRecipeHandler extends TemplateRecipeHandler {
CachedMeteorRecipe meteorRecipe = (CachedMeteorRecipe) this.arecipes.get(recipe);
for (PositionedStack pStack : meteorRecipe.outputs) {
// if (!gui.isMouseOver(pStack, recipe)) continue; // put it back when NEI is properly patched
if (!(pStack instanceof TooltipStack)) break;
if (!(pStack instanceof TooltipStack tStack)) break;
TooltipStack tStack = (TooltipStack) pStack;
if (Arrays.stream(tStack.items).anyMatch(s -> NEIServerUtils.areStacksSameTypeCrafting(s, stack))) {
currenttip.addAll(tStack.getTooltips());
break;
@@ -275,6 +291,85 @@ public class NEIMeteorRecipeHandler extends TemplateRecipeHandler {
return currenttip;
}
@Override
public List<String> handleTooltip(GuiRecipe<?> gui, List<String> currenttip, int recipeIndex) {
if (GuiContainerManager.shouldShowTooltip(gui) && currenttip.isEmpty()) {
CachedRecipe cRecipe = arecipes.get(recipeIndex);
Point mousePos = GuiDraw.getMousePosition();
if (cRecipe instanceof CachedMeteorRecipe cachedRecipe) {
if (cachedRecipe.costInfo.getRect(gui).contains(mousePos)) {
currenttip.add(StatCollector.translateToLocal("nei.recipe.meteor.cost"));
if (APISpellHelper.getPlayerLPTag(mc.thePlayer) < cachedRecipe.getCost()) {
currenttip.add(
EnumChatFormatting.RED
+ StatCollector.translateToLocal("nei.recipe.meteor.tooExpensive"));
}
} else if (cachedRecipe.radiusInfo.getRect(gui).contains(mousePos)) {
currenttip.add(
StatCollector.translateToLocalFormatted(
"nei.recipe.meteor.diameter",
2 * cachedRecipe.radiusInfo.getRadius() + 1));
} else if (ritualInfo.getRect(gui).contains(mousePos)) {
ritualInfo.onHover(currenttip);
} else if (reagentInfo.getRect(gui).contains(mousePos)) {
reagentInfo.onHover(currenttip);
addMeteorReagentInfo(currenttip, cachedRecipe);
}
}
}
return super.handleTooltip(gui, currenttip, recipeIndex);
}
private void addMeteorReagentInfo(List<String> list, CachedMeteorRecipe cachedRecipe) {
DecimalFormat fmt = new DecimalFormat("###.##");
for (Map.Entry<Reagent, MeteorReagent> entry : MeteorReagentRegistry.reagents.entrySet()) {
ArrayList<String> l = new ArrayList<>();
Reagent r = entry.getKey();
MeteorReagent mr = entry.getValue();
if (mr.radiusChange != 0) {
l.add(
StatCollector.translateToLocalFormatted(
"nei.recipe.reagent.meteor.radius",
mr.radiusChange,
Meteor.getNewRadius(cachedRecipe.getRadius(), Collections.singletonList(r))));
}
if (cachedRecipe.fillerChance > 0) {
if (mr.fillerChanceChange != 0 || mr.rawFillerChanceChange != 0) {
l.add(
StatCollector.translateToLocalFormatted(
"nei.recipe.reagent.meteor.filler.chance",
fmt.format(
Meteor.getNewFillerChance(
cachedRecipe.fillerChance,
Collections.singletonList(r)))));
}
if (!mr.filler.isEmpty()) {
l.add(
StatCollector.translateToLocalFormatted(
"nei.recipe.reagent.meteor.filler.blocks",
reagentFillerBlockNames(mr)));
}
}
if (mr.disableExplosions) {
l.add(StatCollector.translateToLocal("nei.recipe.reagent.meteor.explosions"));
} else if (mr.invertExplosionBlockDamage && AlchemicalWizardry.doMeteorsDestroyBlocks) {
l.add(StatCollector.translateToLocal("nei.recipe.reagent.meteor.blockDamage.off"));
} else if (mr.invertExplosionBlockDamage) {
l.add(StatCollector.translateToLocal("nei.recipe.reagent.meteor.blockDamage.on"));
}
if (!l.isEmpty()) {
list.add(r.name + ":");
list.addAll(l);
}
}
}
@Override
public String getRecipeName() {
return I18n.format("nei.recipe.meteor.category");
@@ -292,4 +387,12 @@ public class NEIMeteorRecipeHandler extends TemplateRecipeHandler {
private int getEstimatedAmount(float chance, int radius) {
return (int) Math.ceil(4f / 3 * Math.PI * Math.pow(radius + 0.5, 3) * chance);
}
private String reagentFillerBlockNames(MeteorReagent mr) {
ArrayList<String> blockNames = new ArrayList<>();
for (MeteorComponent mc : mr.filler) {
blockNames.add(mc.getBlock().getDisplayName());
}
return Joiner.on(", ").join(blockNames);
}
}
@@ -0,0 +1,33 @@
package WayofTime.alchemicalWizardry.client.nei.widgets;
import static WayofTime.alchemicalWizardry.client.ClientUtils.mc;
import java.awt.Rectangle;
import net.minecraft.client.gui.FontRenderer;
import codechicken.nei.recipe.GuiRecipe;
public abstract class BMNEIWidget {
protected final float scale;
public int prevX, prevY;
protected BMNEIWidget(float scale) {
this.scale = scale;
}
public Rectangle getRect(GuiRecipe<?> gui) {
return new Rectangle(gui.guiLeft + prevX + 4, gui.guiTop + prevY + 14, (int) (18 * scale), (int) (18 * scale));
}
protected static void drawCenteredText(int x, int y, String text) {
FontRenderer fontRenderer = mc.fontRenderer;
int textWidth = fontRenderer.getStringWidth(text);
int textX = x + 9 - (textWidth / 2);
int textY = y + 18;
fontRenderer.drawString(text, textX, textY, 0x000000);
}
}
@@ -0,0 +1,72 @@
package WayofTime.alchemicalWizardry.client.nei.widgets;
import static WayofTime.alchemicalWizardry.client.ClientUtils.mc;
import java.util.ArrayList;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import org.lwjgl.opengl.GL11;
import WayofTime.alchemicalWizardry.api.items.interfaces.IBloodOrb;
import WayofTime.alchemicalWizardry.api.spell.APISpellHelper;
import WayofTime.alchemicalWizardry.client.nei.NEIConfig;
public class CostInfo extends BMNEIWidget {
private final int cost;
private final ItemStack orbStack;
private static final RenderItem renderItem = new RenderItem();
static {
renderItem.renderWithColor = false;
}
public CostInfo(float scale, int cost) {
super(scale);
this.cost = cost;
Item orb = null;
ArrayList<Item> orbList = NEIConfig.getOrbsByCapacity();
for (Item o : orbList) {
if (((IBloodOrb) o).getMaxEssence() >= cost) {
orb = o;
break;
}
}
if (orb == null) {
orb = orbList.get(orbList.size() - 1);
}
orbStack = new ItemStack(orb);
}
public int getCost() {
return cost;
}
public void onDraw(int x, int y) {
prevX = x;
prevY = y;
GL11.glPushMatrix();
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
if (cost > APISpellHelper.getPlayerLPTag(mc.thePlayer)) {
GL11.glColor4f(0.4f, 0.4f, 0.4f, 1.0f);
} else {
GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}
renderItem.renderItemAndEffectIntoGUI(mc.fontRenderer, mc.getTextureManager(), orbStack, x, y);
GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
GL11.glDisable(GL11.GL_BLEND);
GL11.glPopMatrix();
drawCenteredText(x, y, String.format("%,d", cost));
}
}
@@ -0,0 +1,36 @@
package WayofTime.alchemicalWizardry.client.nei.widgets;
import static WayofTime.alchemicalWizardry.client.ClientUtils.mc;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.item.ItemStack;
import net.minecraft.util.StatCollector;
import WayofTime.alchemicalWizardry.ModItems;
public class RadiusInfo extends BMNEIWidget {
private final int radius;
private static final RenderItem renderItem = new RenderItem();
// It's a circle with a dot in the center. Couldn't ask for a better item!
private static final ItemStack item = new ItemStack(ModItems.demonPlacer);
public RadiusInfo(float scale, int radius) {
super(scale);
this.radius = radius;
}
public int getRadius() {
return radius;
}
public void onDraw(int x, int y) {
prevX = x;
prevY = y;
renderItem.renderItemAndEffectIntoGUI(mc.fontRenderer, mc.getTextureManager(), item, x, y);
drawCenteredText(x, y, StatCollector.translateToLocalFormatted("nei.recipe.meteor.radius", radius));
}
}
@@ -0,0 +1,41 @@
package WayofTime.alchemicalWizardry.client.nei.widgets;
import static WayofTime.alchemicalWizardry.client.ClientUtils.mc;
import java.util.List;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.item.ItemStack;
import net.minecraft.util.StatCollector;
import org.lwjgl.opengl.GL11;
import WayofTime.alchemicalWizardry.ModBlocks;
public class ReagentInfo extends BMNEIWidget {
private static final RenderItem renderItem = new RenderItem();
private static final ItemStack item = new ItemStack(ModBlocks.blockReagentConduit);
public ReagentInfo(float scale) {
super(scale);
}
public void onDraw(int x, int y) {
prevX = x;
prevY = y;
GL11.glPushMatrix();
GL11.glTranslatef(x, y, 0);
GL11.glScalef(scale, scale, 1.0f);
renderItem.renderItemAndEffectIntoGUI(mc.fontRenderer, mc.getTextureManager(), item, 0, 0);
GL11.glPopMatrix();
}
/**
* Adds the text Reagent effects: to the tooltip list.
*/
public void onHover(List<String> list) {
list.add(StatCollector.translateToLocal("nei.recipe.reagent.text"));
}
}
@@ -0,0 +1,58 @@
package WayofTime.alchemicalWizardry.client.nei.widgets;
import static WayofTime.alchemicalWizardry.client.ClientUtils.mc;
import java.util.List;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.item.ItemStack;
import net.minecraft.util.StatCollector;
import org.lwjgl.opengl.GL11;
import WayofTime.alchemicalWizardry.ModItems;
import WayofTime.alchemicalWizardry.api.rituals.Rituals;
public class RitualInfo extends BMNEIWidget {
private final String id;
private final int cost;
private final ItemStack crystal;
private static final RenderItem renderItem = new RenderItem();
public RitualInfo(float scale, String id) {
super(scale);
this.id = id;
this.cost = Rituals.getCostForActivation(id);
Rituals r = Rituals.ritualMap.get(id);
// This is hardcoded unlike the orbs. I'm not aware of any addon that makes tier 3 rituals or crystals.
if (r == null || r.crystalLevel == 1) {
crystal = new ItemStack(ModItems.activationCrystal);
} else {
crystal = new ItemStack(ModItems.activationCrystal, 1, 1);
}
}
public int getCost() {
return cost;
}
public void onDraw(int x, int y) {
prevX = x;
prevY = y;
GL11.glPushMatrix();
GL11.glTranslatef(x, y, 0);
GL11.glScalef(scale, scale, 1.0f);
renderItem.renderItemAndEffectIntoGUI(mc.fontRenderer, mc.getTextureManager(), crystal, 0, 0);
GL11.glPopMatrix();
}
public void onHover(List<String> list) {
list.add(
StatCollector
.translateToLocalFormatted("nei.recipe.ritual.name", Rituals.getLocalizedNameOfRitual(id)));
list.add(StatCollector.translateToLocalFormatted("nei.recipe.ritual.cost", this.cost));
}
}
@@ -87,13 +87,13 @@ public class Meteor {
}
}
private int getNewRadius(int radius, List<Reagent> reagents) {
public static int getNewRadius(int radius, List<Reagent> reagents) {
radius += MeteorReagentRegistry.getLargestRadiusIncrease(reagents);
radius += MeteorReagentRegistry.getLargestRadiusDecrease(reagents);
return Math.max(radius, 1);
}
private float getNewFillerChance(float fillerChance, List<Reagent> reagents) {
public static float getNewFillerChance(float fillerChance, List<Reagent> reagents) {
// Don't add filler to meteors that have none
if (fillerChance <= 0) {
return 0;
@@ -120,7 +120,7 @@ public class Meteor {
* @return a new filler list. The original list is entirely replaced if any of the supplied reagents have a filler
* config.
*/
private List<MeteorComponent> getNewFillerList(List<MeteorComponent> fillerList, List<Reagent> reagents) {
public static List<MeteorComponent> getNewFillerList(List<MeteorComponent> fillerList, List<Reagent> reagents) {
List<MeteorComponent> reagentFillers = getFillerList(reagents);
reagentFillers = removeBlocksMissingRequiredReagents(reagentFillers, reagents);
if (!reagentFillers.isEmpty() && reagentFillers.get(0) != defaultMeteorBlock) {
@@ -129,7 +129,7 @@ public class Meteor {
return removeBlocksMissingRequiredReagents(fillerList, reagents);
}
private List<MeteorComponent> removeBlocksMissingRequiredReagents(List<MeteorComponent> blockList,
public static List<MeteorComponent> removeBlocksMissingRequiredReagents(List<MeteorComponent> blockList,
List<Reagent> reagents) {
ArrayList<MeteorComponent> newList = new ArrayList<>();
for (MeteorComponent component : blockList) {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -275,12 +275,24 @@ text.recipe.altar.tier=Tier: %s
text.recipe.altar.bloodRequired=LP: %s
text.recipe.shapedOrb=Shaped Orb Recipe
nei.recipe.meteor.category=Meteor Ritual
nei.recipe.meteor.cost=Cost: %s LP
nei.recipe.meteor.cost=LP cost to summon this meteor
nei.recipe.meteor.tooExpensive=Insufficient LP in Soul Network
nei.recipe.meteor.radius=Radius: %s
nei.recipe.meteor.diameter=Diameter: %d (2r + 1)
nei.recipe.meteor.chance=Chance: %s%%
nei.recipe.meteor.amount=Estimated amount: %s
nei.recipe.meteor.filler=§7Filler block
nei.recipe.meteor.reagent=§nRequired reagent§r: %s
nei.recipe.ritual.name=Ritual Name: %s
nei.recipe.ritual.cost=Activation Cost: %,d
nei.recipe.reagent.text=Reagent Effects:
nei.recipe.reagent.meteor.radius= %+d radius (%s)
nei.recipe.reagent.meteor.filler.chance= Changes chance for filler block to %f%%
nei.recipe.reagent.meteor.filler.blocks= Replaces filler with %s
nei.recipe.reagent.meteor.explosions= Entirely disables meteor explosions
nei.recipe.reagent.meteor.blockDamage.on= Enables meteor block damage
nei.recipe.reagent.meteor.blockDamage.off= Disables meteor block damage
nei.recipe.reagent.none=No reagents can be added to this ritual.
#Rituals
ritual.AW001Water.name=Ritual of the Full Spring