aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures
diff options
context:
space:
mode:
authorBuildTools <james.jenour@protonmail.com>2021-05-06 08:03:15 +0800
committerBuildTools <james.jenour@protonmail.com>2021-05-06 08:03:15 +0800
commit9aa7b49d224bfde055e12bc84f6908ba0a50090d (patch)
tree3485af44e6570b143867ec8867c123435244643e /src/main/java/io/github/moulberry/notenoughupdates/miscfeatures
parent03b9a8dbcc1ebd5f8c39e4733a741a4092ab0a1d (diff)
downloadnotenoughupdates-9aa7b49d224bfde055e12bc84f6908ba0a50090d.tar.gz
notenoughupdates-9aa7b49d224bfde055e12bc84f6908ba0a50090d.tar.bz2
notenoughupdates-9aa7b49d224bfde055e12bc84f6908ba0a50090d.zip
fine ironman
Diffstat (limited to 'src/main/java/io/github/moulberry/notenoughupdates/miscfeatures')
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BetterContainers.java47
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java34
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesTextures.java3
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java21
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java53
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCustomizeManager.java278
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/NPCRetexturing.java99
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java120
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SlotLocking.java357
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/StorageManager.java595
11 files changed, 1512 insertions, 97 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BetterContainers.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BetterContainers.java
index b2ab13e6..5af6e8bb 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BetterContainers.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BetterContainers.java
@@ -1,6 +1,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures;
import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.NEUEventListener;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.util.TexLoc;
import io.github.moulberry.notenoughupdates.util.Utils;
@@ -67,40 +68,26 @@ public class BetterContainers {
}
public static void bindHook(TextureManager textureManager, ResourceLocation location) {
- if(isChestOpen()) {
- Container container = ((GuiChest)Minecraft.getMinecraft().currentScreen).inventorySlots;
- if(container instanceof ContainerChest) {
- usingCached = true;
- IInventory lower = ((ContainerChest)container).getLowerChestInventory();
- int size = lower.getSizeInventory();
- for(int index=0; index<size; index++) {
- if(lower.getStackInSlot(index) != null) {
- for(int index2=0; index2<size; index2++) {
- itemCache.put(index2, lower.getStackInSlot(index2));
- }
- usingCached = false;
- break;
- }
- }
- }
-
- if((texture != null && loaded && lastClickedSlot != getClickedSlot()) ||
- lastUsingCached != getUsingCache() ||
- (texture == null && !loaded)) {
+ if(isChestOpen() && NEUEventListener.inventoryLoaded) {
+ if((texture != null && lastClickedSlot != getClickedSlot()) ||
+ lastUsingCached != getUsingCache() || !loaded) {
lastUsingCached = getUsingCache();
lastClickedSlot = getClickedSlot();
generateTex(location);
}
if(texture != null && loaded) {
- if(!usingCached) lastRenderMillis = System.currentTimeMillis();
lastRenderMillis = System.currentTimeMillis();
GlStateManager.color(1, 1, 1, 1);
-
textureManager.loadTexture(rl, texture);
textureManager.bindTexture(rl);
return;
}
+ } else if(System.currentTimeMillis() - lastRenderMillis < 200 && texture != null) {
+ GlStateManager.color(1, 1, 1, 1);
+ textureManager.loadTexture(rl, texture);
+ textureManager.bindTexture(rl);
+ return;
}
GlStateManager.enableBlend();
textureManager.bindTexture(location);
@@ -120,7 +107,7 @@ public class BetterContainers {
}
public static boolean isOverriding() {
- return isChestOpen() && ((loaded && texture != null)) && !isBlacklistedInventory();
+ return isChestOpen() && ((loaded && texture != null) || System.currentTimeMillis() - lastRenderMillis < 200) && !isBlacklistedInventory();
}
public static boolean isBlankStack(ItemStack stack) {
@@ -166,7 +153,7 @@ public class BetterContainers {
private static void generateTex(ResourceLocation location) {
if(!hasItem()) return;
- texture = null;
+
loaded = true;
Container container = ((GuiChest)Minecraft.getMinecraft().currentScreen).inventorySlots;
@@ -300,19 +287,25 @@ public class BetterContainers {
}
}
}
- texture = new DynamicTexture(bufferedImageNew);
+ if(texture != null) {
+ bufferedImageNew.getRGB(0, 0, bufferedImageNew.getWidth(), bufferedImageNew.getHeight(),
+ texture.getTextureData(), 0, bufferedImageNew.getWidth());
+ texture.updateDynamicTexture();
+ } else {
+ texture = new DynamicTexture(bufferedImageNew);
+ }
+ return;
} catch(Exception e) {
e.printStackTrace();
}
}
+ texture = null;
}
public static void reset() {
- texture = null;
loaded = false;
clickedSlot = -1;
clickedSlotMillis = 0;
- textColour = 4210752;
}
private static boolean isChestOpen() {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java
index b96fefef..e953ba60 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java
@@ -129,6 +129,7 @@ public class CrystalOverlay {
private static ExecutorService es = Executors.newSingleThreadExecutor();
public static void tick() {
+ if(!NotEnoughUpdates.INSTANCE.config.itemOverlays.enableCrystalOverlay) return;
if(Minecraft.getMinecraft().theWorld == null) return;
EntityPlayerSP p = Minecraft.getMinecraft().thePlayer;
@@ -136,23 +137,28 @@ public class CrystalOverlay {
long currentTime = System.currentTimeMillis();
- if(currentTime - displayMillis > 10*1000) {
- crystals.clear();
- displayMillis = -1;
- }
+ if(NotEnoughUpdates.INSTANCE.config.itemOverlays.alwaysShowCrystal) {
+ displayMillis = currentTime;
+ } else {
+ if(currentTime - displayMillis > 10*1000) {
+ crystals.clear();
+ displayMillis = -1;
+ }
- ItemStack held = p.getHeldItem();
- String internal = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(held);
- if(internal != null) {
- if(internal.endsWith("_CRYSTAL") && !internal.equals("POWER_CRYSTAL")) {
- displayMillis = System.currentTimeMillis();
+ ItemStack held = p.getHeldItem();
+ String internal = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(held);
+ if(internal != null) {
+ if(internal.endsWith("_CRYSTAL") && !internal.equals("POWER_CRYSTAL")) {
+ displayMillis = currentTime;
+ }
}
- }
- if(displayMillis < 0) {
- return;
+ if(displayMillis < 0) {
+ return;
+ }
}
+
Set<CrystalType> foundTypes = new HashSet<>();
for(Entity entity : Minecraft.getMinecraft().theWorld.loadedEntityList) {
if(entity instanceof EntityArmorStand) {
@@ -198,6 +204,8 @@ public class CrystalOverlay {
@SubscribeEvent
public void onTick(TickEvent.ClientTickEvent event) {
+ if(!NotEnoughUpdates.INSTANCE.config.itemOverlays.enableCrystalOverlay) return;
+
if(displayMillis < 0) {
return;
}
@@ -248,6 +256,8 @@ public class CrystalOverlay {
@SubscribeEvent
public void onRenderLast(RenderWorldLastEvent event) {
+ if(!NotEnoughUpdates.INSTANCE.config.itemOverlays.enableCrystalOverlay) return;
+
if(displayMillis < 0) {
return;
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java
index 20915503..e49644bf 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java
@@ -209,7 +209,7 @@ public class CustomItemEffects {
if(NotEnoughUpdates.INSTANCE.config.itemOverlays.highlightTargeted) {
List<Entity> entities = Minecraft.getMinecraft().theWorld.getEntitiesWithinAABBExcludingEntity(Minecraft.getMinecraft().thePlayer, bb);
for(Entity entity : entities) {
- if(entity instanceof EntityLivingBase && !(entity instanceof EntityArmorStand)) {
+ if(entity instanceof EntityLivingBase && !(entity instanceof EntityArmorStand) && !entity.isInvisible()) {
if(!bonemeragedEntities.contains(entity)) {
bonemeragedEntities.add((EntityLivingBase)entity);
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesTextures.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesTextures.java
index caa1441c..65b47ec0 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesTextures.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesTextures.java
@@ -50,6 +50,7 @@ public class DwarvenMinesTextures {
private static boolean error = false;
public static int retexture(BlockPos pos) {
+ if(!NotEnoughUpdates.INSTANCE.config.mining.dwarvenTextures) return 0;
if(error) return 0;
if(Minecraft.getMinecraft().theWorld == null) return 0;
@@ -220,6 +221,8 @@ public class DwarvenMinesTextures {
//Don't render clay - mesaPlateau_F
public static void tick() {
+ if(!NotEnoughUpdates.INSTANCE.config.mining.dwarvenTextures) return;
+
time = System.currentTimeMillis();
Set<ChunkCoordIntPair> remove = new HashSet<>();
for(Map.Entry<ChunkCoordIntPair, Long> entry : lastRetextureCheck.entrySet()) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java
index 26e87ae9..01d81460 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java
@@ -311,12 +311,19 @@ public class EnchantingSolvers {
if(chronomatronReplayIndex < chronomatronOrder.size()) {
String chronomatronCurrent = chronomatronOrder.get(chronomatronReplayIndex);
- if(true) {
+ /*if(!NotEnoughUpdates.INSTANCE.config.enchantingSolvers.preventMisclicks ||
+ chronomatronCurrent.equals(displayName)) {
chronomatronReplayIndex++;
Minecraft.getMinecraft().playerController.windowClick(windowId, slotId,
2, mode, Minecraft.getMinecraft().thePlayer);
millisLastClick = currentTime;
+ }*/
+ if(chronomatronCurrent.equals(displayName)) {
+ chronomatronReplayIndex++;
}
+ Minecraft.getMinecraft().playerController.windowClick(windowId, slotId,
+ 2, mode, Minecraft.getMinecraft().thePlayer);
+ millisLastClick = currentTime;
}
return true;
}
@@ -333,11 +340,21 @@ public class EnchantingSolvers {
return true;
}
long currentTime = System.currentTimeMillis();
- if(currentTime - millisLastClick > 150) {
+ /*if(currentTime - millisLastClick > 150 &&
+ (!NotEnoughUpdates.INSTANCE.config.enchantingSolvers.preventMisclicks ||
+ current.containerIndex == slotId)) {
ultrasequencerReplayIndex++;
Minecraft.getMinecraft().playerController.windowClick(windowId, slotId,
2, mode, Minecraft.getMinecraft().thePlayer);
millisLastClick = currentTime;
+ }*/
+ if(currentTime - millisLastClick > 150) {
+ if(current.containerIndex == slotId) {
+ ultrasequencerReplayIndex++;
+ }
+ Minecraft.getMinecraft().playerController.windowClick(windowId, slotId,
+ 2, mode, Minecraft.getMinecraft().thePlayer);
+ millisLastClick = currentTime;
}
return true;
} else {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java
index 4a572110..c36f619e 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java
@@ -12,20 +12,30 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import java.util.*;
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ItemCooldowns {
private static Map<ItemStack, Float> durabilityOverrideMap = new HashMap<>();
- private static long pickaxeUseCooldownMillisRemaining = -1;
+ public static long pickaxeUseCooldownMillisRemaining = -1;
private static long treecapitatorCooldownMillisRemaining = -1;
private static long lastMillis = 0;
+ public static long pickaxeCooldown = -1;
+
public static TreeMap<Long, BlockPos> blocksClicked = new TreeMap<>();
+ private static int tickCounter = 0;
+
@SubscribeEvent
public void tick(TickEvent.ClientTickEvent event) {
- if(event.phase == TickEvent.Phase.END) {
+ if(event.phase == TickEvent.Phase.END && NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) {
+ if(tickCounter++ >= 20*10) {
+ tickCounter = 0;
+ pickaxeCooldown = -1;
+ }
+
long currentTime = System.currentTimeMillis();
Long key;
@@ -48,8 +58,10 @@ public class ItemCooldowns {
}
@SubscribeEvent
- public void onWorldUnload(WorldEvent.Unload event) {
+ public void onWorldUnload(WorldEvent.Load event) {
blocksClicked.clear();
+ pickaxeCooldown = -1;
+ pickaxeUseCooldownMillisRemaining = 60*1000;
}
public static long getTreecapCooldownWithPet(){
@@ -95,15 +107,42 @@ public class ItemCooldowns {
private static Pattern PICKAXE_ABILITY_REGEX = Pattern.compile("\\u00a7r\\u00a7aYou used your " +
"\\u00a7r\\u00a7..+ \\u00a7r\\u00a7aPickaxe Ability!\\u00a7r");
+ private static Pattern PICKAXE_COOLDOWN_LORE_REGEX = Pattern.compile("\\u00a78Cooldown: \\u00a7a(\\d+)s");
+
+ private static void updatePickaxeCooldown() {
+ if(pickaxeCooldown == -1) {
+ for(ItemStack stack : Minecraft.getMinecraft().thePlayer.inventory.mainInventory) {
+ if(stack != null && stack.hasTagCompound()) {
+ String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(stack);
+ if(internalname != null && (internalname.endsWith("_PICKAXE") || internalname.contains("_DRILL_"))) {
+ for(String line : NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(stack.getTagCompound())) {
+ Matcher matcher = PICKAXE_COOLDOWN_LORE_REGEX.matcher(line);
+ if(matcher.find()) {
+ try {
+ pickaxeCooldown = Integer.parseInt(matcher.group(1));
+ return;
+ } catch(Exception ignored) {}
+ }
+ }
+ }
+ }
+ }
+ pickaxeCooldown = 120;
+ }
+ }
+
+
@SubscribeEvent
public void onChatMessage(ClientChatReceivedEvent event) {
if(PICKAXE_ABILITY_REGEX.matcher(event.message.getFormattedText()).matches()) {
- pickaxeUseCooldownMillisRemaining = 120*1000;
+ updatePickaxeCooldown();
+ pickaxeUseCooldownMillisRemaining = pickaxeCooldown*1000;
}
}
public static float getDurabilityOverride(ItemStack stack) {
if(Minecraft.getMinecraft().theWorld == null) return -1;
+ if(!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return -1;
if(durabilityOverrideMap.containsKey(stack)) {
return durabilityOverrideMap.get(stack);
@@ -116,15 +155,17 @@ public class ItemCooldowns {
}
if(internalname.endsWith("_PICKAXE") || internalname.contains("_DRILL_")) {
+ updatePickaxeCooldown();
+
if(pickaxeUseCooldownMillisRemaining < 0) {
durabilityOverrideMap.put(stack, -1f);
return -1;
}
- if(pickaxeUseCooldownMillisRemaining > 120*1000) {
+ if(pickaxeUseCooldownMillisRemaining > pickaxeCooldown*1000) {
return stack.getItemDamage();
}
- float dura = (float)(pickaxeUseCooldownMillisRemaining/(120.0*1000.0));
+ float dura = (float)(pickaxeUseCooldownMillisRemaining/(pickaxeCooldown*1000.0));
durabilityOverrideMap.put(stack, dura);
return dura;
} else if(internalname.equals("TREECAPITATOR_AXE") || internalname.equals("JUNGLE_AXE")) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCustomizeManager.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCustomizeManager.java
new file mode 100644
index 00000000..b07408a8
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCustomizeManager.java
@@ -0,0 +1,278 @@
+package io.github.moulberry.notenoughupdates.miscfeatures;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.ChromaColour;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.client.renderer.texture.DynamicTexture;
+import net.minecraft.client.renderer.texture.TextureMap;
+import net.minecraft.client.resources.IResourceManager;
+import net.minecraft.client.resources.IResourceManagerReloadListener;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.ResourceLocation;
+import org.lwjgl.opengl.GL11;
+import org.lwjgl.opengl.GL14;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.function.Consumer;
+
+public class ItemCustomizeManager {
+
+ public static class ReloadListener implements IResourceManagerReloadListener {
+ @Override
+ public void onResourceManagerReload(IResourceManager resourceManager) {
+ ItemCustomizeManager.loadedCustomGlintTexture = false;
+ }
+ }
+
+ public static boolean disableTextureBinding = false;
+
+ private static ResourceLocation CUSTOM_GLINT_TEXTURE = new ResourceLocation("notenoughupdates:dynamic/custom_glint_texture");
+ private static boolean loadedCustomGlintTexture = false;
+
+ public static final String DEFAULT_GLINT_COLOR = ChromaColour.special(0, 0xcc, 0x6419FF); //A050FF 0x8040cc 100,25,255 64,19
+
+ private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
+ private static ItemDataMap itemDataMap = new ItemDataMap();
+ private static HashMap<Integer, String> itemUuidCache = new HashMap<>();
+
+ public static class ItemDataMap {
+ public HashMap<String, ItemData> itemData = new HashMap<>();
+ }
+
+ public static class ItemData {
+ public String customName = null;
+ public boolean overrideEnchantGlint = false;
+ public boolean enchantGlintValue;
+
+ public String customGlintColour = DEFAULT_GLINT_COLOR;
+
+ public String customLeatherColour = null;
+ }
+
+ public static void putItemData(String uuid, ItemData data) {
+ itemDataMap.itemData.put(uuid, data);
+ }
+
+ public static void setCustomBlendFunc(String colour) {
+
+ /*int argb = ChromaColour.specialToChromaRGB(colour);
+ float[] hsv = Color.RGBtoHSB((argb >> 16) & 0xff, (argb >> 8) & 0xff, argb & 0xff, null);
+ GL14.glBlendColor(1, 1, 1, hsv[2]);*/
+
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_CONSTANT_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ //GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE, GL11.GL_ONE);
+ }
+
+ private static void renderEffect(Consumer<Integer> renderModelCallback, int color) {
+ GL11.glPushMatrix();
+
+ GlStateManager.enableBlend();
+ GlStateManager.depthMask(false);
+ GlStateManager.depthFunc(GL11.GL_EQUAL);
+ GlStateManager.disableLighting();
+ Minecraft.getMinecraft().getTextureManager().bindTexture(getCustomGlintTexture());
+ GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
+ GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
+
+ GlStateManager.matrixMode(5890);
+ GlStateManager.pushMatrix();
+ GlStateManager.scale(8.0F, 8.0F, 8.0F);
+ float f = (float)(Minecraft.getSystemTime() % 3000L) / 3000.0F / 8.0F;
+ GlStateManager.translate(f, 0.0F, 0.0F);
+ GlStateManager.rotate(-50.0F, 0.0F, 0.0F, 1.0F);
+ renderModelCallback.accept(color);
+ GlStateManager.matrixMode(5890);
+ GlStateManager.popMatrix();
+
+ GlStateManager.pushMatrix();
+ GlStateManager.scale(8.0F, 8.0F, 8.0F);
+ float f1 = (float)(Minecraft.getSystemTime() % 4873L) / 4873.0F / 8.0F;
+ GlStateManager.translate(-f1, 0.0F, 0.0F);
+ GlStateManager.rotate(10.0F, 0.0F, 0.0F, 1.0F);
+ renderModelCallback.accept(color);
+ GlStateManager.matrixMode(5890);
+ GlStateManager.popMatrix();
+
+ GlStateManager.matrixMode(5888);
+ GlStateManager.blendFunc(770, 771);
+ GlStateManager.enableLighting();
+ GlStateManager.depthFunc(515);
+ GlStateManager.depthMask(true);
+ Minecraft.getMinecraft().getTextureManager().bindTexture(TextureMap.locationBlocksTexture);
+
+ GL11.glPopMatrix();
+ }
+
+ private static void renderArmorGlint(Runnable renderModelCallback, float existed, int color) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(getCustomGlintTexture());
+ GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
+ GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
+ GlStateManager.enableBlend();
+ GlStateManager.depthFunc(514);
+ GlStateManager.depthMask(false);
+ float f1 = 0.5F;
+ GlStateManager.color(f1, f1, f1, 1.0F);
+
+ for (int i = 0; i < 2; ++i)
+ {
+ GlStateManager.disableLighting();
+
+ float red = ((color >> 16) & 0xFF) / 255f;
+ float green = ((color >> 8) & 0xFF) / 255f;
+ float blue = (color & 0xFF) / 255f;
+ float alpha = ((color >> 24) & 0xFF) / 255f;
+
+ GlStateManager.color(red, green, blue, alpha);
+ GlStateManager.matrixMode(5890);
+ GlStateManager.loadIdentity();
+ float f3 = 0.33333334F;
+ GlStateManager.scale(f3, f3, f3);
+ GlStateManager.rotate(30.0F - (float)i * 60.0F, 0.0F, 0.0F, 1.0F);
+ GlStateManager.translate(0.0F, existed * (0.001F + (float)i * 0.003F) * 20.0F, 0.0F);
+ GlStateManager.matrixMode(5888);
+ renderModelCallback.run();
+ }
+
+ GlStateManager.matrixMode(5890);
+ GlStateManager.loadIdentity();
+ GlStateManager.matrixMode(5888);
+ GlStateManager.enableLighting();
+ GlStateManager.depthMask(true);
+ GlStateManager.depthFunc(515);
+ GlStateManager.disableBlend();
+ }
+
+ public static void pre() {
+ GlStateManager.matrixMode(GL11.GL_MODELVIEW);
+ }
+
+ public static boolean render3DGlint(String customEnchantGlint, float existed, Runnable renderModelCallback) {
+ if(customEnchantGlint != null) {
+ int colour = ChromaColour.specialToChromaRGB(customEnchantGlint);
+
+ float[] hsv = Color.RGBtoHSB((colour >> 16) & 0xff, (colour >> 8) & 0xff, colour & 0xff, null);
+ GL14.glBlendColor(1, 1, 1, hsv[2]);
+
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_ZERO, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ZERO, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ int alphaValue = (int)((1-hsv[2]*hsv[2])*0xff) * ((colour >> 24) & 0xff) / 0xff;
+ renderArmorGlint(renderModelCallback, existed, alphaValue << 24);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE, GL11.GL_ONE);
+ renderArmorGlint(renderModelCallback, existed, colour);
+
+ return true;
+ }
+ return false;
+ }
+
+ public static boolean renderEffectHook(String customEnchantGlint, Consumer<Integer> renderModelCallback) {
+ if(customEnchantGlint != null) {
+ int colour = ChromaColour.specialToChromaRGB(customEnchantGlint);
+
+ float[] hsv = Color.RGBtoHSB((colour >> 16) & 0xff, (colour >> 8) & 0xff, colour & 0xff, null);
+ GL14.glBlendColor(1, 1, 1, hsv[2]);
+
+ GL11.glPushMatrix();
+
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_ZERO, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ZERO, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ int alphaValue = (int)((1-hsv[2]*hsv[2])*0xff) * ((colour >> 24) & 0xff) / 0xff;
+ renderEffect(renderModelCallback, alphaValue << 24);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE, GL11.GL_ONE);
+ renderEffect(renderModelCallback, colour);
+
+ GL11.glPopMatrix();
+
+ return true;
+ }
+ return false;
+ }
+
+ public static ResourceLocation getCustomGlintTexture() {
+ if(!loadedCustomGlintTexture) {
+ loadedCustomGlintTexture = true;
+
+ final ResourceLocation RES_ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png");
+
+ try {
+ BufferedImage originalGlint = ImageIO.read(Minecraft.getMinecraft().getResourceManager().getResource(RES_ITEM_GLINT).getInputStream());
+ BufferedImage newGlint = new BufferedImage(originalGlint.getWidth(), originalGlint.getHeight(), BufferedImage.TYPE_INT_ARGB);
+
+ for(int x=0; x<originalGlint.getWidth(); x++) {
+ for(int y=0; y<originalGlint.getHeight(); y++) {
+ int argb = originalGlint.getRGB(x, y);
+
+ int avgRGB = ((((argb >> 16) & 0xff) + ((argb >> 8) & 0xff) + (argb & 0xff))/3) & 0xff;
+
+ int newArgb = (avgRGB << 24) | (avgRGB << 16) | (avgRGB << 8) | avgRGB;
+
+ newGlint.setRGB(x, y, newArgb);
+ }
+ }
+
+ Minecraft.getMinecraft().getTextureManager().loadTexture(CUSTOM_GLINT_TEXTURE, new DynamicTexture(newGlint));
+ } catch(Exception e) {
+ e.printStackTrace();
+ CUSTOM_GLINT_TEXTURE = RES_ITEM_GLINT;
+ }
+ }
+ return CUSTOM_GLINT_TEXTURE;
+ }
+
+ private static String getUuidForItem(ItemStack stack) {
+ if(!stack.hasTagCompound()) return null;
+
+ int nbtHash = stack.getTagCompound().hashCode();
+
+ if(itemUuidCache.containsKey(nbtHash)) {
+ return itemUuidCache.get(nbtHash);
+ }
+
+ String uuid = NotEnoughUpdates.INSTANCE.manager.getUUIDForItem(stack);
+
+ itemUuidCache.put(nbtHash, uuid);
+ return uuid;
+ }
+
+ public static ItemData getDataForItem(ItemStack stack) {
+ if(stack == null) return null;
+
+ String uuid = getUuidForItem(stack);
+
+ if(uuid == null) {
+ return null;
+ } else {
+ return itemDataMap.itemData.get(uuid);
+ }
+ }
+
+ public static void tick() {
+ itemUuidCache.clear();
+ disableTextureBinding = false;
+ }
+
+ public static void loadCustomization(File file) {
+ try(BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) {
+ itemDataMap = GSON.fromJson(reader, ItemDataMap.class);
+ } catch(Exception ignored) {}
+ if(itemDataMap == null) {
+ itemDataMap = new ItemDataMap();
+ }
+ }
+
+ public static void saveCustomization(File file) {
+ try {
+ file.createNewFile();
+ try(BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) {
+ writer.write(GSON.toJson(itemDataMap));
+ }
+ } catch(Exception ignored) {}
+ }
+
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/NPCRetexturing.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/NPCRetexturing.java
new file mode 100644
index 00000000..465d3ea9
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/NPCRetexturing.java
@@ -0,0 +1,99 @@
+package io.github.moulberry.notenoughupdates.miscfeatures;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.AbstractClientPlayer;
+import net.minecraft.client.renderer.block.model.ModelBlock;
+import net.minecraft.client.resources.IResourceManager;
+import net.minecraft.client.resources.IResourceManagerReloadListener;
+import net.minecraft.client.resources.model.ModelRotation;
+import net.minecraft.util.ResourceLocation;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+
+public class NPCRetexturing implements IResourceManagerReloadListener {
+
+ private static final NPCRetexturing INSTANCE = new NPCRetexturing();
+
+ private static final ResourceLocation npcRetexturingJson = new ResourceLocation("notenoughupdates:npccustomtextures/config.json");
+
+ private final Gson gson = new GsonBuilder().create();
+
+ public static class Skin {
+ public ResourceLocation skinLocation;
+ public boolean skinny;
+
+ public Skin(ResourceLocation skinLocation, boolean skinny) {
+ this.skinLocation = skinLocation;
+ this.skinny = skinny;
+ }
+ }
+
+ private HashMap<AbstractClientPlayer, Skin> skinOverrideCache = new HashMap<>();
+ private HashMap<String, Skin> skinMap = new HashMap<>();
+
+ private boolean gettingSkin = false;
+
+ public Skin getSkin(AbstractClientPlayer player) {
+ if(gettingSkin) return null;
+
+ if(player.getUniqueID().version() == 4) return null;
+
+ if(skinOverrideCache.containsKey(player)) {
+ return skinOverrideCache.get(player);
+ }
+
+ gettingSkin = true;
+ ResourceLocation loc = player.getLocationSkin();
+ gettingSkin = false;
+
+ if(skinMap.containsKey(loc.getResourcePath())) {
+ Skin skin = skinMap.get(loc.getResourcePath());
+ skinOverrideCache.put(player, skin);
+ return skin;
+ }
+
+ skinOverrideCache.put(player, null);
+ return null;
+ }
+
+ public void tick() {
+ skinOverrideCache.clear();
+ }
+
+ @Override
+ public void onResourceManagerReload(IResourceManager resourceManager) {
+ skinMap.clear();
+
+