Jump to content

bewi

Members
  • Posts

    3
  • Joined

  • Last visited

Everything posted by bewi

  1. Hi, The spawnEntityIntoClientWorld() function in FMLClientHandler does not work properly for multi-part entities (Entity.getParts() != null). entity.entityId will be set before the offsets are calculated for the parts. This leads to getEntityByID() in NetServerHandler always returning a wrong entity (or null in most cases) for those parts. A simple solution is to move the assignment of the entity ID after the assignments of the parts' ids. public Entity spawnEntityIntoClientWorld(EntityRegistration er, EntitySpawnPacket packet){ /*snip*/ entity = (Entity)(cls.getConstructor(World.class).newInstance(wc)); entity.entityId = packet.entityId; /*snip*/ Entity parts[] = entity.getParts(); if (parts != null) { int i = packet.entityId - entity.entityId; //<- will always be 0 for (int j = 0; j < parts.length; j++) { parts[j].entityId += i; } } /*snip*/ }
  2. I became really annoyed while trying to create a multipart mob and the hitboxes were not visible. It turns out that minecraft does not actually render the hitboxes when pressing F3+B but just a box with a size of width*height*width centered on the mobs position. I modified the code slightly and thought it might be a good idea to incorporate this into forge. Here is the changed function in net.minecraft.client.renderer.entity.RenderManager.java private void func_85094_b(Entity par1Entity, double par2, double par4, double par6, float par8, float par9) { //GL11.glDepthMask(false); GL11.glDisable(GL11.GL_TEXTURE_2D); GL11.glDisable(GL11.GL_LIGHTING); GL11.glDisable(GL11.GL_CULL_FACE); GL11.glDisable(GL11.GL_BLEND); GL11.glPushMatrix(); Tessellator var10 = Tessellator.instance; var10.startDrawingQuads(); var10.setColorRGBA(255, 255, 255, 32); var10.addVertex(par1Entity.boundingBox.minX, par1Entity.boundingBox.minY, par1Entity.boundingBox.minZ); var10.addVertex(par1Entity.boundingBox.minX, par1Entity.boundingBox.maxY, par1Entity.boundingBox.minZ); var10.addVertex(par1Entity.boundingBox.minX, par1Entity.boundingBox.maxY, par1Entity.boundingBox.maxZ); var10.addVertex(par1Entity.boundingBox.minX, par1Entity.boundingBox.minY, par1Entity.boundingBox.maxZ); var10.addVertex(par1Entity.boundingBox.minX, par1Entity.boundingBox.minY, par1Entity.boundingBox.minZ); var10.addVertex(par1Entity.boundingBox.maxX, par1Entity.boundingBox.minY, par1Entity.boundingBox.minZ); var10.addVertex(par1Entity.boundingBox.maxX, par1Entity.boundingBox.maxY, par1Entity.boundingBox.minZ); var10.addVertex(par1Entity.boundingBox.minX, par1Entity.boundingBox.maxY, par1Entity.boundingBox.minZ); var10.addVertex(par1Entity.boundingBox.maxX, par1Entity.boundingBox.minY, par1Entity.boundingBox.minZ); var10.addVertex(par1Entity.boundingBox.maxX, par1Entity.boundingBox.maxY, par1Entity.boundingBox.minZ); var10.addVertex(par1Entity.boundingBox.maxX, par1Entity.boundingBox.maxY, par1Entity.boundingBox.maxZ); var10.addVertex(par1Entity.boundingBox.maxX, par1Entity.boundingBox.minY, par1Entity.boundingBox.maxZ); var10.addVertex(par1Entity.boundingBox.minX, par1Entity.boundingBox.minY, par1Entity.boundingBox.maxZ); var10.addVertex(par1Entity.boundingBox.maxX, par1Entity.boundingBox.minY, par1Entity.boundingBox.maxZ); var10.addVertex(par1Entity.boundingBox.maxX, par1Entity.boundingBox.maxY, par1Entity.boundingBox.maxZ); var10.addVertex(par1Entity.boundingBox.minX, par1Entity.boundingBox.maxY, par1Entity.boundingBox.maxZ); Entity[] parts = par1Entity.getParts(); if(parts != null) { for(Entity part : parts) { var10.addVertex(part.boundingBox.minX, part.boundingBox.minY, part.boundingBox.minZ); var10.addVertex(part.boundingBox.minX, part.boundingBox.maxY, part.boundingBox.minZ); var10.addVertex(part.boundingBox.minX, part.boundingBox.maxY, part.boundingBox.maxZ); var10.addVertex(part.boundingBox.minX, part.boundingBox.minY, part.boundingBox.maxZ); var10.addVertex(part.boundingBox.minX, part.boundingBox.minY, part.boundingBox.minZ); var10.addVertex(part.boundingBox.maxX, part.boundingBox.minY, part.boundingBox.minZ); var10.addVertex(part.boundingBox.maxX, part.boundingBox.maxY, part.boundingBox.minZ); var10.addVertex(part.boundingBox.minX, part.boundingBox.maxY, part.boundingBox.minZ); var10.addVertex(part.boundingBox.maxX, part.boundingBox.minY, part.boundingBox.minZ); var10.addVertex(part.boundingBox.maxX, part.boundingBox.maxY, part.boundingBox.minZ); var10.addVertex(part.boundingBox.maxX, part.boundingBox.maxY, part.boundingBox.maxZ); var10.addVertex(part.boundingBox.maxX, part.boundingBox.minY, part.boundingBox.maxZ); var10.addVertex(part.boundingBox.minX, part.boundingBox.minY, part.boundingBox.maxZ); var10.addVertex(part.boundingBox.maxX, part.boundingBox.minY, part.boundingBox.maxZ); var10.addVertex(part.boundingBox.maxX, part.boundingBox.maxY, part.boundingBox.maxZ); var10.addVertex(part.boundingBox.minX, part.boundingBox.maxY, part.boundingBox.maxZ); } } GL11.glTranslatef((float)(par2-par1Entity.posX), (float)(par4-par1Entity.posY), (float)(par6-par1Entity.posZ)); var10.draw(); GL11.glPopMatrix(); GL11.glEnable(GL11.GL_TEXTURE_2D); GL11.glEnable(GL11.GL_LIGHTING); GL11.glEnable(GL11.GL_CULL_FACE); GL11.glDisable(GL11.GL_BLEND); //GL11.glDepthMask(true); }
  3. Hi, I've recently started modding and was looking for a tool to properly generate a texture map for mobs. Fortunately notch already wrote such a tool (http://pastebin.com/0AcY6YV2). However this does not work with forge so I changed the necessary variables to make it work. To use it simply pass a "new ModelMob().parts" in the main class and wait for the results. You will need to put all of your boxes into a list called parts (protected ArrayList<ModelRenderer> parts = new ArrayList<ModelRenderer>(); ). Here's an example mob (only the constructor and the list): protected ArrayList<ModelRenderer> parts = new ArrayList<ModelRenderer>(); ModelMob() { textureWidth = 128; //change this to the same size as in ImageGenerator (WIDTH) textureHeight = 64; setTextureOffset("null.part1", 0, 0); // important (needs to be called with any offset for the first time, otherwise you will get a NullPtr exception) setTextureOffset("null.part2", 0, 0); // change it to the output of ImageGenerator afterwards ModelRenderer part1 = new ModelRenderer(this, 0, 0); parts.add(part1); part1.addBox("part1",-8F, -8F, 0F, 16, 16, 32); //some other code ModelRenderer part2 = new ModelRenderer(this, 0, 0); parts.add(part2); part2.addBox("part2",-0.5F, 0F, 0F, 1, 8, ; //some other code } Finally here is the actual code: import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; import java.util.*; import java.util.List; import javax.imageio.ImageIO; import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelBox; import net.minecraft.client.model.ModelRenderer; /* * Generates a texture map for a specified model * modified from: http://pastebin.com/0AcY6YV2 */ public class ImageGenerator { private static final int WIDTH = 256; private static final int HEIGHT = 256; private class Region { public int x1, y1, x2, y2; public Region(int x1, int y1, int x2, int y2) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; } public void move(int xo, int yo) { x1 += xo; y1 += yo; x2 += xo; y2 += yo; } public boolean overlaps(Region r2, int xo, int yo) { if (r2.x2 + xo <= x1) return false; if (r2.y2 + yo <= y1) return false; if (r2.x1 + xo >= x2) return false; if (r2.y1 + yo >= y2) return false; return true; } public void render(Graphics g) { g.fillRect(x1, y1, x2 - x1, y2 - y1); } } private class UnfoldedCube { public int x, y; public Region[] cubeRegions = new Region[6]; public String id; public int width, height; public UnfoldedCube(ModelBox cube) { int xs = (int) Math.ceil(cube.posX2 - cube.posX1); int ys = (int) Math.ceil(cube.posY2 - cube.posY1); int zs = (int) Math.ceil(cube.posZ2 - cube.posZ1); width = xs * 2 + zs * 2; height = zs + ys; id = cube.field_78247_g; cubeRegions[0] = new Region(0, zs, zs, zs + ys); cubeRegions[1] = new Region(zs, zs, zs + xs, zs + ys); cubeRegions[2] = new Region(zs + xs, zs, zs + xs + zs, zs + ys); cubeRegions[3] = new Region(zs + xs + zs, zs, zs + xs + zs + xs, zs + ys); cubeRegions[4] = new Region(zs, 0, zs + xs, zs); cubeRegions[5] = new Region(zs + xs, 0, zs + xs * 2, zs); } public boolean fits(int x, int y) { for (int i = 0; i < 6; i++) { if (!isFree(cubeRegions[i], x, y)) return false; } return true; } public void place(int x, int y) { this.x = x; this.y = y; for (int i = 0; i < 6; i++) { cubeRegions[i].move(x, y); occupiedRegions.add(cubeRegions[i]); } } public void render(Graphics g) { float hue = (float) Math.random(); g.setColor(new Color(Color.HSBtoRGB(hue, 1, 0.7f))); cubeRegions[5].render(g); g.setColor(new Color(Color.HSBtoRGB(hue, 1, 1.0f))); cubeRegions[4].render(g); g.setColor(new Color(Color.HSBtoRGB(hue, 1, 0.9f))); cubeRegions[1].render(g); cubeRegions[3].render(g); g.setColor(new Color(Color.HSBtoRGB(hue, 1, 0.8f))); cubeRegions[0].render(g); cubeRegions[2].render(g); } } private List<Region> occupiedRegions = new ArrayList<Region>(); private boolean isFree(Region region, int xo, int yo) { if (region.x1 + xo < 0) return false; if (region.y1 + yo < 0) return false; if (region.x2 + xo > WIDTH) return false; if (region.y2 + yo > HEIGHT) return false; for (int i = 0; i < occupiedRegions.size(); i++) { if (occupiedRegions.get(i).overlaps(region, xo, yo)) return false; } return true; } public void generateImage(List<ModelRenderer> parts) { List<ModelBox> cubes = new ArrayList<ModelBox>(); for (ModelRenderer mp : parts) { getCubes(mp, cubes); } Collections.sort(cubes, new Comparator<ModelBox>() { @Override public int compare(ModelBox c0, ModelBox c1) { int xs = (int) Math.ceil(c0.posX2 - c0.posX1); int ys = (int) Math.ceil(c0.posY2 - c0.posY1); int zs = (int) Math.ceil(c0.posZ2 - c0.posZ1); int ww0 = xs * 2 + zs * 2; int hh0 = zs + ys; xs = (int) Math.ceil(c1.posX2 - c1.posX1); ys = (int) Math.ceil(c1.posY2 - c1.posY1); zs = (int) Math.ceil(c1.posZ2 - c1.posZ1); int ww1 = xs * 2 + zs * 2; int hh1 = zs + ys; if (ww0 * hh0 < ww1 * hh1) { return 1; } else if (ww0 * hh0 > ww1 * hh1) { return -1; } return 0; } }); List<UnfoldedCube> unfolded = new ArrayList<UnfoldedCube>(); for (ModelBox cube : cubes) { UnfoldedCube uc = new UnfoldedCube(cube); boolean placed = false; positionLoop: for (int y = 0; y < HEIGHT - uc.height; y++) { for (int x = 0; x < WIDTH - uc.width; x++) { if (uc.fits(x, y)) { uc.place(x, y); placed = true; break positionLoop; } } } if (!placed) { System.out.println("Failed to place " + uc.id); } else { unfolded.add(uc); } } BufferedImage img = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB); Graphics g = img.getGraphics(); System.out.println("----------------"); for (UnfoldedCube uc : unfolded) { System.out.println("setTextureOffset(\"" + uc.id + "\", " + uc.x + ", " + uc.y + ");"); uc.render(g); } try { ImageIO.write(img, "png", new File("output.png")); } catch (IOException e) { e.printStackTrace(); } } public void getCubes(ModelRenderer mp, List<ModelBox> cubeList) { addLoop: for (ModelBox cube : (List<ModelBox>)mp.cubeList) { if (cube.field_78247_g != null) { for (ModelBox otherCube : cubeList) { if (otherCube.field_78247_g != null) { if (otherCube.field_78247_g.equals(cube.field_78247_g)) { System.out.println("Duplicate " + cube.field_78247_g); continue addLoop; } } } } cubeList.add(cube); } } public static void main(String[] args) { new ImageGenerator().generateImage(new ModelMob().parts ); } } I hope it helps.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.