diff options
36 files changed, 2067 insertions, 189 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java index e0a487b6..59d71520 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java @@ -3,20 +3,20 @@ package io.github.moulberry.notenoughupdates; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import io.github.moulberry.notenoughupdates.auction.APIManager; import io.github.moulberry.notenoughupdates.auction.CustomAHGui; +import io.github.moulberry.notenoughupdates.core.config.Position; import io.github.moulberry.notenoughupdates.cosmetics.CapeManager; import io.github.moulberry.notenoughupdates.dungeons.DungeonBlocks; import io.github.moulberry.notenoughupdates.dungeons.DungeonWin; import io.github.moulberry.notenoughupdates.gamemodes.SBGamemodes; -import io.github.moulberry.notenoughupdates.miscfeatures.BetterContainers; -import io.github.moulberry.notenoughupdates.miscfeatures.FairySouls; -import io.github.moulberry.notenoughupdates.miscfeatures.StreamerMode; +import io.github.moulberry.notenoughupdates.miscfeatures.*; import io.github.moulberry.notenoughupdates.miscgui.*; import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; +import io.github.moulberry.notenoughupdates.textoverlays.TextOverlay; +import io.github.moulberry.notenoughupdates.textoverlays.TextOverlayStyle; +import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.RequestFocusListener; import io.github.moulberry.notenoughupdates.util.SBInfo; -import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; @@ -58,8 +58,8 @@ import java.awt.datatransfer.StringSelection; import java.io.File; import java.io.IOException; import java.text.NumberFormat; -import java.util.*; import java.util.List; +import java.util.*; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -71,7 +71,7 @@ import static io.github.moulberry.notenoughupdates.util.GuiTextures.dungeon_ches public class NEUEventListener { - private NotEnoughUpdates neu; + private final NotEnoughUpdates neu; private boolean hoverInv = false; private boolean focusInv = false; @@ -135,16 +135,26 @@ public class NEUEventListener { private long notificationDisplayMillis = 0; private List<String> notificationLines = null; - private static Pattern BAD_ITEM_REGEX = Pattern.compile("x[0-9]{1,2}$"); + private static final Pattern BAD_ITEM_REGEX = Pattern.compile("x[0-9]{1,2}$"); + + public static Class<? extends TextOverlay> dontRenderOverlay = null; + private final List<TextOverlay> textOverlays = new ArrayList<>(); + { + textOverlays.add(new CommissionOverlay(NotEnoughUpdates.INSTANCE.config.mining.overlayPosition, () -> { + int style = NotEnoughUpdates.INSTANCE.config.mining.overlayStyle; + if(style >= 0 && style < TextOverlayStyle.values().length) { + return TextOverlayStyle.values()[style]; + } + return TextOverlayStyle.BACKGROUND; + })); + } /** * 1)Will send the cached message from #sendChatMessage when at least 200ms has passed since the last message. * This is used in order to prevent the mod spamming messages. * 2)Adds unique items to the collection log */ - private HashMap<String, Long> newItemAddMap = new HashMap<>(); private long lastLongUpdate = 0; - private long lastVeryLongUpdate = 0; private long lastSkyblockScoreboard = 0; @SubscribeEvent public void onTick(TickEvent.ClientTickEvent event) { @@ -163,7 +173,12 @@ public class NEUEventListener { } DungeonWin.tick(); if(longUpdate) { + CrystalOverlay.tick(); + DwarvenMinesTextures.tick(); FairySouls.tick(); + for(TextOverlay overlay : textOverlays) { + overlay.tick(); + } if(TradeWindow.hypixelTradeWindowActive()) { for(int i=0; i<16; i++) { int x = i % 4; @@ -270,8 +285,8 @@ public class NEUEventListener { neu.manager.auctionManager.markNeedsUpdate(); } } - if(longUpdate && neu.hasSkyblockScoreboard()) { - /*if(neu.manager.getCurrentProfile() == null || neu.manager.getCurrentProfile().length() == 0) { + /*if(longUpdate && neu.hasSkyblockScoreboard()) { + if(neu.manager.getCurrentProfile() == null || neu.manager.getCurrentProfile().length() == 0) { ProfileViewer.Profile profile = NotEnoughUpdates.profileViewer.getProfile(Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", ""), callback->{}); if(profile != null) { @@ -324,11 +339,11 @@ public class NEUEventListener { } } newItemAddMap.keySet().retainAll(newItem); - }*/ - } + } + }*/ } - private void processUniqueStack(ItemStack stack, HashSet<String> newItem) { + /*private void processUniqueStack(ItemStack stack, HashSet<String> newItem) { if(stack != null && stack.hasTagCompound()) { String internalname = neu.manager.getInternalNameForItem(stack); if(internalname != null) { @@ -344,13 +359,13 @@ public class NEUEventListener { } else { newItemAddMap.put(internalname, System.currentTimeMillis()); } - }*/ + } } } - } + }*/ @SubscribeEvent(priority= EventPriority.HIGHEST) - public void onRenderEntitySpecials(RenderLivingEvent.Specials.Pre event) { + public void onRenderEntitySpecials(RenderLivingEvent.Specials.Pre<EntityPlayer> event) { if(Minecraft.getMinecraft().currentScreen instanceof GuiProfileViewer) { if(((GuiProfileViewer)Minecraft.getMinecraft().currentScreen).getEntityPlayer() == event.entity) { event.setCanceled(true); @@ -371,6 +386,13 @@ public class NEUEventListener { long timeRemaining = 15000 - (System.currentTimeMillis() - notificationDisplayMillis); if(event.type == RenderGameOverlayEvent.ElementType.ALL) { DungeonWin.render(event.partialTicks); + for(TextOverlay overlay : textOverlays) { + if(dontRenderOverlay != null && dontRenderOverlay.isAssignableFrom(overlay.getClass())) { + continue; + } + overlay.render(); + } + dontRenderOverlay = null; } if(event.type == RenderGameOverlayEvent.ElementType.ALL && timeRemaining > 0 && notificationLines != null && notificationLines.size() > 0) { @@ -393,7 +415,7 @@ public class NEUEventListener { Gui.drawRect(midX-width/2+2, sr.getScaledHeight()*3/4-height/2+2, midX+width/2-2, sr.getScaledHeight()*3/4+height/2-2, 0xFFC8C8C8); - Minecraft.getMinecraft().fontRendererObj.drawString((timeRemaining/1000)+"s", midX-width/2+3, + Minecraft.getMinecraft().fontRendererObj.drawString((timeRemaining/1000)+"s", midX-width/2f+3, topY+3, 0xFF000000, false); Utils.drawStringCentered(notificationLines.get(0), Minecraft.getMinecraft().fontRendererObj, @@ -542,7 +564,6 @@ public class NEUEventListener { } } }, 200, TimeUnit.MILLISECONDS); - return; } } } @@ -653,7 +674,6 @@ public class NEUEventListener { focusInv = true; } } catch(NullPointerException npe) { - npe.printStackTrace(); focusInv = !hoverPane; } } @@ -1609,7 +1629,7 @@ public class NEUEventListener { } } }*/ - if(!Keyboard.isKeyDown(Keyboard.KEY_LCONTROL)/* || /*!neu.config.hidden.dev*/) return; + if(!Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || !neu.config.hidden.dev) return; if(event.toolTip.size()>0&&event.toolTip.get(event.toolTip.size()-1).startsWith(EnumChatFormatting.DARK_GRAY + "NBT: ")) { event.toolTip.remove(event.toolTip.size()-1); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java index 6b787964..ad42fcfd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java @@ -99,7 +99,7 @@ public class NotEnoughUpdates { //Stolen from Biscut and used for detecting whether in skyblock private static final Set<String> SKYBLOCK_IN_ALL_LANGUAGES = Sets.newHashSet("SKYBLOCK","\u7A7A\u5C9B\u751F\u5B58", "\u7A7A\u5CF6\u751F\u5B58"); - private GuiScreen openGui = null; + public GuiScreen openGui = null; SimpleCommand collectionLogCommand = new SimpleCommand("neucl", new SimpleCommand.ProcessCommandRunnable() { public void processCommand(ICommandSender sender, String[] args) { @@ -903,6 +903,9 @@ public class NotEnoughUpdates { MinecraftForge.EVENT_BUS.register(new SunTzu()); MinecraftForge.EVENT_BUS.register(new MiningStuff()); MinecraftForge.EVENT_BUS.register(new FairySouls()); + MinecraftForge.EVENT_BUS.register(new CrystalOverlay()); + MinecraftForge.EVENT_BUS.register(new ItemCooldowns()); + MinecraftForge.EVENT_BUS.register(new DwarvenMinesTextures()); ClientCommandHandler.instance.registerCommand(collectionLogCommand); ClientCommandHandler.instance.registerCommand(cosmeticsCommand); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementBoolean.java b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementBoolean.java index 85f88a9f..bfd95612 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementBoolean.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementBoolean.java @@ -103,7 +103,7 @@ public class GuiElementBoolean extends GuiElement { if(Mouse.getEventButton() == 0) { if(Mouse.getEventButtonState()) { previewValue = !value; - } else { + } else if(previewValue == !value) { value = !value; toggleCallback.accept(value); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/Config.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/Config.java index 572c9af6..8be828bd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/Config.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/Config.java @@ -1,4 +1,8 @@ package io.github.moulberry.notenoughupdates.core.config; public class Config { + + public void executeRunnable(int runnableId) { + } + } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/Position.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/Position.java new file mode 100644 index 00000000..b30aa680 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/Position.java @@ -0,0 +1,114 @@ +package io.github.moulberry.notenoughupdates.core.config; + +import com.google.gson.annotations.Expose; +import net.minecraft.client.gui.ScaledResolution; + +public class Position { + + @Expose + private int x; + @Expose + private int y; + + public Position(int x, int y) { + this.x = x; + this.y = y; + } + + public Position clone() { + return new Position(x, y); + } + + public int getRawX() { + return x; + } + + public int getRawY() { + return y; + } + + public int getAbsX(ScaledResolution scaledResolution) { + if(x < 0) { + return scaledResolution.getScaledWidth() + x; + } else { + return x; + } + } + + public int getAbsY(ScaledResolution scaledResolution) { + if(y < 0) { + return scaledResolution.getScaledHeight() + y; + } else { + return y; + } + } + + public int moveX(int deltaX, int objWidth, ScaledResolution scaledResolution) { + int screenWidth = scaledResolution.getScaledWidth(); + boolean wasPositiveX = this.x >= 0; + this.x += deltaX; + + if(wasPositiveX) { + if(this.x < 2) { + deltaX += 2-this.x; + this.x = 2; + } + if(this.x > screenWidth-2) { + deltaX += screenWidth-2-this.x; + this.x = screenWidth-2; + } + } else { + if(this.x+objWidth > -2) { + deltaX += -2-objWidth-this.x; + this.x = -2-objWidth; + } + if(this.x+screenWidth < 2) { + deltaX += 2-screenWidth-this.x; + this.x = 2-screenWidth; + } + } + + if(this.x >= 0 && this.x+objWidth/2 > screenWidth/2) { + this.x -= screenWidth; + } + if(this.x < 0 && this.x+objWidth/2 <= -screenWidth/2) { + this.x += screenWidth; + } + return deltaX; + } + + public int moveY(int deltaY, int objHeight, ScaledResolution scaledResolution) { + int screenHeight = scaledResolution.getScaledHeight(); + boolean wasPositiveY = this.y >= 0; + this.y += deltaY; + + if(wasPositiveY) { + if(this.y < 2) { + deltaY += 2-this.y; + this.y = 2; + } + if(this.y > screenHeight-2) { + deltaY += screenHeight-2-this.y; + this.y = screenHeight-2; + } + } else { + if(this.y+objHeight > -2) { + deltaY += -2-objHeight-this.y; + this.y = -2-objHeight; + } + if(this.y+screenHeight < 2) { + deltaY += 2-screenHeight-this.y; + this.y = 2-screenHeight; + } + } + + if(this.y >= 0 && this.y-objHeight/2 > screenHeight/2) { + this.y -= screenHeight; + } + if(this.y < 0 && this.y-objHeight/2 <= -screenHeight/2) { + this.y += screenHeight; + } + return deltaY; + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorButton.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorButton.java new file mode 100644 index 00000000..5fe7fcb4 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorButton.java @@ -0,0 +1,15 @@ +package io.github.moulberry.notenoughupdates.core.config.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ConfigEditorButton { + + int runnableId(); + String buttonText() default ""; + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorButton.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorButton.java new file mode 100644 index 00000000..03a01ef2 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorButton.java @@ -0,0 +1,66 @@ +package io.github.moulberry.notenoughupdates.core.config.gui; + +import io.github.moulberry.notenoughupdates.core.ChromaColour; +import io.github.moulberry.notenoughupdates.core.config.Config; +import io.github.moulberry.notenoughupdates.core.config.struct.ConfigProcessor; +import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; +import io.github.moulberry.notenoughupdates.core.util.render.TextRenderUtils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraftforge.client.ClientCommandHandler; +import org.lwjgl.input.Mouse; + +import static io.github.moulberry.notenoughupdates.util.GuiTextures.button_tex; +import static io.github.moulberry.notenoughupdates.util.GuiTextures.button_white; + +public class GuiOptionEditorButton extends GuiOptionEditor { + + private int runnableId; + private String buttonText; + private Config config; + + public GuiOptionEditorButton(ConfigProcessor.ProcessedOption option, int runnableId, String buttonText, Config config) { + super(option); + this.runnableId = runnableId; + this.config = config; + + this.buttonText = buttonText; + if(this.buttonText != null && this.buttonText.isEmpty()) this.buttonText = null; + } + + @Override + public void render(int x, int y, int width) { + super.render(x, y, width); + + int height = getHeight(); + + GlStateManager.color(1, 1, 1, 1); + Minecraft.getMinecraft().getTextureManager().bindTexture(button_tex); + RenderUtils.drawTexturedRect(x+width/6-24, y+height-7-14, 48, 16); + + if(buttonText != null) { + TextRenderUtils.drawStringCenteredScaledMaxWidth(buttonText, Minecraft.getMinecraft().fontRendererObj, + x+width/6, y+height-7-6, + false, 44, 0xFF303030); + } + } + + @Override + public boolean mouseInput(int x, int y, int width, int mouseX, int mouseY) { + if(Mouse.getEventButtonState()) { + int height = getHeight(); + if(mouseX > x+width/6-24 && mouseX < x+width/6+24 && + mouseY > y+height-7-14 && mouseY < y+height-7+2) { + config.executeRunnable(runnableId); + return true; + } + } + + return false; + } + + @Override + public boolean keyboardInput() { + return false; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDropdown.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDropdown.java index 20779e01..a3e36919 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDropdown.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDropdown.java @@ -41,11 +41,11 @@ public class GuiOptionEditorDropdown extends GuiOptionEditor { selectedString = values[selected]; } - RenderUtils.drawFloatingRectWithAlpha(left, top, dropdownWidth, 14, 0xff, false); - TextRenderUtils.drawStringScaled("\u25BC", fr, left+dropdownWidth-10, y+height-7-15, false, 0xff404040, 2); + RenderUtils.drawFloatingRectDark(left, top, dropdownWidth, 14, false); + TextRenderUtils.drawStringScaled("\u25BC", fr, left+dropdownWidth-10, y+height-7-15, false, 0xffa0a0a0, 2); TextRenderUtils.drawStringScaledMaxWidth(selectedString, fr, left+3, top+3, false, - dropdownWidth-16, 0xff404040); + dropdownWidth-16, 0xffa0a0a0); //fr.drawString(selectedString, left+3, top+3, 0xff404040); } } @@ -67,8 +67,8 @@ public class GuiOptionEditorDropdown extends GuiOptionEditor { int dropdownHeight = 13 + 12*values.length; - int main = 0xffc0c0c0; - int blue = 0xff3365bd; + int main = 0xff202026; + int blue = 0xff2355ad; Gui.drawRect(left, top, left+1, top+dropdownHeight, blue); //Left Gui.drawRect(left+1, top, left+dropdownWidth, top+1, blue); //Top Gui.drawRect(left+dropdownWidth-1, top+1, left+dropdownWidth, top+dropdownHeight, blue); //Right @@ -82,15 +82,15 @@ public class GuiOptionEditorDropdown extends GuiOptionEditor { if(option.isEmpty()) { option = "<NONE>"; } - TextRenderUtils.drawStringScaledMaxWidth(option, fr, left+3, top+3+dropdownY, false, dropdownWidth-6, 0xff404040); + TextRenderUtils.drawStringScaledMaxWidth(option, fr, left+3, top+3+dropdownY, false, dropdownWidth-6, 0xffa0a0a0); dropdownY += 12; } - TextRenderUtils.drawStringScaled("\u25B2", fr, left+dropdownWidth-10, y+height-7-15, false, 0xff404040, 2); + TextRenderUtils.drawStringScaled("\u25B2", fr, left+dropdownWidth-10, y+height-7-15, false, 0xffa0a0a0, 2); TextRenderUtils.drawStringScaledMaxWidth(selectedString, fr, left+3, top+3, false, - dropdownWidth-16, 0xff404040); + dropdownWidth-16, 0xffa0a0a0); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiPositionEditor.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiPositionEditor.java new file mode 100644 index 00000000..117a97bd --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiPositionEditor.java @@ -0,0 +1,109 @@ +package io.github.moulberry.notenoughupdates.core.config.gui; + +import io.github.moulberry.notenoughupdates.core.config.Position; +import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.ScaledResolution; + +import java.io.IOException; + +public class GuiPositionEditor extends GuiScreen { + + private Position position; + private Position originalPosition; + private int elementWidth; + private int elementHeight; + private Runnable renderCallback; + private Runnable positionChangedCallback; + private Runnable closedCallback; + private boolean clicked = false; + private int grabbedX = 0; + private int grabbedY = 0; + + private int oldMouseX = 0; + private int oldMouseY = 0; + + public GuiPositionEditor(Position position, int elementWidth, int elementHeight, + Runnable renderCallback, + Runnable positionChangedCallback, + Runnable closedCallback) { + this.position = position; + this.originalPosition = position.clone(); + this.elementWidth = elementWidth; + this.elementHeight = elementHeight; + this.renderCallback = renderCallback; + this.positionChangedCallback = positionChangedCallback; + this.closedCallback = closedCallback; + } + + @Override + public void onGuiClosed() { + super.onGuiClosed(); + closedCallback.run(); + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + super.drawScreen(mouseX, mouseY, partialTicks); + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); + + this.width = scaledResolution.getScaledWidth(); + this.height = scaledResolution.getScaledHeight(); + + drawDefaultBackground(); + + if(clicked) { + grabbedX += position.moveX(mouseX - grabbedX, elementWidth, scaledResolution); + grabbedY += position.moveY(mouseY - grabbedY, elementHeight, scaledResolution); + } + + renderCallback.run(); + + int x = position.getAbsX(scaledResolution); + int y = position.getAbsY(scaledResolution); + + Gui.drawRect(x, y, x+elementWidth, y+elementHeight, 0x80404040); + } + + @Override + protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { + super.mouseClicked(mouseX, mouseY, mouseButton); + + if(mouseButton == 0) { + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); + + int x = position.getAbsX(scaledResolution); + int y = position.getAbsY(scaledResolution); + + if(mouseX >= x && mouseY >= y && + mouseX <= x+elementWidth && mouseY <= y+elementHeight) { + clicked = true; + grabbedX = mouseX; + grabbedY = mouseY; + } + } + } + + @Override + protected void mouseReleased(int mouseX, int mouseY, int state) { + super.mouseReleased(mouseX, mouseY, state); + clicked = false; + } + + @Override + protected void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) { + super.mouseClickMove(mouseX, mouseY, clickedMouseButton, timeSinceLastClick); + + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); + if(clicked) { + oldMouseX = mouseX; + oldMouseY = mouseY; + + grabbedX += position.moveX(mouseX - grabbedX, elementWidth, scaledResolution); + grabbedY += position.moveY(mouseY - grabbedY, elementHeight, scaledResolution); + positionChangedCallback.run(); + } + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java index f91b8410..513e32bb 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java @@ -101,6 +101,10 @@ public class ConfigProcessor { GuiOptionEditor editor = null; Class<?> optionType = optionField.getType(); + if(optionField.isAnnotationPresent(ConfigEditorButton.class)) { + ConfigEditorButton configEditorAnnotation = optionField.getAnnotation(ConfigEditorButton.class); + editor = new GuiOptionEditorButton(option, configEditorAnnotation.runnableId(), configEditorAnnotation.buttonText(), config); + } if(optionType.isAssignableFrom(boolean.class) && optionField.isAnnotationPresent(ConfigEditorBoolean.class)) { editor = new GuiOptionEditorBoolean(option); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java index 777a91cc..da93b059 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java @@ -44,8 +44,8 @@ public class CapeManager { private HashSet<String> availableCapes = new HashSet<>(); private String[] capes = new String[]{"patreon1", "patreon2", "fade", "contrib", "nullzee", - "gravy", "space", "mcworld", "lava", "packshq", "mbstaff", "thebakery", "negative", "void", "ironmoon", "krusty" }; - public Boolean[] specialCapes = new Boolean[]{ true, true, false, true, true, true, false, false, false, true, true, true, false, false, true, false }; + "gravy", "space", "mcworld", "lava", "packshq", "mbstaff", "thebakery", "negative", "void", "ironmoon", "krusty", "furf" }; + public Boolean[] specialCapes = new Boolean[]{ true, true, false, true, true, true, false, false, false, true, true, true, false, false, true, false, true }; public static CapeManager getInstance() { return INSTANCE; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java index d93b8bb0..3af37cdd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java @@ -734,15 +734,23 @@ public class NEUCape { newPosition.y = node.lastPosition.y + (node.position.y - node.lastPosition.y) * partialRenderTick; newPosition.z = node.lastPosition.z + (node.position.z - node.lastPosition.z) * partialRenderTick; - if(node.oldRenderPosition[node.oldRenderPosition.length-1] == null) { + int length = node.oldRenderPosition.length; + int fps = Minecraft.getDebugFPS(); + if(fps < 50) { + length = 2; + } else if(fps < 100) { + length = 2+(int)((fps-50)/50f*3); + } + + if(node.oldRenderPosition[length-1] == null) { node.renderPosition = newPosition; } else { Vector3f accum = new Vector3f(); - for(int i=0; i<node.oldRenderPosition.length; i++) { + for(int i=0; i<length; i++) { Vector3f.add(accum, node.oldRenderPosition[i], accum); Vector3f.add(accum, avgPositionFixed, accum); } - accum.scale(1/(float)node.oldRenderPosition.length); + accum.scale(1/(float)length); float blendFactor = 0.5f+0.3f*y/(float)(nodes.size()-1); //0.5/0.5 -> 0.8/0.2 //0-1 accum.scale(blendFactor); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java index 59cbfee5..be2b030a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java @@ -3,6 +3,7 @@ package io.github.moulberry.notenoughupdates.dungeons; import com.google.common.collect.Iterables; import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.core.BackgroundBlur; +import io.github.moulberry.notenoughupdates.core.config.Position; import io.github.moulberry.notenoughupdates.util.NEUResourceManager; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.util.SpecialColour; @@ -1465,8 +1466,10 @@ public class DungeonMap { } } - renderMap((int)(NotEnoughUpdates.INSTANCE.config.dungeonMap.dmCenterX/100*Minecraft.getMinecraft().displayWidth/2), - (int)(NotEnoughUpdates.INSTANCE.config.dungeonMap.dmCenterY/100*Minecraft.getMinecraft().displayHeight/2), + Position pos = NotEnoughUpdates.INSTANCE.config.dungeonMap.dmPosition; + + int size = 80 + Math.round(40*NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBorderSize); + renderMap(pos.getAbsX(event.resolution)+size/2, pos.getAbsY(event.resolution)+size/2, colourMap, decorations, roomSizeBlocks, actualPlayers, true, event.partialTicks); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java index 5677bf9e..cd951830 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java @@ -1,5 +1,8 @@ package io.github.moulberry.notenoughupdates.dungeons; +import io.github.moulberry.notenoughupdates.core.config.gui.GuiPositionEditor; +import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; +import io.github.moulberry.notenoughupdates.core.util.render.TextRenderUtils; import io.github.moulberry.notenoughupdates.options.NEUConfig; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.GuiElementColour; @@ -43,16 +46,6 @@ public class GuiDungeonMapEditor extends GuiScreen { private List<Button> buttons = new ArrayList<>(); - private static final int colourEditorBG = new Color(80, 80, 80, 220).getRGB(); - private static ResourceLocation colourPickerLocation = new ResourceLocation("notenoughupdates:dynamic/colourpicker"); - private static ResourceLocation colourPickerBarValueLocation = new ResourceLocation("notenoughupdates:dynamic/colourpickervalue"); - private static ResourceLocation colourPickerBarOpacityLocation = new ResourceLocation("notenoughupdates:dynamic/colourpickeropacity"); - - private GuiElementTextField hexField = new GuiElementTextField("", - GuiElementTextField.SCALE_TEXT | GuiElementTextField.FORCE_CAPS | GuiElementTextField.NO_SPACE); - - private GuiElementTextField xField = new GuiElementTextField("", GuiElementTextField.NUM_ONLY | GuiElementTextField.NO_SPACE); - private GuiElementTextField yField = new GuiElementTextField("", GuiElementTextField.NUM_ONLY | GuiElementTextField.NO_SPACE); private GuiElementTextField blurField = new GuiElementTextField("", GuiElementTextField.NUM_ONLY | GuiElementTextField.NO_SPACE); private GuiElementColour activeColourEditor = null; @@ -178,30 +171,6 @@ public class GuiDungeonMapEditor extends GuiScreen { //buttons.add(new Button(30, 52, 56, "XLarge", options.dmBorderSize)); { - double val = NotEnoughUpdates.INSTANCE.config.dungeonMap.dmCenterX; - String strVal; - if(val % 1 == 0) { - strVal = Integer.toString((int)val); - } else { - strVal = Double.toString(val); - strVal = strVal.replaceAll("(\\.\\d\\d\\d)(?:\\d)+", "$1"); - strVal = strVal.replaceAll("0+$", ""); - } - xField.setText(strVal); - } - { - double val = NotEnoughUpdates.INSTANCE.config.dungeonMap.dmCenterY; - String strVal; - if(val % 1 == 0) { - strVal = Integer.toString((int)val); - } else { - strVal = Double.toString(val); - strVal = strVal.replaceAll("(\\.\\d\\d\\d)(?:\\d)+", "$1"); - strVal = strVal.replaceAll("0+$", ""); - } - yField.setText(strVal); - } - { double val = NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBackgroundBlur; String strVal; if(val % 1 == 0) { @@ -329,10 +298,8 @@ public class GuiDungeonMapEditor extends GuiScreen { Utils.drawStringCenteredScaledMaxWidth("Chroma Type", Minecraft.getMinecraft().fontRendererObj, guiLeft+108+139, guiTop+175, false, 60, 0xFFB4B4B4); - Utils.drawStringCenteredScaledMaxWidth("X (%)", Minecraft.getMinecraft().fontRendererObj, - guiLeft+44, guiTop+209, false, 60, 0xFFB4B4B4); - Utils.drawStringCenteredScaledMaxWidth("Y (%)", Minecraft.getMinecraft().fontRendererObj, - guiLeft+108, guiTop+209, false, 60, 0xFFB4B4B4); + Utils.drawStringCenteredScaledMaxWidth("Edit Map Position", Minecraft.getMinecraft().fontRendererObj, + guiLeft+76, guiTop+209, false, 200, 0xFFB4B4B4); try { drawSlider(NEUConfig.DungeonMap.class.getDeclaredField("dmBorderSize"), guiLeft+76, guiTop+45); @@ -358,11 +325,13 @@ public class GuiDungeonMapEditor extends GuiScreen { buttons.get(28-6).text = options.dmChromaBorder ? "Scroll" : "Normal"; blurField.setSize(48, 16); - xField.setSize(48, 16); - yField.setSize(48, 16); blurField.render(guiLeft+20+139, guiTop+181); - xField.render(guiLeft+20, guiTop+215); - yField.render(guiLeft+84, guiTop+215); + + GlStateManager.color(1, 1, 1, 1); + Minecraft.getMinecraft().getTextureManager().bindTexture(button_tex); + RenderUtils.drawTexturedRect(guiLeft+52, guiTop+215, 48, 16); + TextRenderUtils.drawStringCenteredScaledMaxWidth("Edit", fontRendererObj, guiLeft+76, guiTop+223, + false, 48, 0xFF303030); Map<String, Vec4b> decorations = new HashMap<>(); Vec4b vec4b = new Vec4b((byte)3, (byte)(((50)-64)*2), (byte)(((40)-64)*2), (byte)((60)*16/360)); @@ -465,8 +434,6 @@ public class GuiDungeonMapEditor extends GuiScreen { mouseY >= guiTop+button.y && mouseY <= guiTop+button.y+16) { buttonClicked(mouseX, mouseY, button.id); - xField.otherComponentClick(); - yField.otherComponentClick(); blurField.otherComponentClick(); return; } @@ -493,27 +460,37 @@ public class GuiDungeonMapEditor extends GuiScreen { if(mouseY > guiTop+181 && mouseY < guiTop+181+16) { if(mouseX > guiLeft+20+139 && mouseX < guiLeft+20+139+48) { blurField.mouseClicked(mouseX, mouseY, mouseButton); - xField.otherComponentClick(); - yField.otherComponentClick(); return; } } else if(mouseY > guiTop+215 && mouseY < guiTop+215+16) { - if(mouseX > guiLeft+20 && mouseX < guiLeft+20+48) { - xField.mouseClicked(mouseX, mouseY, mouseButton); - yField.otherComponentClick(); - blurField.otherComponentClick(); - return; - } else if(mouseX > guiLeft+84 && mouseX < guiLeft+84+48) { - yField.mouseClicked(mouseX, mouseY, mouseButton); - xField.otherComponentClick(); - blurField.otherComponentClick(); + if(mouseX > guiLeft+52 && mouseX < guiLeft+100) { + int size = 80 + Math.round(40*NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBorderSize); + + Map<String, Vec4b> decorations = new HashMap<>(); + Vec4b vec4b = new Vec4b((byte)3, (byte)(((50)-64)*2), (byte)(((40)-64)*2), (byte)((60)*16/360)); + decorations.put(Minecraft.getMinecraft().thePlayer.getName(), vec4b); + + HashSet<String> players = new HashSet<>(); + players.add(Minecraft.getMinecraft().thePlayer.getName()); + GlStateManager.color(1, 1, 1, 1); + + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); + + Minecraft.getMinecraft().displayGuiScreen(new GuiPositionEditor( + NotEnoughUpdates.INSTANCE.config.dungeonMap.dmPosition, + size, size, () -> { + demoMap.renderMap(NotEnoughUpdates.INSTANCE.config.dungeonMap.dmPosition.getAbsX(scaledResolution)+size/2, + NotEnoughUpdates.INSTANCE.config.dungeonMap.dmPosition.getAbsY(scaledResolution)+size/2, + NotEnoughUpdates.INSTANCE.colourMap, decorations, 0, + players, false, 0); + }, () -> { + }, () -> NotEnoughUpdates.INSTANCE.openGui = new GuiDungeonMapEditor() + )); return; } } blurField.otherComponentClick(); - xField.otherComponentClick(); - yField.otherComponentClick(); } @Override @@ -540,25 +517,7 @@ public class GuiDungeonMapEditor extends GuiScreen { protected void keyTyped(char typedChar, int keyCode) throws IOException { super.keyTyped(typedChar, keyCode); - if(xField.getFocus()) { - xField.keyTyped(typedChar, keyCode); - - try { - xField.setCustomBorderColour(-1); - NotEnoughUpdates.INSTANCE.config.dungeonMap.dmCenterX = Float.parseFloat(xField.getText()); - } catch(Exception e) { - xField.setCustomBorderColour(Color.RED.getRGB()); - } - } else if(yField.getFocus()) { - yField.keyTyped(typedChar, keyCode); - - try { - yField.setCustomBorderColour(-1); - NotEnoughUpdates.INSTANCE.config.dungeonMap.dmCenterY = Float.parseFloat(yField.getText()); - } catch(Exception e) { - yField.setCustomBorderColour(Color.RED.getRGB()); - } - } else if(blurField.getFocus()) { + if(blurField.getFocus()) { blurField.keyTyped(typedChar, keyCode); try { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CommissionOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CommissionOverlay.java new file mode 100644 index 00000000..33cf9c4b --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CommissionOverlay.java @@ -0,0 +1,164 @@ +package io.github.moulberry.notenoughupdates.miscfeatures; + +import com.google.common.collect.ComparisonChain; +import com.google.common.collect.Ordering; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.config.Position; +import io.github.moulberry.notenoughupdates.core.util.StringUtils; +import io.github.moulberry.notenoughupdates.core.util.lerp.LerpUtils; +import io.github.moulberry.notenoughupdates.textoverlays.TextOverlay; +import io.github.moulberry.notenoughupdates.textoverlays.TextOverlayStyle; +import io.github.moulberry.notenoughupdates.util.SBInfo; +import net.minecraft.client.Minecraft; +import net.minecraft.client.network.NetworkPlayerInfo; +import net.minecraft.scoreboard.ScorePlayerTeam; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.world.WorldSettings; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import java.util.*; +import java.util.function.Supplier; + +import static net.minecraft.util.EnumChatFormatting.*; + +public class CommissionOverlay extends TextOverlay { + + public CommissionOverlay(Position position, Supplier<TextOverlayStyle> styleSupplier) { + super(position, styleSupplier); + } + + @Override + public void update() { + overlayStrings = new ArrayList<>(); + + if(SBInfo.getInstance().getLocation() == null) return; + if(!SBInfo.getInstance().getLocation().equals("mining_3")) return; + + Map<String, Float> commissionProgress = new LinkedHashMap<>(); + List<String> forgeStrings = new ArrayList<>(); + String mithrilPowder = null; + + boolean commissions = false; + boolean forges = false; + List<NetworkPlayerInfo> players = playerOrdering.sortedCopy(Minecraft.getMinecraft().thePlayer.sendQueue.getPlayerInfoMap()); + for(NetworkPlayerInfo info : players) { + String name = Minecraft.getMinecraft().ingameGUI.getTabList().getPlayerName(info); + if(name.contains("Mithril Powder")) { + mithrilPowder = trimIgnoreColour(name); + } + if(name.equals(RESET.toString()+BLUE+BOLD+"Forges"+RESET)) { + commissions = false; + forges = true; + continue; + } else if(name.equals(RESET.toString()+BLUE+BOLD+"Commissions"+RESET)) { + commissions = true; + forges = false; + continue; + } + String clean = StringUtils.cleanColour(name); + if(forges && clean.startsWith(" ")) { + if(name.contains("LOCKED")) continue; + if(NotEnoughUpdates.INSTANCE.config.mining.hideEmptyForges && name.contains("EMPTY")) continue; + forgeStrings.add(DARK_AQUA+"Forge "+trimIgnoreColour(name)); + } else if(commissions && clean.startsWith(" ")) { + String[] split = clean.trim().split(": "); + if(split.length == 2) { + if(split[1].endsWith("%")) { + try { + float progress = Float.parseFloat(split[1].replace("%", ""))/100; + progress = LerpUtils.clampZeroOne(progress); + commissionProgress.put(split[0], progress); + } catch(Exception ignored) {} + } else { + commissionProgress.put(split[0], 1.0f); + } + } + } else { + commissions = false; + forges = false; + } + } + + List<String> commissionsStrings = new ArrayList<>(); + for(Map.Entry<String, Float> entry : commissionProgress.entrySet()) { + if(entry.getValue() >= 1) { + commissionsStrings.add(DARK_AQUA+entry.getKey() + ": " + GREEN + "DONE"); + } else { + EnumChatFormatting col = RED; + if(entry.getValue() >= 0.75) { + col = GREEN; + } else if(entry.getValue() >= 0.5) { + col = YELLOW; + } else if(entry.getValue() >= 0.25) { + col = GOLD; + } + + String valS = String.valueOf(entry.getValue()*100); + int periodIndex = valS.indexOf('.');//1.3 + if(periodIndex > 0) { + valS = valS.substring(0, Math.min(valS.length(), periodIndex+2)); + } + if(valS.endsWith("0")) { + valS = valS.substring(0, Math.max(0, valS.length()-2)); + } + + commissionsStrings.add(DARK_AQUA+entry.getKey() + ": " + col+valS+"%"); + } + } + boolean hasAny = false; + if(NotEnoughUpdates.INSTANCE.config.mining.commissionsOverlay) { + overlayStrings.addAll(commissionsStrings); + hasAny = true; + } + if(NotEnoughUpdates.INSTANCE.config.mining.powderOverlay) { + if(mithrilPowder != null) { + if(hasAny) overlayStrings.add(null); + overlayStrings.add(DARK_AQUA+mithrilPowder); + hasAny = true; + } + } + if(NotEnoughUpdates.INSTANCE.config.mining.forgeOverlay) { + if(hasAny) overlayStrings.add(null); + overlayStrings.addAll(forgeStrings); + } + } + + private String trimIgnoreColour(String str) { + str = str.trim(); + boolean colourCodeLast = false; + for(int i=0; i<str.length(); i++) { + char c = str.charAt(i); + if(colourCodeLast) { + colourCodeLast = false; + continue; + } + if(c == '\u00A7') { + colourCodeLast = true; + } else if(c != ' ') { + return str.substring(i); + } + } + + return ""; + } + + private static final Ordering<NetworkPlayerInfo> playerOrdering = Ordering.from(new PlayerComparator()); + + @SideOnly(Side.CLIENT) + static class PlayerComparator implements Comparator<NetworkPlayerInfo> { + private PlayerComparator() { } + + public int compare(NetworkPlayerInfo o1, NetworkPlayerInfo o2) { + ScorePlayerTeam team1 = o1.getPlayerTeam(); + ScorePlayerTeam team2 = o2.getPlayerTeam(); + return ComparisonChain.start().compareTrueFirst( + o1.getGameType() != WorldSettings.GameType.SPECTATOR, + o2.getGameType() != WorldSettings.GameType.SPECTATOR) + .compare(team1 != null ? team1.getRegisteredName() : "", team2 != null ? team2.getRegisteredName() : "") + .compare(o1.getGameProfile().getName(), o2.getGameProfile().getName()).result(); + } + } + + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java new file mode 100644 index 00000000..2c1d1fab --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java @@ -0,0 +1,327 @@ +package io.github.moulberry.notenoughupdates.miscfeatures; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.util.ReverseWorldRenderer; +import io.github.moulberry.notenoughupdates.util.SpecialColour; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.client.renderer.vertex.VertexFormatElement; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityArmorStand; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.BlockPos; +import net.minecraftforge.client.event.RenderWorldLastEvent; +import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import org.lwjgl.opengl.GL11; + +import java.awt.*; +import java.nio.ByteBuffer; +import java.util.*; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class CrystalOverlay { + + private enum CrystalType { + FARMING_MINION(8, 0xDAA520), + MINING_MINION(40, 0x6e5a49), + FORAGING_MINION(12, 0x01a552), + DESERT(16, 0xfff178), + FISHING(15, 0x1972a6), + WART(5, 0x821530), + WHEAT(6, 0xff9d00); + + CrystalType(int radius, int rgb) { + this.radius = radius; + this.rgb = rgb; + } + + public Set<BlockPos> getCircleOffsets() { + if(circleOffsets != null) return circleOffsets; + circleOffsets = new HashSet<>(); + + for(int x=-radius; x<=radius; x++) { + for(int y=-radius; y<=radius; y++) { + for(int z=-radius; z<=radius; z++) { + float distSq = (x-0.5f)*(x-0.5f) + y*y + (z-0.5f)*(z-0.5f); + if(distSq > (radius-1)*(radius-1) && distSq < radius*radius) { + circleOffsets.add(new BlockPos(x, y, z)); + } + } + } + } + + return circleOffsets; + } + + public ReverseWorldRenderer getOverlayVBO() { + if(overlayVBO != null) return overlayVBO; + + EntityPlayerSP p = Minecraft.getMinecraft().thePlayer; + if(p == null) return null; + + if(!crystals.containsKey(this)) { + return null; + } + + //per vertex = 6 + //per size = 4 + //per block = 8 + //total per block = 196 + + ReverseWorldRenderer worldRenderer = new ReverseWorldRenderer(196*getCircleOffsets().size()); + worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR); + + String col = SpecialColour.special(0, 180, rgb); + for(BlockPos offset : getCircleOffsets()) { + BlockPos overlayPos = new BlockPos(offset.getX(), offset.getY(), offset.getZ()); + + AxisAlignedBB bb = new AxisAlignedBB( + overlayPos.getX(), + overlayPos.getY(), + overlayPos.getZ(), + overlayPos.getX()+1, + overlayPos.getY()+1, + overlayPos.getZ()+1 + ).expand(0.001f*(this.ordinal()+1), 0.001f*(this.ordinal()+1), 0.001f*(this.ordinal()+1)); + uploadFilledBoundingBox(bb, 1f, col, worldRenderer); + } + + overlayVBO = worldRenderer; + return overlayVBO; + } + + ReverseWorldRenderer overlayVBO = null; + Set<BlockPos> circleOffsets = null; + int updates = 0; + int rgb; + int radius; + } + + private static HashMap<String, CrystalType> skullId = new HashMap<>(); + static { + skullId.put("d9c3168a-8654-3dd8-b297-4d3b7e55b95a", CrystalType.FARMING_MINION); + skullId.put("949d100c-aa74-3b09-a642-af5529f808aa", CrystalType.MINING_MINION); + skullId.put("bd79a474-cf07-3f8c-b5a4-98657c33520a", CrystalType.FORAGING_MINION); + skullId.put("2e474ee3-5361-3218-84db-880eb1cface1", CrystalType.FISHING); + } + + public static long displayMillis = 0; + + public static HashMap<CrystalType, BlockPos> crystals = new HashMap<>(); + + private static ExecutorService es = Executors.newSingleThreadExecutor(); + + public static void tick() { + if(Minecraft.getMinecraft().theWorld == null) return; + + EntityPlayerSP p = Minecraft.getMinecraft().thePlayer; + if(p == null) return; + + long currentTime = System.currentTimeMillis(); + + if(currentTime - displayMillis > 10*1000) { + displayMillis = -1; + } + + ItemStack held = p.getHeldItem(); + String internal = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(held); + if(internal != null) { + if(internal.endsWith("_CRYSTAL")) { + displayMillis = System.currentTimeMillis(); + } + } + + if(displayMillis < 0) { + return; + } + + Set<CrystalType> foundTypes = new HashSet<>(); + for(Entity entity : Minecraft.getMinecraft().theWorld.loadedEntityList) { + if(entity instanceof EntityArmorStand) { + EntityArmorStand armorStand = (EntityArmorStand) entity; + + if(armorStand.isChild() && armorStand.getEquipmentInSlot(4) != null) { + ItemStack helmet = armorStand.getEquipmentInSlot(4); + + if(helmet.getItem() == Items.skull && helmet.hasTagCompound()) { + NBTTagCompound tag = helmet.getTagCompound(); + if(tag.hasKey("SkullOwner", 10)) { + NBTTagCompound skullOwner = tag.getCompoundTag("SkullOwner"); + if(skullOwner.hasKey("Id", 8)) { + String id = skullOwner.getString("Id"); + + if(skullId.containsKey(id)) { + CrystalType type = skullId.get(id); + foundTypes.add(type); + BlockPos pos = new BlockPos(armorStand.posX, armorStand.posY+0.5f, armorStand.posZ); + + if(crystals.containsKey(type)) { + BlockPos old = crystals.get(type); + if(old.equals(pos)) { + type.updates = 0; + } else { + if(++type.updates >= 3) { + type.updates = 0; + crystals.put(type, pos); + } + } + } else { + crystals.put(type, pos); + } + } + } + } + } + } + } + } + crystals.keySet().retainAll(foundTypes); + } + + @SubscribeEvent + public void onTick(TickEvent.ClientTickEvent event) { + EntityPlayerSP p = Minecraft.getMinecraft().thePlayer; + if(p == null) return; + + if(event.phase == TickEvent.Phase.START) { + for(CrystalType type : crystals.keySet()) { + ReverseWorldRenderer worldRenderer = type.getOverlayVBO(); + if(worldRenderer != null) { + BlockPos crystal = crystals.get(type); + + worldRenderer.setTranslation(0, 0,0 ); + worldRenderer.sortVertexData( + (float)p.posX-crystal.getX(), + (float)p.posY-crystal.getY(), + (float)p.posZ-crystal.getZ()); + } + } + } + } + + @SubscribeEvent + public void onRenderLast(RenderWorldLastEvent event) { + if(displayMillis < 0) { + return; + } + + Entity viewer = Minecraft.getMinecraft().getRenderViewEntity(); + double viewerX = viewer.lastTickPosX + (viewer.posX - viewer.lastTickPosX) * event.partialTicks; + double viewerY = viewer.lastTickPosY + (viewer.posY - viewer.lastTickPosY) * event.partialTicks; + double viewerZ = viewer.lastTickPosZ + (viewer.posZ - viewer.lastTickPosZ) * event.partialTicks; + + GlStateManager.enableBlend(); + GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); + GlStateManager.disableTexture2D(); + + GlStateManager.translate(-viewerX, -viewerY, -viewerZ); + + GL11.glPolygonOffset(5, 5); + for(CrystalType type : crystals.keySet()) { + ReverseWorldRenderer worldRenderer = type.getOverlayVBO(); + if(worldRenderer != null && worldRenderer.getVertexCount() > 0) { + BlockPos crystal = crystals.get(type); + GlStateManager.translate(crystal.getX(), crystal.getY(), crystal.getZ()); + + VertexFormat vertexformat = worldRenderer.getVertexFormat(); + int stride = vertexformat.getNextOffset(); + ByteBuffer bytebuffer = worldRenderer.getByteBuffer(); + List<VertexFormatElement> list = vertexformat.getElements(); + + for (int index = 0; index < list.size(); index++) { + VertexFormatElement vertexformatelement = list.get(index); + vertexformatelement.getUsage().preDraw(vertexformat, index, stride, bytebuffer); + } + + GL11.glDrawArrays(worldRenderer.getDrawMode(), 0, worldRenderer.getVertexCount()); + + for (int index = 0; index < list.size(); index++) { + VertexFormatElement vertexformatelement = list.get(index); + vertexformatelement.getUsage().postDraw(vertexformat, index, stride, bytebuffer); + } + + GlStateManager.translate(-crystal.getX(), -crystal.getY(), -crystal.getZ()); + } + } + GL11.glPolygonOffset(0, 0); + + GlStateManager.translate(viewerX, viewerY, viewerZ); + + GlStateManager.enableTexture2D(); + } + + @SubscribeEvent + public void onWorldUnload(WorldEvent.Unload event) { + crystals.clear(); + } + + public static void uploadFilledBoundingBox(AxisAlignedBB p_181561_0_, float alpha, String special, ReverseWorldRenderer worldrenderer) { + Color c = new Color(SpecialColour.specialToChromaRGB(special), true); + + //vertical + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.minZ) + .color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.minZ) + .color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.maxZ) + .color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.maxZ) + .color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.maxZ) + .color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.maxZ) + .color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.minZ) + .color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.minZ) + .color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha).endVertex(); + + //x + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.maxZ) + .color(c.getRed()/255f*0.8f, c.getGreen()/255f*0.8f, c.getBlue()/255f*0.8f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.maxZ) + .color(c.getRed()/255f*0.8f, c.getGreen()/255f*0.8f, c.getBlue()/255f*0.8f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.minZ) + .color(c.getRed()/255f*0.8f, c.getGreen()/255f*0.8f, c.getBlue()/255f*0.8f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.minZ) + .color(c.getRed()/255f*0.8f, c.getGreen()/255f*0.8f, c.getBlue()/255f*0.8f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.minZ) + .color(c.getRed()/255f*0.8f, c.getGreen()/255f*0.8f, c.getBlue()/255f*0.8f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.minZ) + .color(c.getRed()/255f*0.8f, c.getGreen()/255f*0.8f, c.getBlue()/255f*0.8f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.maxZ) + .color(c.getRed()/255f*0.8f, c.getGreen()/255f*0.8f, c.getBlue()/255f*0.8f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.maxZ) + .color(c.getRed()/255f*0.8f, c.getGreen()/255f*0.8f, c.getBlue()/255f*0.8f, c.getAlpha()/255f*alpha).endVertex(); + + //z + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.minZ) + .color(c.getRed()/255f*0.9f, c.getGreen()/255f*0.9f, c.getBlue()/255f*0.9f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.minZ) + .color(c.getRed()/255f*0.9f, c.getGreen()/255f*0.9f, c.getBlue()/255f*0.9f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.minZ) + .color(c.getRed()/255f*0.9f, c.getGreen()/255f*0.9f, c.getBlue()/255f*0.9f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.minZ) + .color(c.getRed()/255f*0.9f, c.getGreen()/255f*0.9f, c.getBlue()/255f*0.9f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.maxZ) + .color(c.getRed()/255f*0.9f, c.getGreen()/255f*0.9f, c.getBlue()/255f*0.9f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.maxZ) + .color(c.getRed()/255f*0.9f, c.getGreen()/255f*0.9f, c.getBlue()/255f*0.9f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.maxZ) + .color(c.getRed()/255f*0.9f, c.getGreen()/255f*0.9f, c.getBlue()/255f*0.9f, c.getAlpha()/255f*alpha).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.maxZ) + .color(c.getRed()/255f*0.9f, c.getGreen()/255f*0.9f, c.getBlue()/255f*0.9f, c.getAlpha()/255f*alpha).endVertex(); + } + +} 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 763da0b5..de0d7406 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java @@ -703,7 +703,6 @@ public class CustomItemEffects { public static void drawFilledBoundingBox(AxisAlignedBB p_181561_0_, float alpha, String special) { Color c = new Color(SpecialColour.specialToChromaRGB(special), true); - GlStateManager.color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha); GlStateManager.enableBlend(); GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); @@ -712,6 +711,8 @@ public class CustomItemEffects { Tessellator tessellator = Tessellator.getInstance(); WorldRenderer worldrenderer = tessellator.getWorldRenderer(); + GlStateManager.color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha); + //vertical worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION); worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.minZ).endVertex(); @@ -720,18 +721,21 @@ public class CustomItemEffects { worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.maxZ).endVertex(); tessellator.draw(); worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION); - worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.minZ).endVertex(); - worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.minZ).endVertex(); - worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.maxZ).endVertex(); worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.maxZ).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.maxZ).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.minZ).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.minZ).endVertex(); tessellator.draw(); - //x + + GlStateManager.color(c.getRed()/255f*0.8f, c.getGreen()/255f*0.8f, c.getBlue()/255f*0.8f, c.getAlpha()/255f*alpha); + + //x worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION); - worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.minZ).endVertex(); - worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.minZ).endVertex(); - worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.maxZ).endVertex(); worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.maxZ).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.maxZ).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.minZ).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.minZ).endVertex(); tessellator.draw(); worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION); worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.minZ).endVertex(); @@ -740,12 +744,14 @@ public class CustomItemEffects { worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.maxZ).endVertex(); tessellator.draw(); + + GlStateManager.color(c.getRed()/255f*0.9f, c.getGreen()/255f*0.9f, c.getBlue()/255f*0.9f, c.getAlpha()/255f*alpha); //z worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION); - worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.minZ).endVertex(); - worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.minZ).endVertex(); - worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.minZ).endVertex(); worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.minZ).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.minZ).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.minZ).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.minZ).endVertex(); tessellator.draw(); worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION); worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.maxZ).endVertex(); @@ -753,7 +759,6 @@ public class CustomItemEffects { worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.maxZ).endVertex(); worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.maxZ).endVertex(); tessellator.draw(); - } public static void drawFilledBoundingBoxSide(AxisAlignedBB p_181561_0_, EnumFacing facing, float alpha, String special) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesTextures.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesTextures.java new file mode 100644 index 00000000..4a639287 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesTextures.java @@ -0,0 +1,90 @@ +package io.github.moulberry.notenoughupdates.miscfeatures; + +import io.github.moulberry.notenoughupdates.util.SBInfo; +import net.minecraft.client.Minecraft; +import net.minecraft.world.ChunkCoordIntPair; +import net.minecraft.world.biome.BiomeGenBase; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class DwarvenMinesTextures { + + private static final byte biomeId1 = (byte)(BiomeGenBase.extremeHillsEdge.biomeID & 255); + private static final byte[] biomeMap1 = new byte[16*16]; + private static final byte biomeId2 = (byte)(BiomeGenBase.extremeHillsPlus.biomeID & 255); + private static final byte[] biomeMap2 = new byte[16*16]; + static { + Arrays.fill(biomeMap1, biomeId1); + Arrays.fill(biomeMap2, biomeId2); + } + + public static void tick() { + if(Minecraft.getMinecraft().theWorld == null) return; + + if(SBInfo.getInstance().getLocation() == null) return; + if(!SBInfo.getInstance().getLocation().equals("mining_3")) return; + + int playerX = (int)Minecraft.getMinecraft().thePlayer.posX; + int playerZ = (int)Minecraft.getMinecraft().thePlayer.posZ; + + for(int xC=-10; xC<=10; xC++) { + for(int zC=-10; zC<=10; zC++) { + ChunkCoordIntPair pair = new ChunkCoordIntPair(playerX/16+xC, playerZ/16+zC); + + if(!ignoredChunks.contains(pair)) { + Minecraft.getMinecraft().theWorld.getChunkFromChunkCoords(pair.chunkXPos, pair.chunkZPos).setBiomeArray(biomeMap1); + } else { + Minecraft.getMinecraft().theWorld.getChunkFromChunkCoords(pair.chunkXPos, pair.chunkZPos).setBiomeArray(biomeMap2); + } + } + } + } + + private static Set<ChunkCoordIntPair> ignoredChunks = new HashSet<>(); + static { + ignoredChunks.add(new ChunkCoordIntPair(9, 3)); + ignoredChunks.add(new ChunkCoordIntPair(6, 0)); + ignoredChunks.add(new ChunkCoordIntPair(0, -4)); + ignoredChunks.add(new ChunkCoordIntPair(1, -6)); + ignoredChunks.add(new ChunkCoordIntPair(-1, -3)); + ignoredChunks.add(new ChunkCoordIntPair(6, 5)); + ignoredChunks.add(new ChunkCoordIntPair(-1, -2)); + ignoredChunks.add(new ChunkCoordIntPair(8, -1)); + ignoredChunks.add(new ChunkCoordIntPair(8, -2)); + ignoredChunks.add(new ChunkCoordIntPair(6, 6)); + ignoredChunks.add(new ChunkCoordIntPair(6, 1)); + ignoredChunks.add(new ChunkCoordIntPair(9, -1)); + ignoredChunks.add(new ChunkCoordIntPair(9, 4)); + ignoredChunks.add(new ChunkCoordIntPair(8, 0)); + ignoredChunks.add(new ChunkCoordIntPair(9, 2)); + ignoredChunks.add(new ChunkCoordIntPair(1, -4)); + ignoredChunks.add(new ChunkCoordIntPair(0, -6)); + ignoredChunks.add(new ChunkCoordIntPair(-1, -5)); + ignoredChunks.add(new ChunkCoordIntPair(9, 1)); + ignoredChunks.add(new ChunkCoordIntPair(9, 6)); + ignoredChunks.add(new ChunkCoordIntPair(-1, -6)); + ignoredChunks.add(new ChunkCoordIntPair(6, 4)); + ignoredChunks.add(new ChunkCoordIntPair(1, -3)); + ignoredChunks.add(new ChunkCoordIntPair(9, 5)); + ignoredChunks.add(new ChunkCoordIntPair(1, -2)); + ignoredChunks.add(new ChunkCoordIntPair(0, -5)); + ignoredChunks.add(new ChunkCoordIntPair(7, -1)); + ignoredChunks.add(new ChunkCoordIntPair(7, -2)); + ignoredChunks.add(new ChunkCoordIntPair(9, 0)); + ignoredChunks.add(new ChunkCoordIntPair(6, 3)); + ignoredChunks.add(new ChunkCoordIntPair(0, -3)); + ignoredChunks.add(new ChunkCoordIntPair(-1, -4)); + ignoredChunks.add(new ChunkCoordIntPair(1, -5)); + ignoredChunks.add(new ChunkCoordIntPair(6, 2)); + ignoredChunks.add(new ChunkCoordIntPair(0, -2)); + ignoredChunks.add(new ChunkCoordIntPair(-2, -4)); + ignoredChunks.add(new ChunkCoordIntPair(-2, -5)); + ignoredChunks.add(new ChunkCoordIntPair(-2, -6)); + ignoredChunks.add(new ChunkCoordIntPair(-1, -7)); + ignoredChunks.add(new ChunkCoordIntPair(0, -7)); + ignoredChunks.add(new ChunkCoordIntPair(1, -7)); + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java index 70a701e0..b5a98704 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java @@ -106,6 +106,8 @@ public class FairySouls { } JsonObject fairySouls = Constants.FAIRYSOULS; + if(fairySouls == null) return; + String location = SBInfo.getInstance().getLocation(); if(location == null) { currentSoulList = null; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java new file mode 100644 index 00000000..8edd9217 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java @@ -0,0 +1,135 @@ +package io.github.moulberry.notenoughupdates.miscfeatures; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.item.ItemStack; +import net.minecraft.network.play.server.S23PacketBlockChange; +import net.minecraft.util.BlockPos; +import net.minecraftforge.client.event.ClientChatReceivedEvent; +import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; + +import java.util.*; +import java.util.regex.Pattern; + +public class ItemCooldowns { + + private static Map<ItemStack, Float> durabilityOverrideMap = new HashMap<>(); + private static long pickaxeUseCooldownMillisRemaining = -1; + private static long treecapitatorCooldownMillisRemaining = -1; + private static long lastMillis = 0; + + public static TreeMap<Long, BlockPos> blocksClicked = new TreeMap<>(); + + @SubscribeEvent + public void tick(TickEvent.ClientTickEvent event) { + if(event.phase == TickEvent.Phase.END) { + long currentTime = System.currentTimeMillis(); + + Long key; + while((key = blocksClicked.floorKey(currentTime - 1500)) != null) { + blocksClicked.remove(key); + } + + long millisDelta = currentTime - lastMillis; + lastMillis = currentTime; + + durabilityOverrideMap.clear(); + + if(pickaxeUseCooldownMillisRemaining >= 0) { + pickaxeUseCooldownMillisRemaining -= millisDelta; + } + if(treecapitatorCooldownMillisRemaining >= 0) { + treecapitatorCooldownMillisRemaining -= millisDelta; + } + } + } + + @SubscribeEvent + public void onWorldUnload(WorldEvent.Unload event) { + blocksClicked.clear(); + } + + public static void blockClicked(BlockPos pos) { + long currentTime = System.currentTimeMillis(); + blocksClicked.put(currentTime, pos); + } + + public static void processBlockChangePacket(S23PacketBlockChange packetIn) { + BlockPos pos = packetIn.getBlockPosition(); + + if(blocksClicked.containsValue(pos)) { + IBlockState oldState = Minecraft.getMinecraft().theWorld.getBlockState(pos); + if(oldState.getBlock() != packetIn.getBlockState().getBlock()) { + onBlockMined(pos); + } + } + } + + public static void onBlockMined(BlockPos pos) { + ItemStack held = Minecraft.getMinecraft().thePlayer.getHeldItem(); + String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(held); + if(internalname != null) { + if(treecapitatorCooldownMillisRemaining < 0 && + (internalname.equals("TREECAPITATOR_AXE") || internalname.equals("JUNGLE_AXE"))) { + treecapitatorCooldownMillisRemaining = 2*1000; + } + } + } + + private static Pattern PICKAXE_ABILITY_REGEX = Pattern.compile("\\u00a7r\\u00a7aYou used your " + + "\\u00a7r\\u00a7e.+ \\u00a7r\\u00a7aPickaxe Ability!\\u00a7r"); + + @SubscribeEvent + public void onChatMessage(ClientChatReceivedEvent event) { + if(PICKAXE_ABILITY_REGEX.matcher(event.message.getFormattedText()).matches()) { + pickaxeUseCooldownMillisRemaining = 120*1000; + } + } + + public static float getDurabilityOverride(ItemStack stack) { + if(Minecraft.getMinecraft().theWorld == null) return -1; + + if(durabilityOverrideMap.containsKey(stack)) { + return durabilityOverrideMap.get(stack); + } + + String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(stack); + if(internalname == null) { + durabilityOverrideMap.put(stack, -1f); + return -1; + } + + if(internalname.endsWith("_PICKAXE") || internalname.contains("_DRILL_")) { + if(pickaxeUseCooldownMillisRemaining < 0) { + durabilityOverrideMap.put(stack, -1f); + return -1; + } + + if(pickaxeUseCooldownMillisRemaining > 120*1000) { + return stack.getItemDamage(); + } + float dura = (float)(pickaxeUseCooldownMillisRemaining/(120.0*1000.0)); + durabilityOverrideMap.put(stack, dura); + return dura; + } else if(internalname.equals("TREECAPITATOR_AXE") || internalname.equals("JUNGLE_AXE")) { + if(treecapitatorCooldownMillisRemaining < 0) { + durabilityOverrideMap.put(stack, -1f); + return -1; + } + + if(treecapitatorCooldownMillisRemaining > 2*1000) { + return stack.getItemDamage(); + } + float dura = (float)(treecapitatorCooldownMillisRemaining/(2.0*1000.0)); + durabilityOverrideMap.put(stack, dura); + return dura; + } + + durabilityOverrideMap.put(stack, -1f); + return -1; + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/MiningStuff.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/MiningStuff.java index 97bb8377..d803778b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/MiningStuff.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/MiningStuff.java @@ -109,8 +109,6 @@ public class MiningStuff { overlayLoc.getY()+1-viewerY, overlayLoc.getZ()+1-viewerZ).expand(0.01f, 0.01f, 0.01f); - //181 / 195 / 135 - GlStateManager.disableCull(); CustomItemEffects.drawFilledBoundingBox(bb, 1f, SpecialColour.special(0, 100, 0xff0000)); GlStateManager.enableCull(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/AccessoryBagOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/AccessoryBagOverlay.java index 75c9415c..c7e01bfa 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/AccessoryBagOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/AccessoryBagOverlay.java @@ -4,7 +4,9 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.util.StringUtils; import io.github.moulberry.notenoughupdates.profileviewer.PlayerStats; +import io.github.moulberry.notenoughupdates.textoverlays.TextOverlayStyle; import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; @@ -172,7 +174,7 @@ public class AccessoryBagOverlay { int yIndex = 0; for(Map.Entry<Integer, Integer> entry : talismanCountRarity.descendingMap().entrySet()) { String rarityName = rarityArrC[entry.getKey()]; - renderAlignedString(rarityName, EnumChatFormatting.WHITE.toString()+entry.getValue(), x+5, y+20+11*yIndex, 70); + Utils.renderAlignedString(rarityName, EnumChatFormatting.WHITE.toString()+entry.getValue(), x+5, y+20+11*yIndex, 70); yIndex++; } } @@ -201,7 +203,7 @@ public class AccessoryBagOverlay { GlStateManager.color(1, 1, 1, 1); GlStateManager.enableBlend(); GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA); - renderAlignedString(statNamePretty, EnumChatFormatting.WHITE.toString()+val, x+5, y+20+11*yIndex, 70); + Utils.renderAlignedString(statNamePretty, EnumChatFormatting.WHITE.toString()+val, x+5, y+20+11*yIndex, 70); yIndex++; } @@ -230,7 +232,7 @@ public class AccessoryBagOverlay { GlStateManager.color(1, 1, 1, 1); GlStateManager.enableBlend(); GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA); - renderAlignedString(statNamePretty, EnumChatFormatting.WHITE.toString()+val, x+5, y+20+11*yIndex, 70); + Utils.renderAlignedString(statNamePretty, EnumChatFormatting.WHITE.toString()+val, x+5, y+20+11*yIndex, 70); yIndex++; } @@ -291,7 +293,8 @@ public class AccessoryBagOverlay { int yIndex = 0; for(ItemStack duplicate : duplicates) { - renderAlignedString(duplicate.getDisplayName(), "", x+5, y+20+11*yIndex, 70); + String s = duplicate.getDisplayName(); + Utils.renderShadowedString(s, x+40, y+20+11*yIndex, 70); if(duplicates.size() > 11) { if(++yIndex >= 10) break; } else { @@ -382,8 +385,27 @@ public class AccessoryBagOverlay { new Color(80, 80, 80).getRGB()); int yIndex = 0; + long currentTime = System.currentTimeMillis(); + int marqueeOffset = (int)(currentTime/500 % 100); for(ItemStack missingStack : missing) { - renderAlignedString(missingStack.getDisplayName(), "", x+5, y+20+11*yIndex, 70); + String s = missingStack.getDisplayName(); + + //int marueeOffset + //if(s.length()) { + + //} + + s = Minecraft.getMinecraft().fontRendererObj.trimStringToWidth(s, 70); + + String clean = StringUtils.cleanColourNotModifiers(s); + for(int xO = -1; xO <= 1; xO++) { + for(int yO = -1; yO <= 1; yO++) { + int col = 0xff202020; + //if(xO != 0 && yO != 0) col = 0xff252525; + Minecraft.getMinecraft().fontRendererObj.drawString(clean, x+5+xO, y+20+11*yIndex+yO, col, false); + } + } + Minecraft.getMinecraft().fontRendererObj.drawString(s, x+5, y+20+11*yIndex, 0xffffff, false); if(missing.size() > 11) { if(++yIndex >= 10) break; } else { @@ -674,7 +696,7 @@ public class AccessoryBagOverlay { } } - private static void renderAlignedString(String first, String second, float x, float y, int length) { + /*private static void renderAlignedString(String first, String second, float x, float y, int length) { FontRenderer fontRendererObj = Minecraft.getMinecraft().fontRendererObj; if(fontRendererObj.getStringWidth(first + " " + second) >= length) { @@ -718,7 +740,7 @@ public class AccessoryBagOverlay { GlStateManager.color(1, 1, 1, 1); fontRendererObj.drawString(second, x+length-secondLen, y, 4210752, false); } - } + }*/ private static final Pattern HEALTH_PATTERN_BONUS = Pattern.compile("^Health: (?:\\+|-)[0-9]+ HP \\([a-zA-Z]+ ((?:\\+|-)[0-9]+)"); private static final Pattern DEFENCE_PATTERN_BONUS = Pattern.compile("^Defense: (?:\\+|-)[0-9]+ \\([a-zA-Z]+ ((?:\\+|-)[0-9]+)"); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEffectRenderer.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEffectRenderer.java index 68e0a7c3..e4c51618 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEffectRenderer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEffectRenderer.java @@ -3,6 +3,7 @@ package io.github.moulberry.notenoughupdates.mixins; import io.github.moulberry.notenoughupdates.miscfeatures.CustomItemEffects; import net.minecraft.client.particle.EffectRenderer; import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.renderer.GlStateManager; import org.lwjgl.util.vector.Vector3f; import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; @@ -13,43 +14,19 @@ import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(EffectRenderer.class) public class MixinEffectRenderer { - /*@Redirect(method="renderParticles", at=@At( - value = "FIELD", - opcode = Opcodes.PUTSTATIC, - target = "Lnet/minecraft/client/particle/EntityFX;interpPosX:D") - ) - public void renderParticles_interpPosX(double interpPosX) { - Vector3f currentPosition = CustomItemEffects.INSTANCE.getCurrentPosition(); - if(currentPosition != null) { - EntityFX.interpPosX = currentPosition.x; - } - EntityFX.interpPosX = interpPosX; - } - @Redirect(method="renderParticles", at=@At( - value = "FIELD", - opcode = Opcodes.PUTSTATIC, - target = "Lnet/minecraft/client/particle/EntityFX;interpPosY:D") + value = "INVOKE", + target = "Lnet/minecraft/client/renderer/GlStateManager;enableBlend()V") ) - public void renderParticles_interpPosY(double interpPosY) { - Vector3f currentPosition = CustomItemEffects.INSTANCE.getCurrentPosition(); - if(currentPosition != null) { - EntityFX.interpPosY = currentPosition.y; - } - EntityFX.interpPosY = interpPosY; - } + public void renderParticles_enableBlend() { + GlStateManager.enableBlend(); - @Redirect(method="renderParticles", at=@At( - value = "FIELD", - opcode = Opcodes.PUTSTATIC, - target = "Lnet/minecraft/client/particle/EntityFX;interpPosZ:D") - ) - public void renderParticles_interpPosZ(double interpPosZ) { Vector3f currentPosition = CustomItemEffects.INSTANCE.getCurrentPosition(); if(currentPosition != null) { + EntityFX.interpPosX = currentPosition.x; + EntityFX.interpPosY = currentPosition.y; EntityFX.interpPosZ = currentPosition.z; } - EntityFX.interpPosZ = interpPosZ; - }*/ + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinItemStack.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinItemStack.java index 34f1ea62..c20ccebe 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinItemStack.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinItemStack.java @@ -1,6 +1,7 @@ package io.github.moulberry.notenoughupdates.mixins; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.miscfeatures.ItemCooldowns; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinNetHandlerPlayClient.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinNetHandlerPlayClient.java index c0e15d52..876338da 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinNetHandlerPlayClient.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinNetHandlerPlayClient.java @@ -3,6 +3,7 @@ package io.github.moulberry.notenoughupdates.mixins; import io.github.moulberry.notenoughupdates.miscfeatures.CustomItemEffects; import io.github.moulberry.notenoughupdates.miscfeatures.EnchantingSolvers; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.miscfeatures.ItemCooldowns; import io.github.moulberry.notenoughupdates.miscfeatures.MiningStuff; import net.minecraft.client.network.NetHandlerPlayClient; import net.minecraft.entity.player.EntityPlayer; @@ -36,6 +37,7 @@ public class MixinNetHandlerPlayClient { @Inject(method="handleBlockChange", at=@At("HEAD")) public void handleBlockChange(S23PacketBlockChange packetIn, CallbackInfo ci) { MiningStuff.processBlockChangePacket(packetIn); + ItemCooldowns.processBlockChangePacket(packetIn); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinPlayerControllerMP.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinPlayerControllerMP.java index 0e978640..b821113b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinPlayerControllerMP.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinPlayerControllerMP.java @@ -1,6 +1,7 @@ package io.github.moulberry.notenoughupdates.mixins; import io.github.moulberry.notenoughupdates.miscfeatures.FairySouls; +import io.github.moulberry.notenoughupdates.miscfeatures.ItemCooldowns; import io.github.moulberry.notenoughupdates.miscfeatures.MiningStuff; import net.minecraft.client.multiplayer.PlayerControllerMP; import net.minecraft.util.BlockPos; @@ -16,6 +17,7 @@ public class MixinPlayerControllerMP { @Inject(method="clickBlock", at=@At("HEAD")) public void clickBlock(BlockPos loc, EnumFacing face, CallbackInfoReturnable<Boolean> cir) { MiningStuff.blockClicked(loc); + ItemCooldowns.blockClicked(loc); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderItem.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderItem.java index 6e552e3c..afd44fd3 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderItem.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderItem.java @@ -1,24 +1,65 @@ package io.github.moulberry.notenoughupdates.mixins; +import io.github.moulberry.notenoughupdates.miscfeatures.ItemCooldowns; import io.github.moulberry.notenoughupdates.miscfeatures.ItemRarityHalo; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.renderer.entity.RenderItem; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.item.ItemStack; import org.lwjgl.input.Keyboard; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin({RenderItem.class}) public abstract class MixinRenderItem { - //Lnet/minecraft/client/renderer/entity/RenderItem;renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/resources/model/IBakedModel;)V - @Inject(method="Lnet/minecraft/client/renderer/entity/RenderItem;renderItemIntoGUI(Lnet/minecraft/item/ItemStack;II)V", - at=@At("HEAD"), cancellable = true) - public void renderItemIntoGUI(ItemStack stack, int x, int y, CallbackInfo ci) { - if(x == 0 && y == 0 || true) return; - ItemRarityHalo.onItemRender(stack, x, y); + private static void func_181565_a(WorldRenderer w, int x, int y, float width, int height, + int r, int g, int b, int a) { + w.begin(7, DefaultVertexFormats.POSITION_COLOR); + w.pos((x + 0), (y + 0), 0.0D) + .color(r, g, b, a).endVertex(); + w.pos((x + 0), (y + height), 0.0D) + .color(r, g, b, a).endVertex(); + w.pos((x + width), (y + height), 0.0D) + .color(r, g, b, a).endVertex(); + w.pos((x + width), (y + 0), 0.0D) + .color(r, g, b, a).endVertex(); + Tessellator.getInstance().draw(); + } + + @Inject(method="renderItemOverlayIntoGUI", at=@At("RETURN")) + public void renderItemOverlayIntoGUI(FontRenderer fr, ItemStack stack, int xPosition, int yPosition, String text, CallbackInfo ci) { + if(stack == null) return; + + float damageOverride = ItemCooldowns.getDurabilityOverride(stack); - if(Keyboard.isKeyDown(Keyboard.KEY_H)) ci.cancel(); + if(damageOverride >= 0) { + float barX = 13.0f - damageOverride * 13.0f; + int col = (int)Math.round(255.0D - damageOverride * 255.0D); + GlStateManager.disableLighting(); + GlStateManager.disableDepth(); + GlStateManager.disableTexture2D(); + GlStateManager.disableAlpha(); + GlStateManager.disableBlend(); + + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldrenderer = tessellator.getWorldRenderer(); + func_181565_a(worldrenderer, xPosition + 2, yPosition + 13, 13, 2, 0, 0, 0, 255); + func_181565_a(worldrenderer, xPosition + 2, yPosition + 13, 12, 1, (255 - col) / 4, 64, 0, 255); + func_181565_a(worldrenderer, xPosition + 2, yPosition + 13, barX, 1, 255 - col, col, 0, 255); + + GlStateManager.enableAlpha(); + GlStateManager.enableTexture2D(); + GlStateManager.enableLighting(); + GlStateManager.enableDepth(); + } } + } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java index c2582508..163a35f0 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java @@ -1,14 +1,66 @@ package io.github.moulberry.notenoughupdates.options; import com.google.common.collect.Lists; +import com.google.gson.JsonObject; import com.google.gson.annotations.Expose; +import io.github.moulberry.notenoughupdates.NEUEventListener; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.GuiScreenElementWrapper; import io.github.moulberry.notenoughupdates.core.config.Config; +import io.github.moulberry.notenoughupdates.core.config.Position; import io.github.moulberry.notenoughupdates.core.config.annotations.*; +import io.github.moulberry.notenoughupdates.core.config.gui.GuiPositionEditor; +import io.github.moulberry.notenoughupdates.dungeons.GuiDungeonMapEditor; +import io.github.moulberry.notenoughupdates.miscfeatures.CommissionOverlay; +import io.github.moulberry.notenoughupdates.textoverlays.TextOverlay; +import io.github.moulberry.notenoughupdates.textoverlays.TextOverlayStyle; +import net.minecraft.client.Minecraft; +import net.minecraftforge.client.ClientCommandHandler; import java.util.ArrayList; +import java.util.regex.Pattern; public class NEUConfig extends Config { + @Override + public void executeRunnable(int runnableId) { + switch (runnableId) { + case 0: + ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/neumap"); + return; + case 1: + final CommissionOverlay overlay = new CommissionOverlay(NotEnoughUpdates.INSTANCE.config.mining.overlayPosition, () -> { + int style = NotEnoughUpdates.INSTANCE.config.mining.overlayStyle; + if(style >= 0 && style < TextOverlayStyle.values().length) { + return TextOverlayStyle.values()[style]; + } + return TextOverlayStyle.BACKGROUND; + }); + overlay.tick(); + JsonObject test = null; + if(overlay.overlayWidth <= 0 || overlay.overlayHeight <= 0) { + Minecraft.getMinecraft().displayGuiScreen(new GuiPositionEditor( + NotEnoughUpdates.INSTANCE.config.mining.overlayPosition, + 300, 100, () -> { + }, () -> { + }, () -> NotEnoughUpdates.INSTANCE.openGui = new GuiScreenElementWrapper( + new NEUConfigEditor(NotEnoughUpdates.INSTANCE.config)) + )); + } else { + Minecraft.getMinecraft().displayGuiScreen(new GuiPositionEditor( + NotEnoughUpdates.INSTANCE.config.mining.overlayPosition, + overlay.overlayWidth+10, overlay.overlayHeight+10, () -> { + overlay.render(); + NEUEventListener.dontRenderOverlay = CommissionOverlay.class; + }, () -> { + }, () -> NotEnoughUpdates.INSTANCE.openGui = new GuiScreenElementWrapper( + new NEUConfigEditor(NotEnoughUpdates.INSTANCE.config)) + )); + } + return; + } + } + @Expose @Category( name = "Misc", @@ -83,6 +135,13 @@ public class NEUConfig extends Config { @Expose @Category( + name = "Mining", + desc = "Mining" + ) + public Mining mining = new Mining(); + + @Expose + @Category( name = "NEU Auction House", desc = "NEU Auction House" ) @@ -123,6 +182,14 @@ public class NEUConfig extends Config { ) public BuilderWand builderWand = new BuilderWand(); + + @Expose + @Category( + name = "Dungeon Map", + desc = "Dungeon Map" + ) + public DungeonMapOpen dungeonMapOpen = new DungeonMapOpen(); + @Expose @Category( name = "Dungeon Block Overlay", @@ -671,6 +738,79 @@ public class NEUConfig extends Config { public int supPower = 11; } + public static class Mining { + @Expose + @ConfigOption( + name = "Puzzler Solver", + desc = "Show the correct block to mine for the puzzler puzzle in Dwarven Mines" + ) + @ConfigEditorBoolean + public boolean puzzlerSolver = true; + + @Expose + @ConfigOption( + name = "Titanium Alert", + desc = "Show an alert whenever titanium appears nearby" + ) + @ConfigEditorBoolean + public boolean titaniumAlert = true; + + @Expose + @ConfigOption( + name = "Overlay Position", + desc = "Change the position of the Dwarven Mines information overlay (commisions, powder & forge statuses)" + ) + @ConfigEditorButton( + runnableId = 1, + buttonText = "Edit" + ) + public Position overlayPosition = new Position(10, 100); + + @Expose + @ConfigOption( + name = "Overlay Style", + desc = "Change the style of the Dwarven Mines information overlay" + ) + @ConfigEditorDropdown( + values = {"Background", "No Shadow", "Shadow", "Full Shadow"} + ) + public int overlayStyle = 0; + + @Expose + @ConfigOption( + name = "Commissions Overlay", + desc = "Show current commissions on the screen while in Dwarven Mines" + ) + @ConfigEditorBoolean + public boolean commissionsOverlay = true; + + @Expose + @ConfigOption( + name = "Powder Overlay", + desc = "Show powder count on the screen while in Dwarven Mines" + ) + @ConfigEditorBoolean + public boolean powderOverlay = true; + + @Expose + @ConfigOption( + name = "Forges Overlay", + desc = "Show forge statuses on the screen while in Dwarven Mines" + ) + @ConfigEditorBoolean + public boolean forgeOverlay = true; + + @Expose + @ConfigOption( + name = "Hide Empty Forges", + desc = "Hide empty forges in the information overlay" + ) + @ConfigEditorBoolean + public boolean hideEmptyForges = true; + + + } + public static class NeuAuctionHouse { @Expose @ConfigOption( @@ -855,6 +995,20 @@ public class NEUConfig extends Config { public String wandOverlayColour = "00:50:64:224:208"; } + public static class DungeonMapOpen { + @Expose + @ConfigOption( + name = "Edit Dungeon Map", + desc = "The NEU dungeon map has it's own editor (/neumap).\n" + + "Click the button on the left to open it" + ) + @ConfigEditorButton( + runnableId = 0, + buttonText = "Edit" + ) + public int editDungeonMap = 0; + } + public static class DungeonBlock { @Expose @ConfigOption( @@ -1218,17 +1372,10 @@ public class NEUConfig extends Config { @Expose @ConfigOption( - name = "Center X (%)", - desc = "The horizontal position of the map" - ) - public double dmCenterX = 8.5; - - @Expose - @ConfigOption( - name = "Center Y (%)", - desc = "The vertical position of the map" + name = "Position", + desc = "The position of the map" ) - public double dmCenterY = 15.0; + public Position dmPosition = new Position(10, 10); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java index 2a8a2c04..d870e858 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java @@ -39,7 +39,7 @@ public class NEUConfigEditor extends GuiElement { }; private static final String[] socialsLink = new String[] { "https://discord.gg/moulberry", - "https://github.com/Moulberry/Hychat", + "https://github.com/Moulberry/NotEnoughUpdates", "https://twitter.com/moulberry/", "https://www.youtube.com/channel/UCPh-OKmRSS3IQi9p6YppLcw", "https://patreon.com/moulberry" diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java index 724c0953..b9f9b03d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java @@ -1047,9 +1047,8 @@ public class ProfileViewer { } public Profile getProfileReset(String uuid, Consumer<Profile> callback) { - Profile profile = getProfile(uuid, callback); - profile.resetCache(); - return profile; + if(uuidToProfileMap.containsKey(uuid)) uuidToProfileMap.get(uuid).resetCache(); + return getProfile(uuid, callback); } private static JsonObject resourceCollection = null; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/textoverlays/TextOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/textoverlays/TextOverlay.java new file mode 100644 index 00000000..f111f20a --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/textoverlays/TextOverlay.java @@ -0,0 +1,90 @@ +package io.github.moulberry.notenoughupdates.textoverlays; + +import io.github.moulberry.notenoughupdates.core.config.Position; +import io.github.moulberry.notenoughupdates.core.util.StringUtils; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.ScaledResolution; + +import java.awt.*; +import java.util.List; +import java.util.function.Supplier; + +public abstract class TextOverlay { + + private Position position; + private Supplier<TextOverlayStyle> styleSupplier; + public int overlayWidth = -1; + public int overlayHeight = -1; + public List<String> overlayStrings = null; + + private static final int PADDING_X = 5; + private static final int PADDING_Y = 5; + + public TextOverlay(Position position, Supplier<TextOverlayStyle> styleSupplier) { + this.position = position; + this.styleSupplier = styleSupplier; + } + + public void tick() { + update(); + + if(overlayStrings != null) { + overlayHeight = 0; + overlayWidth = 0; + for(String s : overlayStrings) { + if(s == null) { + overlayHeight += 3; + continue; + } + int sWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(s); + if(sWidth > overlayWidth) { + overlayWidth = sWidth; + } + overlayHeight += 10; + } + overlayHeight -= 2; + } + } + + public abstract void update(); + + public void render() { + if(overlayStrings != null) { + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); + + int x = position.getAbsX(scaledResolution); + int y = position.getAbsY(scaledResolution); + + TextOverlayStyle style = styleSupplier.get(); + + if(style == TextOverlayStyle.BACKGROUND) Gui.drawRect(x, y, x+overlayWidth+PADDING_X*2, y+overlayHeight+PADDING_Y*2, 0x80000000); + + int yOff = 0; + for(String s : overlayStrings) { + if(s == null) { + yOff += 3; + } else { + if(style == TextOverlayStyle.FULL_SHADOW) { + String clean = Utils.cleanColourNotModifiers(s); + for(int xO=-2; xO<=2; xO++) { + for(int yO=-2; yO<=2; yO++) { + if(Math.abs(xO) != Math.abs(yO)) { + Minecraft.getMinecraft().fontRendererObj.drawString(clean, + x+PADDING_X+xO/2f, y+PADDING_Y+yOff+yO/2f, + new Color(0, 0, 0, 200/Math.max(Math.abs(xO), Math.abs(yO))).getRGB(), false); + } + } + } + } + Minecraft.getMinecraft().fontRendererObj.drawString(s, + x+PADDING_X, y+PADDING_Y+yOff, 0xffffff, style == TextOverlayStyle.MC_SHADOW); + + yOff += 10; + } + } + } + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/textoverlays/TextOverlayStyle.java b/src/main/java/io/github/moulberry/notenoughupdates/textoverlays/TextOverlayStyle.java new file mode 100644 index 00000000..7bd620b6 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/textoverlays/TextOverlayStyle.java @@ -0,0 +1,10 @@ +package io.github.moulberry.notenoughupdates.textoverlays; + +public enum TextOverlayStyle { + + BACKGROUND, + NO_SHADOW, + MC_SHADOW, + FULL_SHADOW + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/ReverseWorldRenderer.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ReverseWorldRenderer.java new file mode 100644 index 00000000..d9d9dd90 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ReverseWorldRenderer.java @@ -0,0 +1,552 @@ +package io.github.moulberry.notenoughupdates.util; + +import com.google.common.primitives.Floats; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.ShortBuffer; +import java.util.Arrays; +import java.util.BitSet; +import java.util.Comparator; + +import net.minecraft.client.renderer.GLAllocation; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.client.renderer.vertex.VertexFormatElement; +import net.minecraft.util.MathHelper; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import org.apache.logging.log4j.LogManager; + +@SideOnly(Side.CLIENT) +public class ReverseWorldRenderer { + private ByteBuffer byteBuffer; + private IntBuffer rawIntBuffer; + private ShortBuffer rawShortBuffer; + private FloatBuffer rawFloatBuffer; + private int vertexCount; + private VertexFormatElement vertexFormatElement; + private int vertexFormatIndex; + /** + * None + */ + private boolean noColor; + private int drawMode; + private double xOffset; + private double yOffset; + private double zOffset; + private VertexFormat vertexFormat; + private boolean isDrawing; + + public ReverseWorldRenderer(int bufferSizeIn) { + this.byteBuffer = GLAllocation.createDirectByteBuffer(bufferSizeIn * 4); + this.rawIntBuffer = this.byteBuffer.asIntBuffer(); + this.rawShortBuffer = this.byteBuffer.asShortBuffer(); + this.rawFloatBuffer = this.byteBuffer.asFloatBuffer(); + } + + private void growBuffer(int p_181670_1_) { + if (p_181670_1_ > this.rawIntBuffer.remaining()) { + int i = this.byteBuffer.capacity(); + int j = i % 2097152; + int k = j + (((this.rawIntBuffer.position() + p_181670_1_) * 4 - j) / 2097152 + 1) * 2097152; + LogManager.getLogger().warn("Needed to grow BufferBuilder buffer: Old size " + i + " bytes, new size " + k + " bytes."); + int l = this.rawIntBuffer.position(); + ByteBuffer bytebuffer = GLAllocation.createDirectByteBuffer(k); + this.byteBuffer.position(0); + bytebuffer.put(this.byteBuffer); + bytebuffer.rewind(); + this.byteBuffer = bytebuffer; + this.rawFloatBuffer = this.byteBuffer.asFloatBuffer().asReadOnlyBuffer(); + this.rawIntBuffer = this.byteBuffer.asIntBuffer(); + this.rawIntBuffer.position(l); + this.rawShortBuffer = this.byteBuffer.asShortBuffer(); + this.rawShortBuffer.position(l << 1); + } + } + + public void sortVertexData(float p_181674_1_, float p_181674_2_, float p_181674_3_) { + int i = this.vertexCount / 4; + final float[] afloat = new float[i]; + + for (int j = 0; j < i; ++j) { + afloat[j] = func_181665_a(this.rawFloatBuffer, (float) ((double) p_181674_1_ + this.xOffset), (float) ((double) p_181674_2_ + this.yOffset), (float) ((double) p_181674_3_ + this.zOffset), this.vertexFormat.func_181719_f(), j * this.vertexFormat.getNextOffset()); + } + + Integer[] ainteger = new Integer[i]; + + for (int k = 0; k < ainteger.length; ++k) { + ainteger[k] = Integer.valueOf(k); + } + + Arrays.sort(ainteger, new Comparator<Integer>() { + public int compare(Integer p_compare_1_, Integer p_compare_2_) { + return -Floats.compare(afloat[p_compare_2_.intValue()], afloat[p_compare_1_.intValue()]); + } + }); + BitSet bitset = new BitSet(); + int l = this.vertexFormat.getNextOffset(); + int[] aint = new int[l]; + + for (int l1 = 0; (l1 = bitset.nextClearBit(l1)) < ainteger.length; ++l1) { + int i1 = ainteger[l1].intValue(); + + if (i1 != l1) { + this.rawIntBuffer.limit(i1 * l + l); + this.rawIntBuffer.position(i1 * l); + this.rawIntBuffer.get(aint); + int j1 = i1; + + for (int k1 = ainteger[i1].intValue(); j1 != l1; k1 = ainteger[k1].intValue()) { + this.rawIntBuffer.limit(k1 * l + l); + this.rawIntBuffer.position(k1 * l); + IntBuffer intbuffer = this.rawIntBuffer.slice(); + this.rawIntBuffer.limit(j1 * l + l); + this.rawIntBuffer.position(j1 * l); + this.rawIntBuffer.put(intbuffer); + bitset.set(j1); + j1 = k1; + } + + this.rawIntBuffer.limit(l1 * l + l); + this.rawIntBuffer.position(l1 * l); + this.rawIntBuffer.put(aint); + } + + bitset.set(l1); + } + } + + public State getVertexState() { + this.rawIntBuffer.rewind(); + int i = this.getBufferSize(); + this.rawIntBuffer.limit(i); + int[] aint = new int[i]; + this.rawIntBuffer.get(aint); + this.rawIntBuffer.limit(this.rawIntBuffer.capacity()); + this.rawIntBuffer.position(i); + return new State(aint, new VertexFormat(this.vertexFormat)); + } + + private int getBufferSize() { + return this.vertexCount * this.vertexFormat.func_181719_f(); + } + + private static float func_181665_a(FloatBuffer p_181665_0_, float p_181665_1_, float p_181665_2_, float p_181665_3_, int p_181665_4_, int p_181665_5_) { + float f = p_181665_0_.get(p_181665_5_ + p_181665_4_ * 0 + 0); + float f1 = p_181665_0_.get(p_181665_5_ + p_181665_4_ * 0 + 1); + float f2 = p_181665_0_.get(p_181665_5_ + p_181665_4_ * 0 + 2); + float f3 = p_181665_0_.get(p_181665_5_ + p_181665_4_ * 1 + 0); + float f4 = p_181665_0_.get(p_181665_5_ + p_181665_4_ * 1 + 1); + float f5 = p_181665_0_.get(p_181665_5_ + p_181665_4_ * 1 + 2); + float f6 = p_181665_0_.get(p_181665_5_ + p_181665_4_ * 2 + 0); + float f7 = p_181665_0_.get(p_181665_5_ + p_181665_4_ * 2 + 1); + float f8 = p_181665_0_.get(p_181665_5_ + p_181665_4_ * 2 + 2); + float f9 = p_181665_0_.get(p_181665_5_ + p_181665_4_ * 3 + 0); + float f10 = p_181665_0_.get(p_181665_5_ + p_181665_4_ * 3 + 1); + float f11 = p_181665_0_.get(p_181665_5_ + p_181665_4_ * 3 + 2); + float f12 = (f + f3 + f6 + f9) * 0.25F - p_181665_1_; + float f13 = (f1 + f4 + f7 + f10) * 0.25F - p_181665_2_; + float f14 = (f2 + f5 + f8 + f11) * 0.25F - p_181665_3_; + return f12 * f12 + f13 * f13 + f14 * f14; + } + + public void setVertexState(State state) { + this.rawIntBuffer.clear(); + this.growBuffer(state.getRawBuffer().length); + this.rawIntBuffer.put(state.getRawBuffer()); + this.vertexCount = state.getVertexCount(); + this.vertexFormat = new VertexFormat(state.getVertexFormat()); + } + + public void reset() { + this.vertexCount = 0; + this.vertexFormatElement = null; + this.vertexFormatIndex = 0; + } + + public void begin(int glMode, VertexFormat format) { + if (this.isDrawing) { + throw new IllegalStateException("Already building!"); + } else { + this.isDrawing = true; + this.reset(); + this.drawMode = glMode; + this.vertexFormat = format; + this.vertexFormatElement = format.getElement(this.vertexFormatIndex); + this.noColor = false; + this.byteBuffer.limit(this.byteBuffer.capacity()); + } + } + + public ReverseWorldRenderer tex(double u, double v) { + int i = this.vertexCount * this.vertexFormat.getNextOffset() + this.vertexFormat.func_181720_d(this.vertexFormatIndex); + + switch (this.vertexFormatElement.getType()) { + case FLOAT: + this.byteBuffer.putFloat(i, (float) u); + this.byteBuffer.putFloat(i + 4, (float) v); + break; + case UINT: + case INT: + this.byteBuffer.putInt(i, (int) u); + this.byteBuffer.putInt(i + 4, (int) v); + break; + case USHORT: + case SHORT: + this.byteBuffer.putShort(i, (short) ((int) v)); + this.byteBuffer.putShort(i + 2, (short) ((int) u)); + break; + case UBYTE: + case BYTE: + this.byteBuffer.put(i, (byte) ((int) v)); + this.byteBuffer.put(i + 1, (byte) ((int) u)); + } + + this.nextVertexFormatIndex(); + return this; + } + + public ReverseWorldRenderer lightmap(int p_181671_1_, int p_181671_2_) { + int i = this.vertexCount * this.vertexFormat.getNextOffset() + this.vertexFormat.func_181720_d(this.vertexFormatIndex); + + switch (this.vertexFormatElement.getType()) { + case FLOAT: + this.byteBuffer.putFloat(i, (float) p_181671_1_); + this.byteBuffer.putFloat(i + 4, (float) p_181671_2_); + break; + case UINT: + case INT: + this.byteBuffer.putInt(i, p_181671_1_); + this.byteBuffer.putInt(i + 4, p_181671_2_); + break; + case USHORT: + case SHORT: + this.byteBuffer.putShort(i, (short) p_181671_2_); + this.byteBuffer.putShort(i + 2, (short) p_181671_1_); + break; + case UBYTE: + case BYTE: + this.byteBuffer.put(i, (byte) p_181671_2_); + this.byteBuffer.put(i + 1, (byte) p_181671_1_); + } + + this.nextVertexFormatIndex(); + return this; + } + + public void putBrightness4(int p_178962_1_, int p_178962_2_, int p_178962_3_, int p_178962_4_) { + int i = (this.vertexCount - 4) * this.vertexFormat.func_181719_f() + this.vertexFormat.getUvOffsetById(1) / 4; + int j = this.vertexFormat.getNextOffset() >> 2; + this.rawIntBuffer.put(i, p_178962_1_); + this.rawIntBuffer.put(i + j, p_178962_2_); + this.rawIntBuffer.put(i + j * 2, p_178962_3_); + this.rawIntBuffer.put(i + j * 3, p_178962_4_); + } + + public void putPosition(double x, double y, double z) { + int i = this.vertexFormat.func_181719_f(); + int j = (this.vertexCount - 4) * i; + + for (int k = 0; k < 4; ++k) { + int l = j + k * i; + int i1 = l + 1; + int j1 = i1 + 1; + this.rawIntBuffer.put(l, Float.floatToRawIntBits((float) (x + this.xOffset) + Float.intBitsToFloat(this.rawIntBuffer.get(l)))); + this.rawIntBuffer.put(i1, Float.floatToRawIntBits((float) (y + this.yOffset) + Float.intBitsToFloat(this.rawIntBuffer.get(i1)))); + this.rawIntBuffer.put(j1, Float.floatToRawIntBits((float) (z + this.zOffset) + Float.intBitsToFloat(this.rawIntBuffer.get(j1)))); + } + } + + /** + * Takes in the pass the call list is being requested for. Args: renderPass + */ + public int getColorIndex(int p_78909_1_) { + return ((this.vertexCount - p_78909_1_) * this.vertexFormat.getNextOffset() + this.vertexFormat.getColorOffset()) / 4; + } + + public void putColorMultiplier(float red, float green, float blue, int p_178978_4_) { + int i = this.getColorIndex(p_178978_4_); + int j = -1; + + if (!this.noColor) { + j = this.rawIntBuffer.get(i); + + if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) { + int k = (int) ((float) (j & 255) * red); + int l = (int) ((float) (j >> 8 & 255) * green); + int i1 = (int) ((float) (j >> 16 & 255) * blue); + j = j & -16777216; + j = j | i1 << 16 | l << 8 | k; + } else { + int j1 = (int) ((float) (j >> 24 & 255) * red); + int k1 = (int) ((float) (j >> 16 & 255) * green); + int l1 = (int) ((float) (j >> 8 & 255) * blue); + j = j & 255; + j = j | j1 << 24 | k1 << 16 | l1 << 8; + } + } + + this.rawIntBuffer.put(i, j); + } + + private void putColor(int argb, int p_178988_2_) { + int i = this.getColorIndex(p_178988_2_); + int j = argb >> 16 & 255; + int k = argb >> 8 & 255; + int l = argb & 255; + int i1 = argb >> 24 & 255; + this.putColorRGBA(i, j, k, l, i1); + } + + public void putColorRGB_F(float red, float green, float blue, int p_178994_4_) { + int i = this.getColorIndex(p_178994_4_); + int j = MathHelper.clamp_int((int) (red * 255.0F), 0, 255); + int k = MathHelper.clamp_int((int) (green * 255.0F), 0, 255); + int l = MathHelper.clamp_int((int) (blue * 255.0F), 0, 255); + this.putColorRGBA(i, j, k, l, 255); + } + + public void putColorRGBA(int index, int red, int p_178972_3_, int p_178972_4_, int p_178972_5_) { + if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) { + this.rawIntBuffer.put(index, p_178972_5_ << 24 | p_178972_4_ << 16 | p_178972_3_ << 8 | red); + } else { + this.rawIntBuffer.put(index, red << 24 | p_178972_3_ << 16 | p_178972_4_ << 8 | p_178972_5_); + } + } + + /** + * Disabels color processing. + */ + public void noColor() { + this.noColor = true; + } + + public ReverseWorldRenderer color(float red, float green, float blue, float alpha) { + return this.color((int) (red * 255.0F), (int) (green * 255.0F), (int) (blue * 255.0F), (int) (alpha * 255.0F)); + } + + public ReverseWorldRenderer color(int red, int green, int blue, int alpha) { + if (this.noColor) { + return this; + } else { + int i = this.vertexCount * this.vertexFormat.getNextOffset() + this.vertexFormat.func_181720_d(this.vertexFormatIndex); + + switch (this.vertexFormatElement.getType()) { + case FLOAT: + this.byteBuffer.putFloat(i, (float) red / 255.0F); + this.byteBuffer.putFloat(i + 4, (float) green / 255.0F); + this.byteBuffer.putFloat(i + 8, (float) blue / 255.0F); + this.byteBuffer.putFloat(i + 12, (float) alpha / 255.0F); + break; + case UINT: + case INT: + this.byteBuffer.putFloat(i, (float) red); + this.byteBuffer.putFloat(i + 4, (float) green); + this.byteBuffer.putFloat(i + 8, (float) blue); + this.byteBuffer.putFloat(i + 12, (float) alpha); + break; + case USHORT: + case SHORT: + this.byteBuffer.putShort(i, (short) red); + this.byteBuffer.putShort(i + 2, (short) green); + this.byteBuffer.putShort(i + 4, (short) blue); + this.byteBuffer.putShort(i + 6, (short) alpha); + break; + case UBYTE: + case BYTE: + + if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) { + this.byteBuffer.put(i, (byte) red); + this.byteBuffer.put(i + 1, (byte) green); + this.byteBuffer.put(i + 2, (byte) blue); + this.byteBuffer.put(i + 3, (byte) alpha); + } else { + this.byteBuffer.put(i, (byte) alpha); + this.byteBuffer.put(i + 1, (byte) blue); + this.byteBuffer.put(i + 2, (byte) green); + this.byteBuffer.put(i + 3, (byte) red); + } + } + + this.nextVertexFormatIndex(); + return this; + } + } + + public void addVertexData(int[] vertexData) { + this.growBuffer(vertexData.length); + this.rawIntBuffer.position(this.getBufferSize()); + this.rawIntBuffer.put(vertexData); + this.vertexCount += vertexData.length / this.vertexFormat.func_181719_f(); + } + + public void endVertex() { + ++this.vertexCount; + this.growBuffer(this.vertexFormat.func_181719_f()); + } + + public ReverseWorldRenderer pos(double x, double y, double z) { + int i = this.vertexCount * this.vertexFormat.getNextOffset() + this.vertexFormat.func_181720_d(this.vertexFormatIndex); + + switch (this.vertexFormatElement.getType()) { + case FLOAT: + this.byteBuffer.putFloat(i, (float) (x + this.xOffset)); + this.byteBuffer.putFloat(i + 4, (float) (y + this.yOffset)); + this.byteBuffer.putFloat(i + 8, (float) (z + this.zOffset)); + break; + case UINT: + case INT: + this.byteBuffer.putInt(i, Float.floatToRawIntBits((float) (x + this.xOffset))); + this.byteBuffer.putInt(i + 4, Float.floatToRawIntBits((float) (y + this.yOffset))); + this.byteBuffer.putInt(i + 8, Float.floatToRawIntBits((float) (z + this.zOffset))); + break; + case USHORT: + case SHORT: + this.byteBuffer.putShort(i, (short) ((int) (x + this.xOffset))); + this.byteBuffer.putShort(i + 2, (short) ((int) (y + this.yOffset))); + this.byteBuffer.putShort(i + 4, (short) ((int) (z + this.zOffset))); + break; + case UBYTE: + case BYTE: + this.byteBuffer.put(i, (byte) ((int) (x + this.xOffset))); + this.byteBuffer.put(i + 1, (byte) ((int) (y + this.yOffset))); + this.byteBuffer.put(i + 2, (byte) ((int) (z + this.zOffset))); + } + + this.nextVertexFormatIndex(); + return this; + } + + public void putNormal(float x, float y, float z) { + int i = (byte) ((int) (x * 127.0F)) & 255; + int j = (byte) ((int) (y * 127.0F)) & 255; + int k = (byte) ((int) (z * 127.0F)) & 255; + int l = i | j << 8 | k << 16; + int i1 = this.vertexFormat.getNextOffset() >> 2; + int j1 = (this.vertexCount - 4) * i1 + this.vertexFormat.getNormalOffset() / 4; + this.rawIntBuffer.put(j1, l); + this.rawIntBuffer.put(j1 + i1, l); + this.rawIntBuffer.put(j1 + i1 * 2, l); + this.rawIntBuffer.put(j1 + i1 * 3, l); + } + + private void nextVertexFormatIndex() { + ++this.vertexFormatIndex; + this.vertexFormatIndex %= this.vertexFormat.getElementCount(); + this.vertexFormatElement = this.vertexFormat.getElement(this.vertexFormatIndex); + + if (this.vertexFormatElement.getUsage() == VertexFormatElement.EnumUsage.PADDING) { + this.nextVertexFormatIndex(); + } + } + + public ReverseWorldRenderer normal(float p_181663_1_, float p_181663_2_, float p_181663_3_) { + int i = this.vertexCount * this.vertexFormat.getNextOffset() + this.vertexFormat.func_181720_d(this.vertexFormatIndex); + + switch (this.vertexFormatElement.getType()) { + case FLOAT: + this.byteBuffer.putFloat(i, p_181663_1_); + this.byteBuffer.putFloat(i + 4, p_181663_2_); + this.byteBuffer.putFloat(i + 8, p_181663_3_); + break; + case UINT: + case INT: + this.byteBuffer.putInt(i, (int) p_181663_1_); + this.byteBuffer.putInt(i + 4, (int) p_181663_2_); + this.byteBuffer.putInt(i + 8, (int) p_181663_3_); + break; + case USHORT: + case SHORT: + this.byteBuffer.putShort(i, (short) ((int) (p_181663_1_ * 32767) & 65535)); + this.byteBuffer.putShort(i + 2, (short) ((int) (p_181663_2_ * 32767) & 65535)); + this.byteBuffer.putShort(i + 4, (short) ((int) (p_181663_3_ * 32767) & 65535)); + break; + case UBYTE: + case BYTE: + this.byteBuffer.put(i, (byte) ((int) (p_181663_1_ * 127) & 255)); + this.byteBuffer.put(i + 1, (byte) ((int) (p_181663_2_ * 127) & 255)); + this.byteBuffer.put(i + 2, (byte) ((int) (p_181663_3_ * 127) & 255)); + } + + this.nextVertexFormatIndex(); + return this; + } + + public void setTranslation(double x, double y, double z) { + this.xOffset = x; + this.yOffset = y; + this.zOffset = z; + } + + public void finishDrawing() { + if (!this.isDrawing) { + throw new IllegalStateException("Not building!"); + } else { + this.isDrawing = false; + this.byteBuffer.position(0); + this.byteBuffer.limit(this.getBufferSize() * 4); + } + } + + public ByteBuffer getByteBuffer() { + return this.byteBuffer; + } + + public VertexFormat getVertexFormat() { + return this.vertexFormat; + } + + public int getVertexCount() { + return this.vertexCount; + } + + public int getDrawMode() { + return this.drawMode; + } + + public void putColor4(int argb) { + for (int i = 0; i < 4; ++i) { + this.putColor(argb, i + 1); + } + } + + public void putColorRGB_F4(float red, float green, float blue) { + for (int i = 0; i < 4; ++i) { + this.putColorRGB_F(red, green, blue, i + 1); + } + } + + public void checkAndGrow() { + this.growBuffer(vertexFormat.getNextOffset()/* / 4 * 4 */); + } + + public boolean isColorDisabled() { + /** None */ + return noColor; + } + + @SideOnly(Side.CLIENT) + public class State { + private final int[] stateRawBuffer; + private final VertexFormat stateVertexFormat; + + public State(int[] buffer, VertexFormat format) { + this.stateRawBuffer = buffer; + this.stateVertexFormat = format; + } + + public int[] getRawBuffer() { + return this.stateRawBuffer; + } + + public int getVertexCount() { + return this.stateRawBuffer.length / this.stateVertexFormat.func_181719_f(); + } + + public VertexFormat getVertexFormat() { + return this.stateVertexFormat; + } + } +}
\ No newline at end of file diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java index f8621f2b..e40edd4f 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java @@ -518,11 +518,20 @@ public class Utils { } public static void renderShadowedString(String str, float x, float y, int maxLength) { + int strLen = Minecraft.getMinecraft().fontRendererObj.getStringWidth(str); + float factor; + if(maxLength < 0) { + factor = 1; + } else { + factor = maxLength/(float)strLen; + factor = Math.min(1, factor); + } + for(int xOff=-2; xOff<=2; xOff++) { for(int yOff=-2; yOff<=2; yOff++) { if(Math.abs(xOff) != Math.abs(yOff)) { Utils.drawStringCenteredScaledMaxWidth(Utils.cleanColourNotModifiers(str), Minecraft.getMinecraft().fontRendererObj, - x+xOff/2f, y+4+yOff/2f, false, maxLength, + x+xOff/2f*factor, y+4+yOff/2f*factor, false, maxLength, new Color(0, 0, 0, 200/Math.max(Math.abs(xOff), Math.abs(yOff))).getRGB()); } } diff --git a/src/main/resources/assets/notenoughupdates/capes/furf.png b/src/main/resources/assets/notenoughupdates/capes/furf.png Binary files differindex 70f8f98a..ce9f4c19 100644 --- a/src/main/resources/assets/notenoughupdates/capes/furf.png +++ b/src/main/resources/assets/notenoughupdates/capes/furf.png diff --git a/src/main/resources/assets/notenoughupdates/capes/furf_preview.png b/src/main/resources/assets/notenoughupdates/capes/furf_preview.png Binary files differnew file mode 100644 index 00000000..a4ee6851 --- /dev/null +++ b/src/main/resources/assets/notenoughupdates/capes/furf_preview.png |