deerangle
Members-
Posts
259 -
Joined
-
Last visited
-
Days Won
1
Everything posted by deerangle
-
I've added a horizontal parameter to every gradient text function so that you can make horizontal and vertical gradients. This is the updated code: public class GradientFontRenderer extends FontRenderer { private static final String charmap = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000"; public GradientFontRenderer(GameSettings gameSettingsIn, ResourceLocation location, TextureManager textureManagerIn, boolean unicode) { super(gameSettingsIn, location, textureManagerIn, unicode); } public int drawGradientString(String text, float x, float y, int topColor, int bottomColor, boolean dropShadow, boolean horizontal) { enableAlpha(); int i; if (dropShadow) { i = this.renderGradientString(text, x + 1.0F, y + 1.0F, topColor, bottomColor, true, horizontal); i = Math.max(i, this.renderGradientString(text, x, y, topColor, bottomColor, false, horizontal)); } else { i = this.renderGradientString(text, x, y, topColor, bottomColor, false, horizontal); } return i; } private int renderGradientString(String text, float x, float y, int startColor, int endColor, boolean dropShadow, boolean horizontal) { if (text == null) { return 0; } else { if ((startColor & -67108864) == 0) { startColor |= -16777216; } if ((endColor & -67108864) == 0) { endColor |= -16777216; } if (dropShadow) { startColor = (startColor & 16579836) >> 2 | startColor & -16777216; endColor = (endColor & 16579836) >> 2 | endColor & -16777216; } this.posX = x; this.posY = y; this.renderGradientStringAtPos(text, dropShadow, startColor, endColor, horizontal); return (int) this.posX; } } private void renderGradientStringAtPos(String text, boolean shadow, int startColor, int endColor, boolean horizontal) { float totalWidth = this.getStringWidth(text); float currentCountWidth = 0; for (int i = 0; i < text.length(); ++i) { char c0 = text.charAt(i); int j = charmap.indexOf(c0); float f1 = j == -1 ? 0.5f : 1f; boolean flag = (c0 == 0 || j == -1) && shadow; if (flag) { this.posX -= f1; this.posY -= f1; } float f; if (horizontal) { float nextCharWidth = this.getCharWidth(c0); float firstMix = currentCountWidth / totalWidth; float lastMix = (currentCountWidth + nextCharWidth) / totalWidth; int firstColor = colorMix(startColor, endColor, firstMix); int lastColor = colorMix(startColor, endColor, lastMix); f = this.renderGradientChar(c0, firstColor, lastColor, true); currentCountWidth += f; } else { f = this.renderGradientChar(c0, startColor, endColor, false); } if (flag) { this.posX += f1; this.posY += f1; } doDraw(f); } } private int colorMix(int startColor, int endColor, float mix) { float startAlpha = ((startColor >> 24) & 0xFF) / 255f; float startRed = ((startColor >> 16) & 0xFF) / 255f; float startGreen = ((startColor >> 8) & 0xFF) / 255f; float startBlue = (startColor & 0xFF) / 255f; float endAlpha = ((endColor >> 24) & 0xFF) / 255f; float endRed = ((endColor >> 16) & 0xFF) / 255f; float endGreen = ((endColor >> 8) & 0xFF) / 255f; float endBlue = (endColor & 0xFF) / 255f; int mixAlpha = (int) (((1 - mix) * startAlpha + mix * endAlpha) * 255); int mixRed = (int) (((1 - mix) * startRed + mix * endRed) * 255); int mixGreen = (int) (((1 - mix) * startGreen + mix * endGreen) * 255); int mixBlue = (int) (((1 - mix) * startBlue + mix * endBlue) * 255); return (mixAlpha << 24) | (mixRed << 16) | (mixGreen << 8) | mixBlue; } private float renderGradientChar(char ch, int startColor, int endColor, boolean horizontal) { if (ch == 160) return 4.0F; // forge: display nbsp as space. MC-2595 if (ch == ' ') { return 4.0F; } else { int i = charmap.indexOf(ch); if (i != -1) { return this.renderGradientDefaultChar(i, startColor, endColor, horizontal); } else { throw new RuntimeException("Unrecognized char: " + ch); } } } protected float renderGradientDefaultChar(int ch, int startColor, int endColor, boolean horizontal) { float startAlpha = ((startColor >> 24) & 0xFF) / 255f; float startRed = ((startColor >> 16) & 0xFF) / 255f; float startGreen = ((startColor >> 8) & 0xFF) / 255f; float startBlue = (startColor & 0xFF) / 255f; float endAlpha = ((endColor >> 24) & 0xFF) / 255f; float endRed = ((endColor >> 16) & 0xFF) / 255f; float endGreen = ((endColor >> 8) & 0xFF) / 255f; float endBlue = (endColor & 0xFF) / 255f; float charXPos = ch % 16 * 8f; float charYPos = (ch / 16) * 8f; bindTexture(this.locationFontTexture); int charWidth = this.charWidth[ch]; float width = (float) charWidth - 0.01F; GlStateManager.shadeModel(GL11.GL_SMOOTH); GlStateManager.glBegin(GL11.GL_QUADS); GlStateManager.color(startRed, startGreen, startBlue, startAlpha); GlStateManager.glTexCoord2f(charXPos / 128.0F, charYPos / 128.0F); // 0 0 GlStateManager.glVertex3f(this.posX, this.posY, 0.0F); if (horizontal) { GlStateManager.color(startRed, startGreen, startBlue, startAlpha); } else { GlStateManager.color(endRed, endGreen, endBlue, endAlpha); } GlStateManager.glTexCoord2f(charXPos / 128.0F, (charYPos + 7.99F) / 128.0F); // 0 1 GlStateManager.glVertex3f(this.posX, this.posY + 7.99F, 0.0F); GlStateManager.color(endRed, endGreen, endBlue, endAlpha); GlStateManager.glTexCoord2f((charXPos + width - 1.0F) / 128.0F, (charYPos + 7.99F) / 128.0F); // 1 1 GlStateManager.glVertex3f(this.posX + width - 1.0F, this.posY + 7.99F, 0.0F); if (horizontal) { GlStateManager.color(endRed, endGreen, endBlue, endAlpha); } else { GlStateManager.color(startRed, startGreen, startBlue, startAlpha); } GlStateManager.glTexCoord2f((charXPos + width - 1.0F) / 128.0F, charYPos / 128.0F); // 1 0 GlStateManager.glVertex3f(this.posX + width - 1.0F, this.posY, 0.0F); GlStateManager.glEnd(); GlStateManager.shadeModel(GL11.GL_FLAT); return (float) charWidth; } } Pretty basic. It just linearly interpolates the colors for each char so that the gradient colors of each char match up.
-
So I decided to make all the functions to render with any gradient, and here's the code (it only supports normal text, no italics, no bold, no formatting or coloring, no unicode, but you can add that with some extra work if you need it): public class GradientFontRenderer extends FontRenderer { public GradientFontRenderer(GameSettings gameSettingsIn, ResourceLocation location, TextureManager textureManagerIn, boolean unicode) { super(gameSettingsIn, location, textureManagerIn, unicode); } public int drawGradientString(String text, float x, float y, int topColor, int bottomColor, boolean dropShadow) { enableAlpha(); int i; if (dropShadow) { i = this.renderGradientString(text, x + 1.0F, y + 1.0F, topColor, bottomColor, true); i = Math.max(i, this.renderGradientString(text, x, y, topColor, bottomColor, false)); } else { i = this.renderGradientString(text, x, y, topColor, bottomColor, false); } return i; } private int renderGradientString(String text, float x, float y, int topColor, int bottomColor, boolean dropShadow) { if (text == null) { return 0; } else { if ((topColor & -67108864) == 0) { topColor |= -16777216; } if ((bottomColor & -67108864) == 0) { bottomColor |= -16777216; } if (dropShadow) { topColor = (topColor & 16579836) >> 2 | topColor & -16777216; bottomColor = (bottomColor & 16579836) >> 2 | bottomColor & -16777216; } this.posX = x; this.posY = y; this.renderGradientStringAtPos(text, dropShadow, topColor, bottomColor); return (int)this.posX; } } private void renderGradientStringAtPos(String text, boolean shadow, int topColor, int bottomColor) { for (int i = 0; i < text.length(); ++i) { char c0 = text.charAt(i); int j = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000".indexOf(c0); float f1 = j == -1 ? 0.5f : 1f; boolean flag = (c0 == 0 || j == -1) && shadow; if (flag) { this.posX -= f1; this.posY -= f1; } float f = this.renderGradientChar(c0, topColor, bottomColor); if (flag) { this.posX += f1; this.posY += f1; } doDraw(f); } } private float renderGradientChar(char ch, int topColor, int bottomColor) { if (ch == 160) return 4.0F; // forge: display nbsp as space. MC-2595 if (ch == ' ') { return 4.0F; } else { int i = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000".indexOf(ch); if (i != -1) { return this.renderGradientDefaultChar(i, topColor, bottomColor); } else { throw new RuntimeException("Unrecognized char: " + ch); } } } protected float renderGradientDefaultChar(int ch, int topColor, int bottomColor) { float topAlpha = ((topColor >> 24) & 0xFF) / 255f; float topRed = ((topColor >> 16) & 0xFF) / 255f; float topGreen = ((topColor >> 8) & 0xFF) / 255f; float topBlue = (topColor & 0xFF) / 255f; float bottomAlpha = ((bottomColor >> 24) & 0xFF) / 255f; float bottomRed = ((bottomColor >> 16) & 0xFF) / 255f; float bottomGreen = ((bottomColor >> 8) & 0xFF) / 255f; float bottomBlue = (bottomColor & 0xFF) / 255f; float charXPos = ch % 16 * 8f; float charYPos = (ch / 16) * 8f; bindTexture(this.locationFontTexture); int charWidth = this.charWidth[ch]; float width = (float) charWidth - 0.01F; GlStateManager.shadeModel(GL11.GL_SMOOTH); GlStateManager.glBegin(GL11.GL_QUADS); GlStateManager.color(topRed, topGreen, topBlue, topAlpha); GlStateManager.glTexCoord2f(charXPos / 128.0F, charYPos / 128.0F); // 0 0 GlStateManager.glVertex3f(this.posX, this.posY, 0.0F); GlStateManager.color(bottomRed, bottomGreen, bottomBlue, bottomAlpha); GlStateManager.glTexCoord2f(charXPos / 128.0F, (charYPos + 7.99F) / 128.0F); // 0 1 GlStateManager.glVertex3f(this.posX, this.posY + 7.99F, 0.0F); GlStateManager.color(bottomRed, bottomGreen, bottomBlue, bottomAlpha); GlStateManager.glTexCoord2f((charXPos + width - 1.0F) / 128.0F, (charYPos + 7.99F) / 128.0F); // 1 1 GlStateManager.glVertex3f(this.posX + width - 1.0F, this.posY + 7.99F, 0.0F); GlStateManager.color(topRed, topGreen, topBlue, topAlpha); GlStateManager.glTexCoord2f((charXPos + width - 1.0F) / 128.0F, charYPos / 128.0F); // 1 0 GlStateManager.glVertex3f(this.posX + width - 1.0F, this.posY, 0.0F); GlStateManager.glEnd(); GlStateManager.shadeModel(GL11.GL_FLAT); return (float) charWidth; } } Then change this code from above to the following: public void drawCenteredGradientString(GradientFontRenderer fontRendererIn, String text, int x, int y, int color, int colorBottom) { fontRendererIn.drawGradientString(text, x - fontRendererIn.getStringWidth(text) / 2, y, color, colorBottom, true); } And it should work.
-
So after a little testing I came up with this (for 1.12.2): I created a Subclass of FontRenderer called GradientFontRenderer. In this class, I override the method renderDefaultChar (you should probably override the unicode method too.) so that It uses the above mentioned shadeModel and has the correct vertex order. The code for this is the following, and creates a gradient from red to blue: @Override protected float renderDefaultChar(int ch, boolean italic) { float charXPos = ch % 16 * 8f; float charYPos = (ch / 16) * 8f; float italicOffset = italic ? 1f : 0f; bindTexture(this.locationFontTexture); int charWidth = this.charWidth[ch]; float width = (float)charWidth - 0.01F; GlStateManager.shadeModel(GL11.GL_SMOOTH); GlStateManager.glBegin(GL11.GL_QUADS); GlStateManager.color(1.0f, 0.0f, 0.0f); GlStateManager.glTexCoord2f(charXPos / 128.0F, charYPos / 128.0F); // 0 0 GlStateManager.glVertex3f(this.posX + italicOffset, this.posY, 0.0F); GlStateManager.color(0.0f, 0.0f, 1.0f); GlStateManager.glTexCoord2f(charXPos / 128.0F, (charYPos + 7.99F) / 128.0F); // 0 1 GlStateManager.glVertex3f(this.posX - italicOffset, this.posY + 7.99F, 0.0F); GlStateManager.color(0.0f, 0.0f, 1.0f); GlStateManager.glTexCoord2f((charXPos + width - 1.0F) / 128.0F, (charYPos + 7.99F) / 128.0F); // 1 1 GlStateManager.glVertex3f(this.posX + width - 1.0F - italicOffset, this.posY + 7.99F, 0.0F); GlStateManager.color(1.0f, 0.0f, 0.0f); GlStateManager.glTexCoord2f((charXPos + width - 1.0F) / 128.0F, charYPos / 128.0F); // 1 0 GlStateManager.glVertex3f(this.posX + width - 1.0F + italicOffset, this.posY, 0.0F); GlStateManager.glEnd(); GlStateManager.shadeModel(GL11.GL_FLAT); return (float)charWidth; } I'm sure you can expand on this code by adding parameters and auxiliary functions to control the gradient colors to your desire. For instantiating the GradientFontRenderer, I just created an Instance in the constructor of my Gui class. You also need to call onResourceManagerReload to load the texture for the fontrenderer and all. This is the GuiScreen code: public class TestGuiScreen extends GuiScreen { private GradientFontRenderer gradientFontRenderer; public TestGuiScreen() { Minecraft mc = Minecraft.getMinecraft(); gradientFontRenderer = new GradientFontRenderer(mc.gameSettings, new ResourceLocation("textures/font/ascii.png"), mc.renderEngine, false); gradientFontRenderer.onResourceManagerReload(null); } public void render() { ScaledResolution res = new ScaledResolution(Minecraft.getMinecraft()); this.width = res.getScaledWidth(); this.height = res.getScaledHeight(); int x = (this.width) / 2; int y = (this.height) / 2; drawHelloTextWithGradient(x, y-16, 0xFFFFFFFF, 0xFFFF0000); } private void drawHelloTextWithGradient(int x, int y, int topColor, int bottomColor) { drawRect(x-20, y-8, x+20, y+8, 0x7F000000); drawCenteredGradientString(gradientFontRenderer, "hello", x, y-4, topColor, bottomColor); } public void drawCenteredGradientString(GradientFontRenderer fontRendererIn, String text, int x, int y, int color, int colorBottom) { fontRendererIn.drawString(text, x - fontRendererIn.getStringWidth(text) / 2, y, color); } } Here is a screenshot of how it looks. I hope this was helpful. If you have any further questions, just ask
-
The drawGradientRect method uses the following trick to render a gradient: The top two vertices of the quad are in one color, and the bottom two vertices are in another. Then, the shadeModel GL11.GL_SMOOTH is used, so that these colors are interpolated and create a gradient effect. To render a String, the drawString method calls the renderString method, which calls the renderStringAtPos method which ultimately calls the renderGlyph method, which calls the render method of the TexturedGlyph class. In that last render method, the color is set via the function parameters. If you created a custom TexturedGlyph that hat a render method with two colors as input, you could enable the above mentioned shadeModel to render a text with a gradient. It's a bit of work but seems definitely possible. Just have a look at net.minecraft.client.gui.fonts.TexturedGlyph::render and net.minecraftforge.fml.client.config.GuiUtils::drawGradientRect PS: Since I'm currently working with 1.14, the class names (any maybe the function names) differ, but apart from that, everything I said should be applicable.
-
[1.14] Output redstone signal for all sides except input
deerangle replied to Samusoidal's topic in Modder Support
The @Override public int getWeakPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side) { return super.getWeakPower(blockState, blockAccess, pos, side); } method can be overridden. (You should also override getStrongPower to return the value of getWeakPower). If you return 15 from there, then all sides will output a 15-strength redstone signal. Now you can get the input side from the blockstate and return 15 for all but the input side. -
A workaround would be to create an air-like block (that doesn't render and has no bounding box) and give that the desired light level. You could then place this block wherever it's needed to create an artificial light source.
-
So I got some things working. I can now correctly render my Blocks with translucent and solid layers using the MultiLayerModel class (or in my case an edited version of that class to manage particle textures, but its essentially the same). Now I would like to rotate my models, as the Block I'm making the model for is a HorizontalBlock. Currently, this is my code: @SubscribeEvent public static void onModelBake(ModelBakeEvent event) { ModelResourceLocation wooden_frame_location = new ModelResourceLocation(new ResourceLocation(LaserMod.MODID, "wooden_frame"), ""); ModelResourceLocation orange_glass_location = new ModelResourceLocation(new ResourceLocation(LaserMod.MODID, "orange_glass"), ""); IBakedModel wooden_frame = getBakedModel(new ResourceLocation(LaserMod.MODID, "wooden_frame"), event.getModelLoader(), ModelRotation.X0_Y0); event.getModelRegistry().put(wooden_frame_location, wooden_frame); IBakedModel orange_glass = getBakedModel(new ResourceLocation(LaserMod.MODID, "orange_glass"), event.getModelLoader(), ModelRotation.X0_Y90); event.getModelRegistry().put(orange_glass_location, orange_glass); IBakedModel orange_wooden_lens = makeLensModel(wooden_frame_location, orange_glass_location, event.getModelLoader(), ModelRotation.X0_Y90, new ResourceLocation("block/oak_log_top")); event.getModelRegistry().put(new ModelResourceLocation(new ResourceLocation(LaserMod.MODID, "orange_wooden_lens"), "distance=8,facing=south"), orange_wooden_lens); } private static IBakedModel makeLensModel(ModelResourceLocation solid, ModelResourceLocation translucent, ModelLoader loader, ModelRotation rotation, ResourceLocation particle) { ImmutableMap<Optional<BlockRenderLayer>, ModelResourceLocation> map = ImmutableMap.<Optional<BlockRenderLayer>, ModelResourceLocation>builder() .put(Optional.of(BlockRenderLayer.SOLID), solid) .put(Optional.of(BlockRenderLayer.TRANSLUCENT), translucent) .build(); LensModel model = new LensModel(map, particle); return bakeModel(model, loader, rotation); } private static IBakedModel getBakedModel(ResourceLocation location, ModelLoader loader, ModelRotation rotation) { BlockModel model = (BlockModel) loader.getUnbakedModel(location); return bakeModel(model, loader, rotation); } private static IBakedModel bakeModel(IUnbakedModel model, ModelLoader loader, ModelRotation rotation) { return model.bake(loader, ModelLoader.defaultTextureGetter(), new BasicState(TRSRTransformation.from(rotation), false), DefaultVertexFormats.BLOCK); } As you can see I tried inputting ModelRotations when calling the bake method, but with no success... The model looks exactly the same, no matter what rotation values I use. I really don't want to make extra models to have rotation, so I am asking how I can rotate my models before (or maybe even after) baking?
-
[1.14.4] Issues registering custom structure.
deerangle replied to deerangle's topic in Modder Support
bump -
I want to make a custom Structure for my minecraft mod. I have been able to register other world features (flowers in my case) without any problems, but registering this structure isn't working. In the locate command, my structure is displayed as "minecraft:labyrinth" instead of with my modid. I put a breakpoint where the structure-start of my labyrinth is initialized (init method), but it doesn't seem to be called. This is my code for registering: @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) public class WorldGenRegistry { public static Feature<NoFeatureConfig> ENERGY_FLOWER; public static Structure<LabyrinthConfig> LABYRINTH; @SubscribeEvent public static void registerFeatures(RegistryEvent.Register<Feature<?>> event) { IForgeRegistry<Feature<?>> registry = event.getRegistry(); ENERGY_FLOWER = registerFeature(new EnergyFlowersFeature(NoFeatureConfig::deserialize), "energy_flowers"); LABYRINTH = registerStructure(new LabyrinthStructure(LabyrinthConfig::deserialize), "labyrinth"); registry.registerAll( ENERGY_FLOWER, LABYRINTH ); } private static <T extends IFeatureConfig> Feature<T> registerFeature(Feature<T> feature, String registryName) { feature.setRegistryName(registryName); return feature; } private static <T extends IFeatureConfig> Structure<T> registerStructure(Structure<T> structure, String registryName) { structure.setRegistryName(registryName); return structure; } } And my labyrinth structure: public class LabyrinthStructure extends Structure<LabyrinthConfig> { public LabyrinthStructure(Function<Dynamic<?>, ? extends LabyrinthConfig> deserializer) { super(deserializer); } @Override public boolean hasStartAt(ChunkGenerator<?> generator, Random random, int chunkX, int chunkZ) { ChunkPos pos = this.getStartPositionForPosition(generator, random, chunkX, chunkZ, 0, 0); if (chunkX == pos.x && chunkZ == pos.z) { Biome biome = generator.getBiomeProvider().getBiome(new BlockPos((chunkX << 4) + 9, 0, (chunkZ << 4) + 9)); return generator.hasStructure(biome, WorldGenRegistry.LABYRINTH); } else { return false; } } @Override public IStartFactory getStartFactory() { return Start::new; } @Override public String getStructureName() { return "Labyrinth"; } @Override public int getSize() { return 8; //TODO what is this? } public static class Start extends MarginedStructureStart { public Start(Structure<?> structure, int chunkPosX, int chunkPosZ, Biome biome, MutableBoundingBox bounds, int reference, long seed) { super(structure, chunkPosX, chunkPosZ, biome, bounds, reference, seed); } @Override public void init(ChunkGenerator<?> generator, TemplateManager templateManagerIn, int chunkX, int chunkZ, Biome biomeIn) { LabyrinthConfig config = generator.getStructureConfig(biomeIn, WorldGenRegistry.LABYRINTH); BlockPos pos = new BlockPos(chunkX * 16, 0, chunkZ * 16); System.out.println("GENERATE LABYRINTh"); //breakpoint here //TODO: VillagePieces.func_214838_a(generator, templateManagerIn, pos, this.components, this.rand, config); this.recalculateStructureSize(); } } } I doubt anything is wrong with the LabyrinthConfig, so I'm not posting it unless requested. Any help is greatly appreciated!
-
This is embarassing...
-
I am trying to create an entity, but It doesn't work on client side. I have tried creating a custom packet that spawns the entity on the client, but that entity disappears after about 3 ticks for no reason. When I try to use NetworkHooks.getEntitySpawningPacket(this); In createSpawnPacket, I get this error: java.lang.RuntimeException: Missing custom spawn data for entity type net.minecraft.entity.EntityType@7430ed93 at net.minecraft.entity.EntityType.customClientSpawn(EntityType.java:527) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {} at net.minecraftforge.fml.network.FMLPlayMessages$SpawnEntity.lambda$null$0(FMLPlayMessages.java:153) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {} at java.util.Optional.map(Optional.java:215) ~[?:1.8.0_222] {} at net.minecraftforge.fml.network.FMLPlayMessages$SpawnEntity.lambda$handle$2(FMLPlayMessages.java:153) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {} at net.minecraftforge.fml.network.NetworkEvent$Context.enqueueWork(NetworkEvent.java:185) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {} at net.minecraftforge.fml.network.FMLPlayMessages$SpawnEntity.handle(FMLPlayMessages.java:145) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {} at net.minecraftforge.fml.network.simple.IndexedMessageCodec.lambda$tryDecode$3(IndexedMessageCodec.java:114) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {} at java.util.Optional.ifPresent(Optional.java:159) ~[?:1.8.0_222] {} at net.minecraftforge.fml.network.simple.IndexedMessageCodec.tryDecode(IndexedMessageCodec.java:114) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {} at net.minecraftforge.fml.network.simple.IndexedMessageCodec.consume(IndexedMessageCodec.java:147) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {} at net.minecraftforge.fml.network.simple.SimpleChannel.networkEventListener(SimpleChannel.java:65) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {} at net.minecraftforge.eventbus.EventBus.doCastFilter(EventBus.java:212) ~[eventbus-1.0.0-service.jar:?] {} at net.minecraftforge.eventbus.EventBus.lambda$addListener$11(EventBus.java:204) ~[eventbus-1.0.0-service.jar:?] {} at net.minecraftforge.eventbus.EventBus.post(EventBus.java:258) ~[eventbus-1.0.0-service.jar:?] {} at net.minecraftforge.fml.network.NetworkInstance.dispatch(NetworkInstance.java:82) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {} at net.minecraftforge.fml.network.NetworkHooks.lambda$onCustomPayload$0(NetworkHooks.java:69) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {} at java.util.Optional.map(Optional.java:215) ~[?:1.8.0_222] {} at net.minecraftforge.fml.network.NetworkHooks.onCustomPayload(NetworkHooks.java:69) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {} at net.minecraft.client.network.play.ClientPlayNetHandler.handleCustomPayload(ClientPlayNetHandler.java:1782) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {pl:runtimedistcleaner:A} at net.minecraft.network.play.server.SCustomPayloadPlayPacket.processPacket(SCustomPayloadPlayPacket.java:55) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {} at net.minecraft.network.play.server.SCustomPayloadPlayPacket.processPacket(SCustomPayloadPlayPacket.java:11) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {} at net.minecraft.network.PacketThreadUtil.func_225383_a(SourceFile:21) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {} at net.minecraft.util.concurrent.ThreadTaskExecutor.run(SourceFile:144) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {pl:accesstransformer:B} at net.minecraft.util.concurrent.RecursiveEventLoop.run(SourceFile:23) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {} at net.minecraft.util.concurrent.ThreadTaskExecutor.driveOne(SourceFile:118) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {pl:accesstransformer:B} at net.minecraft.util.concurrent.ThreadTaskExecutor.drainTasks(SourceFile:103) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {pl:accesstransformer:B} at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:858) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {pl:accesstransformer:B,pl:runtimedistcleaner:A} at net.minecraft.client.Minecraft.run(Minecraft.java:384) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {pl:accesstransformer:B,pl:runtimedistcleaner:A} at net.minecraft.client.main.Main.main(SourceFile:155) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {pl:runtimedistcleaner:A} at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_222] {} at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_222] {} at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_222] {} at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_222] {} at net.minecraftforge.userdev.FMLUserdevClientLaunchProvider.lambda$launchService$0(FMLUserdevClientLaunchProvider.java:55) ~[forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {} at cpw.mods.modlauncher.LaunchServiceHandlerDecorator.launch(LaunchServiceHandlerDecorator.java:37) [modlauncher-3.2.0.jar:?] {} at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:50) [modlauncher-3.2.0.jar:?] {} at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:68) [modlauncher-3.2.0.jar:?] {} at cpw.mods.modlauncher.Launcher.run(Launcher.java:80) [modlauncher-3.2.0.jar:?] {} at cpw.mods.modlauncher.Launcher.main(Launcher.java:65) [modlauncher-3.2.0.jar:?] {} at net.minecraftforge.userdev.LaunchTesting.main(LaunchTesting.java:101) [forge-1.14.4-28.1.1_mapped_snapshot_20190719-1.14.3.jar:?] {} I have no Idea why in the world I'm getting this error as I have .setCustomClientFactory((InventoryFallingBlockEntity::new)) When registering my entity... Registry code: @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) public class EntityRegistry { public static EntityType<InventoryFallingBlockEntity> AMPHORE; @SubscribeEvent public static void registerEntities(RegistryEvent.Register<EntityType<?>> event) { IForgeRegistry<EntityType<?>> registry = event.getRegistry(); AMPHORE = EntityType.Builder.<InventoryFallingBlockEntity>create(InventoryFallingBlockEntity::new, EntityClassification.MISC) .size(0.98F, 0.98F) .setCustomClientFactory((InventoryFallingBlockEntity::new)) .build("amphore"); AMPHORE.setRegistryName("amphore"); registry.registerAll(); } }
-
Is it possible to create a block model JSON where part of the model has the enchanted effect? Like an overlay with an the enchanted effect.
-
Easily solved with this code for creating the Creative Tab in my Main Mod file: public static final ItemGroup ITEM_GROUP = new ItemGroup(MODID) { @OnlyIn(Dist.CLIENT) public ItemStack createIcon() { return new ItemStack(ItemRegistry.berylGem); } }; and using the group method on the properties builder
-
You need to add them to the minecraft::walls tag. Question remains about the Creative Tabs though!
-
I created a custom wall, which works fine in every aspect except for the fact that walls don't connect to each other. Here is how I initialize the wall: CHERT_BRICK_WALL = new WallBlock(Block.Properties.from(CHERT_BRICKS)).setRegistryName("chert_brick_wall"); All the JSON files are copied from vanilla: models: chert_brick_wall_post.json chert_brick_wall_side.json chert_brick_wall_inventory.json Where could the error be? Also, how do I make creative tabs?
-
I want to access fields in the TOML of my mod like the name such that I don't have to redundantly declare my mod's name for use inside of the code.
-
In 1.12 you could just return an IMessage in the IMessageHandler if you wanted to send a packet back, but in 1.13, there is no IMessageHandler and instead the handler is a void function. Do I send the packet back as I would send a normal packet or is there a way as there was in 1.12?
-
I didn't explicitly enable ambient occulsion, as far as I know.
-
bump
-
1.7.10 is acutally no longer supported, I think. Also, I noticed that the class SimpleChannel cannot be found, and I think that SimpleChannel only exists (or is called that) since forge 1.13. So are you loading any 1.13 mods in 1.7.10? As far as I can see, xaeros minimap is causing the error.
-
Have a look at net.minecraft.util.datafix.fixes.ItemStackDataFlattening There you can see how the items and their metadata are mapped to their flattened names. Here is a little snippet from the file: p_209282_0_.put("minecraft:sapling.3", "minecraft:jungle_sapling"); p_209282_0_.put("minecraft:sapling.4", "minecraft:acacia_sapling"); p_209282_0_.put("minecraft:sapling.5", "minecraft:dark_oak_sapling"); p_209282_0_.put("minecraft:planks.0", "minecraft:oak_planks"); p_209282_0_.put("minecraft:planks.1", "minecraft:spruce_planks"); I'm not sure how you would implement your own DataFix.
-
As can be seen in the given image, the sides of my JSON model that are facing downwards are being underlit, while on the stairs, they are not too dark. What must I do such that those faces aren't that dark?