From b3fd9f12c8a327384af0fc813f10c34a9a1c96ee Mon Sep 17 00:00:00 2001 From: Hypeirochus Date: Tue, 12 Jun 2018 13:37:35 -0400 Subject: [PATCH 01/19] Updated forge and mappings. --- build.gradle | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 3f9e96e..3d17524 100644 --- a/build.gradle +++ b/build.gradle @@ -42,10 +42,12 @@ artifacts { } minecraft { - version = "1.12.2-14.23.1.2583" + version = "1.12.2-14.23.4.2705" runDir = "run" replace '${version}', project.version - mappings = "snapshot_20180203" + + //Formatted as YYYYMMDD + mappings = "snapshot_20180611" } repositories { From 15ad6f05eb169caf79f4f47bc8572d105361d7a6 Mon Sep 17 00:00:00 2001 From: Hypeirochus Date: Tue, 12 Jun 2018 14:02:45 -0400 Subject: [PATCH 02/19] Added access handler. --- .../core/access/AccessHandler.java | 46 +++++++++++++++++++ src/main/resources/META-INF/CJCore_at.cfg | 25 ++++++++++ 2 files changed, 71 insertions(+) create mode 100644 src/main/java/cjminecraft/core/access/AccessHandler.java create mode 100644 src/main/resources/META-INF/CJCore_at.cfg diff --git a/src/main/java/cjminecraft/core/access/AccessHandler.java b/src/main/java/cjminecraft/core/access/AccessHandler.java new file mode 100644 index 0000000..4a7e60e --- /dev/null +++ b/src/main/java/cjminecraft/core/access/AccessHandler.java @@ -0,0 +1,46 @@ +package cjminecraft.core.access; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.launchwrapper.Launch; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +/** + * A utility class for handling all things to do with the game (which normally we don't have access to) + * + * @author Hypeirochus + */ +public class AccessHandler { + + /** + * @return The minecraft instance + */ + @SideOnly(Side.CLIENT) + public static Minecraft getMinecraft() { + return Minecraft.instance; + } + + /** + * @return The minecraft font renderer instance + */ + @SideOnly(Side.CLIENT) + public static FontRenderer getFontRenderer() { + return getMinecraft().fontRenderer; + } + + /** + * @return The percentage from last update and this update + */ + @SideOnly(Side.CLIENT) + public static float getPartialTicks() { + return getMinecraft().timer.renderPartialTicks; + } + + /** + * @return Whether or not the environment is deobfuscated + */ + public static boolean isDeobfuscatedEnvironment() { + return (boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment"); + } +} \ No newline at end of file diff --git a/src/main/resources/META-INF/CJCore_at.cfg b/src/main/resources/META-INF/CJCore_at.cfg new file mode 100644 index 0000000..bf97ea9 --- /dev/null +++ b/src/main/resources/META-INF/CJCore_at.cfg @@ -0,0 +1,25 @@ +# ItemRenderer +public net.minecraft.client.renderer.ItemRenderer * +public net.minecraft.client.renderer.ItemRenderer *() + +# Minecraft +public net.minecraft.client.Minecraft * +public net.minecraft.client.Minecraft *() + +# EntityRenderer +public net.minecraft.client.renderer.EntityRenderer * +public net.minecraft.client.renderer.EntityRenderer *() + +# EntityMoveHelper +public net.minecraft.entity.ai.EntityMoveHelper * +public net.minecraft.entity.ai.EntityMoveHelper *() + +# EntityLookHelper +public net.minecraft.entity.ai.EntityLookHelper * +public net.minecraft.entity.ai.EntityLookHelper *() + +# Block +public net.minecraft.block.Block * + +# RenderLivingBase +public net.minecraft.client.renderer.entity.RenderLivingBase * From d3a4f8b814f9831a7f34fde1101f4f8fb422f56c Mon Sep 17 00:00:00 2001 From: Hypeirochus Date: Tue, 12 Jun 2018 14:30:56 -0400 Subject: [PATCH 03/19] Added rendering utilities. --- .../core/client/GameResources.java | 13 + .../cjminecraft/core/client/render/Color.java | 73 + .../cjminecraft/core/client/render/Draw.java | 1189 +++++++++++++++++ .../core/client/render/OpenGL.java | 439 ++++++ .../core/client/render/ScaledResolution.java | 60 + .../core/client/render/Screen.java | 114 ++ .../core/client/render/Texture.java | 24 + .../cjminecraft/core/client/render/UV.java | 39 + .../core/client/render/Vertex.java | 71 + 9 files changed, 2022 insertions(+) create mode 100644 src/main/java/cjminecraft/core/client/GameResources.java create mode 100644 src/main/java/cjminecraft/core/client/render/Color.java create mode 100644 src/main/java/cjminecraft/core/client/render/Draw.java create mode 100644 src/main/java/cjminecraft/core/client/render/OpenGL.java create mode 100644 src/main/java/cjminecraft/core/client/render/ScaledResolution.java create mode 100644 src/main/java/cjminecraft/core/client/render/Screen.java create mode 100644 src/main/java/cjminecraft/core/client/render/Texture.java create mode 100644 src/main/java/cjminecraft/core/client/render/UV.java create mode 100644 src/main/java/cjminecraft/core/client/render/Vertex.java diff --git a/src/main/java/cjminecraft/core/client/GameResources.java b/src/main/java/cjminecraft/core/client/GameResources.java new file mode 100644 index 0000000..aa2f26c --- /dev/null +++ b/src/main/java/cjminecraft/core/client/GameResources.java @@ -0,0 +1,13 @@ +package cjminecraft.core.client; + +import cjminecraft.core.CJCore; +import cjminecraft.core.client.render.Texture; + +public class GameResources { + public static final Texture PARTICLES = new Texture("textures/particle/particles.png"); + public static final Texture SKY_SUN = new Texture("textures/environment/sun.png"); + public static final Texture SKY_RAIN = new Texture("textures/environment/rain.png"); + public static final Texture SKY_CLOUDS = new Texture("textures/environment/clouds.png"); + + public static final Texture BLANK = new Texture(CJCore.MODID, "textures/misc/blank.png"); +} \ No newline at end of file diff --git a/src/main/java/cjminecraft/core/client/render/Color.java b/src/main/java/cjminecraft/core/client/render/Color.java new file mode 100644 index 0000000..b71c5af --- /dev/null +++ b/src/main/java/cjminecraft/core/client/render/Color.java @@ -0,0 +1,73 @@ +package cjminecraft.core.client.render; + +import java.nio.ByteBuffer; + +public class Color { + public float r, g, b, a; + + public Color(float r, float g, float b, float a) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + + public Color(Color c) { + this(c.r, c.g, c.b, c.a); + } + + /** + * Converts 4 RGBA values into a single hexadecimal color value. + * + * @param alpha + * - Alpha value ranged from 0-255 + * @param red + * - Red value ranged from 0-255 + * @param green + * - Green value ranged from 0-255 + * @param blue + * - Blue value ranged from 0-255 + * @return Hexadecimal created from the provided RGBA values. + */ + public static int createHexadecimal(int alpha, int red, int green, int blue) { + org.lwjgl.util.Color color = new org.lwjgl.util.Color(alpha, red, green, blue); + ByteBuffer dest = ByteBuffer.allocate(4); + + color.writeRGBA(dest); + dest.rewind(); + + return dest.getInt(); + } + + public int toHexadecimal() { + org.lwjgl.util.Color color = new org.lwjgl.util.Color(toIntRange(a), toIntRange(r), toIntRange(g), toIntRange(b)); + ByteBuffer dest = ByteBuffer.allocate(4); + + color.writeRGBA(dest); + dest.rewind(); + + return dest.getInt(); + } + + /** + * Convert float color range to integer color range. + * + * @param f + * - Float color range (0.0F - 1.0F) + * @return Integer color range (1 - 255) + */ + public static int toIntRange(float f) { + return (int) ((f * 255) / 1F); + } + + /** + * Convert integer color range to float color range. + * + * @param i + * - Integer color range (1 - 255) + * @return Float color range (0.0F - 1.0F) + */ + public static float toFloatRange(int i) { + return (i * 1.0F) / 255; + } +} \ No newline at end of file diff --git a/src/main/java/cjminecraft/core/client/render/Draw.java b/src/main/java/cjminecraft/core/client/render/Draw.java new file mode 100644 index 0000000..3e8b22b --- /dev/null +++ b/src/main/java/cjminecraft/core/client/render/Draw.java @@ -0,0 +1,1189 @@ +package cjminecraft.core.client.render; + +import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA; +import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA; + +import java.awt.Dimension; +import java.util.ArrayList; +import java.util.List; + +import org.lwjgl.opengl.GL11; + +import cjminecraft.core.access.AccessHandler; +import cjminecraft.core.client.GameResources; +import cjminecraft.core.world.Worlds; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.util.text.translation.I18n; + +public class Draw { + + public static BufferBuilder buffer() { + return Tessellator.getInstance().getBuffer(); + } + + public static void startQuads() { + buffer().begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + } + + public static void startTriangleFan() { + buffer().begin(GL11.GL_TRIANGLE_FAN, DefaultVertexFormats.POSITION); + } + + public static void startQuadsColored() { + buffer().begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR); + } + + public static void tessellate() { + Tessellator.getInstance().draw(); + } + + public static BufferBuilder vertex(int x, int y, int z) { + return vertex((double) x, (double) y, (double) z); + } + + public static BufferBuilder vertex(double x, double y, double z) { + return buffer().pos(x, y, z); + } + + public static BufferBuilder vertex(int x, int y, int z, float u, float v) { + return vertex((double) x, (double) y, (double) z, u, v); + } + + public static BufferBuilder vertex(double x, double y, double z, float u, float v) { + return buffer().pos(x, y, z).tex(u, v); + } + + public static BufferBuilder vertex(double x, double y, double z, double u, double v) { + return buffer().pos(x, y, z).tex(u, v); + } + + public static void triangle(Vertex vertex1, Vertex vertex2, Vertex vertex3) { + triangle(vertex1, vertex2, vertex3, false); + } + + public static void triangle(Vertex vertex1, Vertex vertex2, Vertex vertex3, boolean cullFace) { + Draw.startTriangleFan(); + Draw.vertex(vertex1.x, vertex1.y, vertex1.z).endVertex(); + Draw.vertex(vertex2.x, vertex2.y, vertex2.z).endVertex(); + Draw.vertex(vertex3.x, vertex3.y, vertex3.z).endVertex(); + + if (cullFace) { + Draw.vertex(vertex3.x, vertex3.y, vertex3.z).endVertex(); + Draw.vertex(vertex2.x, vertex2.y, vertex2.z).endVertex(); + Draw.vertex(vertex1.x, vertex1.y, vertex1.z).endVertex(); + } + Draw.tessellate(); + } + + public static interface ITooltipLineHandler { + public Dimension getSize(); + + public void draw(int x, int y); + } + + public static void line(int x1, int y1, int x2, int y2, float depth, float width, int color) { + GL11.glLineWidth(width); + OpenGL.color4i(color); + OpenGL.translate(0F, 0F, depth); + // TODO: Find a replacement for this, doesn't seem to have an existing + // replacement in GLStateManager. + GL11.glEnable(GL11.GL_LINE_SMOOTH); + GL11.glBegin(GL11.GL_LINES); + GL11.glVertex2d(x1, y1); + GL11.glVertex2d(x2, y2); + GL11.glEnd(); + GL11.glLineWidth(1.0F); + OpenGL.translate(0F, 0F, -depth); + } + + /** + * Draws a rectangle at the specified coordinates, with the specified width, height and color. + * + * @param x + * - x coordinate + * @param y + * - y coordinate + * @param w + * - Width of this rectangle + * @param h + * - Height of this rectangle + * @param color + * - Color of this rectangle + */ + public static void drawRect(int x, int y, int w, int h, int color) { + Draw.drawGradientRect(x, y, w, h, color, color); + } + + /** + * Draws a rectangle at the specified coordinates, with the specified width, height and linear gradient color. + * + * @param x + * - x coordinate + * @param y + * - y coordinate + * @param w + * - Width of this rectangle + * @param h + * - Height of this rectangle + * @param color1 + * - First color of the linear gradient + * @param color2 + * - Second color of the linear gradient + */ + public static void drawGradientRect(int x, int y, int w, int h, int color1, int color2) { + Draw.drawGradientRect(x, y, x + w, y + h, 0, color1, color2); + } + + /** + * Draws a rectangle at the specified coordinates, with the specified width, height and linear gradient color. + * + * @param x + * - x coordinate + * @param y + * - y coordinate + * @param w + * - Width of this rectangle + * @param h + * - Height of this rectangle + * @param zLevel + * - z level of which to draw the rectangle on. + * @param color1 + * - First color of the linear gradient + * @param color2 + * - Second color of the linear gradient + */ + public static void drawGradientRect(int x, int y, int w, int h, int zLevel, int color1, int color2) { + OpenGL.disableTexture2d(); + OpenGL.shadeSmooth(); + startQuadsColored(); + vertex(w, y, zLevel).color((color1 >> 16 & 255) / 255.0F, (color1 >> 8 & 255) / 255.0F, (color1 & 255) / 255.0F, (color1 >> 24 & 255) / 255.0F).endVertex(); + vertex(x, y, zLevel).color((color1 >> 16 & 255) / 255.0F, (color1 >> 8 & 255) / 255.0F, (color1 & 255) / 255.0F, (color1 >> 24 & 255) / 255.0F).endVertex(); + vertex(x, h, zLevel).color((color2 >> 16 & 255) / 255.0F, (color2 >> 8 & 255) / 255.0F, (color2 & 255) / 255.0F, (color2 >> 24 & 255) / 255.0F).endVertex(); + vertex(w, h, zLevel).color((color2 >> 16 & 255) / 255.0F, (color2 >> 8 & 255) / 255.0F, (color2 & 255) / 255.0F, (color2 >> 24 & 255) / 255.0F).endVertex(); + tessellate(); + OpenGL.shadeFlat(); + OpenGL.enableTexture2d(); + } + + /** + * Draws a quad at the specified coordinates, with the specified width and height + * + * @param x + * - x coordinate + * @param y + * - y coordinate + * @param w + * - Width of this quad + * @param h + * - Height of this quad + */ + public static void drawQuad(int x, int y, int w, int h) { + Draw.drawQuad(x, y, w, h, -90); + } + + /** + * Draws a quad at the specified coordinates, with the specified width and height on the specified z level. + * + * @param x + * - x coordinate + * @param y + * - y coordinate + * @param w + * - Width of this quad + * @param h + * - Height of this quad + * @param z + * - z level to render this quad on + */ + public static void drawQuad(int x, int y, int w, int h, int z) { + Draw.drawQuad(x, y, w, h, z, 0, 1, 0, 1); + } + + /** + * Draws a quad at the specified coordinates, with the specified width and height and specified texture uv coords. + * + * @param x + * - x coordinate + * @param y + * - y coordinate + * @param w + * - Width of this quad + * @param h + * - Height of this quad + * @param u + * - x coordinate of the texture to draw on the quad. + * @param v + * - y coordinate of the texture to draw on the quad. + */ + public static void drawQuad(int x, int y, int w, int h, int u, int v) { + Draw.drawQuad(x, y, w, h, -90, u, v); + } + + /** + * Draws a quad at the specified coordinates, with the specified width and height and specified texture uv coords. + * + * @param x + * - x coordinate + * @param y + * - y coordinate + * @param w + * - Width of this quad + * @param h + * - Height of this quad + * @param z + * - z level to render this quad on + * @param u + * - x coordinate of the texture to draw on the quad. + * @param v + * - y coordinate of the texture to draw on the quad. + */ + public static void drawQuad(int x, int y, int w, int h, int z, int u, int v) { + float f = 0.00390625F; + float f1 = 0.00390625F; + startQuads(); + vertex(x + 0, y + h, z, (u + 0) * f, (v + h) * f1).endVertex(); + vertex(x + w, y + h, z, (u + w) * f, (v + h) * f1).endVertex(); + vertex(x + w, y + 0, z, (u + w) * f, (v + 0) * f1).endVertex(); + vertex(x + 0, y + 0, z, (u + 0) * f, (v + 0) * f1).endVertex(); + tessellate(); + } + + /** + * Draws a quad at the specified coordinates, with the specified width and height and specified texture uv coords. + * + * @param x + * - x coordinate + * @param y + * - y coordinate + * @param w + * - Width of this quad + * @param h + * - Height of this quad + * @param minU + * - x coordinate of the texture to draw on the quad. + * @param maxU + * - width of the texture being draw on this quad. + * @param minV + * - y coordinate of the texture to draw on the quad. + * @param maxV + * - height of the texture being draw on this quad. + */ + public static void drawQuad(int x, int y, int w, int h, float minU, float maxU, float minV, float maxV) { + Draw.drawQuad(x, y, w, h, -90, minU, maxU, minV, maxV); + } + + /** + * Draws a quad at the specified coordinates, with the specified width and height and specified texture uv coords. + * + * @param x + * - x coordinate + * @param y + * - y coordinate + * @param w + * - Width of this quad + * @param h + * - Height of this quad + * @param z + * - z level to render this quad on + * @param minU + * - x coordinate of the texture to draw on the quad. + * @param maxU + * - width of the texture being draw on this quad. + * @param minV + * - y coordinate of the texture to draw on the quad. + * @param maxV + * - height of the texture being draw on this quad. + */ + public static void drawQuad(int x, int y, int w, int h, int z, float minU, float maxU, float minV, float maxV) { + startQuads(); + vertex(x + 0, y + h, z, minU, maxV).endVertex(); + vertex(x + w, y + h, z, maxU, maxV).endVertex(); + vertex(x + w, y + 0, z, maxU, minV).endVertex(); + vertex(x + 0, y + 0, z, minU, minV).endVertex(); + tessellate(); + } + + /** + * Draw the specified String at the specified coordinates using the specified color. + * + * @param text + * - String to draw + * @param x + * - x coordinate to draw at + * @param y + * - y coordinate to draw at + * @param color + * - Color to draw using + * @param shadow + * - Set to true to draw a shadow beneath the rendered string. + */ + public static void drawString(String text, int x, int y, int color, boolean shadow) { + String original = text; + text = I18n.translateToLocal(text); + + if (text.toLowerCase().contains("error:".toLowerCase())) { + text = original; + } + + if (shadow) { + AccessHandler.getFontRenderer().drawStringWithShadow(text, x, y, color); + } + + if (!shadow) { + AccessHandler.getFontRenderer().drawString(text, x, y, color); + } + + OpenGL.color3i(0xFFFFFF); + GlStateManager.resetColor(); + } + + /** + * Draw the specified String at the specified coordinates using the specified color. + * + * @param text + * - String to draw + * @param x + * - x coordinate to draw at + * @param y + * - y coordinate to draw at + * @param color + * - Color to draw using + */ + public static void drawString(String text, int x, int y, int color) { + drawString(text, x, y, color, true); + } + + /** + * Draw the specified String centered at the specified coordinates using the specified color. + * + * @param text + * - String to draw + * @param x + * - x coordinate to draw at + * @param y + * - y coordinate to draw at + * @param w + * - width of the string + * @param h + * - height of the string + * @param color + * - Color to draw using + * @param shadow + * - Set to true to draw a shadow beneath the rendered string. + */ + public static void drawStringAlignCenter(String text, int x, int y, int w, int h, int color, boolean shadow) { + drawString(text, x + (w - Draw.getStringRenderWidth(I18n.translateToLocal(text))) / 2, y + (h - 8) / 2, color, shadow); + } + + /** + * Draw the specified String centered at the specified coordinates using the specified color. + * + * @param text + * - String to draw + * @param x + * - x coordinate to draw at + * @param y + * - y coordinate to draw at + * @param color + * - Color to draw using + */ + public static void drawStringAlignCenter(String text, int x, int y, int w, int h, int color) { + drawStringAlignCenter(text, x, y, w, h, color, true); + } + + /** + * Draw the specified String centered at the specified coordinates using the specified color. + * + * @param text + * - String to draw + * @param x + * - x coordinate to draw at + * @param y + * - y coordinate to draw at + * @param color + * - Color to draw using + * @param shadow + * - Set to true to draw a shadow beneath the rendered string. + */ + public static void drawStringAlignCenter(String text, int x, int y, int color, boolean shadow) { + drawString(text, x - Draw.getStringRenderWidth(I18n.translateToLocal(text)) / 2, y, color, shadow); + } + + /** + * Draw the specified String centered at the specified coordinates using the specified color. + * + * @param text + * - String to draw + * @param x + * - x coordinate to draw at + * @param y + * - y coordinate to draw at + * @param color + * - Color to draw using + */ + public static void drawStringAlignCenter(String text, int x, int y, int color) { + drawStringAlignCenter(text, x, y, color, true); + } + + /** + * Draw the specified String aligned to the right at the specified coordinates using the specified color. + * + * @param text + * - String to draw + * @param x + * - x coordinate to draw at + * @param y + * - y coordinate to draw at + * @param color + * - Color to draw using + * @param shadow + * - Set to true to draw a shadow beneath the rendered string. + */ + public static void drawStringAlignRight(String text, int x, int y, int color, boolean shadow) { + drawString(text, x - Draw.getStringRenderWidth(I18n.translateToLocal(text)), y, color, shadow); + } + + /** + * Draw the specified String aligned to the right at the specified coordinates using the specified color. + * + * @param text + * - String to draw + * @param x + * - x coordinate to draw at + * @param y + * - y coordinate to draw at + * @param color + * - Color to draw using + */ + public static void drawStringAlignRight(String text, int x, int y, int color) { + drawStringAlignRight(text, x, y, color, true); + } + + /** + * @param s + * - String to get the render width for. + * @return The render width of the specified String. + */ + public static int getStringRenderWidth(String s) { + return AccessHandler.getFontRenderer().getStringWidth(TextFormatting.getTextWithoutFormattingCodes(s)); + } + + public static final String TOOLTIP_LINESPACE = "\u00A7h"; + public static final String TOOLTIP_HANDLER = "\u00A7x"; + public static List tipLineHandlers = new ArrayList(); + + public static int getTipLineId(ITooltipLineHandler handler) { + tipLineHandlers.add(handler); + return tipLineHandlers.size() - 1; + } + + public static ITooltipLineHandler getTipLine(String line) { + return !line.startsWith(TOOLTIP_HANDLER) ? null : tipLineHandlers.get(Integer.parseInt(line.substring(2))); + } + + /** + * Draws a tooltip box at the specified cordinates, with the specified width and height. + * + * @param x + * - x coordinate + * @param y + * - y coordinate + * @param w + * - Width of the box + * @param h + * - Height of the box + */ + public static void drawTooltipBox(int x, int y, int w, int h) { + int bg = 0xf0100010; + drawGradientRect(x + 1, y, w - 1, 1, bg, bg); + drawGradientRect(x + 1, y + h, w - 1, 1, bg, bg); + drawGradientRect(x + 1, y + 1, w - 1, h - 1, bg, bg); + drawGradientRect(x, y + 1, 1, h - 1, bg, bg); + drawGradientRect(x + w, y + 1, 1, h - 1, bg, bg); + int grad1 = 0x505000ff; + int grad2 = 0x5028007F; + drawGradientRect(x + 1, y + 2, 1, h - 3, grad1, grad2); + drawGradientRect(x + w - 1, y + 2, 1, h - 3, grad1, grad2); + drawGradientRect(x + 1, y + 1, w - 1, 1, grad1, grad1); + drawGradientRect(x + 1, y + h - 1, w - 1, 1, grad2, grad2); + } + + /** + * Draws a progress bar. + * + * @param label + * - Label to draw on top of the progress bar. + * @param maxProgress + * - Maximum progress + * @param curProgress + * - Current progress + * @param posX + * - x coordinate to draw the bar at + * @param posY + * - y coordinate to draw the bar at + * @param barWidth + * - The width of the progress bar + * @param barHeight + * - The height of the progress bar + * @param stringPosY + * - The offset height of the label text (0 is default) + * @param color + * - The color of the progress bar + * @param barStyle + * - Set to false for a solid style progress bar. Set to true for a box-style progress bar. + */ + public static void drawProgressBar(String label, int maxProgress, int curProgress, int posX, int posY, int barWidth, int barHeight, int stringPosY, int color, boolean barStyle) { + OpenGL.pushMatrix(); + { + Gui.drawRect(posX + 0, posY + 0, posX + barWidth, posY + 5 + barHeight, 0x77000000); + + if (!barStyle && curProgress > maxProgress / barWidth) { + Gui.drawRect(posX + 1, posY + 1, posX + ((((curProgress * maxProgress) / maxProgress) * barWidth) / maxProgress) - 1, posY + 4 + barHeight, color); + Gui.drawRect(posX + 1, posY + 2 + (barHeight / 2), posX + ((((curProgress * maxProgress) / maxProgress) * barWidth) / maxProgress) - 1, posY + 4 + barHeight, 0x55000000); + } else if (curProgress > maxProgress / barWidth) { + int spaceBetweenBars = 1; + int amountOfBars = 70; + int widthOfBar = (barWidth / amountOfBars - spaceBetweenBars); + + for (int x = 1; x <= amountOfBars - ((curProgress * amountOfBars) / maxProgress); x++) { + int barStartX = (posX + widthOfBar) * (x) - widthOfBar; + + Gui.drawRect(barStartX + spaceBetweenBars * x, posY + 1, barStartX + widthOfBar + spaceBetweenBars * x, posY + 4 + barHeight, color); + Gui.drawRect(barStartX + spaceBetweenBars * x, posY + 2 + (barHeight / 2), barStartX + widthOfBar + spaceBetweenBars * x, posY + 4 + barHeight, 0x55000000); + } + } + + AccessHandler.getFontRenderer().drawStringWithShadow(label, posX + (barWidth / 2) - AccessHandler.getFontRenderer().getStringWidth(label) + (AccessHandler.getFontRenderer().getStringWidth(label) / 2), (posY - 1) + stringPosY, 0xFFFFFFFF); + } + OpenGL.popMatrix(); + } + + /** + * Draws a centered rectangle with an outline at the specified coordinates and the specified width, height, and color. + * + * @param x + * - x coordinate + * @param y + * - y coordinate + * @param w + * - Width of this rectangle + * @param h + * - Height of this rectangle + * @param borderWidth + * - Width of the rectangle's border + * @param fillColor + * - Color of the inner portion of this rectangle + * @param borderColor + * - Color of the border of this rectangle + */ + public static void drawCenteredRectWithOutline(int x, int y, int w, int h, int borderWidth, int fillColor, int borderColor) { + drawRect(x - w / 2 + borderWidth, y - h / 2, w, h, fillColor); + drawRect(x - w / 2 + borderWidth, y - h / 2, w, borderWidth, borderColor); + drawRect(x - w / 2, y + h / 2, w, borderWidth, borderColor); + drawRect(x - w / 2, y - h / 2, borderWidth, h, borderColor); + drawRect(x + w / 2, y - h / 2 + borderWidth, borderWidth, h, borderColor); + } + + /** + * Draws a rectangle with an outline at the specified coordinates and the specified width, height, and color. + * + * @param x + * - x coordinate + * @param y + * - y coordinate + * @param w + * - Width of this rectangle + * @param h + * - Height of this rectangle + * @param borderWidth + * - Width of the rectangle's border + * @param fillColor + * - Color of the inner portion of this rectangle + * @param borderColor + * - Color of the border of this rectangle + */ + public static void drawRectWithOutline(int x, int y, int w, int h, int borderWidth, int fillColor, int borderColor) { + int x1 = x; + int y1 = y; + int x2 = x + w; + int y2 = y + h; + + Gui.drawRect(x1, y1, x2, y2, fillColor); + Gui.drawRect(x1, y1, x2, y2 - h + borderWidth, borderColor); + Gui.drawRect(x1, y1 + h - borderWidth, x2, y2, borderColor); + Gui.drawRect(x1, y1 + borderWidth, x2 - w + borderWidth, y2 - borderWidth, borderColor); + Gui.drawRect(x1 + w - borderWidth, y1 + borderWidth, x2, y2 - borderWidth, borderColor); + } + + /** + * Draws an overlay across the entire screen using the specified ResourceLocation + * + * @param resource + * - The ResourceLocation to draw + */ + public static void drawOverlay(ResourceLocation resource) { + Draw.drawOverlay(resource, 1.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Draws an overlay across the entire screen using the specified ResourceLocation and an alpha value. + * + * @param resource + * - The ResourceLocation to draw + * @param a + * - Alpha value to render the overlay at. For transparency. + */ + public static void drawOverlay(ResourceLocation resource, float a) { + Draw.drawOverlay(resource, 1.0F, 1.0F, 1.0F, a); + } + + /** + * Draws an overlay across the entire screen using the specified ResourceLocation and 3 RGB color values. + * + * @param resource + * - The ResourceLocation to draw + * @param r + * - Red value to render the overlay at. + * @param g + * - Green value to render the overlay at. + * @param b + * - Blue value to render the overlay at. + */ + public static void drawOverlay(ResourceLocation resource, float r, float g, float b) { + Draw.drawOverlay(resource, r, g, b, 1.0F); + } + + /** + * Draws an overlay across the entire screen using the specified ResourceLocation and 4 RGBA color values. + * + * @param resource + * - The ResourceLocation to draw + * @param r + * - Red value to render the overlay at. + * @param g + * - Green value to render the overlay at. + * @param b + * - Blue value to render the overlay at. + * @param a + * - Alpha value to render the overlay at. For transparency. + */ + public static void drawOverlay(ResourceLocation resource, float r, float g, float b, float a) { + OpenGL.enableBlend(); + OpenGL.disableDepthTest(); + OpenGL.depthMask(false); + OpenGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + OpenGL.color(r, g, b, a); + OpenGL.disableAlphaTest(); + Draw.bindTexture(resource); + drawQuad(0, 0, Screen.scaledDisplayResolution().getScaledWidth(), Screen.scaledDisplayResolution().getScaledHeight()); + OpenGL.depthMask(true); + OpenGL.enableDepthTest(); + OpenGL.enableAlphaTest(); + OpenGL.color(1.0F, 1.0F, 1.0F, 1.0F); + OpenGL.disableBlend(); + } + + /** + * Draw the specified ModelBase instance at 0,0,0 with the specified ResourceLocation. + * + * @param model + * - ModelBase instance to draw. + * @param resource + * - ResourceLocation to draw on the ModelBase instance. + */ + public static void drawModel(ModelBase model, ResourceLocation resource) { + Draw.drawModel(null, model, resource, 0, 0, 0); + } + + /** + * Draw the specified ModelBase instance at the specified coordinates with the specified ResourceLocation. + * + * @param model + * - ModelBase instance to draw. + * @param resource + * - ResourceLocation to draw on the ModelBase instance. + * @param posX + * - x coordinate to draw this model at. + * @param posY + * - y coordinate to draw this model at. + * @param posZ + * - z coordinate to draw this model at. + */ + public static void drawModel(ModelBase model, ResourceLocation resource, double posX, double posY, double posZ) { + Draw.drawModel(null, model, resource, posX, posY, posZ); + } + + /** + * Draw the specified ModelBase instance at the specified coordinates with the specified ResourceLocation. + * + * @param entity + * - The entity class to provide the ModelBase instance with. + * @param model + * - ModelBase instance to draw. + * @param resource + * - ResourceLocation to draw on the ModelBase instance. + */ + public static void drawModel(Entity entity, ModelBase model, ResourceLocation resource) { + Draw.drawModel(entity, model, resource, 0, 0, 0); + } + + /** + * Draw the specified ModelBase instance at the specified coordinates with the specified ResourceLocation. + * + * @param entity + * - The entity class to provide the ModelBase instance with. + * @param model + * - ModelBase instance to draw. + * @param resource + * - ResourceLocation to draw on the ModelBase instance. + * @param posX + * - x coordinate to draw this model at. + * @param posY + * - y coordinate to draw this model at. + * @param posZ + * - z coordinate to draw this model at. + */ + public static void drawModel(Entity entity, ModelBase model, ResourceLocation resource, double posX, double posY, double posZ) { + OpenGL.disableCullFace(); + Draw.bindTexture(resource); + OpenGL.translate(posX, posY, posZ); + model.render(entity, 0, 0, 0, 0, 0, 0.625F); + } + + /** + * Draw the specified ModelBase instance at the specified coordinates with the specified ResourceLocation. + * + * @param model + * - ModelBase instance to draw. + * @param resource + * - ResourceLocation to draw on the ModelBase instance. + * @param x + * - x coordinate to draw this model at. + * @param y + * - y coordinate to draw this model at. + * @param scale + * - The scale this model should be rendered at. + */ + public static void drawShowcaseModel(ModelBase model, ResourceLocation resource, int x, int y, float scale) { + OpenGL.color(1.0F, 1.0F, 1.0F, 1.0F); + OpenGL.pushMatrix(); + OpenGL.translate(x, y - (scale * 0.43f), 10); + OpenGL.scale(0.06f * scale, 0.06f * scale, 1); + OpenGL.rotate(-20, 1, 0, 0); + OpenGL.rotate(205, 0, 1, 0); + OpenGL.disableCullFace(); + OpenGL.enableDepthTest(); + Draw.bindTexture(resource); + model.render(null, 0F, 0F, 0F, 0F, 0F, 0.0625F); + OpenGL.enableCullFace(); + OpenGL.disableDepthTest(); + OpenGL.popMatrix(); + } + + /** + * Draw the specified entity at the specified coordinates using the specified scale, yaw, and pitch. + * + * @param x + * - x coordinate + * @param y + * - y coordinate + * @param scale + * - The scale this model should be rendered at. + * @param yaw + * - The rotation yaw. + * @param pitch + * - The rotation pitch. + * @param entity + * - The Entity instance that is being rendered. + */ + public static void drawEntity(int x, int y, int scale, float yaw, float pitch, Entity entity) { + if (!AccessHandler.getMinecraft().world.isRemote) { + GlStateManager.enableColorMaterial(); + OpenGL.pushMatrix(); + { + OpenGL.translate(x, y, 100.0F); + OpenGL.scale(-scale, scale, scale); + OpenGL.rotate(180.0F, 0.0F, 0.0F, 1.0F); + OpenGL.rotate(yaw, 0.0F, 1.0F, 0.0F); + OpenGL.rotate(pitch, 1.0F, 0.0F, 0.0F); + AccessHandler.getMinecraft().getRenderManager().renderEntityStatic(entity, AccessHandler.getPartialTicks(), true); + OpenGL.enableLightMapping(); + } + OpenGL.popMatrix(); + } + } + + /** + * Draw the client player's face. Will default to a Steve face if one is not present. + * + * @param player + * - The client player + * @param x + * - x coordinate + * @param y + * - y coordinate + * @param width + * - Width to render the face at. + * @param height + * - Height to render the face at. + */ + public static void drawPlayerFace(EntityPlayer player, int x, int y, int width, int height) { + if (player instanceof AbstractClientPlayer) { + AbstractClientPlayer clientPlayer = (AbstractClientPlayer) player; + Draw.bindTexture(clientPlayer.getLocationSkin()); + drawQuad(x, y, width, height, 90, 0.125F, 0.25F, 0.125F, 0.25F); + drawQuad(x, y, width, height, 90, 0.625F, 0.75F, 0.125F, 0.25F); + } + } + + /** + * Draw the specified ResourceLocation at the specified coordinates and dimensions. + * + * @param resource + * - ResourceLocation to render + * @param posX + * - x coordinate + * @param posY + * - y coordinate + * @param width + * - Width to render this resource at. + * @param height + * - Height to render this resource at. + */ + public static void drawResource(ResourceLocation resource, int posX, int posY, int width, int height) { + Draw.drawResource(resource, posX, posY, width, height, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + } + + /** + * Draw the specified ResourceLocation at the specified coordinates and dimensions. + * + * @param resource + * - ResourceLocation to render + * @param posX + * - x coordinate + * @param posY + * - y coordinate + * @param width + * - Width to render this resource at. + * @param height + * - Height to render this resource at. + * @param r + * - Red value + * @param g + * - Green value + * @param b + * - Blue value + * @param a + * - Alpha value (Transparency) + */ + public static void drawResource(ResourceLocation resource, int posX, int posY, int width, int height, float r, float g, float b, float a) { + Draw.drawResource(resource, posX, posY, width, height, r, g, b, a, 1.0f, 1.0f); + } + + /** + * Draw the specified ResourceLocation at the specified coordinates and dimensions. + * + * @param resource + * - ResourceLocation to render + * @param posX + * - x coordinate + * @param posY + * - y coordinate + * @param width + * - Width to render this resource at. + * @param height + * - Height to render this resource at. + * @param r + * - Red value + * @param g + * - Green value + * @param b + * - Blue value + * @param a + * - Alpha value (Transparency) + * @param u + * - x coordinate of the texture offset + * @param v + * - y coordinate of the texture offset + */ + public static void drawResource(ResourceLocation resource, int posX, int posY, int width, int height, float r, float g, float b, float a, float u, float v) { + OpenGL.disableLighting(); + OpenGL.disableFog(); + Draw.bindTexture(resource); + OpenGL.color(r, g, b, a); + drawQuad(posX, posY, width, height, 0, 0, u, 0, v); + } + + /** + * Draw the specified ResourceLocation centered at the specified coordinates and dimensions. + * + * @param resource + * - ResourceLocation to render + * @param posX + * - x coordinate + * @param posY + * - y coordinate + * @param width + * - Width to render this resource at. + * @param height + * - Height to render this resource at. + */ + public static void drawResourceCentered(ResourceLocation resource, int posX, int posY, int width, int height) { + Draw.drawResourceCentered(resource, posX, posY, width, height, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + } + + /** + * Draw the specified ResourceLocation centered at the specified coordinates and dimensions. + * + * @param resource + * - ResourceLocation to render + * @param posX + * - x coordinate + * @param posY + * - y coordinate + * @param width + * - Width to render this resource at. + * @param height + * - Height to render this resource at. + * @param r + * - Red value + * @param g + * - Green value + * @param b + * - Blue value + * @param a + * - Alpha value (Transparency) + */ + public static void drawResourceCentered(ResourceLocation resource, int posX, int posY, int width, int height, float r, float g, float b, float a) { + Draw.drawResourceCentered(resource, posX, posY, width, height, r, g, b, a, 1.0f, 1.0f); + } + + /** + * Draw the specified ResourceLocation centered at the specified coordinates and dimensions. + * + * @param resource + * - ResourceLocation to render + * @param posX + * - x coordinate + * @param posY + * - y coordinate + * @param width + * - Width to render this resource at. + * @param height + * - Height to render this resource at. + * @param r + * - Red value + * @param g + * - Green value + * @param b + * - Blue value + * @param a + * - Alpha value (Transparency) + * @param u + * - x coordinate of the texture offset + * @param v + * - y coordinate of the texture offset + */ + public static void drawResourceCentered(ResourceLocation resource, int posX, int posY, int width, int height, float r, float g, float b, float a, float u, float v) { + OpenGL.disableLighting(); + OpenGL.disableFog(); + Draw.bindTexture(resource); + OpenGL.color(r, g, b, a); + drawQuad(posX - (width / 2), posY, width, height, 0, 0, u, 0, v); + } + + /** + * Draw the specified particle at the specified coordinates and dimensions. + * + * @param particleId + * - ID of the particle to draw + * @param x + * - x coordinate + * @param y + * - y coordinate + * @param width + * - Width to render the particle at + * @param height + * - Height to render the particle at + */ + public static void drawParticle(int index, int x, int y, int width, int height) { + float tS = 0.0624375F; + float u = (float) (index % 16) / 16.0F; + float mU = u + tS; + float v = (float) (index / 16) / 16.0F; + float mV = v + tS; + + Draw.bindTexture(GameResources.PARTICLES); + drawQuad(x, y, width, height, 0, u, mU, v, mV); + } + + public static void renderItem(ItemStack stack, int x, int y) { + OpenGL.pushMatrix(); + OpenGL.translate(0F, 0F, -100F); + + GlStateManager.pushMatrix(); + AccessHandler.getMinecraft().getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); + AccessHandler.getMinecraft().getTextureManager().getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).setBlurMipmap(false, false); + GlStateManager.enableRescaleNormal(); + GlStateManager.enableAlpha(); + GlStateManager.alphaFunc(516, 0.1F); + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + + GlStateManager.translate((float) x, (float) y, 100F); + GlStateManager.translate(8.0F, 8.0F, 0.0F); + GlStateManager.scale(1.0F, -1.0F, 1.0F); + GlStateManager.scale(16.0F, 16.0F, 16.0F); + + IBakedModel ibakedmodel = AccessHandler.getMinecraft().getRenderItem().getItemModelMesher().getItemModel(stack); + ibakedmodel = ibakedmodel.getOverrides().handleItemState(ibakedmodel, stack, AccessHandler.getMinecraft().world, AccessHandler.getMinecraft().player); + ibakedmodel = net.minecraftforge.client.ForgeHooksClient.handleCameraTransforms(ibakedmodel, ItemCameraTransforms.TransformType.GUI, false); + + AccessHandler.getMinecraft().getRenderItem().renderItem(stack, ibakedmodel); + GlStateManager.disableAlpha(); + GlStateManager.disableRescaleNormal(); + GlStateManager.disableLighting(); + GlStateManager.popMatrix(); + AccessHandler.getMinecraft().getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); + AccessHandler.getMinecraft().getTextureManager().getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).restoreLastBlurMipmap(); + + OpenGL.popMatrix(); + } + + /** + * Draw the specified itemstack in a GUI with a flat icon. No 3D rendering is done. + * + * @param stack + * - The itemstack to draw + * @param x + * - x coordinate + * @param y + * - y corodinate + * @param width + * - Width to render the icon at + * @param height + * - Height to render the icon at + * @param u + * - x coordinate of the texture offset + * @param v + * - y coordinate of the texture offset + */ + public static void drawItem(ItemStack stack, int x, int y, int width, int height) { + IBakedModel ibakedmodel = AccessHandler.getMinecraft().getRenderItem().getItemModelMesher().getItemModel(stack); + ibakedmodel = ibakedmodel.getOverrides().handleItemState(ibakedmodel, stack, AccessHandler.getMinecraft().world, AccessHandler.getMinecraft().player); + + GlStateManager.pushMatrix(); + GlStateManager.enableRescaleNormal(); + GlStateManager.enableAlpha(); + GlStateManager.alphaFunc(516, 0.1F); + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.disableLighting(); + Draw.bindTexture(getResourceLocationFullPath(ibakedmodel.getParticleTexture())); + Draw.drawQuad(x, y, width, height); + GlStateManager.disableAlpha(); + GlStateManager.disableRescaleNormal(); + GlStateManager.disableLighting(); + GlStateManager.popMatrix(); + } + + /** + * Binds a texture to OpenGL using Minecraft's render engine. + * + * @param resource + * - The ResourceLocation of the resource to bind. + */ + public static void bindTexture(ResourceLocation resource) { + AccessHandler.getMinecraft().renderEngine.bindTexture(resource); + } + + /** + * Get the full path of the specified ResourceLocation. Format: domain:path/to/resource.png + * + * @param resource + * - The ResourceLocation to retrieve a path of. + * @return The full path of the resource, including the domain. + */ + public static String getResourcePath(ResourceLocation resource) { + return String.format("%s:%s", resource.getResourceDomain(), resource.getResourcePath()); + } + + public static ResourceLocation getMissingTexture() { + return getResourceLocationPartialPath(AccessHandler.getMinecraft().getTextureMapBlocks().getMissingSprite()); + } + + public static ResourceLocation getResourceLocationFullPath(TextureAtlasSprite sprite) { + if (sprite != null) { + Minecraft mc = AccessHandler.getMinecraft(); + ResourceLocation r = new ResourceLocation(sprite.getIconName()); + return new ResourceLocation(r.getResourceDomain(), String.format("%s/%s%s", new Object[] { mc.getTextureMapBlocks().getBasePath(), r.getResourcePath(), ".png" })); + } + + return getMissingTexture(); + } + + public static ResourceLocation getResourceLocationPartialPath(TextureAtlasSprite sprite) { + if (sprite != null) { + ResourceLocation r = new ResourceLocation(sprite.getIconName()); + return new ResourceLocation(r.getResourceDomain(), String.format("%s", new Object[] { r.getResourcePath() })); + } + + return getMissingTexture(); + } + + public static void lightingHelper(Entity entity, float offset) { + + int brightness = Worlds.getLightAtCoord(entity.world, entity.getPosition()); + OpenGL.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, brightness % 65536, brightness / 65536); + OpenGL.color(1.0F, 1.0F, 1.0F); + } + + public static ArrayList wrapString(String string, int width) { + ArrayList strings = new ArrayList(); + int stringWidth = getStringRenderWidth(string); + + if (stringWidth > width) { + String currentLine = ""; + + for (String word : string.split(" ")) { + int wordWidth = getStringRenderWidth(word); + int currentLineWidth = getStringRenderWidth(currentLine); + + if ((currentLineWidth + wordWidth) <= width) { + currentLine = currentLine.isEmpty() ? word : currentLine + " " + word; + } else { + strings.add(currentLine); + currentLine = word; + } + } + + if (!currentLine.isEmpty()) { + strings.add(currentLine); + } + } else { + strings.add(string); + } + + return strings; + } + +} \ No newline at end of file diff --git a/src/main/java/cjminecraft/core/client/render/OpenGL.java b/src/main/java/cjminecraft/core/client/render/OpenGL.java new file mode 100644 index 0000000..2e78cee --- /dev/null +++ b/src/main/java/cjminecraft/core/client/render/OpenGL.java @@ -0,0 +1,439 @@ +package cjminecraft.core.client.render; + +import static org.lwjgl.opengl.GL11.GL_CLAMP; +import static org.lwjgl.opengl.GL11.GL_LINEAR; +import static org.lwjgl.opengl.GL11.GL_ONE; +import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA; +import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_S; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_T; +import static org.lwjgl.opengl.GL11.GL_ZERO; + +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.util.ArrayList; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +import cjminecraft.core.access.AccessHandler; +import cjminecraft.core.world.tile.IRotatableXAxis; +import cjminecraft.core.world.tile.IRotatableYAxis; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.texture.ITextureObject; +import net.minecraft.client.renderer.texture.SimpleTexture; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.client.shader.Framebuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +public class OpenGL { + public static ArrayList frameBuffers = new ArrayList(); + public static boolean lightmapTexUnitTextureEnable; + public static int lightmapTexUnit = OpenGlHelper.lightmapTexUnit; + public static int defaultTexUnit = OpenGlHelper.defaultTexUnit; + + public static void pushMatrix() { + GL11.glPushMatrix(); + } + + public static void popMatrix() { + GL11.glPopMatrix(); + } + + public static void translate(double offsetX, double offsetY, double offsetZ) { + GL11.glTranslated(offsetX, offsetY, offsetZ); + } + + public static void translate(float offsetX, float offsetY, float offsetZ) { + GL11.glTranslatef(offsetX, offsetY, offsetZ); + } + + public static void scale(double scaleX, double scaleY, double scaleZ) { + GL11.glScaled(scaleX, scaleY, scaleZ); + } + + public static void scale(float scaleX, float scaleY, float scaleZ) { + GL11.glScalef(scaleX, scaleY, scaleZ); + } + + public static void begin(int mode) { + GL11.glBegin(mode); + } + + public static void end() { + GL11.glEnd(); + } + + public static void newList(int list, int mode) { + GL11.glNewList(list, mode); + } + + public static void callList(int list) { + GL11.glCallList(list); + } + + public static void endList() { + GL11.glEndList(); + } + + public static void enableTexture2d() { + GlStateManager.enableTexture2D(); + } + + public static void disableTexture2d() { + GlStateManager.disableTexture2D(); + } + + public static void normal(float x, float y, float z) { + GL11.glNormal3f(x, y, z); + } + + public static void texCoord(float u, float v) { + GL11.glTexCoord2f(u, v); + } + + public static void vertex(float x, float y, float z) { + GL11.glVertex3f(x, y, z); + } + + public static void rotate(float angle, float x, float y, float z) { + GL11.glRotatef(angle, x, y, z); + } + + public static void enableBlend() { + GlStateManager.disableBlend(); + GlStateManager.enableBlend(); + } + + public static void disableBlend() { + GlStateManager.disableBlend(); + } + + public static void color(float r, float g, float b) { + GL11.glColor3f(r, g, b); + } + + public static void color(float r, float g, float b, float a) { + GL11.glColor4f(r, g, b, a); + } + + /** + * Same functionality as GlStateManager.color + * + * @param color + * - Hexadecimal color value + */ + public static void color4i(int color) { + float a = (color >> 24 & 255) / 255.0F; + float r = (color >> 16 & 255) / 255.0F; + float g = (color >> 8 & 255) / 255.0F; + float b = (color & 255) / 255.0F; + color(r, g, b, a); + } + + /** + * Same functionality as glColor3f + * + * @param color + * - Hexadecimal color value + */ + public static void color3i(int color) { + float r = (color >> 16 & 255) / 255.0F; + float g = (color >> 8 & 255) / 255.0F; + float b = (color & 255) / 255.0F; + color(r, g, b); + } + + public static String getString(int name) { + return GL11.glGetString(name); + } + + public static void enableDepthTest() { + GlStateManager.enableDepth(); + } + + public static void disableDepthTest() { + GlStateManager.disableDepth(); + } + + public static void enable(int cap) { + GL11.glEnable(cap); + } + + public static void disable(int cap) { + GL11.glDisable(cap); + } + + public static void blendFunc(int sfactor, int dfactor) { + GL11.glBlendFunc(sfactor, dfactor); + } + + public static void depthMask(boolean flag) { + GL11.glDepthMask(flag); + } + + public static void setLightmapTextureCoords(int lightmapTexUnit, float x, float y) { + OpenGlHelper.setLightmapTextureCoords(lightmapTexUnit, x, y); + } + + public static void setActiveTexture(int id) { + OpenGlHelper.setActiveTexture(id); + } + + public static void enableLighting() { + GlStateManager.enableLighting(); + } + + public static void disableLighting() { + GlStateManager.disableLighting(); + } + + public static boolean getBoolean(int pname) { + return GL11.glGetBoolean(pname); + } + + public static void texParameter(int target, int pname, int param) { + GL11.glTexParameteri(target, pname, param); + } + + public static void texParameter(int target, int pname, float param) { + GL11.glTexParameterf(target, pname, param); + } + + public static void texParameter(int target, int pname, FloatBuffer buffer) { + GL11.glTexParameter(target, pname, buffer); + } + + public static void texParameter(int target, int pname, IntBuffer buffer) { + GL11.glTexParameter(target, pname, buffer); + } + + /** + * @param resource + * - The ResourceLocation of which to get the GL texture ID from. + * @return Returns the GL texture ID of the specified ResourceLocation + */ + public static int getTextureId(ResourceLocation resource) { + Object object = AccessHandler.getMinecraft().getTextureManager().getTexture(resource); + object = object == null ? new SimpleTexture(resource) : object; + return ((ITextureObject) object).getGlTextureId(); + } + + public static void shadeSmooth() { + GL11.glShadeModel(GL11.GL_SMOOTH); + } + + public static void shadeFlat() { + GL11.glShadeModel(GL11.GL_FLAT); + } + + public static void enableRescaleNormal() { + enable(GL12.GL_RESCALE_NORMAL); + } + + public static void disableRescaleNormal() { + disable(GL12.GL_RESCALE_NORMAL); + } + + public static void enableStandardItemLighting() { + RenderHelper.enableStandardItemLighting(); + } + + public static void disableStandardItemLighting() { + RenderHelper.disableStandardItemLighting(); + } + + public static void enableAlphaTest() { + GlStateManager.enableAlpha(); + } + + public static void disableAlphaTest() { + GlStateManager.disableAlpha(); + } + + public static void readBuffer(int mode) { + GL11.glReadBuffer(mode); + } + + public static void readPixels(int x, int y, int width, int height, int format, int type, ByteBuffer pixels) { + GL11.glReadPixels(x, y, width, height, format, type, pixels); + } + + public static void enableCullFace() { + GlStateManager.enableCull(); + } + + public static void disableCullFace() { + GlStateManager.disableCull(); + } + + /** + * Disable lightmapping, enable GL_BLEND, and reset the colors to default + * values. + */ + public static void disableLightMapping() { + char light = 61680; + OpenGL.enableBlend(); + OpenGL.blendFunc(GL_ONE, GL_ONE); + OpenGL.depthMask(true); + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) light % 65536 / 1.0F, (float) light / 65536 / 1.0F); + OpenGL.color(1.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Enable lightmapping, disable GL_BLEND, and reset the colors to default + * values. + */ + public static void enableLightMapping() { + char light = 61680; + OpenGL.disableBlend(); + OpenGL.depthMask(true); + OpenGL.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) light % 65536 / 1.0F, (float) light / 65536 / 1.0F); + OpenGL.color(1.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Disable lighting + */ + public static void disableLight() { + OpenGL.setActiveTexture(OpenGL.lightmapTexUnit); + if (lightmapTexUnitTextureEnable = OpenGL.getBoolean(GL11.GL_TEXTURE_2D)) { + OpenGL.disableTexture2d(); + } + OpenGL.setActiveTexture(OpenGlHelper.defaultTexUnit); + OpenGL.disableLighting(); + } + + /** + * Enable lighting + */ + public static void enableLight() { + OpenGL.setActiveTexture(OpenGL.lightmapTexUnit); + if (lightmapTexUnitTextureEnable) { + OpenGL.enableTexture2d(); + } + OpenGL.setActiveTexture(OpenGL.defaultTexUnit); + OpenGL.enableLighting(); + } + + public static void blendClear() { + OpenGlHelper.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); + } + + /** + * Combonation of GL functions used to smooth out the rough edges of a 2D + * texture. + */ + public static void antiAlias2d() { + OpenGL.texParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + OpenGL.texParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + OpenGL.texParameter(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + OpenGL.texParameter(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + } + + public static void enableFog() { + GlStateManager.enableFog(); + } + + public static void disableFog() { + GlStateManager.disableFog(); + } + + public static void bindTexture(int target, int texture) { + GL11.glBindTexture(target, texture); + } + + public static void copyTexSubImage(int target, int level, int xoffset, int yoffset, int x, int y) { + GL11.glCopyTexSubImage1D(target, level, xoffset, yoffset, x, y); + } + + public static void copyTexSubImage(int target, int level, int xoffset, int yoffset, int x, int y, int width, int height) { + GL11.glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); + } + + public static void copyDownsizedRender(TextureManager manager, ResourceLocation target, int x, int y, int w, int h, int index) { + ITextureObject textureObject = manager.getTexture(target); + + if (textureObject != null) { + OpenGL.bindTexture(GL11.GL_TEXTURE_2D, textureObject.getGlTextureId()); + OpenGL.copyTexSubImage(GL11.GL_TEXTURE_2D, 0, index, index, x, y, w, h); + } + } + + public static Framebuffer createFrameBuffer(int width, int height, boolean useDepth) { + Framebuffer render = new Framebuffer(width, height, useDepth); + frameBuffers.add(render); + return render; + } + + public static void destroyFrameBuffer(Framebuffer buffer) { + OpenGL.enableDepthTest(); + if (buffer.framebufferObject >= 0) { + buffer.deleteFramebuffer(); + } + frameBuffers.remove(buffer); + } + + @SideOnly(Side.CLIENT) + public static void rotate(TileEntity tile) { + if (tile instanceof IRotatableYAxis) { + IRotatableYAxis rotatable = (IRotatableYAxis) tile; + + if (rotatable != null && rotatable.getRotationYAxis() != null) { + if (rotatable.getRotationYAxis() != null) { + if (rotatable.getRotationYAxis() == EnumFacing.NORTH) { + rotate(180F, 0F, 1F, 0F); + } + if (rotatable.getRotationYAxis() == EnumFacing.WEST) { + rotate(-90F, 0F, 1F, 0F); + } else if (rotatable.getRotationYAxis() == EnumFacing.EAST) { + rotate(90F, 0F, 1F, 0F); + } + } + } + } + + if (tile instanceof IRotatableXAxis) { + IRotatableXAxis rotatable = (IRotatableXAxis) tile; + + if (rotatable != null && rotatable.getRotationXAxis() != null) { + if (rotatable.getRotationXAxis() != null) { + if (rotatable.getRotationXAxis() == EnumFacing.DOWN) { + rotate(-180F, 1F, 0F, 0F); + } + } + } + } + } + + @SideOnly(Side.CLIENT) + public static void rotateOpposite(TileEntity tile) { + if (tile instanceof IRotatableYAxis) { + IRotatableYAxis rotatable = (IRotatableYAxis) tile; + + if (rotatable != null && rotatable.getRotationYAxis() != null) { + if (rotatable.getRotationYAxis() != null) { + if (rotatable.getRotationYAxis() == EnumFacing.SOUTH) { + rotate(180F, 0F, 1F, 0F); + } else if (rotatable.getRotationYAxis() == EnumFacing.NORTH) { + rotate(0F, 0F, 0F, 0F); + } else if (rotatable.getRotationYAxis() == EnumFacing.EAST) { + rotate(-90F, 0F, 1F, 0F); + } else if (rotatable.getRotationYAxis() == EnumFacing.WEST) { + rotate(90F, 0F, 1F, 0F); + } + } + } + } + } +} \ No newline at end of file diff --git a/src/main/java/cjminecraft/core/client/render/ScaledResolution.java b/src/main/java/cjminecraft/core/client/render/ScaledResolution.java new file mode 100644 index 0000000..be39469 --- /dev/null +++ b/src/main/java/cjminecraft/core/client/render/ScaledResolution.java @@ -0,0 +1,60 @@ +package cjminecraft.core.client.render; + +import net.minecraft.client.Minecraft; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class ScaledResolution { + private int scaledWidth; + private int scaledHeight; + private double scaledWidthD; + private double scaledHeightD; + private int scaleFactor; + + public ScaledResolution(Minecraft mc, int width, int height) { + this.scaledWidth = width; + this.scaledHeight = height; + this.scaleFactor = 1; + boolean flag = mc.getLanguageManager().isCurrentLocaleUnicode() || mc.gameSettings.forceUnicodeFont; + int scale = mc.gameSettings.guiScale; + + if (scale == 0) { + scale = 1000; + } + + while (this.scaleFactor < scale && this.scaledWidth / (this.scaleFactor + 1) >= 320 && this.scaledHeight / (this.scaleFactor + 1) >= 240) { + ++this.scaleFactor; + } + + if (flag && this.scaleFactor % 2 != 0 && this.scaleFactor != 1) { + --this.scaleFactor; + } + + this.scaledWidthD = (double) this.scaledWidth / (double) this.scaleFactor; + this.scaledHeightD = (double) this.scaledHeight / (double) this.scaleFactor; + this.scaledWidth = MathHelper.ceil(this.scaledWidthD); + this.scaledHeight = MathHelper.ceil(this.scaledHeightD); + } + + public int getScaledWidth() { + return this.scaledWidth; + } + + public int getScaledHeight() { + return this.scaledHeight; + } + + public double getScaledWidth_double() { + return this.scaledWidthD; + } + + public double getScaledHeight_double() { + return this.scaledHeightD; + } + + public int getScaleFactor() { + return this.scaleFactor; + } +} \ No newline at end of file diff --git a/src/main/java/cjminecraft/core/client/render/Screen.java b/src/main/java/cjminecraft/core/client/render/Screen.java new file mode 100644 index 0000000..204a846 --- /dev/null +++ b/src/main/java/cjminecraft/core/client/render/Screen.java @@ -0,0 +1,114 @@ +package cjminecraft.core.client.render; + +import static org.lwjgl.opengl.GL11.GL_RGBA; +import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE; + +import java.awt.Dimension; +import java.awt.Point; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.nio.ByteBuffer; + +import javax.imageio.ImageIO; +import javax.vecmath.Vector2d; + +import org.lwjgl.BufferUtils; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; + +import cjminecraft.core.access.AccessHandler; +import net.minecraft.client.Minecraft; + +public class Screen { + + /** + * Compatibility version of the ScaledResolution class. Returns the current game + * display resolution. + * + * @return Returns an instance of the compatibility version of ScaledResolution. + */ + public static ScaledResolution scaledDisplayResolution() { + return new ScaledResolution(AccessHandler.getMinecraft(), AccessHandler.getMinecraft().displayWidth, AccessHandler.getMinecraft().displayHeight); + } + + /** + * @return Returns a Vector2d instance containing the mouse's scaled coordinates + * in-game. + */ + public static Vector2d scaledMousePosition() { + final int SCALED_WIDTH = scaledDisplayResolution().getScaledWidth(); + final int SCALED_HEIGHT = scaledDisplayResolution().getScaledHeight(); + final int MOUSE_X = Mouse.getX() * SCALED_WIDTH / AccessHandler.getMinecraft().displayWidth; + final int MOUSE_Y = SCALED_HEIGHT - Mouse.getY() * SCALED_HEIGHT / AccessHandler.getMinecraft().displayHeight - 1; + return new Vector2d(MOUSE_X, MOUSE_Y); + } + + /** + * @return Returns the current game display width and height as a Dimension + */ + public static Dimension displayResolution() { + Minecraft mc = AccessHandler.getMinecraft(); + return new Dimension(mc.displayWidth, mc.displayHeight); + } + + /** + * @return Returns the mouse location in-game. + */ + public static Point getMouseLocation() { + ScaledResolution size = scaledDisplayResolution(); + Dimension res = displayResolution(); + return new Point(Mouse.getX() * size.getScaledWidth() / res.width, size.getScaledHeight() - Mouse.getY() * size.getScaledHeight() / res.height - 1); + } + + /** + * Saves a screenshot to the specified location. Default folder is the working + * directory: ".minecraft/" + * + * @param filename + * - File path and name to save the screenshot at. + * @param x + * - x coordinate to start screen capture + * @param y + * - y coordinate to start screen capture + * @param width + * - Width to capture screen at. + * @param height + * - Height to capture screen at. + */ + public static void saveScreenshot(String filename, int x, int y, int width, int height) { + File file = new File(AccessHandler.getMinecraft().mcDataDir.getPath()); + + if (!file.exists()) { + file.mkdirs(); + } + + if (AccessHandler.getMinecraft().ingameGUI != null && Keyboard.isKeyDown(Keyboard.KEY_F3) && Keyboard.isKeyDown(Keyboard.KEY_U)) { + try { + OpenGL.readBuffer(GL11.GL_FRONT); + int bpp = 4; + ByteBuffer pixels = BufferUtils.createByteBuffer(width * height * bpp); + OpenGL.readPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + String format = "png"; + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + + for (int px = x; px < width; px++) { + for (int py = y; py < height; py++) { + int i = (px + (width * py)) * bpp; + int r = pixels.get(i) & 0xFF; + int g = pixels.get(i + 1) & 0xFF; + int b = pixels.get(i + 2) & 0xFF; + image.setRGB(px, height - (py + 1), (0xFF << 24) | (r << 16) | (g << 8) | b); + } + } + + ImageIO.write(image, format, new File(file, filename)); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + +} \ No newline at end of file diff --git a/src/main/java/cjminecraft/core/client/render/Texture.java b/src/main/java/cjminecraft/core/client/render/Texture.java new file mode 100644 index 0000000..515e9c1 --- /dev/null +++ b/src/main/java/cjminecraft/core/client/render/Texture.java @@ -0,0 +1,24 @@ +package cjminecraft.core.client.render; + +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +public class Texture extends ResourceLocation { + public Texture(ResourceLocation resource) { + this(resource.getResourceDomain(), resource.getResourcePath()); + } + + public Texture(String location) { + super(location); + } + + public Texture(String domain, String location) { + super(domain, location); + } + + @SideOnly(Side.CLIENT) + public void bind() { + Draw.bindTexture(this); + } +} \ No newline at end of file diff --git a/src/main/java/cjminecraft/core/client/render/UV.java b/src/main/java/cjminecraft/core/client/render/UV.java new file mode 100644 index 0000000..3d60491 --- /dev/null +++ b/src/main/java/cjminecraft/core/client/render/UV.java @@ -0,0 +1,39 @@ +package cjminecraft.core.client.render; + +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.Vec3d; + +public class UV { + public float u; + public float v; + + public UV(float u, float v) { + this.u = u; + this.v = v; + } + + public UV(EnumFacing facing, Vec3d vec3d) { + switch (facing.getAxis()) { + case X: + this.u = Math.round(vec3d.z * 16); + this.v = Math.round(vec3d.y * 16); + break; + case Y: + this.u = Math.round(vec3d.x * 16); + this.v = Math.round(vec3d.z * 16); + break; + case Z: + this.u = Math.round(vec3d.x * 16); + this.v = Math.round(vec3d.y * 16); + break; + } + } + + public float getU() { + return u; + } + + public float getV() { + return v; + } +} \ No newline at end of file diff --git a/src/main/java/cjminecraft/core/client/render/Vertex.java b/src/main/java/cjminecraft/core/client/render/Vertex.java new file mode 100644 index 0000000..49087f1 --- /dev/null +++ b/src/main/java/cjminecraft/core/client/render/Vertex.java @@ -0,0 +1,71 @@ +package cjminecraft.core.client.render; + +import net.minecraft.client.renderer.Tessellator; + +public class Vertex { + public static Vertex unitX = new Vertex(1, 0, 0); + public static Vertex unitY = new Vertex(0, 1, 0); + public static Vertex unitZ = new Vertex(0, 0, 1); + public static Vertex unitNX = new Vertex(-1, 0, 0); + public static Vertex unitNY = new Vertex(0, -1, 0); + public static Vertex unitNZ = new Vertex(0, 0, -1); + public static Vertex unitPYNZ = new Vertex(0, 0.707, -0.707); + public static Vertex unitPXPY = new Vertex(0.707, 0.707, 0); + public static Vertex unitPYPZ = new Vertex(0, 0.707, 0.707); + public static Vertex unitNXPY = new Vertex(-0.707, 0.707, 0); + + public float x, y, z; + + public Vertex(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + } + + public Vertex(double x, double y, double z) { + this((float) x, (float) y, (float) z); + } + + public Vertex(int x, int y, int z) { + this((float) x, (float) y, (float) z); + } + + public Vertex normalize() { + float sq = (float) Math.sqrt(x * x + y * y + z * z); + x = x / sq; + y = y / sq; + z = z / sq; + return this; + } + + public Vertex tessellate(Tessellator tessellator) { + return this.tessellateWithUV(tessellator, null); + } + + public Vertex tessellateWithUV(Tessellator tessellator, UV uv) { + if (uv == null) { + tessellator.getBuffer().pos(x, y, z); + } else { + tessellator.getBuffer().pos(x, y, z); + tessellator.getBuffer().tex(uv.u, uv.v); + } + return this; + } + + public Vertex add(double x, double y, double z) { + return new Vertex(this.x + x, this.y + y, this.z + z); + } + + public Vertex add(Vertex v) { + return add(v.x, v.y, v.z); + } + + public Vertex mul(double c) { + return new Vertex(c * x, c * y, c * z); + } + + @Override + public String toString() { + return String.format("Vertex(%s, %s, %s)", this.x, this.y, this.z); + } +} \ No newline at end of file From af251715af841b9c768560c226e748e30030d154 Mon Sep 17 00:00:00 2001 From: Hypeirochus Date: Tue, 12 Jun 2018 14:31:10 -0400 Subject: [PATCH 04/19] Added electric arc particles. --- .../client/particle/EntityFXElectricArc.java | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 src/main/java/cjminecraft/core/client/particle/EntityFXElectricArc.java diff --git a/src/main/java/cjminecraft/core/client/particle/EntityFXElectricArc.java b/src/main/java/cjminecraft/core/client/particle/EntityFXElectricArc.java new file mode 100644 index 0000000..7f22bee --- /dev/null +++ b/src/main/java/cjminecraft/core/client/particle/EntityFXElectricArc.java @@ -0,0 +1,142 @@ +package cjminecraft.core.client.particle; + +import java.util.Random; + +import org.lwjgl.opengl.GL11; + +import cjminecraft.core.client.GameResources; +import cjminecraft.core.client.render.OpenGL; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.entity.Entity; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; + +public class EntityFXElectricArc extends Particle { + private static final ResourceLocation PARTICLES = new ResourceLocation("textures/particle/particles.png"); + + private Random rand; + private int color; + private int tessellation; + private float rotYaw; + private float rotPitch; + private float density; + private double targetX; + private double targetY; + private double targetZ; + private double displacement; + private double complexity; + + public EntityFXElectricArc(World world, double x, double y, double z, double targetX, double targetY, double targetZ, int age) { + this(world, x, y, z, targetX, targetY, targetZ, age, 1.6D, 0.1D, 0.1F, 0xFFAA99FF); + } + + public EntityFXElectricArc(World world, double x, double y, double z, double targetX, double targetY, double targetZ, int age, int color) { + this(world, x, y, z, targetX, targetY, targetZ, age, 1.6D, 0.1D, 0.1F, color); + } + + public EntityFXElectricArc(World world, double x, double y, double z, double targetX, double targetY, double targetZ, int age, double displacement, double complexity, float density, int color) { + super(world, x, y, z); + this.rand = new Random(); + this.tessellation = 2; + this.particleMaxAge = age; + this.targetX = targetX; + this.targetY = targetY; + this.targetZ = targetZ; + this.displacement = displacement; + this.complexity = complexity; + this.density = density; + this.color = color; + this.changeDirection((float) (this.posX - this.targetX), (float) (this.posY - this.targetY), (float) (this.posZ - this.targetZ)); + } + + @Override + public void renderParticle(BufferBuilder buffer, Entity entity, float partialTicks, float rX, float rZ, float rYZ, float rXY, float rXZ) { + GameResources.BLANK.bind(); + this.drawArc(buffer, posX, posY, posZ, targetX, targetY, targetZ, displacement, complexity, density); + } + + public EntityFXElectricArc setTessellation(int tessellation) { + this.tessellation = tessellation; + return this; + } + + private void changeDirection(float x, float y, float z) { + double variance = MathHelper.sqrt(x * x + z * z); + this.rotYaw = ((float) (Math.atan2(x, z) * 180.0D / Math.PI)); + this.rotPitch = ((float) (Math.atan2(y, variance) * 180.0D / Math.PI)); + } + + private void drawArc(BufferBuilder buffer, double x, double y, double z, double targetX, double targetY, double targetZ, double displacement, double complexity, float density) { + if (displacement < complexity) { + float rx = (float) (x - targetX); + float ry = (float) (y - targetY); + float rz = (float) (z - targetZ); + + this.changeDirection(rx, ry, rz); + + OpenGL.pushMatrix(); + OpenGL.translate((float) (x - interpPosX), (float) (y - interpPosY), (float) (z - interpPosZ)); + OpenGL.enableBlend(); + OpenGL.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_CURRENT_BIT); + OpenGL.disableCullFace(); + OpenGL.rotate(90.0F, 1.0F, 0.0F, 0.0F); + OpenGL.rotate(180.0F + this.rotYaw, 0.0F, 0.0F, -1.0F); + OpenGL.rotate(this.rotPitch, 1.0F, 0.0F, 0.0F); + OpenGL.disableLightMapping(); + OpenGL.disableLight(); + + double vX1 = density * -0.15; + double vX2 = density * -0.15 * 1.0; + double vY2 = MathHelper.sqrt(rx * rx + ry * ry + rz * rz); + double vY1 = 0.0D; + + int a = (color >> 24 & 255); + int r = (color >> 16 & 255); + int g = (color >> 8 & 255); + int b = (color & 255); + + for (int i2 = 0; i2 < tessellation; i2++) { + GlStateManager.rotate((360F / tessellation) / 2, 0.0F, 1.0F, 0.0F); + OpenGL.color(r / 255F, g / 255F, b / 255F, a / 255F); + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + buffer.pos(vX2, vY2, 0).color(255, 255, 255, 255).endVertex(); + buffer.pos(vX1, vY1, 0).color(255, 255, 255, 255).endVertex(); + buffer.pos(-vX1, vY1, 0).color(255, 255, 255, 255).endVertex(); + buffer.pos(-vX2, vY2, 0).color(255, 255, 255, 255).endVertex(); + Tessellator.getInstance().draw(); + } + + OpenGL.enableLight(); + OpenGL.color(1.0F, 1.0F, 1.0F, 1.0F); + OpenGL.enableCullFace(); + OpenGL.disableBlend(); + OpenGL.popMatrix(); + } else { + double splitX = (targetX + x) / 2; + double splitY = (targetY + y) / 2; + double splitZ = (targetZ + z) / 2; + splitX += (rand.nextFloat() - 0.5) * displacement; + splitY += (rand.nextFloat() - 0.5) * displacement; + splitZ += (rand.nextFloat() - 0.5) * displacement; + drawArc(buffer, x, y, z, splitX, splitY, splitZ, displacement / 2, complexity, density); + drawArc(buffer, targetX, targetY, targetZ, splitX, splitY, splitZ, displacement / 2, complexity, density); + } + } + + @Override + public void onUpdate() { + if (this.particleAge++ > this.particleMaxAge) { + this.setExpired(); + } + } + + @Override + public int getFXLayer() { + return 3; + } +} \ No newline at end of file From d9a1d879ca9c940b67257b4600e2804aecea4d2c Mon Sep 17 00:00:00 2001 From: Hypeirochus Date: Tue, 12 Jun 2018 14:31:46 -0400 Subject: [PATCH 05/19] Added storm and cloud handlers. --- .../client/render/world/CloudProvider.java | 189 ++++++++++ .../client/render/world/IClimateProvider.java | 7 + .../client/render/world/ICloudProvider.java | 34 ++ .../client/render/world/IStormProvider.java | 55 +++ .../client/render/world/StormProvider.java | 351 ++++++++++++++++++ 5 files changed, 636 insertions(+) create mode 100644 src/main/java/cjminecraft/core/client/render/world/CloudProvider.java create mode 100644 src/main/java/cjminecraft/core/client/render/world/IClimateProvider.java create mode 100644 src/main/java/cjminecraft/core/client/render/world/ICloudProvider.java create mode 100644 src/main/java/cjminecraft/core/client/render/world/IStormProvider.java create mode 100644 src/main/java/cjminecraft/core/client/render/world/StormProvider.java diff --git a/src/main/java/cjminecraft/core/client/render/world/CloudProvider.java b/src/main/java/cjminecraft/core/client/render/world/CloudProvider.java new file mode 100644 index 0000000..0eb8ab3 --- /dev/null +++ b/src/main/java/cjminecraft/core/client/render/world/CloudProvider.java @@ -0,0 +1,189 @@ +package cjminecraft.core.client.render.world; + +import org.lwjgl.opengl.GL11; + +import cjminecraft.core.access.AccessHandler; +import cjminecraft.core.client.render.OpenGL; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.WorldClient; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; +import net.minecraftforge.client.IRenderHandler; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +//@EventBusSubscriber +public abstract class CloudProvider extends IRenderHandler implements ICloudProvider { + protected float cloudSpeed = getMaxNormalCloudSpeed(); + protected long cloudTicks; + protected long cloudTicksPrev; + + @SideOnly(Side.CLIENT) + @SubscribeEvent + public static void updateClouds(ClientTickEvent event) { + World world = AccessHandler.getMinecraft().world; + + if (world != null && !AccessHandler.getMinecraft().isGamePaused()) { + if (world.provider instanceof IClimateProvider) { + IClimateProvider weatherProvider = (IClimateProvider) world.provider; + + if (weatherProvider.getCloudProvider() instanceof StormProvider) { + CloudProvider clouds = (CloudProvider) weatherProvider.getCloudProvider(); + IStormProvider storms = (StormProvider) weatherProvider.getStormProvider(); + + if (clouds.areCloudsApplicableTo(world.provider) && storms instanceof IStormProvider) { + if (storms.isStormActive(world)) { + if (clouds.cloudSpeed < clouds.getMaxCloudSpeedDuringStorm()) { + clouds.cloudSpeed += 0.0125F; + } + } else { + if (clouds.cloudSpeed > clouds.getMaxNormalCloudSpeed()) { + clouds.cloudSpeed -= 0.0125F; + } + } + + clouds.cloudTicksPrev = clouds.cloudTicks; + clouds.cloudTicks += clouds.cloudSpeed; + } + } + } + } + } + + @SideOnly(Side.CLIENT) + @Override + public void render(float partialTicks, WorldClient world, Minecraft mc) { + if (world.provider instanceof IClimateProvider) { + IClimateProvider weatherProvider = (IClimateProvider) world.provider; + ICloudProvider clouds = (ICloudProvider) weatherProvider.getCloudProvider(); + + if (clouds.areCloudsApplicableTo(world.provider)) { + if (AccessHandler.getMinecraft().gameSettings.shouldRenderClouds() >= 1) { + OpenGL.pushMatrix(); + { + if (AccessHandler.getMinecraft().gameSettings.fancyGraphics) { + OpenGL.enable(GL11.GL_FOG); + } + + this.renderClouds(partialTicks); + OpenGL.disable(GL11.GL_FOG); + } + OpenGL.popMatrix(); + } + } + } + } + + @SideOnly(Side.CLIENT) + public void renderClouds(float renderPartialTicks) { + GlStateManager.disableCull(); + Entity entity = AccessHandler.getMinecraft().getRenderViewEntity(); + float yOffset = (float) (entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * (double) renderPartialTicks); + byte cloudSections = 4; + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder vertexbuffer = tessellator.getBuffer(); + double viewX = (entity.prevPosX + (entity.posX - entity.prevPosX) * (double) renderPartialTicks + getCloudMovementX(entity.world, cloudTicksPrev, cloudTicks) * 0.029999999329447746D) / 12.0D; + double viewZ = (entity.prevPosZ + (entity.posZ - entity.prevPosZ) * (double) renderPartialTicks + getCloudMovementZ(entity.world, cloudTicksPrev, cloudTicks) * 0.029999999329447746D) / 12.0D; + float cloudHeight = AccessHandler.getMinecraft().world.provider.getCloudHeight() - yOffset + 0.33F; + viewX = viewX - (double) (MathHelper.floor(viewX / 2048.0D) * 2048); + viewZ = viewZ - (double) (MathHelper.floor(viewZ / 2048.0D) * 2048); + getCloudTexture().bind(); + GlStateManager.enableBlend(); + GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); + + float r = (float) entity.world.provider.getCloudColor(renderPartialTicks).x; + float g = (float) entity.world.provider.getCloudColor(renderPartialTicks).y; + float b = (float) entity.world.provider.getCloudColor(renderPartialTicks).z; + + float f17 = (float) MathHelper.floor(viewX) * 0.00390625F; + float f18 = (float) MathHelper.floor(viewZ) * 0.00390625F; + float f19 = (float) (viewX - (double) MathHelper.floor(viewX - 6)); + float f20 = (float) (viewZ - (double) MathHelper.floor(viewZ - 6)); + GlStateManager.scale(12.0F, 1.0F, 12.0F); + + for (int pass = 0; pass < 2; ++pass) { + if (pass == 0) { + GL11.glColorMask(false, false, false, false); + } else { + GL11.glColorMask(true, true, true, true); + } + + for (int x = -cloudSections + 1; x <= cloudSections; ++x) { + for (int z = -cloudSections + 1; z <= cloudSections; ++z) { + vertexbuffer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR_NORMAL); + float cU = (float) (x * 8); + float cV = (float) (z * 8); + float cX = cU - f19; + float cZ = cV - f20; + + if (cloudHeight > -5.0F) { + vertexbuffer.pos((double) (cX + 0.0F), (double) (cloudHeight + 0.0F), (double) (cZ + 8.0F)).tex((double) ((cU + 0.0F) * 0.00390625F + f17), (double) ((cV + 8.0F) * 0.00390625F + f18)).color(r * 0.7F, g * 0.7F, b * 0.7F, 0.8F).normal(0.0F, -1.0F, 0.0F).endVertex(); + vertexbuffer.pos((double) (cX + 8.0F), (double) (cloudHeight + 0.0F), (double) (cZ + 8.0F)).tex((double) ((cU + 8.0F) * 0.00390625F + f17), (double) ((cV + 8.0F) * 0.00390625F + f18)).color(r * 0.7F, g * 0.7F, b * 0.7F, 0.8F).normal(0.0F, -1.0F, 0.0F).endVertex(); + vertexbuffer.pos((double) (cX + 8.0F), (double) (cloudHeight + 0.0F), (double) (cZ + 0.0F)).tex((double) ((cU + 8.0F) * 0.00390625F + f17), (double) ((cV + 0.0F) * 0.00390625F + f18)).color(r * 0.7F, g * 0.7F, b * 0.7F, 0.8F).normal(0.0F, -1.0F, 0.0F).endVertex(); + vertexbuffer.pos((double) (cX + 0.0F), (double) (cloudHeight + 0.0F), (double) (cZ + 0.0F)).tex((double) ((cU + 0.0F) * 0.00390625F + f17), (double) ((cV + 0.0F) * 0.00390625F + f18)).color(r * 0.7F, g * 0.7F, b * 0.7F, 0.8F).normal(0.0F, -1.0F, 0.0F).endVertex(); + } + + if (cloudHeight <= 5.0F) { + vertexbuffer.pos((double) (cX + 0.0F), (double) (cloudHeight + 4.0F - 9.765625E-4F), (double) (cZ + 8.0F)).tex((double) ((cU + 0.0F) * 0.00390625F + f17), (double) ((cV + 8.0F) * 0.00390625F + f18)).color(r, g, b, 0.8F).normal(0.0F, 1.0F, 0.0F).endVertex(); + vertexbuffer.pos((double) (cX + 8.0F), (double) (cloudHeight + 4.0F - 9.765625E-4F), (double) (cZ + 8.0F)).tex((double) ((cU + 8.0F) * 0.00390625F + f17), (double) ((cV + 8.0F) * 0.00390625F + f18)).color(r, g, b, 0.8F).normal(0.0F, 1.0F, 0.0F).endVertex(); + vertexbuffer.pos((double) (cX + 8.0F), (double) (cloudHeight + 4.0F - 9.765625E-4F), (double) (cZ + 0.0F)).tex((double) ((cU + 8.0F) * 0.00390625F + f17), (double) ((cV + 0.0F) * 0.00390625F + f18)).color(r, g, b, 0.8F).normal(0.0F, 1.0F, 0.0F).endVertex(); + vertexbuffer.pos((double) (cX + 0.0F), (double) (cloudHeight + 4.0F - 9.765625E-4F), (double) (cZ + 0.0F)).tex((double) ((cU + 0.0F) * 0.00390625F + f17), (double) ((cV + 0.0F) * 0.00390625F + f18)).color(r, g, b, 0.8F).normal(0.0F, 1.0F, 0.0F).endVertex(); + } + + if (x > -1) { + for (int v = 0; v < 8; ++v) { + vertexbuffer.pos((double) (cX + (float) v + 0.0F), (double) (cloudHeight + 0.0F), (double) (cZ + 8.0F)).tex((double) ((cU + (float) v + 0.5F) * 0.00390625F + f17), (double) ((cV + 8.0F) * 0.00390625F + f18)).color(r * 0.9F, g * 0.9F, b * 0.9F, 0.8F).normal(-1.0F, 0.0F, 0.0F).endVertex(); + vertexbuffer.pos((double) (cX + (float) v + 0.0F), (double) (cloudHeight + 4.0F), (double) (cZ + 8.0F)).tex((double) ((cU + (float) v + 0.5F) * 0.00390625F + f17), (double) ((cV + 8.0F) * 0.00390625F + f18)).color(r * 0.9F, g * 0.9F, b * 0.9F, 0.8F).normal(-1.0F, 0.0F, 0.0F).endVertex(); + vertexbuffer.pos((double) (cX + (float) v + 0.0F), (double) (cloudHeight + 4.0F), (double) (cZ + 0.0F)).tex((double) ((cU + (float) v + 0.5F) * 0.00390625F + f17), (double) ((cV + 0.0F) * 0.00390625F + f18)).color(r * 0.9F, g * 0.9F, b * 0.9F, 0.8F).normal(-1.0F, 0.0F, 0.0F).endVertex(); + vertexbuffer.pos((double) (cX + (float) v + 0.0F), (double) (cloudHeight + 0.0F), (double) (cZ + 0.0F)).tex((double) ((cU + (float) v + 0.5F) * 0.00390625F + f17), (double) ((cV + 0.0F) * 0.00390625F + f18)).color(r * 0.9F, g * 0.9F, b * 0.9F, 0.8F).normal(-1.0F, 0.0F, 0.0F).endVertex(); + } + } + + if (x <= 1) { + for (int v = 0; v < 8; ++v) { + vertexbuffer.pos((double) (cX + (float) v + 1.0F - 9.765625E-4F), (double) (cloudHeight + 0.0F), (double) (cZ + 8.0F)).tex((double) ((cU + (float) v + 0.5F) * 0.00390625F + f17), (double) ((cV + 8.0F) * 0.00390625F + f18)).color(r * 0.9F, g * 0.9F, b * 0.9F, 0.8F).normal(1.0F, 0.0F, 0.0F).endVertex(); + vertexbuffer.pos((double) (cX + (float) v + 1.0F - 9.765625E-4F), (double) (cloudHeight + 4.0F), (double) (cZ + 8.0F)).tex((double) ((cU + (float) v + 0.5F) * 0.00390625F + f17), (double) ((cV + 8.0F) * 0.00390625F + f18)).color(r * 0.9F, g * 0.9F, b * 0.9F, 0.8F).normal(1.0F, 0.0F, 0.0F).endVertex(); + vertexbuffer.pos((double) (cX + (float) v + 1.0F - 9.765625E-4F), (double) (cloudHeight + 4.0F), (double) (cZ + 0.0F)).tex((double) ((cU + (float) v + 0.5F) * 0.00390625F + f17), (double) ((cV + 0.0F) * 0.00390625F + f18)).color(r * 0.9F, g * 0.9F, b * 0.9F, 0.8F).normal(1.0F, 0.0F, 0.0F).endVertex(); + vertexbuffer.pos((double) (cX + (float) v + 1.0F - 9.765625E-4F), (double) (cloudHeight + 0.0F), (double) (cZ + 0.0F)).tex((double) ((cU + (float) v + 0.5F) * 0.00390625F + f17), (double) ((cV + 0.0F) * 0.00390625F + f18)).color(r * 0.9F, g * 0.9F, b * 0.9F, 0.8F).normal(1.0F, 0.0F, 0.0F).endVertex(); + } + } + + if (z > -1) { + for (int v = 0; v < 8; ++v) { + vertexbuffer.pos((double) (cX + 0.0F), (double) (cloudHeight + 4.0F), (double) (cZ + (float) v + 0.0F)).tex((double) ((cU + 0.0F) * 0.00390625F + f17), (double) ((cV + (float) v + 0.5F) * 0.00390625F + f18)).color(r * 0.8F, g * 0.8F, b * 0.8F, 0.8F).normal(0.0F, 0.0F, -1.0F).endVertex(); + vertexbuffer.pos((double) (cX + 8.0F), (double) (cloudHeight + 4.0F), (double) (cZ + (float) v + 0.0F)).tex((double) ((cU + 8.0F) * 0.00390625F + f17), (double) ((cV + (float) v + 0.5F) * 0.00390625F + f18)).color(r * 0.8F, g * 0.8F, b * 0.8F, 0.8F).normal(0.0F, 0.0F, -1.0F).endVertex(); + vertexbuffer.pos((double) (cX + 8.0F), (double) (cloudHeight + 0.0F), (double) (cZ + (float) v + 0.0F)).tex((double) ((cU + 8.0F) * 0.00390625F + f17), (double) ((cV + (float) v + 0.5F) * 0.00390625F + f18)).color(r * 0.8F, g * 0.8F, b * 0.8F, 0.8F).normal(0.0F, 0.0F, -1.0F).endVertex(); + vertexbuffer.pos((double) (cX + 0.0F), (double) (cloudHeight + 0.0F), (double) (cZ + (float) v + 0.0F)).tex((double) ((cU + 0.0F) * 0.00390625F + f17), (double) ((cV + (float) v + 0.5F) * 0.00390625F + f18)).color(r * 0.8F, g * 0.8F, b * 0.8F, 0.8F).normal(0.0F, 0.0F, -1.0F).endVertex(); + } + } + + if (z <= 1) { + for (int v = 0; v < 8; ++v) { + vertexbuffer.pos((double) (cX + 0.0F), (double) (cloudHeight + 4.0F), (double) (cZ + (float) v + 1.0F - 9.765625E-4F)).tex((double) ((cU + 0.0F) * 0.00390625F + f17), (double) ((cV + (float) v + 0.5F) * 0.00390625F + f18)).color(r * 0.8F, g * 0.8F, b * 0.8F, 0.8F).normal(0.0F, 0.0F, 1.0F).endVertex(); + vertexbuffer.pos((double) (cX + 8.0F), (double) (cloudHeight + 4.0F), (double) (cZ + (float) v + 1.0F - 9.765625E-4F)).tex((double) ((cU + 8.0F) * 0.00390625F + f17), (double) ((cV + (float) v + 0.5F) * 0.00390625F + f18)).color(r * 0.8F, g * 0.8F, b * 0.8F, 0.8F).normal(0.0F, 0.0F, 1.0F).endVertex(); + vertexbuffer.pos((double) (cX + 8.0F), (double) (cloudHeight + 0.0F), (double) (cZ + (float) v + 1.0F - 9.765625E-4F)).tex((double) ((cU + 8.0F) * 0.00390625F + f17), (double) ((cV + (float) v + 0.5F) * 0.00390625F + f18)).color(r * 0.8F, g * 0.8F, b * 0.8F, 0.8F).normal(0.0F, 0.0F, 1.0F).endVertex(); + vertexbuffer.pos((double) (cX + 0.0F), (double) (cloudHeight + 0.0F), (double) (cZ + (float) v + 1.0F - 9.765625E-4F)).tex((double) ((cU + 0.0F) * 0.00390625F + f17), (double) ((cV + (float) v + 0.5F) * 0.00390625F + f18)).color(r * 0.8F, g * 0.8F, b * 0.8F, 0.8F).normal(0.0F, 0.0F, 1.0F).endVertex(); + } + } + + tessellator.draw(); + } + } + } + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.disableBlend(); + GlStateManager.enableCull(); + } + + @Override + public float getCloudMovementSpeed(World world) { + return cloudSpeed; + } +} \ No newline at end of file diff --git a/src/main/java/cjminecraft/core/client/render/world/IClimateProvider.java b/src/main/java/cjminecraft/core/client/render/world/IClimateProvider.java new file mode 100644 index 0000000..32e8436 --- /dev/null +++ b/src/main/java/cjminecraft/core/client/render/world/IClimateProvider.java @@ -0,0 +1,7 @@ +package cjminecraft.core.client.render.world; + +public interface IClimateProvider { + public ICloudProvider getCloudProvider(); + + public IStormProvider getStormProvider(); +} \ No newline at end of file diff --git a/src/main/java/cjminecraft/core/client/render/world/ICloudProvider.java b/src/main/java/cjminecraft/core/client/render/world/ICloudProvider.java new file mode 100644 index 0000000..c141bd9 --- /dev/null +++ b/src/main/java/cjminecraft/core/client/render/world/ICloudProvider.java @@ -0,0 +1,34 @@ +package cjminecraft.core.client.render.world; + +import cjminecraft.core.access.AccessHandler; +import cjminecraft.core.client.render.Texture; +import cjminecraft.core.util.MathUtils; +import net.minecraft.world.World; +import net.minecraft.world.WorldProvider; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +public interface ICloudProvider { + public float getCloudMovementSpeed(World world); + + public default float getMaxCloudSpeedDuringStorm() { + return 12F; + } + + public default float getMaxNormalCloudSpeed() { + return 2F; + } + + @SideOnly(Side.CLIENT) + public Texture getCloudTexture(); + + public default double getCloudMovementX(World world, float cloudTicksPrev, float cloudTicks) { + return MathUtils.interpolateRotation(cloudTicksPrev, cloudTicks, AccessHandler.getPartialTicks()); + } + + public default double getCloudMovementZ(World world, float cloudTicksPrev, float cloudTicks) { + return 0; + } + + public boolean areCloudsApplicableTo(WorldProvider provider); +} \ No newline at end of file diff --git a/src/main/java/cjminecraft/core/client/render/world/IStormProvider.java b/src/main/java/cjminecraft/core/client/render/world/IStormProvider.java new file mode 100644 index 0000000..55fa77d --- /dev/null +++ b/src/main/java/cjminecraft/core/client/render/world/IStormProvider.java @@ -0,0 +1,55 @@ +package cjminecraft.core.client.render.world; + +import cjminecraft.core.client.render.Texture; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.WorldClient; +import net.minecraft.init.SoundEvents; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.SoundCategory; +import net.minecraft.world.World; +import net.minecraft.world.WorldProvider; +import net.minecraft.world.biome.Biome; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +public interface IStormProvider { + public boolean isStormApplicableTo(WorldProvider provider); + + public boolean isStormActive(World world); + + public float getStormStrength(); + + public float getStormDensity(); + + public int getStormSize(); + + public boolean isStormVisibleInBiome(Biome biome); + + public float getStormDownfallSpeed(); + + public float getStormWindSpeed(); + + public boolean doesLightingApply(); + + public float getStormDirection(); + + @SideOnly(Side.CLIENT) + public Texture getStormTexture(World world, Biome biome); + + public default void spawnParticleOnGround(World world, double pX, double pY, double pZ) { + world.spawnParticle(EnumParticleTypes.DRIP_LAVA, pX, pY, pZ, 0.0D, 0.0D, 0.0D, new int[0]); + } + + public default void playStormSoundAbove(World world, double x, double y, double z) { + world.playSound(x, y, z, SoundEvents.WEATHER_RAIN_ABOVE, SoundCategory.WEATHER, 0.1F, 0.5F, false); + } + + public default void playStormSound(World world, double x, double y, double z) { + world.playSound(x, y, z, SoundEvents.WEATHER_RAIN, SoundCategory.WEATHER, 0.2F, 1.0F, false); + } + + public void updateStorm(World world); + + @SideOnly(Side.CLIENT) + public void renderStorm(float partialTicks, WorldClient world, Minecraft minecraft); +} \ No newline at end of file diff --git a/src/main/java/cjminecraft/core/client/render/world/StormProvider.java b/src/main/java/cjminecraft/core/client/render/world/StormProvider.java new file mode 100644 index 0000000..12e1ea2 --- /dev/null +++ b/src/main/java/cjminecraft/core/client/render/world/StormProvider.java @@ -0,0 +1,351 @@ +package cjminecraft.core.client.render.world; + +import java.util.Random; + +import com.google.common.base.Predicate; + +import cjminecraft.core.access.AccessHandler; +import cjminecraft.core.client.render.Draw; +import cjminecraft.core.client.render.OpenGL; +import cjminecraft.core.world.Worlds; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.WorldClient; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.util.DamageSource; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; +import net.minecraft.world.biome.Biome; +import net.minecraftforge.client.event.RenderWorldLastEvent; +import net.minecraftforge.fml.common.Mod.EventBusSubscriber; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent.WorldTickEvent; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +/** + * EventBusSubscriber annotation must apply to each individual storm provider. + * Provider will not work without it. + **/ +@EventBusSubscriber +public abstract class StormProvider implements Predicate, IStormProvider { + protected Random random = new Random(); + + protected float[] stormX = null; + protected float[] stormZ = null; + protected float stormDensity = 0.0F; + protected int rainSoundCounter; + protected boolean renderStorm; + + @SideOnly(Side.CLIENT) + @SubscribeEvent + public static void clientTickEvent(ClientTickEvent event) { + if (AccessHandler.getMinecraft().world != null && AccessHandler.getMinecraft().world.provider instanceof IClimateProvider && !AccessHandler.getMinecraft().isGamePaused()) { + IClimateProvider climate = (IClimateProvider) AccessHandler.getMinecraft().world.provider; + + if (climate.getStormProvider() instanceof StormProvider) { + StormProvider storm = (StormProvider) climate.getStormProvider(); + + if (storm.isStormApplicableTo(AccessHandler.getMinecraft().world.provider)) { + int s = storm.getStormSize(); + storm.updateStorm(AccessHandler.getMinecraft().world); + + if (storm.stormX == null || storm.stormZ == null) { + storm.stormX = new float[s * s]; + storm.stormZ = new float[s * s]; + + for (int zCoord = 0; zCoord < s; ++zCoord) { + for (int xCoord = 0; xCoord < s; ++xCoord) { + float x = xCoord - 16; + float z = zCoord - 16; + float sq = MathHelper.sqrt(x * x + z * z); + storm.stormX[zCoord << 5 | xCoord] = -z / sq; + storm.stormZ[zCoord << 5 | xCoord] = x / sq; + } + } + } + + if (storm.isStormActive(AccessHandler.getMinecraft().world)) { + storm.renderStorm = true; + + if (storm.stormDensity < 1.0F) { + storm.stormDensity += 0.0025F; + } + } else { + if (storm.stormDensity >= 0.0F) { + storm.stormDensity -= 0.0025F; + } else { + storm.renderStorm = false; + storm.stormDensity = 0.0F; + } + } + + if (storm.isStormActive(AccessHandler.getMinecraft().world)) { + float strength = storm.getStormStrength(); + + if (!AccessHandler.getMinecraft().gameSettings.fancyGraphics) { + strength /= 2.0F; + } + + if (strength != 0.0F) { + Entity entity = AccessHandler.getMinecraft().getRenderViewEntity(); + World world = entity.world; + BlockPos blockpos = new BlockPos(entity); + double x = 0.0D; + double y = 0.0D; + double z = 0.0D; + int particleCount = 0; + int passes = (int) (100.0F * strength * strength); + + if (AccessHandler.getMinecraft().gameSettings.particleSetting == 1) { + passes >>= 1; + } else if (AccessHandler.getMinecraft().gameSettings.particleSetting == 2) { + passes = 0; + } + + storm.random = new Random(); + + for (int i = 0; i < passes; ++i) { + BlockPos pos1 = world.getPrecipitationHeight(blockpos.add(storm.random.nextInt(10) - storm.random.nextInt(10), 0, storm.random.nextInt(10) - storm.random.nextInt(10))); + Biome biome = world.getBiome(pos1); + BlockPos pos2 = pos1.down(); + IBlockState state = world.getBlockState(pos2); + + if (pos1.getY() <= blockpos.getY() + 10 && pos1.getY() >= blockpos.getY() - 10 && storm.isStormVisibleInBiome(biome)) { + double xOffset = storm.random.nextDouble(); + double zOffset = storm.random.nextDouble(); + AxisAlignedBB box = state.getBoundingBox(world, pos2); + + if (state.getMaterial() != Material.LAVA && state.getBlock() != Blocks.MAGMA) { + if (state.getMaterial() != Material.AIR) { + ++particleCount; + + if (storm.random.nextInt(particleCount) == 0) { + x = (double) pos2.getX() + xOffset; + y = (double) ((float) pos2.getY() + 0.1F) + box.maxY - 1.0D; + z = (double) pos2.getZ() + zOffset; + } + + double pX = (double) pos2.getX() + xOffset; + double pY = (double) ((float) pos2.getY() + 0.1F) + box.maxY; + double pZ = (double) pos2.getZ() + zOffset; + + storm.spawnParticleOnGround(world, pX, pY, pZ); + } + } + } + } + + if (particleCount > 0 && storm.random.nextInt(3) < storm.rainSoundCounter++) { + storm.rainSoundCounter = 0; + + if (y > (double) (blockpos.getY() + 1) && world.getPrecipitationHeight(blockpos).getY() > MathHelper.floor((float) blockpos.getY())) { + storm.playStormSoundAbove(world, x, y, z); + } else { + storm.playStormSound(world, x, y, z); + } + } + } + } + } + } + } + } + + @SubscribeEvent + public static void worldTickEvent(WorldTickEvent event) { + if (event.world != null && event.world.provider instanceof IClimateProvider) { + IClimateProvider climate = (IClimateProvider) event.world.provider; + climate.getStormProvider().updateStorm(event.world); + } + } + + public void updateStorm(World world) { + if (world != null && this.isStormApplicableTo(world.provider) && this.isStormActive(world)) { + for (Object o : world.loadedEntityList.toArray()) { + if (o instanceof Entity) { + Entity entity = (Entity) o; + + if (this.apply(entity) && Worlds.canSeeSky(new BlockPos(entity), world)) { + entity.motionZ += 0.03F; + entity.motionY += MathHelper.sin(world.getWorldTime() * 0.4F) * 0.1F; + entity.fallDistance = 0F; + entity.attackEntityFrom(DamageSource.LAVA, 0.5F); + } + } + } + } + } + + @SideOnly(Side.CLIENT) + @SubscribeEvent + public static void renderLast(RenderWorldLastEvent event) { + if (AccessHandler.getMinecraft().world != null) { + if (AccessHandler.getMinecraft().world.provider instanceof IClimateProvider) { + IClimateProvider climate = (IClimateProvider) AccessHandler.getMinecraft().world.provider; + climate.getStormProvider().renderStorm(event.getPartialTicks(), AccessHandler.getMinecraft().world, Minecraft.getMinecraft()); + } + } + } + + @SideOnly(Side.CLIENT) + public void renderStorm(float partialTicks, WorldClient world, Minecraft mc) { + if (!isStormActive(world) && !renderStorm) { + return; + } + + if (stormX == null || stormZ == null) { + return; + } + + OpenGL.pushMatrix(); + OpenGL.enableLight(); + Entity entity = AccessHandler.getMinecraft().getRenderViewEntity(); + int posX = MathHelper.floor(entity.posX); + int posY = MathHelper.floor(entity.posY); + int posZ = MathHelper.floor(entity.posZ); + BufferBuilder buffer = Draw.buffer(); + GlStateManager.disableCull(); + GlStateManager.glNormal3f(0.0F, 1.0F, 0.0F); + GlStateManager.enableBlend(); + OpenGL.blendClear(); + GlStateManager.enableColorMaterial(); + GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); + + if (!doesLightingApply()) { + OpenGL.disableLight(); + } + + double renderPartialX = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * (double) partialTicks; + double renderPartialY = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * (double) partialTicks; + double renderPartialZ = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * (double) partialTicks; + int renderYFloor = MathHelper.floor(renderPartialY); + int stormDepth = 5; + int stormHeight = 6 + stormDepth; + + if (AccessHandler.getMinecraft().gameSettings.fancyGraphics) { + stormDepth = 10; + } + + int lastPass = -1; + buffer.setTranslation(-renderPartialX, -renderPartialY, -renderPartialZ); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); + + for (int z = posZ - stormDepth; z <= posZ + stormDepth; ++z) { + for (int x = posX - stormDepth; x <= posX + stormDepth; ++x) { + int idx = (z - posZ + 16) * 32 + x - posX + 16; + double rX = (double) this.stormX[idx] * 0.5D; + double rZ = (double) this.stormZ[idx] * 0.5D; + pos.setPos(x, 0, z); + Biome biome = world.getBiome(pos); + + if (isStormVisibleInBiome(biome) && renderStorm) { + int startHeight = world.getPrecipitationHeight(pos).getY(); + int minY = posY - stormHeight; + int maxY = posY + stormHeight; + + if (minY < startHeight) { + minY = startHeight; + } + + if (maxY < startHeight) { + maxY = startHeight; + } + + int vY = startHeight; + + if (startHeight < renderYFloor) { + vY = renderYFloor; + } + + if (minY != maxY) { + this.random.setSeed((long) (x * x * 3121 + x * 45238971 ^ z * z * 418711 + z * 13761)); + pos.setPos(x, minY, z); + OpenGL.enableCullFace(); + + if (lastPass != 0) { + if (lastPass >= 0) { + Tessellator.getInstance().draw(); + } + + lastPass = 0; + getStormTexture(world, biome).bind(); + buffer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR_NORMAL); + } + + float vTravel = -(((AccessHandler.getMinecraft().world.getWorldTime() + (x * x) + x + (z * z) + z) & 31) + partialTicks) / getStormDownfallSpeed(); + float hTravel = (((AccessHandler.getMinecraft().world.getWorldTime() + (x * x) + x + (z * z) + z) & 31) + partialTicks) / getStormWindSpeed(); + + double offsetX = (double) ((float) x + 0.5F) - entity.posX; + double offsetZ = (double) ((float) z + 0.5F) - entity.posZ; + float strength = MathHelper.sqrt(offsetX * offsetX + offsetZ * offsetZ) / (float) stormDepth; + float alpha = ((1.0F - strength * strength) * 0.5F + 0.5F) * getStormDensity(); + pos.setPos(x, vY, z); + int light = world.getCombinedLight(pos, 0); + int lightmapX = light >> 16 & 65535; + int lightmapY = light & 65535; + buffer.pos((double) x - rX + 0.5D, (double) minY, (double) z - rZ + 0.5D + hTravel).tex(0.0D, (double) maxY * 0.25D + vTravel).color(1.0F, 1.0F, 1.0F, alpha).lightmap(lightmapX, lightmapY).endVertex(); + buffer.pos((double) x + rX + 0.5D, (double) minY, (double) z + rZ + 0.5D + hTravel).tex(1.0D, (double) maxY * 0.25D + vTravel).color(1.0F, 1.0F, 1.0F, alpha).lightmap(lightmapX, lightmapY).endVertex(); + buffer.pos((double) x + rX + 0.5D, (double) maxY, (double) z + rZ + 0.5D + hTravel).tex(1.0D, (double) minY * 0.25D + vTravel).color(1.0F, 1.0F, 1.0F, alpha).lightmap(lightmapX, lightmapY).endVertex(); + buffer.pos((double) x - rX + 0.5D, (double) maxY, (double) z - rZ + 0.5D + hTravel).tex(0.0D, (double) minY * 0.25D + vTravel).color(1.0F, 1.0F, 1.0F, alpha).lightmap(lightmapX, lightmapY).endVertex(); + } + } + } + } + + if (lastPass >= 0) { + Tessellator.getInstance().draw(); + } + + buffer.setTranslation(0.0D, 0.0D, 0.0D); + GlStateManager.enableCull(); + GlStateManager.disableBlend(); + GlStateManager.alphaFunc(516, 0.1F); + OpenGL.disableLight(); + OpenGL.popMatrix(); + } + + @Override + public boolean apply(Entity entity) { + if (entity instanceof EntityPlayer) { + EntityPlayer player = (EntityPlayer) entity; + + if (player.capabilities.isCreativeMode) { + return false; + } + } + + return true; + } + + @Override + public float getStormStrength() { + return 1F; + } + + @Override + public float getStormDensity() { + return stormDensity; + } + + @Override + public boolean isStormVisibleInBiome(Biome biome) { + return true; + } + + @Override + public boolean doesLightingApply() { + return true; + } +} \ No newline at end of file From 7b6a2b8abe51b1df8ce1524ba94add37db6f66c1 Mon Sep 17 00:00:00 2001 From: Hypeirochus Date: Tue, 12 Jun 2018 14:32:02 -0400 Subject: [PATCH 06/19] Added world utilities. --- .../java/cjminecraft/core/world/Worlds.java | 258 ++++++++++++++++++ .../core/world/tile/IRotatableXAxis.java | 9 + .../core/world/tile/IRotatableYAxis.java | 9 + .../core/world/tile/IRotatableZAxis.java | 9 + 4 files changed, 285 insertions(+) create mode 100644 src/main/java/cjminecraft/core/world/Worlds.java create mode 100644 src/main/java/cjminecraft/core/world/tile/IRotatableXAxis.java create mode 100644 src/main/java/cjminecraft/core/world/tile/IRotatableYAxis.java create mode 100644 src/main/java/cjminecraft/core/world/tile/IRotatableZAxis.java diff --git a/src/main/java/cjminecraft/core/world/Worlds.java b/src/main/java/cjminecraft/core/world/Worlds.java new file mode 100644 index 0000000..f9ae556 --- /dev/null +++ b/src/main/java/cjminecraft/core/world/Worlds.java @@ -0,0 +1,258 @@ +package cjminecraft.core.world; + +import java.util.Random; +import java.util.UUID; + +import cjminecraft.core.world.entity.Entities; +import net.minecraft.entity.Entity; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.EnumSkyBlock; +import net.minecraft.world.Explosion; +import net.minecraft.world.World; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.feature.WorldGenerator; + +@SuppressWarnings("all") +public class Worlds { + /** + * Create an explosion in the specified world, at the specified coordinates, + * with the specified effects. + * + * @param entity + * - The entity that triggered the explosion. + * @param world + * - The world that the explosion should be created in. + * @param data + * - The CoordData containing the coordinates to create an explosion + * at. + * @param strength + * - The strength of the explosion + * @param isFlaming + * - Set to true if the explosion causes surrounding blocks to catch + * on fire. + * @param isSmoking + * - Set to true if the explosion emits smoke particles. + * @param doesBlockDamage + * - Set to true if the explosion does physical Block damage. + * @return Return the instance of the explosion that was just created. + */ + public static Explosion createExplosion(Entity entity, World world, BlockPos data, float strength, boolean isFlaming, boolean isSmoking, boolean doesBlockDamage) { + Explosion explosion = new Explosion(world, entity, data.getX(), data.getY(), data.getZ(), strength, isFlaming, isSmoking); + + if (doesBlockDamage) { + explosion.doExplosionA(); + } + + explosion.doExplosionB(true); + + return explosion; + } + + /** + * Gets the next safe position above the specified position + * + * @param entity + * - The position we're checking for safe positions above. + * @return The safe position. + */ + public static BlockPos getNextSafePositionAbove(BlockPos pos, World world) { + for (int y = (int) pos.getY(); y < world.getHeight(); y++) { + BlockPos position = new BlockPos(pos.getX(), y + 1, pos.getZ()); + + if (Entities.isPositionSafe(position, world)) { + return position; + } + } + + return pos; + } + + public static boolean canSeeSky(BlockPos pos, World world) { + for (int y = (int) pos.getY(); y < world.getHeight(); y++) { + BlockPos position = new BlockPos(pos.getX(), y + 1, pos.getZ()); + + if (world.getBlockState(position) != net.minecraft.init.Blocks.AIR) { + return false; + } + } + + return true; + } + + /** + * Get the light intensity as an Integer at the specified coordinates in the + * specified world. + * + * @param world + * - World to check for brightness values in. + * @param BlockPos + * - BlockPos containing coordinates of the location to check + * brightness at. + * @return Returns light intensity of a block as an Integer. + */ + public static int getLightAtCoord(World world, BlockPos pos) { + int sky = world.getLightFor(EnumSkyBlock.BLOCK, pos); + int block = world.getLightFor(EnumSkyBlock.SKY, pos) - world.calculateSkylightSubtracted(0F); + + return Math.max(block, sky); + } + + /** + * Gets the next safe position below the specified position + * + * @param pos + * - The position we're checking for safe positions below. + * @return The safe position. + */ + public static BlockPos getNextSafePositionBelow(BlockPos pos, World world) { + for (int y = (int) pos.getY(); y > 0; y--) { + BlockPos position = new BlockPos(pos.getX(), y - 1, pos.getZ()); + + if (Entities.isPositionSafe(position, world)) { + return position; + } + } + + return pos; + } + + /** + * Generate a group of the specified Block in the World, a given amount of + * times, in a Chunk at the given CoordData's X and Z coords using the specified + * group size and seed. + * + * @param world + * - The World instance to generate in. + * @param generator + * - The WorldGenerator instance to generate. + * @param seed + * - The seed to generate random group coords at. + * @param genPerChunk + * - The amount of times to generate this block group per chunk. + * @param chunkCoord + * - The CoordData containing the X and Z coordinates of the Chunk to + * generate in. + */ + public static void generateInChunk(World world, WorldGenerator generator, Random seed, int genPerChunk, BlockPos chunkCoord) { + generateInChunk(world, generator, seed, genPerChunk, 0, 128, chunkCoord); + } + + /** + * Generate a group of the specified Block in the World, a given amount of + * times, in a Chunk at the given CoordData's X and Z coords using the specified + * group size and seed. + * + * @param world + * - The World instance to generate in. + * @param generator + * - The WorldGenerator instance to generate. + * @param seed + * - The seed to generate random group coords at. + * @param genPerChunk + * - The amount of times to generate this block group per chunk. + * @param levelStart + * - The level that this block group can start generating on + * @param levelEnd + * - The level that this block group can stop generating on + * @param chunkCoord + * - The CoordData containing the X and Z coordinates of the Chunk to + * generate in. + */ + public static void generateInChunk(World world, WorldGenerator generator, Random seed, int genPerChunk, int levelStart, int levelEnd, BlockPos pos) { + for (int i = 0; i < genPerChunk; ++i) { + int x = (int) pos.getX() + seed.nextInt(16); + int y = levelStart + seed.nextInt(levelEnd); + int z = (int) pos.getZ() + seed.nextInt(16); + generator.generate(world, seed, new BlockPos(x, y, z)); + } + } + + /** + * Generate a group of the specified Block in the World, a given amount of + * times, in a Chunk at the given CoordData's X and Z coords using the specified + * group size and seed. + * + * @param world + * - The World instance to generate in. + * @param generator + * - The WorldGenerator instance to generate. + * @param seed + * - The seed to generate random group coords at. + * @param genPerChunk + * - The amount of times to generate this block group per chunk. + * @param chunkCoord + * - The CoordData containing the X and Z coordinates of the Chunk to + * generate in. + * @param biomes + * - The BiomeGenBase instances to generate in. + */ + public static void generateInBiome(World world, WorldGenerator generator, Random seed, int genPerChunk, BlockPos chunkCoord, Biome[] biomes) { + generateInBiome(world, generator, seed, genPerChunk, 0, 128, chunkCoord, biomes); + } + + /** + * Generate a group of the specified Block in the World, a given amount of + * times, in a Chunk at the given CoordData's X and Z coords using the specified + * group size and seed. + * + * @param world + * - The World instance to generate in. + * @param generator + * - The WorldGenerator instance to generate. + * @param seed + * - The seed to generate random group coords at. + * @param genPerChunk + * - The amount of times to generate this block group per chunk. + * @param levelStart + * - The level that this block group can start generating on + * @param levelEnd + * - The level that this block group can stop generating on + * @param pos + * - The CoordData containing the X and Z coordinates of the Chunk to + * generate in. + * @param biomes + * - The BiomeGenBase instances to generate in. + */ + public static void generateInBiome(World world, WorldGenerator generator, Random seed, int genPerChunk, int levelStart, int levelEnd, BlockPos pos, Biome[] biomes) { + for (Biome biome : biomes) { + if (world.provider.getBiomeForCoords(pos) == biome) { + generateInChunk(world, generator, seed, genPerChunk, levelStart, levelEnd, pos); + } + } + } + + public static BlockPos randPos(Random seed, BlockPos pos, int width, int height) { + return new BlockPos(pos.getX() + seed.nextInt(width), pos.getY() + seed.nextInt(height), pos.getZ() + seed.nextInt(width)); + } + + public static BlockPos randChunkPos(Random seed, BlockPos pos) { + return randPos(seed, pos, 16, 128); + } + + public static Entity getEntityByUUID(World world, UUID uuid) { + for (Object o : world.loadedEntityList.toArray()) { + if (o instanceof Entity) { + Entity entity = (Entity) o; + + if (entity.getUniqueID().equals(uuid)) { + return entity; + } + } + } + + return null; + } + + public static UUID uuidFromNBT(NBTTagCompound nbt, String key) { + return uuidFromSignature(nbt.getString(key)); + } + + public static UUID uuidFromSignature(String signature) { + if (signature != null && signature.matches("[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[34][0-9a-fA-F]{3}-[89ab][0-9a-fA-F]{3}-[0-9a-fA-F]{12}")) { + return UUID.fromString(signature); + } + + return null; + } +} diff --git a/src/main/java/cjminecraft/core/world/tile/IRotatableXAxis.java b/src/main/java/cjminecraft/core/world/tile/IRotatableXAxis.java new file mode 100644 index 0000000..48fc3ba --- /dev/null +++ b/src/main/java/cjminecraft/core/world/tile/IRotatableXAxis.java @@ -0,0 +1,9 @@ +package cjminecraft.core.world.tile; + +import net.minecraft.util.EnumFacing; + +public interface IRotatableXAxis { + public EnumFacing getRotationXAxis(); + + public void setRotationXAxis(EnumFacing facing); +} \ No newline at end of file diff --git a/src/main/java/cjminecraft/core/world/tile/IRotatableYAxis.java b/src/main/java/cjminecraft/core/world/tile/IRotatableYAxis.java new file mode 100644 index 0000000..b47822b --- /dev/null +++ b/src/main/java/cjminecraft/core/world/tile/IRotatableYAxis.java @@ -0,0 +1,9 @@ +package cjminecraft.core.world.tile; + +import net.minecraft.util.EnumFacing; + +public interface IRotatableYAxis { + public EnumFacing getRotationYAxis(); + + public void setRotationYAxis(EnumFacing facing); +} \ No newline at end of file diff --git a/src/main/java/cjminecraft/core/world/tile/IRotatableZAxis.java b/src/main/java/cjminecraft/core/world/tile/IRotatableZAxis.java new file mode 100644 index 0000000..6f4d7a2 --- /dev/null +++ b/src/main/java/cjminecraft/core/world/tile/IRotatableZAxis.java @@ -0,0 +1,9 @@ +package cjminecraft.core.world.tile; + +import net.minecraft.util.EnumFacing; + +public interface IRotatableZAxis { + public EnumFacing getRotationZAxis(); + + public void setRotationZAxis(EnumFacing facing); +} \ No newline at end of file From 7bce53413124a1007f5f2e84f982d6ea7c91bb14 Mon Sep 17 00:00:00 2001 From: Hypeirochus Date: Tue, 12 Jun 2018 14:32:20 -0400 Subject: [PATCH 07/19] Added model utilities. --- .../core/client/render/model/Model.java | 360 ++++++++++++++++++ 1 file changed, 360 insertions(+) create mode 100644 src/main/java/cjminecraft/core/client/render/model/Model.java diff --git a/src/main/java/cjminecraft/core/client/render/model/Model.java b/src/main/java/cjminecraft/core/client/render/model/Model.java new file mode 100644 index 0000000..714a5e0 --- /dev/null +++ b/src/main/java/cjminecraft/core/client/render/model/Model.java @@ -0,0 +1,360 @@ +package cjminecraft.core.client.render.model; + +import cjminecraft.core.access.AccessHandler; +import cjminecraft.core.util.MathUtils; +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public abstract class Model extends ModelBase { + public static final float DEFAULT_SCALE = 1F / 16F; + + /** + * Set the width and height of this ModelBaseExtension's texture. + * + * @param textureWidth + * - The texture width in pixels + * @param textureHeight + * - The texture height in pixels + */ + public void setTextureDimensions(int textureWidth, int textureHeight) { + this.textureWidth = textureWidth; + this.textureHeight = textureHeight; + } + + /** + * Set the rotation angles of the specified ModelRenderer instance. + * + * @param model + * - The model rotations are being set for. + * @param rotateAngleX + * - Angle by which model will rotate in the X direction. + * @param rotateAngleY + * - Angle by which the model will rotate in the Y direction. + * @param rotateAngleZ + * - Angle by which the model will rotate in the Z direction. + */ + public void setRotation(ModelRenderer model, float rotateAngleX, float rotateAngleY, float rotateAngleZ) { + model.rotateAngleX = rotateAngleX; + model.rotateAngleY = rotateAngleY; + model.rotateAngleZ = rotateAngleZ; + } + + /** + * Renders a model. + * + * @param modelRenderer + * - The ModelRenderer being used. + */ + public static void draw(ModelRenderer modelRenderer) { + modelRenderer.render(DEFAULT_SCALE); + } + + /** + * Renders a group of models. + * + * @param group + * - A group of models for which to be rendered. + */ + public static void draw(ModelRenderer[] group) { + for (ModelRenderer child : group) { + draw(child); + } + } + + /** + * TODO: Figure out what this is, and why. + */ + public void render() { + this.render(null); + } + + /** + * The entity render method from ModelBase with correct parameter mappings. + * Calls the base render method. + * + * @param entity + * - The Entity instance being rendered. + * @param swing + * - The arm swing progress of the Entity being rendered. + * @param swingPrev + * - The previous tick's arm swing progress of the Entity being + * rendered. + * @param idle + * - The idle arm swing progress of the Entity being rendered. + * @param headYaw + * - The head rotation yaw of the Entity being rendered. + * @param headPitch + * - The head rotation pitch of the Entity being rendered. + * @param scale + * - The scale this model will render at. + */ + public void render(Object obj) { + ; + } + + /** + * The entity render method from ModelBase with correct parameter mappings. + * Calls the base render method. + * + * @param entity + * - The Entity instance being rendered. + * @param swing + * - The arm swing progress of the Entity being rendered. + * @param swingPrev + * - The previous tick's arm swing progress of the Entity being + * rendered. + * @param idle + * - The idle arm swing progress of the Entity being rendered. + * @param headYaw + * - The head rotation yaw of the Entity being rendered. + * @param headPitch + * - The head rotation pitch of the Entity being rendered. + * @param scale + * - The scale this model will render at. + */ + @Override + public void render(Entity entity, float swing, float swingPrev, float idle, float headYaw, float headPitch, float scale) { + this.render(entity); + } + + /** + * The standard setRotationAngles method from ModelBase with correct parameter + * mappings. Calls the superclass method. + * + * @param swing + * - The arm swing progress of the Entity being rendered. + * @param swingPrev + * - The previous tick's arm swing progress of the Entity being + * rendered. + * @param idle + * - The idle arm swing progress of the Entity being rendered. + * @param headYaw + * - The head rotation yaw of the Entity being rendered. + * @param headPitch + * - The head rotation pitch of the Entity being rendered. + * @param scale + * - The scale this model will render at. + * @param entity + * - The Entity instance being rendered. + */ + @Override + public void setRotationAngles(float swing, float swingPrev, float idle, float headYaw, float headPitch, float scale, Entity entity) { + ; + } + + /** + * The standard setLivingAnimations method from ModelBase with correct parameter + * mappings. Calls the superclass method. + * + * @param entityLiving + * - The EntityLiving instance currently being rendered. + * @param swingProgress + * - The arm swing progress of the Entity being rendered. + * @param swingProgressPrev + * - The previous tick's arm swing progress of the Entity being + * rendered. + * @param renderPartialTicks + * - Render partial ticks + */ + @Override + public void setLivingAnimations(EntityLivingBase entityLiving, float swingProgress, float swingProgressPrev, float renderPartialTicks) { + ; + } + + /** + * Creates an array or group of ModelRenderers. + * + * @param children + * - The ModelRenderer instances we're adding to this group. + * @return The array or group created. + */ + public static ModelRenderer[] group(ModelRenderer... children) { + return children; + } + + /** + * Constructs a standard ModelBase instance from the specified class. + * + * @param modelClass + * - A class extending ModelBase which will be instantaniated. + * @return Instance of the class specified in the modelClass parameter. + */ + public static ModelBase createModelBase(Class modelClass) { + try { + return (modelClass.getConstructor()).newInstance(new Object[] {}); + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + /** + * Constructs a ModelBaseExtension instance from the specified class. + * + * @param modelClass + * - A class extending ModelBaseExtension which will be + * instantaniated. + * @return Instance of the class specified in the modelClass parameter. + */ + public static Model createExtendedModelBase(Class modelClass) { + try { + return (modelClass.getConstructor()).newInstance(new Object[] {}); + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + /** + * Gets the number of ticks the entity has existed for, plus the time since the + * game last ticked. This allows for precise timing and smooth movement. + * + * @param base + * - The EntityLivingBase class for which to check the ticks existed. + * @return TicksExisted + partialTicks of the entity. + */ + public static float getIdleProgress(EntityLivingBase base) { + return base.ticksExisted + AccessHandler.getPartialTicks(); + } + + /** + * Gets the limb swing progress of an entity. Includes partial ticks for + * precision. + * + * @param base + * - The EntityLivingBase class for which to get the limb swing + * progress from. + * @return How far along the entity is from completing its swing. + */ + public static float getSwingProgress(EntityLivingBase base) { + return base.limbSwing - base.limbSwingAmount * (1.0F - AccessHandler.getPartialTicks()); + } + + /** + * Gets the previous limb swing progress of an entity. Includes partial ticks + * for precision. Basically float-precise timing of ticksExisted, instead of an + * integer value. + * + * @param base + * - The EntityLivingBase class for which to get the previous limb + * swing progress from. + * @return The time since the last limb swing of the entity was completed. + */ + public static float getSwingProgressPrev(EntityLivingBase base) { + return base.prevLimbSwingAmount + (base.limbSwingAmount - base.prevLimbSwingAmount) * AccessHandler.getPartialTicks(); + } + + /** + * Gets the yaw rotation of the entity's head. Includes partial ticks for + * precision. + * + * @param base + * - The entity from which to get the head yaw rotation from. + * @return The value of the yaw rotation the head is at. + */ + public static float getHeadYaw(EntityLivingBase base) { + float yawOffset = MathUtils.interpolateRotation(base.prevRenderYawOffset, base.renderYawOffset, AccessHandler.getPartialTicks()); + float yawHead = MathUtils.interpolateRotation(base.prevRotationYawHead, base.rotationYawHead, AccessHandler.getPartialTicks()); + return yawHead - yawOffset; + } + + /** + * Gets the pitch rotation of the entity's head. Includes partial ticks for + * precision. + * + * @param base + * - The entity from which to get the head pitch rotation from. + * @return The value of the pitch rotation the head is at. + */ + public static float getHeadPitch(EntityLivingBase base) { + return (base.prevRotationPitch + (base.rotationPitch - base.prevRotationPitch) * AccessHandler.getPartialTicks()); + } + + /** + * Gets the idle progress of a generic Object. Uses partial ticks for precision. + * Basically float-precise timing of ticksExisted, instead of an integer value. + * + * @param o + * - The object for which to get the idle progress from. Should be an + * instance of EntityLivingBase. + * @return ticksExisted + partialTicks of the object. + */ + public static float idleProgress(Object o) { + if (o != null && o instanceof EntityLivingBase) { + return getIdleProgress((EntityLivingBase) o); + } + + return 0F; + } + + /** + * Gets the swing process of a generic Object. Uses partial ticks for precision. + * + * @param o + * - The object to get the swing progress of. Should be an instance + * of EntityLivingBase. + * @return How far along the object is from completing its swing. + */ + public static float swingProgress(Object o) { + if (o != null && o instanceof EntityLivingBase) { + return getSwingProgress((EntityLivingBase) o); + } + + return 0F; + } + + /** + * Gets the previous swing progress of a generic Object. + * + * @param o + * - The object to get the previous swing progress of. Should be an + * instance of EntityLivingBase. + * @return The time since the object's last swing was completed. + */ + public static float swingProgressPrev(Object o) { + if (o != null && o instanceof EntityLivingBase) { + return getSwingProgressPrev((EntityLivingBase) o); + } + + return 0F; + } + + /** + * Gets the yaw rotation of a generic Object. + * + * @param o + * - The object from which to get the yaw of. Should be an instance + * of EntityLivingBase. + * @return The yaw rotation of the object. + */ + public static float headYaw(Object o) { + if (o != null && o instanceof EntityLivingBase) { + return getHeadYaw((EntityLivingBase) o); + } + + return 0F; + } + + /** + * Gets the pitch rotation of a generic Object. + * + * @param o + * - The object from which to get the pitch of. Should be an instance + * of EntityLivingBase. + * @return The pitch rotation of the object. + */ + public static float headPitch(Object o) { + if (o != null && o instanceof EntityLivingBase) { + return getHeadPitch((EntityLivingBase) o); + } + + return 0F; + } +} \ No newline at end of file From e5e56397bc87222b136db0ea843a5ba030a91b49 Mon Sep 17 00:00:00 2001 From: Hypeirochus Date: Tue, 12 Jun 2018 14:32:27 -0400 Subject: [PATCH 08/19] Added math utilities. --- .../java/cjminecraft/core/util/MathUtils.java | 150 ++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 src/main/java/cjminecraft/core/util/MathUtils.java diff --git a/src/main/java/cjminecraft/core/util/MathUtils.java b/src/main/java/cjminecraft/core/util/MathUtils.java new file mode 100644 index 0000000..ad4801f --- /dev/null +++ b/src/main/java/cjminecraft/core/util/MathUtils.java @@ -0,0 +1,150 @@ +package cjminecraft.core.util; + +import net.minecraft.util.math.MathHelper; + +public class MathUtils { + public static final double PHI = 1.618033988749894D; + public static final double PI = Math.PI; + public static final double TO_DEG = 57.29577951308232D; + public static final double TO_RAD = 0.017453292519943D; + public static final double SQRT2 = 1.414213562373095D; + + public static double[] SIN_TABLE = new double[65536]; + + static { + for (int i = 0; i < 65536; ++i) { + SIN_TABLE[i] = Math.sin(i / 65536D * 2 * MathUtils.PI); + } + + SIN_TABLE[0] = 0; + SIN_TABLE[16384] = 1; + SIN_TABLE[32768] = 0; + SIN_TABLE[49152] = 1; + } + + public static double sin(double d) { + return SIN_TABLE[(int) ((float) d * 10430.378F) & 65535]; + } + + public static double cos(double d) { + return SIN_TABLE[(int) ((float) d * 10430.378F + 16384.0F) & 65535]; + } + + public static float approachLinear(float a, float b, float max) { + return (a > b) ? (a - b < max ? b : a - max) : (b - a < max ? b : a + max); + } + + public static double approachLinear(double a, double b, double max) { + return (a > b) ? (a - b < max ? b : a - max) : (b - a < max ? b : a + max); + } + + public static float wrapAngle(float a1, float a2, float delta) { + float angle = MathHelper.wrapDegrees(a2 - a1); + + if (angle > delta) { + angle = delta; + } + + if (angle < -delta) { + angle = -delta; + } + + return a1 + angle; + } + + /** + * @param a1 + * - The first angle. + * @param a2 + * - The second angle. + * @param p + * - A float between 0.0 and 1.0 that determines the progress between + * the two angles. + * @return a rotation angle that is between two other rotation angles. 'a1' and + * 'a2' are the angles between which to interpolate. + * + * Example: angle1 = 30, angle2 = 50, progress = 0.5, return = 40 + */ + public static float interpolateRotation(float a1, float a2, float p) { + float angle = a2 - a1; + angle = angle < -180F ? angle += 360F : angle; + return a1 + (p * (angle = angle >= 180F ? angle -= 360F : angle)); + } + + public static float interpolate(float a, float b, float d) { + return a + (b - a) * d; + } + + public static double interpolate(double a, double b, double d) { + return a + (b - a) * d; + } + + public static double approachExp(double a, double b, double ratio) { + return a + (b - a) * ratio; + } + + public static double approachExp(double a, double b, double ratio, double cap) { + double d = (b - a) * ratio; + + if (Math.abs(d) > cap) { + d = Math.signum(d) * cap; + } + + return a + d; + } + + public static double retreatExp(double a, double b, double c, double ratio, double kick) { + double d = (Math.abs(c - a) + kick) * ratio; + + if (d > Math.abs(b - a)) { + return b; + } + + return a + Math.signum(b - a) * d; + } + + public static double clip(double value, double min, double max) { + if (value > max) { + value = max; + } + + if (value < min) { + value = min; + } + + return value; + } + + public static boolean between(double a, double x, double b) { + return a <= x && x <= b; + } + + public static int approachExpI(int a, int b, double ratio) { + int r = (int) Math.round(approachExp(a, b, ratio)); + + return r == a ? b : r; + } + + public static int retreatExpI(int a, int b, int c, double ratio, int kick) { + int r = (int) Math.round(retreatExp(a, b, c, ratio, kick)); + + return r == a ? b : r; + } + + public static int floor(double d) { + int i = (int) d; + return d < (double) i ? i - 1 : i; + } + + public static int roundAway(double d) { + return (int) (d < 0 ? Math.floor(d) : Math.ceil(d)); + } + + public static int compare(int a, int b) { + return a == b ? 0 : a < b ? -1 : 1; + } + + public static int compare(double a, double b) { + return a == b ? 0 : a < b ? -1 : 1; + } +} \ No newline at end of file From c81e44681d5323db63733dd0526fafad987ff298 Mon Sep 17 00:00:00 2001 From: Hypeirochus Date: Tue, 12 Jun 2018 14:32:46 -0400 Subject: [PATCH 09/19] Added entity utilities. --- .../core/world/entity/Entities.java | 807 ++++++++++++++++++ 1 file changed, 807 insertions(+) create mode 100644 src/main/java/cjminecraft/core/world/entity/Entities.java diff --git a/src/main/java/cjminecraft/core/world/entity/Entities.java b/src/main/java/cjminecraft/core/world/entity/Entities.java new file mode 100644 index 0000000..e9f6ed6 --- /dev/null +++ b/src/main/java/cjminecraft/core/world/entity/Entities.java @@ -0,0 +1,807 @@ +package cjminecraft.core.world.entity; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +import cjminecraft.core.access.AccessHandler; +import cjminecraft.core.world.Worlds; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +public class Entities { + private static Entity pointedEntity; + + /** + * Get the first Entity instance of the specified class type found, within specified range, at the specified world coordinates. + * + * @param world + * - World instance to scan for entities in + * @param entityClass + * - Entity class type to scan for. + * @param data + * - The CoordData containing the coordinates to start scanning at. + * @param range + * - Range of blocks to scan within. + * @return First Entity instance found using the specified parameters. + */ + public static Entity getEntityInCoordsRange(World world, Class entityClass, BlockPos data, int range) { + return getEntityInCoordsRange(world, entityClass, data, range, 16); + } + + /** + * Checks if the specified position is safe for an entity to spawn at. + * + * @param pos + * - The position we are checking. + * @param world + * - The world instance we are checking in. + * @return true if the position is safe. + */ + + public static boolean isPositionSafe(BlockPos pos, World world) { + if (pos != null && world != null) { + BlockPos newPos = new BlockPos(pos.getX(), pos.getY(), pos.getZ()); + BlockPos newPosBelow = new BlockPos(pos.getX(), pos.getY() - 1, pos.getZ()); + + return world.getBlockState(newPosBelow) != net.minecraft.init.Blocks.AIR && world.getBlockState(newPos) == net.minecraft.init.Blocks.AIR; + } + + return false; + } + + /** + * Gets a safe position for the entity to spawn at from the given position. + * + * @param pos + * - The position that we should check around. + * @param world + * - The world we're checking for a safe position in. + * @return The safe position. + */ + public static BlockPos getSafePositionAboveBelow(BlockPos pos, World world) { + BlockPos newSafePosition = Worlds.getNextSafePositionAbove(pos, world); + + if (newSafePosition == null) { + newSafePosition = Worlds.getNextSafePositionBelow(pos, world); + } + + return newSafePosition; + } + + /** + * Get the first Entity instance of the specified class type found, within specified range, at the specified world coordinates, within specified height. + * + * @param world + * - World instance to scan for entities in + * @param entityClass + * - Entity class type to scan for. + * @param data + * - The CoordData containing the coordinates to start scanning at. + * @param range + * - Range of blocks to scan within. + * @param height + * - Height to scan for entities within + * @return First Entity instance found using the specified parameters. + */ + public static Entity getEntityInCoordsRange(World world, Class entityClass, BlockPos data, int range, int height) { + List entities = getEntitiesInCoordsRange(world, entityClass, data, range, height); + + return entities.size() >= 1 ? (Entity) entities.get(world.rand.nextInt(entities.size())) : null; + } + + /** + * Get a random Entity instance of the specified class type found, within specified range, at the specified world coordinates, within specified height. + * + * @param world + * - World instance to scan for entities in + * @param entityClass + * - Entity class type to scan for. + * @param data + * - The CoordData containing the coordinates to start scanning at. + * @param range + * - Range of blocks to scan within. + * @return First Entity instance found using the specified parameters. + */ + public static Entity getRandomEntityInCoordsRange(World world, Class entityClass, BlockPos data, int range) { + return getRandomEntityInCoordsRange(world, entityClass, data, range, 16); + } + + /** + * Get a random Entity instance of the specified class type found, within specified range, at the specified world coordinates, within specified height. + * + * @param world + * - World instance to scan for entities in + * @param entityClass + * - Entity class type to scan for. + * @param data + * - The CoordData containing the coordinates to start scanning at. + * @param range + * - Range of blocks to scan within. + * @param height + * - Height to scan for entities within + * @return First Entity instance found using the specified parameters. + */ + public static Entity getRandomEntityInCoordsRange(World world, Class entityClass, BlockPos data, int range, int height) { + List entities = getEntitiesInCoordsRange(world, entityClass, data, range, height); + + return entities.size() > 1 ? (Entity) entities.get((new Random()).nextInt(entities.size())) : null; + } + + /** + * Gets all Entity instances of the specified class type found, within specified range, at the specified world coordinates, within specified height. + * + * @param world + * - World instance to scan for entities in + * @param entityClass + * - Entity class type to scan for. + * @param data + * - The CoordData containing the coordinates to start scanning at. + * @param range + * - Range of blocks to scan within. + * @return All the Entity instances found using the specified parameters. + */ + public static List getEntitiesInCoordsRange(World world, Class entityClass, BlockPos data, int range) { + return getEntitiesInCoordsRange(world, entityClass, data, range, 16); + } + + /** + * Gets all Entity instances of the specified class type found, within specified range, at the specified world coordinates, within specified height. + * + * @param world + * - World instance to scan for entities in + * @param entityClass + * - Entity class type to scan for. + * @param data + * - The CoordData containing the coordinates to start scanning at. + * @param range + * - Range of blocks to scan within. + * @param height + * - Height to scan for entities within + * @return All the Entity instances found using the specified parameters. + */ + public static List getEntitiesInCoordsRange(World world, Class entityClass, BlockPos data, int range, int height) { + return world.getEntitiesWithinAABB(entityClass, new AxisAlignedBB(data.getX(), data.getY(), data.getZ(), data.getX() + 1, data.getY() + 1, data.getZ() + 1).expand(range * 2, height, range * 2)); + } + + public static RayTraceResult.Type getMovingObjectType(int ordinal) { + for (RayTraceResult.Type type : RayTraceResult.Type.values()) { + if (type.ordinal() == ordinal) { + return type; + } + } + + return null; + } + + /** + * @param e1 + * - The entity that entityLooking is looking for. + * @param e2 + * - The entity that is looking for the first entity. + * @return Returns true if the first Entity can be seen by the second Entity. + */ + public static boolean canEntityBeSeenBy(Entity e1, Entity e2) { + return rayTraceBlocks(e1, e2) == null; + } + + public static boolean canEntityBeSeenBy(Entity e, BlockPos pos) { + return rayTraceBlocks(e, pos) == null; + } + + public static boolean canCoordBeSeenBy(World world, BlockPos p1, BlockPos p2) { + return rayTraceBlocks(world, p1, p2) == null; + } + + /** + * Finds what block or object the mouse is over at the specified partial tick time. Args: partialTickTime + */ + @SideOnly(Side.CLIENT) + public static RayTraceResult rayTraceSpecial(double reach, float partialTicks) { + if (AccessHandler.getMinecraft().getRenderViewEntity() != null) { + if (AccessHandler.getMinecraft().world != null) { + pointedEntity = null; + double distance = reach; + Vec3d renderPosition = AccessHandler.getMinecraft().getRenderViewEntity().getPositionEyes(partialTicks); + Vec3d lookVec = AccessHandler.getMinecraft().getRenderViewEntity().getLook(partialTicks); + Vec3d lookPos = renderPosition.addVector(lookVec.x * reach, lookVec.y * reach, lookVec.z * reach); + RayTraceResult blockTrace = rayTraceBlocks(AccessHandler.getMinecraft().world, AccessHandler.getMinecraft().getRenderViewEntity().getPositionEyes(partialTicks), lookPos, false, true, true); + + if (blockTrace != null) { + distance = blockTrace.hitVec.distanceTo(renderPosition); + } + + pointedEntity = null; + Vec3d hitVec = null; + List list = AccessHandler.getMinecraft().world.getEntitiesWithinAABBExcludingEntity(AccessHandler.getMinecraft().getRenderViewEntity(), AccessHandler.getMinecraft().getRenderViewEntity().getEntityBoundingBox().expand(lookVec.x * reach, lookVec.y * reach, lookVec.z * reach).expand((double) 1F, (double) 1F, (double) 1F)); + double entityDist = distance; + + for (int idx = 0; idx < list.size(); ++idx) { + Entity entity = (Entity) list.get(idx); + + if (entity.canBeCollidedWith()) { + AxisAlignedBB axisalignedbb = entity.getEntityBoundingBox().expand((double) entity.getCollisionBorderSize(), (double) entity.getCollisionBorderSize(), (double) entity.getCollisionBorderSize()); + RayTraceResult movingobjectposition = axisalignedbb.calculateIntercept(renderPosition, lookPos); + + if (axisalignedbb.contains(renderPosition)) { + if (0.0D < entityDist || entityDist == 0.0D) { + pointedEntity = entity; + hitVec = movingobjectposition == null ? renderPosition : movingobjectposition.hitVec; + entityDist = 0.0D; + } + } else if (movingobjectposition != null) { + double distToHit = renderPosition.distanceTo(movingobjectposition.hitVec); + + if (distToHit < entityDist || entityDist == 0.0D) { + if (entity == AccessHandler.getMinecraft().getRenderViewEntity().getRidingEntity() && !entity.canRiderInteract()) { + if (entityDist == 0.0D) { + pointedEntity = entity; + hitVec = movingobjectposition.hitVec; + } + } else { + pointedEntity = entity; + hitVec = movingobjectposition.hitVec; + entityDist = distToHit; + } + } + } + } + } + + if (pointedEntity != null && (entityDist < distance)) { + return new RayTraceResult(pointedEntity, hitVec); + } else if (blockTrace != null) { + return blockTrace; + } + } + } + + return null; + } + + /** + * @param e1 + * - The entity that entityLooking is looking for. + * @param e2 + * - The entity that is looking for the first entity. + * @return Returns the MovingObjectPosition hit by the rayTrace. + */ + public static RayTraceResult rayTraceBlocks(Entity e1, Entity e2) { + return e1 != null && e2 != null ? rayTraceBlocks(e1.world, e1.posX, e1.posY + (e1.height / 2), e1.posZ, e2.posX, e2.posY + e2.getEyeHeight(), e2.posZ) : null; + } + + public static RayTraceResult rayTraceBlocks(Entity e, BlockPos p) { + return e != null && p != null ? rayTraceBlocks(e.world, e.posX, e.posY + (e.height / 2), e.posZ, p.getX(), p.getY(), p.getZ()) : null; + } + + public static RayTraceResult rayTraceBlocks(World world, BlockPos p1, BlockPos p2) { + return p1 != null && p2 != null ? rayTraceBlocks(world, p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ()) : null; + } + + public static RayTraceResult rayTraceBlocks(World world, double x1, double y1, double z1, double x2, double y2, double z2) { + return world != null ? rayTraceBlocks(world, new Vec3d(x1, y1, z1), new Vec3d(x2, y2, z2), false, false, false) : null; + } + + public static RayTraceResult rayTraceAll(Entity entity, int reach) { + return rayTraceAll(entity.world, new Vec3d(entity.posX, entity.posY, entity.posZ), entity.rotationYaw, entity.rotationPitch, reach, new ArrayList(Arrays.asList(new Entity[] { entity }))); + } + + public static RayTraceResult rayTraceAll(World world, Vec3d pos, float rotationYaw, float rotationPitch, int reach, ArrayList exclude) { + Vec3d lookVec = getLookVector(rotationYaw, rotationPitch); + + Entity entityHit = null; + Vec3d hitVec = null; + Vec3d posHit = null; + + if (lookVec != null) { + posHit = pos.addVector(lookVec.x * reach, lookVec.y * reach, lookVec.z * reach); + List entities = world.getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(pos.x, pos.y, pos.z, pos.x + 1F, pos.y + 1F, pos.z + 1F).expand(lookVec.x * reach, lookVec.y * reach, lookVec.z * reach).expand(1.0F, 1.0F, 1.0F)); + + for (Entity e : entities) { + if (e != null && e.canBeCollidedWith() && !exclude.contains(e)) { + float size = e.getCollisionBorderSize(); + AxisAlignedBB box = e.getEntityBoundingBox().expand(size, size, size); + RayTraceResult movobjpos = box.calculateIntercept(pos, posHit); + + entityHit = e; + + if (movobjpos == null) { + hitVec = pos; + } else { + hitVec = movobjpos.hitVec; + } + } + } + } + + if (entityHit != null && hitVec != null) { + return new RayTraceResult(entityHit, hitVec); + } + + if (posHit != null) { + RayTraceResult blockHitVec = rayTraceBlocks(world, pos, posHit, true, true, true); + + if (blockHitVec != null) { + return blockHitVec; + } + } + + return null; + } + + public static RayTraceResult rayTraceBlocks(World world, BlockPos pos, BlockPos pos2, boolean hitLiquid, boolean ignoreBlocksWithoutBoundingBox, boolean returnLastUncollidableBlock) { + return rayTraceBlocks(world, new Vec3d(pos.getX(), pos.getY(), pos.getZ()), new Vec3d(pos2.getX(), pos2.getY(), pos2.getZ()), hitLiquid, ignoreBlocksWithoutBoundingBox, returnLastUncollidableBlock); + } + + public static RayTraceResult rayTraceBlocks(World world, Vec3d pos, Vec3d pos2, boolean hitLiquid, boolean ignoreBlockWithoutBoundingBox, boolean returnLastUncollidableBlock) { + if (!Double.isNaN(pos.x) && !Double.isNaN(pos.y) && !Double.isNaN(pos.z)) { + if (!Double.isNaN(pos2.x) && !Double.isNaN(pos2.y) && !Double.isNaN(pos2.z)) { + BlockPos blockpos = new BlockPos(MathHelper.floor(pos.x), MathHelper.floor(pos.y), MathHelper.floor(pos.z)); + IBlockState blockstate = world.getBlockState(blockpos); + Block block = blockstate.getBlock(); + int posMeta = block.getMetaFromState(blockstate); + int posX = blockpos.getX(); + int posY = blockpos.getY(); + int posZ = blockpos.getZ(); + + if ((!ignoreBlockWithoutBoundingBox || blockstate.getCollisionBoundingBox(world, blockpos) != null) && block.isCollidable()) { + RayTraceResult obj = blockstate.collisionRayTrace(world, blockpos, pos, pos2); + + if (obj != null) { + return obj; + } + } + + RayTraceResult movObjPos = null; + int dist = 200; + + double tX = pos.x; + double tY = pos.y; + double tZ = pos.z; + + while (dist-- >= 0) { + if (Double.isNaN(pos.x) || Double.isNaN(pos.y) || Double.isNaN(pos.z)) { + return null; + } + + if (posX == pos2.x && posY == pos2.y && posZ == pos2.z) { + return returnLastUncollidableBlock ? movObjPos : null; + } + + boolean endX = true; + boolean endY = true; + boolean endZ = true; + double distX = 999.0D; + double distY = 999.0D; + double distZ = 999.0D; + + if (pos2.x > posX) { + distX = (double) posX + 1.0D; + } else if (pos2.x < posX) { + distX = (double) posX + 0.0D; + } else { + endX = false; + } + + if (pos2.y > posY) { + distY = (double) posY + 1.0D; + } else if (pos2.y < posY) { + distY = (double) posY + 0.0D; + } else { + endY = false; + } + + if (pos2.z > posZ) { + distZ = (double) posZ + 1.0D; + } else if (pos2.z < posZ) { + distZ = (double) posZ + 0.0D; + } else { + endZ = false; + } + + double dX = 999.0D; + double dY = 999.0D; + double dZ = 999.0D; + double displacementX = pos2.x - pos.x; + double displacementY = pos2.y - pos.y; + double displacementZ = pos2.z - pos.z; + + if (endX) { + dX = (distX - pos.x) / displacementX; + } + + if (endY) { + dY = (distY - pos.y) / displacementY; + } + + if (endZ) { + dZ = (distZ - pos.z) / displacementZ; + } + + byte side; + + if (dX < dY && dX < dZ) { + if (pos2.x > posX) { + side = 4; + } else { + side = 5; + } + + tX = distX; + tY += displacementY * dX; + tZ += displacementZ * dX; + } else if (dY < dZ) { + if (pos2.y > posY) { + side = 0; + } else { + side = 1; + } + + tX += displacementX * dY; + tY = distY; + tZ += displacementZ * dY; + } else { + if (pos2.z > posZ) { + side = 2; + } else { + side = 3; + } + + tX += displacementX * dZ; + tY += displacementY * dZ; + tZ = distZ; + } + + pos = new Vec3d(tX, tY, tZ); + + posX = (int) ((double) MathHelper.floor(pos.x)); + + if (side == 5) { + --posX; + } + + posY = (int) ((double) MathHelper.floor(pos.y)); + + if (side == 1) { + --posY; + } + + posZ = (int) ((double) MathHelper.floor(pos.z)); + + if (side == 3) { + --posZ; + } + + BlockPos newPos = new BlockPos(posX, posY, posZ); + IBlockState newBlockstate = world.getBlockState(newPos); + Block newPosBlock = newBlockstate.getBlock(); + + if (!ignoreBlockWithoutBoundingBox || newBlockstate.getCollisionBoundingBox(world, newPos) != null) { + if (newPosBlock.isCollidable()) { + RayTraceResult obj = newBlockstate.collisionRayTrace(world, newPos, pos, pos2); + + if (obj != null) { + return obj; + } + } else { + movObjPos = new RayTraceResult(RayTraceResult.Type.MISS, pos, EnumFacing.getFront(side), newPos); + } + } + } + + return returnLastUncollidableBlock ? movObjPos : null; + } else { + return null; + } + } else { + return null; + } + } + + /** + * @param partialTicks + * - The partial tick time or amount of partial ticks between each CPU tick. + * @return an interpolated look vector used for ray tracing. + */ + public static Vec3d getLookVector(float rotationYaw, float rotationPitch) { + return getLookVector(rotationYaw, rotationPitch, 0F, 0F, 1.0F); + } + + /** + * @param partialTicks + * - The partial tick time or amount of partial ticks between each CPU tick. + * @return an interpolated look vector used for ray tracing. + */ + public static Vec3d getLookVector(float rotationYaw, float rotationPitch, float prevRotationYaw, float prevRotationPitch, float partialTicks) { + float f1; + float f2; + float f3; + float f4; + + if (partialTicks == 1.0F) { + f1 = MathHelper.cos(-rotationYaw * 0.017453292F - (float) Math.PI); + f2 = MathHelper.sin(-rotationYaw * 0.017453292F - (float) Math.PI); + f3 = -MathHelper.cos(-rotationPitch * 0.017453292F); + f4 = MathHelper.sin(-rotationPitch * 0.017453292F); + return new Vec3d((double) (f2 * f3), (double) f4, (double) (f1 * f3)); + } else { + f1 = prevRotationPitch + (rotationPitch - prevRotationPitch) * partialTicks; + f2 = prevRotationYaw + (rotationYaw - prevRotationYaw) * partialTicks; + f3 = MathHelper.cos(-f2 * 0.017453292F - (float) Math.PI); + f4 = MathHelper.sin(-f2 * 0.017453292F - (float) Math.PI); + float f5 = -MathHelper.cos(-f1 * 0.017453292F); + float f6 = MathHelper.sin(-f1 * 0.017453292F); + return new Vec3d((double) (f4 * f5), (double) f6, (double) (f3 * f5)); + } + } + + /** + * Constructs a new Entity instance from the specified class name in the specified world. + * + * @param world + * - World to construct the Entity instance in. + * @param name + * - String name of the entity class of which will be constructed. + * @return Entity instance constructed using this method. + */ + public static Entity constructEntityViaClasspath(World world, String name) { + try { + return constructEntity(world, (Class) Class.forName(name)); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /** + * Constructs a new Entity instance from the specified class in the specified world. + * + * @param world + * - World to construct the Entity instance in. + * @param c + * - The entity class of which will be constructed. + * @return Entity instance constructed using this method. + */ + public static Entity constructEntity(World world, Class c) { + if (world == null) { + System.out.println("World object null while attempting to construct entity."); + return null; + } + + if (c == null) { + System.out.println("Entity class null while attempting to construct entity."); + return null; + } + + try { + return (c.getConstructor(World.class)).newInstance(new Object[] { world }); + } catch (Exception e) { + System.out.println("Failed to construct entity: " + (c != null ? c.getName() : c)); + e.printStackTrace(); + } + return null; + } + + /** + * Causes the facer entity to face the faced entity. + * + * @param facer + * - The Entity that is going to be facing the faced entity. + * @param faced + * - The Entity that is going to be faced. + * @param maxYaw + * - The max rotation yaw that the facer can rotate. + * @param maxPitch + * - The max rotation pitch that the facer can rotate. + */ + public static void faceEntity(Entity facer, Entity faced, float maxYaw, float maxPitch) { + double xDistance = faced.posX - facer.posX; + double zDistance = faced.posZ - facer.posZ; + double yDistance; + + if (faced instanceof EntityLivingBase) { + EntityLivingBase entitylivingbase = (EntityLivingBase) faced; + yDistance = entitylivingbase.posY + entitylivingbase.getEyeHeight() - (facer.posY + facer.getEyeHeight()); + } else { + yDistance = (faced.getEntityBoundingBox().minY + faced.getEntityBoundingBox().maxY) / 2.0D - (facer.posY + facer.getEyeHeight()); + } + + double d3 = MathHelper.sqrt(xDistance * xDistance + zDistance * zDistance); + float f2 = (float) (Math.atan2(zDistance, xDistance) * 180.0D / Math.PI) - 90.0F; + float f3 = (float) (-(Math.atan2(yDistance, d3) * 180.0D / Math.PI)); + facer.rotationPitch = updateRotation(facer.rotationPitch, f3, maxPitch); + facer.rotationYaw = updateRotation(facer.rotationYaw, f2, maxYaw); + } + + /** + * @param currentRotation + * - The current rotation value. + * @param targetRotation + * - The target rotation value. + * @param maxChange + * - The maximum rotation change allowed. + * @return Amount of rotation that is results based on the current, target, and max rotation. + */ + public static float updateRotation(float currentRotation, float targetRotation, float maxChange) { + float newRotation = MathHelper.wrapDegrees(targetRotation - currentRotation); + return currentRotation + (newRotation > maxChange ? maxChange : newRotation < -maxChange ? -maxChange : maxChange); + } + + /** + * Apply a block collision for the provided Entity instance. + * + * @param entity + * - The entity to apply a collision for + */ + public static void applyCollision(Entity entity) { + int minX = MathHelper.floor(entity.getEntityBoundingBox().minX + 0.001D); + int minY = MathHelper.floor(entity.getEntityBoundingBox().minY + 0.001D); + int minZ = MathHelper.floor(entity.getEntityBoundingBox().minZ + 0.001D); + int maxX = MathHelper.floor(entity.getEntityBoundingBox().maxX - 0.001D); + int maxY = MathHelper.floor(entity.getEntityBoundingBox().maxY - 0.001D); + int maxZ = MathHelper.floor(entity.getEntityBoundingBox().maxZ - 0.001D); + + if (entity.world.isBlockLoaded(entity.getPosition())) { + for (int x = minX; x <= maxX; ++x) { + for (int y = minY; y <= maxY; ++y) { + for (int z = minZ; z <= maxZ; ++z) { + BlockPos pos = new BlockPos(x, y, z); + IBlockState blockstate = entity.world.getBlockState(pos); + Block block = blockstate.getBlock(); + + try { + block.onEntityCollidedWithBlock(entity.world, pos, blockstate, entity); + } catch (Throwable throwable) { + System.out.println("Exception while handling entity collision with block."); + } + } + } + } + } + } + + public static boolean isInLava(Entity entity) { + return isInMaterial(entity, Material.LAVA); + } + + public static boolean isInWater(Entity entity) { + return isInMaterial(entity, Material.WATER); + } + + public static boolean isInMaterial(Entity entity, Material material) { + if (entity != null && entity.world != null && entity.getEntityBoundingBox() != null) { + return entity.world.isMaterialInBB(entity.getEntityBoundingBox().expand(-0.10000000149011612D, -0.4000000059604645D, -0.10000000149011612D), material); + } + + return false; + } + + public static BlockPos getSafeLocationAround(Entity toCheck, BlockPos around) { + ArrayList potentialLocations = cjminecraft.core.world.block.Blocks.getCoordDataInRangeIncluding((int) around.getX(), (int) around.getY(), (int) around.getZ(), 2, toCheck.world, Blocks.AIR); + + for (BlockPos potentialLocation : potentialLocations) { + + Block blockAt = toCheck.world.getBlockState(toCheck.getPosition()).getBlock(); + Block blockBelow = toCheck.world.getBlockState(toCheck.getPosition().add(0, -1, 0)).getBlock(); + + if (blockAt != null && blockBelow != null) { + if (blockAt == Blocks.AIR) { + if (isGround(blockBelow)) { + double entityWidth = toCheck.getEntityBoundingBox().maxX - toCheck.getEntityBoundingBox().minX; + double entityHeight = toCheck.getEntityBoundingBox().maxY - toCheck.getEntityBoundingBox().minY; + double entityDepth = toCheck.getEntityBoundingBox().maxZ - toCheck.getEntityBoundingBox().minZ; + + entityWidth = entityWidth < 1 ? 1 : entityWidth; + entityDepth = entityDepth < 1 ? 1 : entityDepth; + entityHeight = entityHeight < 1 ? 1 : entityHeight; + + Block blockAbove = toCheck.world.getBlockState(toCheck.getPosition().add(0, entityHeight, 0)).getBlock(); + + if (isSafe(blockAbove)) { + + Block blockToLeft = toCheck.world.getBlockState(toCheck.getPosition().add(-entityWidth, 0, 0)).getBlock(); + Block blockToRight = toCheck.world.getBlockState(toCheck.getPosition().add(entityWidth, 0, 0)).getBlock(); + Block blockInFront = toCheck.world.getBlockState(toCheck.getPosition().add(0, 0, entityDepth)).getBlock(); + Block blockInBack = toCheck.world.getBlockState(toCheck.getPosition().add(0, 0, -entityDepth)).getBlock(); + + if (isSafe(blockToLeft) && isSafe(blockToRight) && isSafe(blockInFront) && isSafe(blockInBack)) { + return potentialLocation; + } + } + } + } + } + } + return null; + } + + public static boolean isGround(IBlockState blockstate) { + return blockstate.getMaterial().isSolid() && blockstate.getBlock() != Blocks.AIR; + } + + public static boolean isGround(Block block) { + return block.getDefaultState().getMaterial().isSolid() && block != Blocks.AIR; + } + + public static boolean isSafe(Block block) { + return block == Blocks.AIR; + } + + public static Entity getEntityRiddenBy(Entity check) { + return !check.getPassengers().isEmpty() && check.getPassengers().get(0) != null ? check.getPassengers().get(0) : null; + } + + public static boolean isRiding(Entity check, Entity checkFor) { + return isRiding(check, checkFor.getClass()); + } + + public static boolean isRiding(Entity check, Class type) { + if (check.getPassengers() == null || check.getPassengers() != null && check.getPassengers().isEmpty()) { + return false; + } + + for (Entity entity : check.getPassengers()) { + if (type.isInstance(entity)) { + return true; + } + } + + return false; + } + + public static boolean canPlaceEntityOnSide(World world, Block block, BlockPos pos, boolean skipBoundsCheck, int side, Entity entity, ItemStack stack) { + return canPlaceEntityOnSide(world, block, pos, skipBoundsCheck, EnumFacing.getFront(side), entity, stack); + } + + public static boolean canPlaceEntityOnSide(World world, Block block, BlockPos pos, boolean skipBoundsCheck, EnumFacing side, Entity entity, ItemStack stack) { + IBlockState blockstate = world.getBlockState(pos); + AxisAlignedBB box = skipBoundsCheck ? null : blockstate.getCollisionBoundingBox(world, pos); + return box != null && !world.checkNoEntityCollision(box, entity) ? false : (blockstate.getMaterial() == Material.CIRCUITS && block == Blocks.ANVIL ? true : blockstate.getBlock().isReplaceable(world, pos) && block.isReplaceable(world, pos)); + } + + public static EnumFacing getEntityFacingRotY(Entity entity) { + int dir = MathHelper.floor((entity.rotationYaw / 90) + 0.5) & 3; + + switch (dir) { + case 0: + return EnumFacing.SOUTH; + case 1: + return EnumFacing.WEST; + case 2: + return EnumFacing.NORTH; + case 3: + return EnumFacing.EAST; + default: + return EnumFacing.NORTH; + } + } + + public static EnumFacing getEntityFacingRotX(Entity entity) { + int dir = MathHelper.floor((entity.rotationPitch / 90) + 0.5) & 3; + System.out.println(dir); + + switch (dir) { + case 3: + return EnumFacing.UP; + case 1: + return EnumFacing.DOWN; + default: + return EnumFacing.NORTH; + } + } +} \ No newline at end of file From 22236cb21c96a4d5f5eef7e550aca4562be0a1cc Mon Sep 17 00:00:00 2001 From: Hypeirochus Date: Tue, 12 Jun 2018 14:32:58 -0400 Subject: [PATCH 10/19] Added item dropping utilities. --- .../core/world/entity/ItemDrop.java | 208 ++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 src/main/java/cjminecraft/core/world/entity/ItemDrop.java diff --git a/src/main/java/cjminecraft/core/world/entity/ItemDrop.java b/src/main/java/cjminecraft/core/world/entity/ItemDrop.java new file mode 100644 index 0000000..23af208 --- /dev/null +++ b/src/main/java/cjminecraft/core/world/entity/ItemDrop.java @@ -0,0 +1,208 @@ +package cjminecraft.core.world.entity; + +import java.util.Random; + +import net.minecraft.entity.Entity; +import net.minecraft.item.ItemStack; + +/** + * Created to better manage drop rates of itemstacks from entities. Drops can be + * managed in a single location versus per entity. + **/ +public class ItemDrop { + private ItemStack[] itemstacks; + private int rate; + private DropType dropType; + + /** + * RATE_PERDROP_MULTIPLE - Drop rate applies to all items. Will drop all stacks. + * RATE_PERDROP_SINGLE - Drop rate applies to all items. Will drop one stack at + * random. RATE_INDIVIDUAL_MULTIPLE - Drop rate applies to each individual item. + * Will potentially drop multiple stacks. RATE_INDIVIDUAL_SINGLE - Drop rate + * applies to each individual item. Will drop only one stack. This mode + * increases chance an item will drop. + */ + public static enum DropType { + RATE_PERDROP_MULTIPLE(0), + RATE_PERDROP_SINGLE(1), + RATE_PERSTACK_MULTIPLE(2), + RATE_PERSTACK_SINGLE(3); + + private int id; + + DropType(int id) { + this.id = id; + } + + public int getId() { + return id; + } + } + + /** + * Single stack ItemDrop + * + * @param rate + * - The rate at which this item will drop. Entering 5 will result in + * the ItemStack dropping 5% of the time. + * @param stack + * - The ItemStack instance this drop will consist of. + */ + public ItemDrop(int rate, ItemStack stack) { + this(rate, DropType.RATE_PERDROP_MULTIPLE, new ItemStack[] { stack }); + } + + /** + * Multiple stack ItemDrop + * + * @param rate + * - The rate at which this item will drop. Entering 5 will result in + * the ItemStack dropping 5% of the time. + * @param stacks + * - The ItemStack instance this drop will consist of. + */ + public ItemDrop(int rate, ItemStack... stacks) { + this(rate, DropType.RATE_PERDROP_MULTIPLE, stacks); + } + + /** + * Multiple stack ItemDrop + * + * @param rate + * - The rate at which this item will drop. Entering 5 will result in + * the ItemStack dropping 5% of the time. + * @param dropType + * - The type of drop this is. See + * {@link cjminecraft.core.world.entity.ItemDrop.DropType} for a + * list of types. + * @param stacks + * - The ItemStack instance this drop will consist of. + */ + public ItemDrop(int rate, DropType dropType, ItemStack... stacks) { + this.itemstacks = stacks; + this.dropType = dropType; + this.rate = rate; + } + + /** + * Try to drop this ItemDrop using the predefined options. + * + * @param entity + * - The entity dropping this ItemDrop. + * @return Returns true if an item was dropped. + */ + public boolean tryDrop(Entity entity) { + return this.tryDrop(entity, this.rate, this.dropType); + } + + /** + * Try to drop this ItemDrop, but with a modified drop rate. + * + * @param entity + * - The entity dropping this ItemDrop. + * @param rate + * - The overridden drop rate. A drop rate of 0 will use the + * predefined drop rate. + * @return Returns true if an item was dropped. + */ + public boolean tryDrop(Entity entity, int rate) { + return this.tryDrop(entity, rate, this.dropType); + } + + /** + * Try to drop this ItemDrop, but using a different drop type. See + * {@link cjminecraft.core.world.entity.ItemDrop.DropType} for a list of + * types. + * + * @param entity + * - The entity dropping this ItemDrop. + * @param type + * - The modified drop type. + * @return Returns true if an item was dropped. + */ + public boolean tryDrop(Entity entity, DropType type) { + return this.tryDrop(entity, this.rate, type); + } + + /** + * Try to drop this ItemDrop, but set a different drop type. See + * {@link cjminecraft.core.world.entity.ItemDrop.DropType} for a list of + * types. + * + * @param entity + * - The entity dropping this ItemDrop. + * @param rate + * - The overridden drop rate. A drop rate of 0 will use the + * predefined drop rate. + * @param type + * - The modified drop type. + * @return Returns true if an item was dropped. + */ + public boolean tryDrop(Entity entity, int rate, DropType type) { + if (!entity.world.isRemote) { + Random rand = new Random(); + + switch (type) { + case RATE_PERDROP_MULTIPLE: { + if (rand.nextInt(100 / (rate == 0 ? this.rate : rate)) == 0) { + for (ItemStack stack : itemstacks) { + entity.entityDropItem(stack.copy(), 0F); + } + + return true; + } + } + + case RATE_PERDROP_SINGLE: { + if (rand.nextInt(100 / (rate == 0 ? this.rate : rate)) == 0) { + entity.entityDropItem(itemstacks[rand.nextInt(itemstacks.length)].copy(), 0F); + return true; + } + } + + case RATE_PERSTACK_MULTIPLE: { + for (ItemStack stack : itemstacks) { + if (rand.nextInt(100 / (rate == 0 ? this.rate : rate)) == 0) { + entity.entityDropItem(stack.copy(), 0F); + } + } + return true; + } + + case RATE_PERSTACK_SINGLE: { + for (ItemStack stack : itemstacks) { + if (rand.nextInt(100 / (rate == 0 ? this.rate : rate)) == 0) { + entity.entityDropItem(stack.copy(), 0F); + return true; + } + } + } + } + } + + return false; + } + + /** + * @return An Array of ItemStack instances included in this drop. + */ + public ItemStack[] getItemstacks() { + return itemstacks; + } + + /** + * @return The drop rate of this drop. + */ + public int getRate() { + return rate; + } + + /** + * @return The type of drop this is. See + * {@link cjminecraft.core.world.entity.ItemDrop.DropType} for a list + * of types. + */ + public DropType getDropType() { + return dropType; + } +} \ No newline at end of file From b8cd8f4a9b5676df1233fcd64c18fe0466b8eaf8 Mon Sep 17 00:00:00 2001 From: Hypeirochus Date: Tue, 12 Jun 2018 14:33:06 -0400 Subject: [PATCH 11/19] Added block utilities. --- .../cjminecraft/core/world/block/Blocks.java | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 src/main/java/cjminecraft/core/world/block/Blocks.java diff --git a/src/main/java/cjminecraft/core/world/block/Blocks.java b/src/main/java/cjminecraft/core/world/block/Blocks.java new file mode 100644 index 0000000..78b8f67 --- /dev/null +++ b/src/main/java/cjminecraft/core/world/block/Blocks.java @@ -0,0 +1,111 @@ +package cjminecraft.core.world.block; + +import java.util.ArrayList; +import java.util.Arrays; + +import net.minecraft.block.Block; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public class Blocks { + public static ArrayList getCoordDataInRange(int posX, int posY, int posZ, int range) { + ArrayList data = new ArrayList(); + + for (int x = posX - range; x < posX + range * 2; x++) { + for (int y = posY - range; y < posY + range * 2; y++) { + for (int z = posZ - range; z < posZ + range * 2; z++) { + data.add(new BlockPos(x, y, z)); + } + } + } + + return data; + } + + public static ArrayList getPositionsInRange(int posX, int posY, int posZ, int range) { + ArrayList data = new ArrayList(); + + for (int x = posX - range; x < posX + range * 2; x++) { + for (int y = posY - range; y < posY + range * 2; y++) { + for (int z = posZ - range; z < posZ + range * 2; z++) { + data.add(new BlockPos(x, y, z)); + } + } + } + + return data; + } + + public static ArrayList getCoordDataInRangeIncluding(int posX, int posY, int posZ, int range, World world, Block... types) { + ArrayList data = new ArrayList(); + + for (int x = posX - range; x < posX + range * 2; x++) { + for (int y = posY - range; y < posY + range * 2; y++) { + for (int z = posZ - range; z < posZ + range * 2; z++) { + BlockPos coordData = new BlockPos(x, y, z); + Block block = world.getBlockState(coordData).getBlock(); + + if (Arrays.asList(types).contains(block)) { + data.add(coordData); + } + } + } + } + + return data; + } + + public static ArrayList getBlocksInRangeIncluding(int posX, int posY, int posZ, int range, World world, Block... types) { + ArrayList data = new ArrayList(); + + for (int x = posX - range; x < posX + range * 2; x++) { + for (int y = posY - range; y < posY + range * 2; y++) { + for (int z = posZ - range; z < posZ + range * 2; z++) { + BlockPos position = new BlockPos(x, y, z); + + if (Arrays.asList(types).contains(world.getBlockState(position).getBlock())) { + data.add(position); + } + } + } + } + + return data; + } + + public static ArrayList getCoordDataInRangeExcluding(int posX, int posY, int posZ, int range, World world, Block... types) { + ArrayList data = new ArrayList(); + + for (int x = posX - range; x < posX + range * 2; x++) { + for (int y = posY - range; y < posY + range * 2; y++) { + for (int z = posZ - range; z < posZ + range * 2; z++) { + BlockPos coordData = new BlockPos(x, y, z); + Block block = world.getBlockState(coordData).getBlock(); + + if (!Arrays.asList(types).contains(block)) { + data.add(coordData); + } + } + } + } + + return data; + } + + public static String getDomain(Block block) { + String domain = "minecraft:"; + + if (block.getUnlocalizedName().contains(":")) { + domain = (block.getUnlocalizedName().split(":")[0] + ":").replace("tile.", ""); + } + + return domain; + } + + public static void setCreativeTab(Block block, CreativeTabs tab) { + if (tab != null) { + block.setCreativeTab(tab); + } + } +} \ No newline at end of file From 70c6fc9b43012ccb4c781086e7e119cc266a9242 Mon Sep 17 00:00:00 2001 From: Hypeirochus Date: Tue, 12 Jun 2018 14:33:19 -0400 Subject: [PATCH 12/19] Cleaned imports. --- src/main/java/cjminecraft/core/CJCore.java | 3 --- .../core/client/gui/element/ElementEnergyBar.java | 6 ------ .../core/client/gui/element/ElementItemSlot.java | 1 - .../core/client/gui/element/ElementProgressBar.java | 1 - .../core/client/gui/element/ElementTexture.java | 3 --- .../core/client/gui/overlay/OverlayInventory.java | 1 - .../core/command/CommandEditTileEntity.java | 1 - .../cjminecraft/core/config/CJCoreGuiFactory.java | 3 --- .../cjminecraft/core/crafting/CraftingHandler.java | 7 ------- .../java/cjminecraft/core/energy/EnergyData.java | 2 -- .../java/cjminecraft/core/energy/EnergyUnits.java | 2 -- .../energy/compat/EnergyCapabilityProvider.java | 3 +-- .../core/energy/compat/ForgeEnergyWrapper.java | 4 ---- .../core/energy/compat/ItemBlockEnergy.java | 1 - .../cjminecraft/core/energy/compat/ItemEnergy.java | 1 - .../core/energy/compat/TeslaWrapper.java | 1 - .../core/energy/compat/TileEntityEnergy.java | 1 - .../compat/forge/CustomForgeEnergyStorage.java | 3 --- .../compat/forge/ForgeEnergyCapabilityProvider.java | 1 - .../core/energy/support/ForgeEnergySupport.java | 1 - .../java/cjminecraft/core/fluid/FluidUtils.java | 11 +++++++---- .../java/cjminecraft/core/init/CJCoreEvents.java | 1 - .../java/cjminecraft/core/init/CJCoreItems.java | 1 - .../cjminecraft/core/inventory/InventoryUtils.java | 1 - .../cjminecraft/core/inventory/ItemStackSet.java | 4 ---- .../java/cjminecraft/core/items/ItemMultimeter.java | 9 --------- .../cjminecraft/core/network/PacketHandler.java | 13 ++++++++++--- .../core/network/energy/PacketGetEnergyData.java | 1 - .../core/network/energy/PacketReturnCapacity.java | 2 -- .../core/network/fluid/PacketGetFluidData.java | 3 --- .../core/network/fluid/PacketReturnFluidData.java | 3 --- .../java/cjminecraft/core/proxy/ClientProxy.java | 1 - .../java/cjminecraft/core/proxy/ServerProxy.java | 2 -- .../java/cjminecraft/core/util/VersionChecker.java | 6 ------ 34 files changed, 18 insertions(+), 86 deletions(-) diff --git a/src/main/java/cjminecraft/core/CJCore.java b/src/main/java/cjminecraft/core/CJCore.java index 9ac54d7..003f457 100644 --- a/src/main/java/cjminecraft/core/CJCore.java +++ b/src/main/java/cjminecraft/core/CJCore.java @@ -14,10 +14,7 @@ import cjminecraft.core.init.CJCoreItems; import cjminecraft.core.items.ItemMultimeter; import cjminecraft.core.proxy.CommonProxy; -import net.minecraft.command.ICommandManager; -import net.minecraft.command.ServerCommandManager; import net.minecraftforge.common.ForgeVersion; -import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.CustomProperty; diff --git a/src/main/java/cjminecraft/core/client/gui/element/ElementEnergyBar.java b/src/main/java/cjminecraft/core/client/gui/element/ElementEnergyBar.java index d691d8d..a5346cf 100644 --- a/src/main/java/cjminecraft/core/client/gui/element/ElementEnergyBar.java +++ b/src/main/java/cjminecraft/core/client/gui/element/ElementEnergyBar.java @@ -1,7 +1,6 @@ package cjminecraft.core.client.gui.element; import java.io.IOException; -import java.text.NumberFormat; import java.util.List; import javax.annotation.Nullable; @@ -12,18 +11,13 @@ import cjminecraft.core.config.CJCoreConfig; import cjminecraft.core.energy.EnergyData; import cjminecraft.core.energy.EnergyUnits.EnergyUnit; -import cjminecraft.core.energy.compat.forge.CustomForgeEnergyStorage; import cjminecraft.core.energy.EnergyUtils; import cjminecraft.core.util.RenderUtils; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.resources.I18n; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; -import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.common.capabilities.Capability; diff --git a/src/main/java/cjminecraft/core/client/gui/element/ElementItemSlot.java b/src/main/java/cjminecraft/core/client/gui/element/ElementItemSlot.java index f9b2294..4238046 100644 --- a/src/main/java/cjminecraft/core/client/gui/element/ElementItemSlot.java +++ b/src/main/java/cjminecraft/core/client/gui/element/ElementItemSlot.java @@ -2,7 +2,6 @@ import java.util.List; -import cjminecraft.core.CJCore; import cjminecraft.core.client.gui.GuiCore; import cjminecraft.core.client.gui.ISpecialOverlayElement; import net.minecraft.item.ItemStack; diff --git a/src/main/java/cjminecraft/core/client/gui/element/ElementProgressBar.java b/src/main/java/cjminecraft/core/client/gui/element/ElementProgressBar.java index 093d1ef..49f6472 100644 --- a/src/main/java/cjminecraft/core/client/gui/element/ElementProgressBar.java +++ b/src/main/java/cjminecraft/core/client/gui/element/ElementProgressBar.java @@ -2,7 +2,6 @@ import cjminecraft.core.client.gui.GuiCore; import cjminecraft.core.util.RenderUtils; -import net.minecraft.tileentity.TileEntity; /** * A simple yet effective progress bar which displays an operations progress in diff --git a/src/main/java/cjminecraft/core/client/gui/element/ElementTexture.java b/src/main/java/cjminecraft/core/client/gui/element/ElementTexture.java index 5d8e87e..884cdaf 100644 --- a/src/main/java/cjminecraft/core/client/gui/element/ElementTexture.java +++ b/src/main/java/cjminecraft/core/client/gui/element/ElementTexture.java @@ -1,10 +1,7 @@ package cjminecraft.core.client.gui.element; -import java.util.List; - import cjminecraft.core.CJCore; import cjminecraft.core.client.gui.GuiCore; -import cjminecraft.core.util.RenderUtils; import net.minecraft.util.ResourceLocation; /** diff --git a/src/main/java/cjminecraft/core/client/gui/overlay/OverlayInventory.java b/src/main/java/cjminecraft/core/client/gui/overlay/OverlayInventory.java index bf9c863..a562444 100644 --- a/src/main/java/cjminecraft/core/client/gui/overlay/OverlayInventory.java +++ b/src/main/java/cjminecraft/core/client/gui/overlay/OverlayInventory.java @@ -3,7 +3,6 @@ import java.util.ArrayList; import java.util.List; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import com.google.common.collect.ImmutableList; diff --git a/src/main/java/cjminecraft/core/command/CommandEditTileEntity.java b/src/main/java/cjminecraft/core/command/CommandEditTileEntity.java index 131020b..1dfbf56 100644 --- a/src/main/java/cjminecraft/core/command/CommandEditTileEntity.java +++ b/src/main/java/cjminecraft/core/command/CommandEditTileEntity.java @@ -9,7 +9,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; -import cjminecraft.core.CJCore; import cjminecraft.core.config.CJCoreConfig; import cjminecraft.core.energy.EnergyUnits; import cjminecraft.core.energy.EnergyUnits.EnergyUnit; diff --git a/src/main/java/cjminecraft/core/config/CJCoreGuiFactory.java b/src/main/java/cjminecraft/core/config/CJCoreGuiFactory.java index 215bf2d..4360540 100644 --- a/src/main/java/cjminecraft/core/config/CJCoreGuiFactory.java +++ b/src/main/java/cjminecraft/core/config/CJCoreGuiFactory.java @@ -4,10 +4,7 @@ import java.util.List; import java.util.Set; -import com.google.common.collect.Lists; - import cjminecraft.core.CJCore; -import cjminecraft.core.energy.EnergyUnits; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.resources.I18n; diff --git a/src/main/java/cjminecraft/core/crafting/CraftingHandler.java b/src/main/java/cjminecraft/core/crafting/CraftingHandler.java index 3f2b0d2..12d4449 100644 --- a/src/main/java/cjminecraft/core/crafting/CraftingHandler.java +++ b/src/main/java/cjminecraft/core/crafting/CraftingHandler.java @@ -1,16 +1,9 @@ package cjminecraft.core.crafting; import cjminecraft.core.CJCore; -import cjminecraft.core.init.CJCoreItems; -import net.minecraft.init.Blocks; -import net.minecraft.init.Items; -import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; import net.minecraftforge.common.crafting.CraftingHelper; import net.minecraftforge.common.crafting.IRecipeFactory; -import net.minecraftforge.fml.common.registry.ForgeRegistries; -import net.minecraftforge.fml.common.registry.GameRegistry; -import net.minecraftforge.oredict.ShapedOreRecipe; /** * Handles all of the {@link CJCore} recipes diff --git a/src/main/java/cjminecraft/core/energy/EnergyData.java b/src/main/java/cjminecraft/core/energy/EnergyData.java index 892bfd8..96fa81a 100644 --- a/src/main/java/cjminecraft/core/energy/EnergyData.java +++ b/src/main/java/cjminecraft/core/energy/EnergyData.java @@ -1,7 +1,5 @@ package cjminecraft.core.energy; -import cjminecraft.core.energy.EnergyUnits.EnergyUnit; - /** * Holds energy data for use with syncing to servers. See {@link EnergyUtils} * diff --git a/src/main/java/cjminecraft/core/energy/EnergyUnits.java b/src/main/java/cjminecraft/core/energy/EnergyUnits.java index f7533ac..be7f8ee 100644 --- a/src/main/java/cjminecraft/core/energy/EnergyUnits.java +++ b/src/main/java/cjminecraft/core/energy/EnergyUnits.java @@ -1,7 +1,6 @@ package cjminecraft.core.energy; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import org.apache.commons.lang3.text.WordUtils; @@ -13,7 +12,6 @@ import net.minecraft.client.resources.I18n; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; /** * Handler of all the different types of {@link EnergyUnit} diff --git a/src/main/java/cjminecraft/core/energy/compat/EnergyCapabilityProvider.java b/src/main/java/cjminecraft/core/energy/compat/EnergyCapabilityProvider.java index ec47685..9a75f54 100644 --- a/src/main/java/cjminecraft/core/energy/compat/EnergyCapabilityProvider.java +++ b/src/main/java/cjminecraft/core/energy/compat/EnergyCapabilityProvider.java @@ -1,9 +1,8 @@ package cjminecraft.core.energy.compat; -import cjminecraft.core.CJCore; import cjminecraft.core.energy.EnergyUnits; -import cjminecraft.core.energy.EnergyUtils; import cjminecraft.core.energy.EnergyUnits.EnergyUnit; +import cjminecraft.core.energy.EnergyUtils; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; diff --git a/src/main/java/cjminecraft/core/energy/compat/ForgeEnergyWrapper.java b/src/main/java/cjminecraft/core/energy/compat/ForgeEnergyWrapper.java index 8b742fa..2656475 100644 --- a/src/main/java/cjminecraft/core/energy/compat/ForgeEnergyWrapper.java +++ b/src/main/java/cjminecraft/core/energy/compat/ForgeEnergyWrapper.java @@ -1,9 +1,5 @@ package cjminecraft.core.energy.compat; -import cjminecraft.core.energy.compat.forge.CustomForgeEnergyStorage; -import net.darkhax.tesla.api.ITeslaConsumer; -import net.darkhax.tesla.api.ITeslaHolder; -import net.darkhax.tesla.api.ITeslaProducer; import net.minecraftforge.energy.IEnergyStorage; /** diff --git a/src/main/java/cjminecraft/core/energy/compat/ItemBlockEnergy.java b/src/main/java/cjminecraft/core/energy/compat/ItemBlockEnergy.java index 87cba03..1bfc8b6 100644 --- a/src/main/java/cjminecraft/core/energy/compat/ItemBlockEnergy.java +++ b/src/main/java/cjminecraft/core/energy/compat/ItemBlockEnergy.java @@ -4,7 +4,6 @@ import cjminecraft.core.energy.EnergyUnits; import cjminecraft.core.energy.EnergyUtils; -import cjminecraft.core.energy.compat.forge.CustomForgeEnergyStorage; import cofh.redstoneflux.api.IEnergyContainerItem; import ic2.api.item.IElectricItem; import net.minecraft.block.Block; diff --git a/src/main/java/cjminecraft/core/energy/compat/ItemEnergy.java b/src/main/java/cjminecraft/core/energy/compat/ItemEnergy.java index b1ab23b..44d07d6 100644 --- a/src/main/java/cjminecraft/core/energy/compat/ItemEnergy.java +++ b/src/main/java/cjminecraft/core/energy/compat/ItemEnergy.java @@ -4,7 +4,6 @@ import cjminecraft.core.energy.EnergyUnits; import cjminecraft.core.energy.EnergyUtils; -import cjminecraft.core.energy.compat.forge.CustomForgeEnergyStorage; import cofh.redstoneflux.api.IEnergyContainerItem; import ic2.api.item.IElectricItem; import net.minecraft.client.util.ITooltipFlag; diff --git a/src/main/java/cjminecraft/core/energy/compat/TeslaWrapper.java b/src/main/java/cjminecraft/core/energy/compat/TeslaWrapper.java index 546c01f..f1037e0 100644 --- a/src/main/java/cjminecraft/core/energy/compat/TeslaWrapper.java +++ b/src/main/java/cjminecraft/core/energy/compat/TeslaWrapper.java @@ -1,6 +1,5 @@ package cjminecraft.core.energy.compat; -import cjminecraft.core.energy.compat.forge.CustomForgeEnergyStorage; import net.darkhax.tesla.api.ITeslaConsumer; import net.darkhax.tesla.api.ITeslaHolder; import net.darkhax.tesla.api.ITeslaProducer; diff --git a/src/main/java/cjminecraft/core/energy/compat/TileEntityEnergy.java b/src/main/java/cjminecraft/core/energy/compat/TileEntityEnergy.java index c752ddc..c5ab35f 100644 --- a/src/main/java/cjminecraft/core/energy/compat/TileEntityEnergy.java +++ b/src/main/java/cjminecraft/core/energy/compat/TileEntityEnergy.java @@ -1,7 +1,6 @@ package cjminecraft.core.energy.compat; import cjminecraft.core.energy.EnergyUtils; -import cjminecraft.core.energy.compat.forge.CustomForgeEnergyStorage; import cjminecraft.core.util.TileEntityBase; import ic2.api.energy.event.EnergyTileLoadEvent; import ic2.api.energy.event.EnergyTileUnloadEvent; diff --git a/src/main/java/cjminecraft/core/energy/compat/forge/CustomForgeEnergyStorage.java b/src/main/java/cjminecraft/core/energy/compat/forge/CustomForgeEnergyStorage.java index dea232f..1943a11 100644 --- a/src/main/java/cjminecraft/core/energy/compat/forge/CustomForgeEnergyStorage.java +++ b/src/main/java/cjminecraft/core/energy/compat/forge/CustomForgeEnergyStorage.java @@ -1,11 +1,8 @@ package cjminecraft.core.energy.compat.forge; -import cjminecraft.core.CJCore; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.energy.EnergyStorage; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.relauncher.Side; /** * An improved version of an {@link EnergyStorage} diff --git a/src/main/java/cjminecraft/core/energy/compat/forge/ForgeEnergyCapabilityProvider.java b/src/main/java/cjminecraft/core/energy/compat/forge/ForgeEnergyCapabilityProvider.java index 2f4ba1e..6172f0d 100644 --- a/src/main/java/cjminecraft/core/energy/compat/forge/ForgeEnergyCapabilityProvider.java +++ b/src/main/java/cjminecraft/core/energy/compat/forge/ForgeEnergyCapabilityProvider.java @@ -1,6 +1,5 @@ package cjminecraft.core.energy.compat.forge; -import cjminecraft.core.CJCore; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; diff --git a/src/main/java/cjminecraft/core/energy/support/ForgeEnergySupport.java b/src/main/java/cjminecraft/core/energy/support/ForgeEnergySupport.java index 31e62b3..a9daef0 100644 --- a/src/main/java/cjminecraft/core/energy/support/ForgeEnergySupport.java +++ b/src/main/java/cjminecraft/core/energy/support/ForgeEnergySupport.java @@ -1,6 +1,5 @@ package cjminecraft.core.energy.support; -import cjminecraft.core.CJCore; import cjminecraft.core.energy.EnergyUnits; import cjminecraft.core.energy.EnergyUnits.EnergyUnit; import net.minecraft.item.ItemStack; diff --git a/src/main/java/cjminecraft/core/fluid/FluidUtils.java b/src/main/java/cjminecraft/core/fluid/FluidUtils.java index 5588b9d..5616764 100644 --- a/src/main/java/cjminecraft/core/fluid/FluidUtils.java +++ b/src/main/java/cjminecraft/core/fluid/FluidUtils.java @@ -6,18 +6,21 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; -import cjminecraft.core.CJCore; import cjminecraft.core.config.CJCoreConfig; import cjminecraft.core.network.PacketHandler; -import cjminecraft.core.network.fluid.*; +import cjminecraft.core.network.fluid.PacketGetFluidData; import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.fluids.*; -import net.minecraftforge.fluids.capability.*; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandler; /** * Utility class for fluids diff --git a/src/main/java/cjminecraft/core/init/CJCoreEvents.java b/src/main/java/cjminecraft/core/init/CJCoreEvents.java index d7df805..fc82f0a 100644 --- a/src/main/java/cjminecraft/core/init/CJCoreEvents.java +++ b/src/main/java/cjminecraft/core/init/CJCoreEvents.java @@ -1,7 +1,6 @@ package cjminecraft.core.init; import cjminecraft.core.CJCore; -import cjminecraft.core.crafting.CraftingHandler; import cjminecraft.core.energy.EnergyUtils; import cjminecraft.core.fluid.FluidUtils; import cjminecraft.core.inventory.InventoryUtils; diff --git a/src/main/java/cjminecraft/core/init/CJCoreItems.java b/src/main/java/cjminecraft/core/init/CJCoreItems.java index 2b8cf3a..ddeb6d8 100644 --- a/src/main/java/cjminecraft/core/init/CJCoreItems.java +++ b/src/main/java/cjminecraft/core/init/CJCoreItems.java @@ -8,7 +8,6 @@ import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.fml.common.registry.ForgeRegistries; -import net.minecraftforge.fml.common.registry.GameRegistry; /** * Handles all of {@link CJCore}s items diff --git a/src/main/java/cjminecraft/core/inventory/InventoryUtils.java b/src/main/java/cjminecraft/core/inventory/InventoryUtils.java index d8a8d79..5dd5698 100644 --- a/src/main/java/cjminecraft/core/inventory/InventoryUtils.java +++ b/src/main/java/cjminecraft/core/inventory/InventoryUtils.java @@ -9,7 +9,6 @@ import com.google.common.collect.ImmutableList; -import cjminecraft.core.CJCore; import cjminecraft.core.network.PacketHandler; import cjminecraft.core.network.inventory.PacketGetInventory; import net.minecraft.entity.item.EntityItem; diff --git a/src/main/java/cjminecraft/core/inventory/ItemStackSet.java b/src/main/java/cjminecraft/core/inventory/ItemStackSet.java index fbac0ed..8e3082e 100644 --- a/src/main/java/cjminecraft/core/inventory/ItemStackSet.java +++ b/src/main/java/cjminecraft/core/inventory/ItemStackSet.java @@ -7,12 +7,8 @@ import java.util.List; import java.util.Set; -import org.apache.commons.lang3.tuple.Pair; - import com.google.common.collect.ImmutableList; -import cjminecraft.core.CJCore; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; diff --git a/src/main/java/cjminecraft/core/items/ItemMultimeter.java b/src/main/java/cjminecraft/core/items/ItemMultimeter.java index e5708a1..e66e81d 100644 --- a/src/main/java/cjminecraft/core/items/ItemMultimeter.java +++ b/src/main/java/cjminecraft/core/items/ItemMultimeter.java @@ -1,14 +1,7 @@ package cjminecraft.core.items; import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; import java.util.List; -import java.util.Set; -import java.util.function.Predicate; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Sets; import cjminecraft.core.CJCore; import cjminecraft.core.client.gui.GuiOverlay; @@ -48,8 +41,6 @@ import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; import net.minecraftforge.fluids.FluidTankInfo; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; /** * The item which shows how much energy is in any {@link TileEntity} diff --git a/src/main/java/cjminecraft/core/network/PacketHandler.java b/src/main/java/cjminecraft/core/network/PacketHandler.java index cc662a8..8ca3225 100644 --- a/src/main/java/cjminecraft/core/network/PacketHandler.java +++ b/src/main/java/cjminecraft/core/network/PacketHandler.java @@ -1,9 +1,16 @@ package cjminecraft.core.network; import cjminecraft.core.CJCore; -import cjminecraft.core.network.energy.*; -import cjminecraft.core.network.fluid.*; -import cjminecraft.core.network.inventory.*; +import cjminecraft.core.network.energy.PacketGetCapacity; +import cjminecraft.core.network.energy.PacketGetEnergy; +import cjminecraft.core.network.energy.PacketGetEnergyData; +import cjminecraft.core.network.energy.PacketReturnCapacity; +import cjminecraft.core.network.energy.PacketReturnEnergy; +import cjminecraft.core.network.energy.PacketReturnEnergyData; +import cjminecraft.core.network.fluid.PacketGetFluidData; +import cjminecraft.core.network.fluid.PacketReturnFluidData; +import cjminecraft.core.network.inventory.PacketGetInventory; +import cjminecraft.core.network.inventory.PacketReturnInventory; import cjminecraft.core.proxy.CommonProxy; import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; diff --git a/src/main/java/cjminecraft/core/network/energy/PacketGetEnergyData.java b/src/main/java/cjminecraft/core/network/energy/PacketGetEnergyData.java index 5230043..93521a4 100644 --- a/src/main/java/cjminecraft/core/network/energy/PacketGetEnergyData.java +++ b/src/main/java/cjminecraft/core/network/energy/PacketGetEnergyData.java @@ -2,7 +2,6 @@ import cjminecraft.core.CJCore; import cjminecraft.core.energy.EnergyUnits.EnergyUnit; -import cjminecraft.core.energy.compat.forge.CustomForgeEnergyStorage; import cjminecraft.core.energy.EnergyUtils; import cjminecraft.core.network.PacketHandler; import cjminecraft.core.util.NetworkUtils; diff --git a/src/main/java/cjminecraft/core/network/energy/PacketReturnCapacity.java b/src/main/java/cjminecraft/core/network/energy/PacketReturnCapacity.java index 3b25174..b186673 100644 --- a/src/main/java/cjminecraft/core/network/energy/PacketReturnCapacity.java +++ b/src/main/java/cjminecraft/core/network/energy/PacketReturnCapacity.java @@ -4,8 +4,6 @@ import cjminecraft.core.CJCore; import cjminecraft.core.energy.EnergyData; -import cjminecraft.core.energy.EnergyUnits.EnergyUnit; -import cjminecraft.core.util.NetworkUtils; import cjminecraft.core.energy.EnergyUtils; import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; diff --git a/src/main/java/cjminecraft/core/network/fluid/PacketGetFluidData.java b/src/main/java/cjminecraft/core/network/fluid/PacketGetFluidData.java index ef6a038..4c4dc49 100644 --- a/src/main/java/cjminecraft/core/network/fluid/PacketGetFluidData.java +++ b/src/main/java/cjminecraft/core/network/fluid/PacketGetFluidData.java @@ -1,16 +1,13 @@ package cjminecraft.core.network.fluid; import cjminecraft.core.CJCore; -import cjminecraft.core.energy.EnergyUtils; import cjminecraft.core.fluid.FluidUtils; import cjminecraft.core.network.PacketHandler; -import cjminecraft.core.network.energy.PacketReturnEnergyData; import cjminecraft.core.util.NetworkUtils; import io.netty.buffer.ByteBuf; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; -import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.network.ByteBufUtils; diff --git a/src/main/java/cjminecraft/core/network/fluid/PacketReturnFluidData.java b/src/main/java/cjminecraft/core/network/fluid/PacketReturnFluidData.java index bfeb762..cac7b23 100644 --- a/src/main/java/cjminecraft/core/network/fluid/PacketReturnFluidData.java +++ b/src/main/java/cjminecraft/core/network/fluid/PacketReturnFluidData.java @@ -3,10 +3,7 @@ import java.lang.reflect.Field; import cjminecraft.core.CJCore; -import cjminecraft.core.energy.EnergyData; -import cjminecraft.core.energy.EnergyUtils; import cjminecraft.core.fluid.FluidUtils; -import cjminecraft.core.network.energy.PacketReturnEnergyData; import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; import net.minecraft.nbt.NBTTagCompound; diff --git a/src/main/java/cjminecraft/core/proxy/ClientProxy.java b/src/main/java/cjminecraft/core/proxy/ClientProxy.java index 0d2d34d..d06fca5 100644 --- a/src/main/java/cjminecraft/core/proxy/ClientProxy.java +++ b/src/main/java/cjminecraft/core/proxy/ClientProxy.java @@ -1,7 +1,6 @@ package cjminecraft.core.proxy; import cjminecraft.core.config.CJCoreConfig; -import cjminecraft.core.energy.EnergyUnits; import cjminecraft.core.init.CJCoreItems; import cjminecraft.core.items.ItemMultimeter; import net.minecraftforge.common.MinecraftForge; diff --git a/src/main/java/cjminecraft/core/proxy/ServerProxy.java b/src/main/java/cjminecraft/core/proxy/ServerProxy.java index d7c30ef..baea6d6 100644 --- a/src/main/java/cjminecraft/core/proxy/ServerProxy.java +++ b/src/main/java/cjminecraft/core/proxy/ServerProxy.java @@ -1,7 +1,5 @@ package cjminecraft.core.proxy; -import cjminecraft.core.energy.EnergyUnits; - /** * For all things server * @author CJMinecraft diff --git a/src/main/java/cjminecraft/core/util/VersionChecker.java b/src/main/java/cjminecraft/core/util/VersionChecker.java index 514f06b..8c333ee 100644 --- a/src/main/java/cjminecraft/core/util/VersionChecker.java +++ b/src/main/java/cjminecraft/core/util/VersionChecker.java @@ -1,16 +1,10 @@ package cjminecraft.core.util; -import java.awt.event.ActionEvent; -import java.beans.PropertyChangeListener; import java.io.InputStreamReader; -import java.lang.reflect.Field; import java.net.URL; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import javax.swing.Action; - import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; From 85947e92904cc44ef2d8d8576e943e385dfc9a64 Mon Sep 17 00:00:00 2001 From: Hypeirochus Date: Tue, 12 Jun 2018 15:07:13 -0400 Subject: [PATCH 13/19] Enabled access to PlayerControllerMP. --- src/main/resources/META-INF/CJCore_at.cfg | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/resources/META-INF/CJCore_at.cfg b/src/main/resources/META-INF/CJCore_at.cfg index bf97ea9..b7b5dd6 100644 --- a/src/main/resources/META-INF/CJCore_at.cfg +++ b/src/main/resources/META-INF/CJCore_at.cfg @@ -23,3 +23,7 @@ public net.minecraft.block.Block * # RenderLivingBase public net.minecraft.client.renderer.entity.RenderLivingBase * + +# PlayerControllerMP +public net.minecraft.client.multiplayer.PlayerControllerMP * +public net.minecraft.client.multiplayer.PlayerControllerMP *() \ No newline at end of file From 05c66801aa0d852f15bf67d779d41abd16c0cf3b Mon Sep 17 00:00:00 2001 From: Hypeirochus Date: Tue, 12 Jun 2018 15:27:53 -0400 Subject: [PATCH 14/19] Added generic utils class (needs overview). --- .../java/cjminecraft/core/util/Utils.java | 269 ++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 src/main/java/cjminecraft/core/util/Utils.java diff --git a/src/main/java/cjminecraft/core/util/Utils.java b/src/main/java/cjminecraft/core/util/Utils.java new file mode 100644 index 0000000..45770eb --- /dev/null +++ b/src/main/java/cjminecraft/core/util/Utils.java @@ -0,0 +1,269 @@ +package cjminecraft.core.util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.FloatBuffer; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.codec.language.bm.Lang; +import org.apache.logging.log4j.Logger; +import org.lwjgl.opengl.GL11; +import org.lwjgl.util.vector.Matrix4f; + +import cjminecraft.core.CJCore; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GLAllocation; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.init.Blocks; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.oredict.OreDictionary; + +/** + * @author CJMinecraft + */ + +//TODO: CJMinecraft, please overlook this class and try to move these methods to a better location. +//Or, rename the class to better fit the names of these methods. :) +public class Utils { + + public static final FloatBuffer projection = GLAllocation.createDirectFloatBuffer(16); + public static final FloatBuffer modelview = GLAllocation.createDirectFloatBuffer(16); + + /** + * Makes the variables which will be initialized when there getter method is called + */ + private static Lang lang; + + /** + * @return The player's projection matrix + */ + public static Matrix4f getProjectionMatrix() { + GlStateManager.getFloat(GL11.GL_PROJECTION_MATRIX, projection); + GlStateManager.getFloat(GL11.GL_MODELVIEW_MATRIX, modelview); + Matrix4f projectionMatrix = (Matrix4f) new Matrix4f().load(projection.asReadOnlyBuffer()); + Matrix4f modelViewMatrix = (Matrix4f) new Matrix4f().load(modelview.asReadOnlyBuffer()); + Matrix4f result = Matrix4f.mul(modelViewMatrix, projectionMatrix, null); + return result; + } + + /** + * Returns the logger. This makes System.out.println look shabby + * + * @return The {@link Logger} + */ + public static Logger getLogger() { + return CJCore.logger; + } + + /** + * Gets the text from the path specified. + * + * @param location + * The location of the text + * @return an array holding each line of the text + */ + public static List loadTextFromFile(ResourceLocation location) { + List output = new ArrayList(); + try { + InputStreamReader is = new InputStreamReader(Minecraft.getMinecraft().getResourceManager().getResource(location).getInputStream()); + BufferedReader reader = new BufferedReader(is); + String line = reader.readLine(); + while (line != null) { + output.add(line); + line = reader.readLine(); + } + } catch (IOException e) { + e.printStackTrace(); + } + return output; + } + + /** + * Calculate the redstone current from a item stack handler + * + * @param handler + * The handler + * @return The redstone power + */ + public static int calculateRedstone(IItemHandler handler) { + int i = 0; + float f = 0.0F; + for (int j = 0; j < handler.getSlots(); j++) { + ItemStack stack = handler.getStackInSlot(j); + if (!stack.isEmpty()) { + f += (float) stack.getCount() / (float) Math.min(handler.getStackInSlot(j).getMaxStackSize(), stack.getMaxStackSize()); + i++; + } + } + f = f / (float) handler.getSlots(); + return (int) (Math.floor(f * 14.0F) + (i > 0 ? 1 : 0)); + } + + /** + * Adds the chosen item stack to the inventory + * + * @param handler + * The holder of the items + * @param stack + * The stack to add + * @param simulate + * Is the task a simulation? + * @return The remainder left if the slot was full + */ + public static ItemStack addStackToInventory(IItemHandler handler, ItemStack stack, boolean simulate) { + return addStackToInventory(handler, handler.getSlots(), stack, simulate); + } + + /** + * Adds the chosen item stack to the inventory + * + * @param handler + * The holder of the items + * @param maxSlot + * The max slot to add to + * @param stack + * The stack to add + * @param simulate + * Is the task a simulation? + * @return The remainder left if the slot was full + */ + public static ItemStack addStackToInventory(IItemHandler handler, int maxSlot, ItemStack stack, boolean simulate) { + ItemStack remainer = stack.copy(); + for(int slot = 0; slot < maxSlot; slot++) { + ItemStack tempStack = handler.insertItem(slot, remainer, simulate); + if(tempStack.isEmpty()) + return ItemStack.EMPTY; + remainer = tempStack.copy(); + } + return remainer; + } + + /** + * Takes the chosen item stack from a specified slot to the inventory + * + * @param handler + * The holder of the items + * @param maxSlot + * The max slot to take from + * @param amount + * The amount to take + * @param simulate + * Is the task a simulation? + * @return The remainder left if the slot was full + */ + public static ItemStack removeStackFromInventory(IItemHandler handler, int maxSlot, int amount, boolean simulate) { + ItemStack remainder = ItemStack.EMPTY; + for (int slot = 0; slot < maxSlot; slot++) { + remainder = handler.extractItem(slot, amount, simulate); + if (remainder.isEmpty()) + break; + } + return remainder; + } + + /** + * Checks if the inventory is full + * + * @param handler + * The inventory + * @return true if it is full + */ + public static boolean isInventoryFull(IItemHandler handler) { + return isInventoryFull(handler, handler.getSlots()); + } + + /** + * Checks if the inventory is full + * + * @param handler + * The inventory + * @param maxSlot + * The number of slots to check + * @return true if it is full + */ + public static boolean isInventoryFull(IItemHandler handler, int maxSlot) { + for (int slot = 0; slot < maxSlot; slot++) { + if (handler.getStackInSlot(slot).getCount() < handler.getStackInSlot(slot).getMaxStackSize()) { + return false; + } + } + return true; + } + + /** + * Gets the correct colour from any item stack using the ore dictionary The item must be registered as a dye + * + * @param stack + * The {@link ItemStack} to test + * @return The {@link EnumDyeColor} of the {@link ItemStack} to test. If the stack is not registered as a dye, the {@link EnumDyeColor#WHITE} will be used + */ + public static EnumDyeColor getColorFromDye(ItemStack stack) { + for (int id : OreDictionary.getOreIDs(stack)) { + if (id == OreDictionary.getOreID("dyeBlack")) + return EnumDyeColor.BLACK; + if (id == OreDictionary.getOreID("dyeRed")) + return EnumDyeColor.RED; + if (id == OreDictionary.getOreID("dyeGreen")) + return EnumDyeColor.GREEN; + if (id == OreDictionary.getOreID("dyeBrown")) + return EnumDyeColor.BROWN; + if (id == OreDictionary.getOreID("dyeBlue")) + return EnumDyeColor.BLUE; + if (id == OreDictionary.getOreID("dyePurple")) + return EnumDyeColor.PURPLE; + if (id == OreDictionary.getOreID("dyeCyan")) + return EnumDyeColor.CYAN; + if (id == OreDictionary.getOreID("dyeLightGray")) + return EnumDyeColor.SILVER; + if (id == OreDictionary.getOreID("dyeGray")) + return EnumDyeColor.GRAY; + if (id == OreDictionary.getOreID("dyePink")) + return EnumDyeColor.PINK; + if (id == OreDictionary.getOreID("dyeLime")) + return EnumDyeColor.LIME; + if (id == OreDictionary.getOreID("dyeYellow")) + return EnumDyeColor.YELLOW; + if (id == OreDictionary.getOreID("dyeLightBlue")) + return EnumDyeColor.LIGHT_BLUE; + if (id == OreDictionary.getOreID("dyeMagenta")) + return EnumDyeColor.MAGENTA; + if (id == OreDictionary.getOreID("dyeOrange")) + return EnumDyeColor.ORANGE; + if (id == OreDictionary.getOreID("dyeWhite")) + return EnumDyeColor.WHITE; + } + return EnumDyeColor.WHITE; + } + + public static boolean checkSurroundingBlocks(World world, IBlockState state) { + for (int x = -1; x < 2; x++) { + for (int y = -1; y < 2; y++) { + for (int z = -1; z < 2; z++) { + if (world.getBlockState(new BlockPos(x, y, z)) == state) + return true; + } + } + } + return false; + } + + public static boolean checkSurroundingBlocks(World world) { + for (int x = -1; x < 2; x++) { + for (int y = -1; y < 2; y++) { + for (int z = -1; z < 2; z++) { + if (world.getBlockState(new BlockPos(x, y, z)) != Blocks.AIR) + return true; + } + } + } + return false; + } +} \ No newline at end of file From 75ea20d6c90f391f165b5b5ef490bf6e049f7025 Mon Sep 17 00:00:00 2001 From: Hypeirochus Date: Tue, 12 Jun 2018 17:55:41 -0400 Subject: [PATCH 15/19] Added keybinding handler. --- .../core/client/KeyBindingHandler.java | 17 +++++++++++++++++ .../core/client/render/model/Model.java | 5 +---- 2 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 src/main/java/cjminecraft/core/client/KeyBindingHandler.java diff --git a/src/main/java/cjminecraft/core/client/KeyBindingHandler.java b/src/main/java/cjminecraft/core/client/KeyBindingHandler.java new file mode 100644 index 0000000..9d1f8b8 --- /dev/null +++ b/src/main/java/cjminecraft/core/client/KeyBindingHandler.java @@ -0,0 +1,17 @@ +package cjminecraft.core.client; + +import net.minecraft.client.settings.KeyBinding; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.client.registry.ClientRegistry; + +public class KeyBindingHandler { + + public static void registerKeybinding(String unlocalizedName, int keyboardCode, String CATEGORY) { + KeyBinding key = new KeyBinding(unlocalizedName, keyboardCode, CATEGORY); + ClientRegistry.registerKeyBinding(key); + } + + public static void registerKeybinding(KeyBinding key) { + ClientRegistry.registerKeyBinding(key); + } +} diff --git a/src/main/java/cjminecraft/core/client/render/model/Model.java b/src/main/java/cjminecraft/core/client/render/model/Model.java index 714a5e0..020f738 100644 --- a/src/main/java/cjminecraft/core/client/render/model/Model.java +++ b/src/main/java/cjminecraft/core/client/render/model/Model.java @@ -66,9 +66,6 @@ public static void draw(ModelRenderer[] group) { } } - /** - * TODO: Figure out what this is, and why. - */ public void render() { this.render(null); } @@ -199,7 +196,7 @@ public static ModelBase createModelBase(Class modelClass) { * * @param modelClass * - A class extending ModelBaseExtension which will be - * instantaniated. + * instantiated. * @return Instance of the class specified in the modelClass parameter. */ public static Model createExtendedModelBase(Class modelClass) { From 28f6902d7d8e2dda200829a576e9217ec910d68d Mon Sep 17 00:00:00 2001 From: Hypeirochus Date: Tue, 12 Jun 2018 18:38:00 -0400 Subject: [PATCH 16/19] Added more helper functions. --- .../core/client/KeyBindingHandler.java | 1 - .../java/cjminecraft/core/world/Worlds.java | 33 ++++++++++++ .../core/world/entity/Entities.java | 50 +++++++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/main/java/cjminecraft/core/client/KeyBindingHandler.java b/src/main/java/cjminecraft/core/client/KeyBindingHandler.java index 9d1f8b8..f7a20b5 100644 --- a/src/main/java/cjminecraft/core/client/KeyBindingHandler.java +++ b/src/main/java/cjminecraft/core/client/KeyBindingHandler.java @@ -1,7 +1,6 @@ package cjminecraft.core.client; import net.minecraft.client.settings.KeyBinding; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.client.registry.ClientRegistry; public class KeyBindingHandler { diff --git a/src/main/java/cjminecraft/core/world/Worlds.java b/src/main/java/cjminecraft/core/world/Worlds.java index f9ae556..b069399 100644 --- a/src/main/java/cjminecraft/core/world/Worlds.java +++ b/src/main/java/cjminecraft/core/world/Worlds.java @@ -1,9 +1,11 @@ package cjminecraft.core.world; +import java.util.ArrayList; import java.util.Random; import java.util.UUID; import cjminecraft.core.world.entity.Entities; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.math.BlockPos; @@ -255,4 +257,35 @@ public static UUID uuidFromSignature(String signature) { return null; } + + /** + * Checks a cubic volume for any instances of {@code blockState}. The anchor is in the absolute center of the cube. Make sure the side length is an odd number + * + * @param world + * the world + * @param blockState + * the {@link IBlockState} to check for + * @param pos + * the anchor {@link BlockPos} + * @param sideLength + * the length of the cube's sides + * @return {@link ArrayList} of all the BlockPos instances that contain {@code blockState} + */ + public static ArrayList checkCube(World world, IBlockState blockState, BlockPos pos, int sideLength) { + ArrayList posList = new ArrayList(); + + for (int x = -sideLength / 2; x < sideLength / 2 + 1; x++) { + for (int y = -sideLength / 2; y < sideLength / 2 + 1; y++) { + for (int z = -sideLength / 2; z < sideLength / 2 + 1; z++) { + BlockPos currPos = pos.add(x, y, z); + + if (world.getBlockState(currPos).equals(blockState)) { + posList.add(currPos); + } + } + } + } + + return posList; + } } diff --git a/src/main/java/cjminecraft/core/world/entity/Entities.java b/src/main/java/cjminecraft/core/world/entity/Entities.java index e9f6ed6..91796cf 100644 --- a/src/main/java/cjminecraft/core/world/entity/Entities.java +++ b/src/main/java/cjminecraft/core/world/entity/Entities.java @@ -804,4 +804,54 @@ public static EnumFacing getEntityFacingRotX(Entity entity) { return EnumFacing.NORTH; } } + + /** + * Replaces {@code current} with {@code next} in the same world. Can transfer pitch and yaw rotation angles from {@code current} to {@code next}. If pitch/yaw not transferred, they are both set to {@code 0} + * + * @param current + * the entity to replace + * @param next + * the replacement + * @param keepRot + * whether or not to transfer the pitch and yaw rotation angles of {@code current} to {@code next} + */ + public static void replaceEntity(boolean keepRot, Entity current, Entity... next) { + if (!current.world.isRemote) { + if (keepRot) { + for (Entity e : next) { + e.setLocationAndAngles(current.posX, current.posY, current.posZ, current.rotationYaw, current.rotationPitch); + } + } else { + for (Entity e : next) { + e.setLocationAndAngles(current.posX, current.posY, current.posZ, 0, 0); + } + } + + for (Entity e : next) { + current.world.spawnEntity(e); + } + + current.setDead(); + } + } + + /** + * Replaces {@code current} with {@code next} in the same world. Sets the pitch/yaw of all objects on {@code next} to {@code pitch} and {@code yaw}, respectively.
+ * This is done by setting {@code current}'s pitch/yaw, then calling {@link #replaceEntity(boolean, Entity, Entity)} with parameters {@code true}, {@code current}, and {@code next} as a means of transferring {@code current}'s new pitch/yaw angles to {@code next} + * + * @param pitch + * the pitch to use + * @param yaw + * the yaw to use + * @param current + * the {@link Entity} to replace + * @param next + * the {@link Entity} objects to replace {@code current} + */ + public static void replaceEntity(float pitch, float yaw, Entity current, Entity... next) { + if (!current.world.isRemote) { + current.setLocationAndAngles(current.posX, current.posY, current.posZ, yaw, pitch); + replaceEntity(true, current, next); + } + } } \ No newline at end of file From ffda43c3e220cf1bb814104ee60e3511b1c28b89 Mon Sep 17 00:00:00 2001 From: Hypeirochus Date: Tue, 12 Jun 2018 18:38:19 -0400 Subject: [PATCH 17/19] Added shape generation class. --- .../core/world/generation/GenPattern.java | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/main/java/cjminecraft/core/world/generation/GenPattern.java diff --git a/src/main/java/cjminecraft/core/world/generation/GenPattern.java b/src/main/java/cjminecraft/core/world/generation/GenPattern.java new file mode 100644 index 0000000..4ce9657 --- /dev/null +++ b/src/main/java/cjminecraft/core/world/generation/GenPattern.java @@ -0,0 +1,76 @@ +package cjminecraft.core.world.generation; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public class GenPattern { + + /** + * Makes a cube out of {@code blockState} anchored at the bottom-middle. NOTE: this ignores the anchor. Also, make sure the side length is an odd natural number, else you'll break something + * + * @param world + * the world + * @param blockState + * the blockState to make a cube of (use {@link Block#getDefaultState()} if unsure) + * @param pos + * the {@link BlockPos} of the anchor + * @param sideLength + * the length of the sides of the cube + */ + public static void blockCube(World world, IBlockState blockState, BlockPos pos, int sideLength) { + for (int x = -sideLength / 2; x < sideLength / 2 + 1; x++) { + for (int y = 0; y < sideLength + 1; y++) { + for (int z = -sideLength / 2; z < sideLength / 2 + 1; z++) { + if (x == 0 && y == 0 && z == 0) { + continue; + } else { + world.setBlockState(pos.add(x, y, z), blockState); + } + } + } + } + } + + + //TODO: Add block filtering capabilities. + public static void genSquare(World world, BlockPos center, int radius, IBlockState state) { + BlockPos pos = center.add(-radius, 0, -radius); + EnumFacing facing = EnumFacing.EAST; + for (int i = 0; i < 4; i++) { + for (int k = radius * 2 - 1; k >= 0; k--) { + if (world.getBlockState(pos).getBlock() == Blocks.AIR) + world.setBlockState(pos, state); + pos = pos.offset(facing); + } + facing = facing.rotateY(); + } + } + + /** + * Creates a dome. + * + * @param world + * the world + * @param pos + * the bottom-middle of the shield + * @param domeHeight + * difference in height between {@code pos} and the peak of the dome + */ + //TODO: Add block filtering capabilities. + public static void genTruncatedPyramid(World world, BlockPos pos, IBlockState state, int domeHeight, int domeTopLength, int slope) { + int radius = domeTopLength / 2; + for (int i = domeHeight - 1; i >= 0; i -= slope) { + for (int k = 0; k >= -slope + 1 && i + k >= 0; k--) + genSquare(world, new BlockPos(pos.getX(), pos.getY() + i + k, pos.getZ()), (domeHeight - i - 1) / slope + radius, state); + } + for (int x = -radius; x <= radius; x++) + for (int z = -radius; z <= radius; z++) + if (world.getBlockState(pos.add(x, domeHeight - 1, z)).getBlock() == Blocks.SNOW_LAYER || world.getBlockState(pos.add(x, domeHeight - 1, z)).getBlock() == Blocks.AIR) + world.setBlockState(pos.add(x, domeHeight - 1, z), state); + } + + //TODO: Add sphere, pyramid, cube, cylinder, tetrahedron, triangular prism +} From cd879fb65be9e734347ae946eb7b083d18c68cdd Mon Sep 17 00:00:00 2001 From: Hypeirochus Date: Tue, 12 Jun 2018 19:48:18 -0400 Subject: [PATCH 18/19] Add ticks <-> seconds conversion methods. --- src/main/java/cjminecraft/core/util/MathUtils.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/cjminecraft/core/util/MathUtils.java b/src/main/java/cjminecraft/core/util/MathUtils.java index ad4801f..b59f30e 100644 --- a/src/main/java/cjminecraft/core/util/MathUtils.java +++ b/src/main/java/cjminecraft/core/util/MathUtils.java @@ -147,4 +147,12 @@ public static int compare(int a, int b) { public static int compare(double a, double b) { return a == b ? 0 : a < b ? -1 : 1; } + + public static int secondsToTicks(int seconds) { + return seconds * 20; + } + + public static float ticksToSeconds(int ticks) { + return ticks / 20; + } } \ No newline at end of file From dd6a3bda43611781aee9e77246c03d8498c5fba9 Mon Sep 17 00:00:00 2001 From: Hypeirochus Date: Tue, 12 Jun 2018 19:59:59 -0400 Subject: [PATCH 19/19] Added 3D item renderer. --- .../core/client/render/item/ItemRenderer.java | 201 ++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 src/main/java/cjminecraft/core/client/render/item/ItemRenderer.java diff --git a/src/main/java/cjminecraft/core/client/render/item/ItemRenderer.java b/src/main/java/cjminecraft/core/client/render/item/ItemRenderer.java new file mode 100644 index 0000000..fd56ba5 --- /dev/null +++ b/src/main/java/cjminecraft/core/client/render/item/ItemRenderer.java @@ -0,0 +1,201 @@ +package cjminecraft.core.client.render.item; + +import java.util.Collections; +import java.util.List; + +import javax.vecmath.Matrix4f; + +import org.apache.commons.lang3.tuple.Pair; + +import com.google.common.collect.Lists; + +import cjminecraft.core.client.render.Draw; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType; +import net.minecraft.client.renderer.block.model.ItemOverride; +import net.minecraft.client.renderer.block.model.ItemOverrideList; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +/** + * A neat class that removes the need for JSON in item rendering. + * + * @author Hypeirochus +*/ +public abstract class ItemRenderer implements IBakedModel { + + public static class ItemRenderList extends ItemOverrideList { + + public ItemRenderList() { + super(Lists.newArrayList()); + } + + @Override + public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, World world, EntityLivingBase entity) { + if (originalModel instanceof ItemRenderer) { + ItemRenderer model = (ItemRenderer) originalModel; + model.setItemstack(stack); + model.setEntity(entity); + } + + return super.handleItemState(originalModel, stack, world, entity); + } + } + + protected static final Minecraft mc = Minecraft.getMinecraft(); + private static List quads = Collections.emptyList(); + protected EntityLivingBase entity; + protected ModelBase model; + private ItemRenderList overrides; + protected ResourceLocation resource; + private final Pair selfPair; + + protected ItemStack stack; + + public ItemRenderer(ModelBase model, ResourceLocation resource) { + this.overrides = new ItemRenderList(); + this.selfPair = Pair.of(this, null); + this.model = model; + this.resource = resource; + } + + @Override + public ItemCameraTransforms getItemCameraTransforms() { + return ItemCameraTransforms.DEFAULT; + } + + public ModelBase getModel() { + return model; + } + + @Override + public ItemOverrideList getOverrides() { + return overrides; + } + + @Override + public TextureAtlasSprite getParticleTexture() { + return null; + } + + @Override + public List getQuads(IBlockState state, EnumFacing side, long rand) { + return quads; + } + + public ResourceLocation getResourceLocation() { + return resource; + } + + protected void bindTexture() { + Draw.bindTexture(resource); + } + + @Override + public Pair handlePerspective(TransformType type) { + renderPre(stack, entity, type); + + switch (type) { + case FIRST_PERSON_LEFT_HAND: { + renderFirstPersonLeft(stack, entity, type); + } + break; + case FIRST_PERSON_RIGHT_HAND: { + renderFirstPersonRight(stack, entity, type); + } + break; + case GUI: { + renderInInventory(stack, entity, type); + } + break; + case THIRD_PERSON_LEFT_HAND: { + renderThirdPersonLeft(stack, entity, type); + } + break; + case THIRD_PERSON_RIGHT_HAND: { + renderThirdPersonRight(stack, entity, type); + } + break; + case GROUND: { + renderInWorld(stack, entity, type); + } + break; + case FIXED: { + renderFixed(stack, entity, type); + } + break; + case HEAD: { + renderHead(stack, entity, type); + } + break; + + default: + break; + } + + renderPost(stack, entity, type); + + GlStateManager.bindTexture(Minecraft.getMinecraft().getTextureMapBlocks().getGlTextureId()); + + return selfPair; + } + + @Override + public boolean isAmbientOcclusion() { + return true; + } + + @Override + public boolean isBuiltInRenderer() { + return false; + } + + @Override + public boolean isGui3d() { + return true; + } + + public abstract void renderFirstPersonLeft(ItemStack itemstack, EntityLivingBase entity, TransformType cameraTransformType); + + public abstract void renderFirstPersonRight(ItemStack itemstack, EntityLivingBase entity, TransformType cameraTransformType); + + public abstract void renderInInventory(ItemStack itemstack, EntityLivingBase entity, TransformType cameraTransformType); + + public abstract void renderInWorld(ItemStack itemstack, EntityLivingBase entity, TransformType cameraTransformType); + + public void renderPost(ItemStack itemstack, EntityLivingBase entity, TransformType cameraTransformType) { + } + + public void renderPre(ItemStack itemstack, EntityLivingBase entity, TransformType cameraTransformType) { + } + + public abstract void renderThirdPersonLeft(ItemStack itemstack, EntityLivingBase entity, TransformType cameraTransformType); + + public abstract void renderThirdPersonRight(ItemStack itemstack, EntityLivingBase entity, TransformType cameraTransformType); + + public abstract void renderFixed(ItemStack itemstack, EntityLivingBase entity, TransformType cameraTransformType); + + public abstract void renderHead(ItemStack itemstack, EntityLivingBase entity, TransformType cameraTransformType); + + private void setEntity(EntityLivingBase entity) { + this.entity = entity; + } + + private void setItemstack(ItemStack stack) { + this.stack = stack; + } + + public void setResourceLocation(ResourceLocation resource) { + this.resource = resource; + } +} \ No newline at end of file