Jump to content

Glenn

Members
  • Posts

    37
  • Joined

  • Last visited

Everything posted by Glenn

  1. You need some clever use of the method which fetches the icon for each side of the block. I won't go into detail about that. You just need to check any surrounding blocks and see if they are of the same type, then determine which texture (from a list of textures for all 2^4=16 possible states) to use.
  2. It doesn't work in an obfuscated environment because it's an obfuscated environment. This means class names, fields and methods are an alphabet soup. ClientCommandHandler is a forge class, which means that its name is not obfuscated. This is why you are able to fetch the class. The reason why you are unable to fetch the method is because ClientCommandHandler extends CommandHandler, which is a vanilla class. Any overrided methods in ClientCommandHandler will therefore have a reobfuscated name in an obfuscated environment. In an obfuscated environment, the "executeCommand" method is called "a". You'll have to account for that.
  3. Make sure the texture in your resource pack is also accompanied with an .mcmeta file which adds the animation. It seems that adding animation to the original resource doesn't guarantee that it will also happen to overriding textures.
  4. Try making the whole texture semi-transparent. Also, I believe you have to move all the rendering to the second render pass.
  5. It should be safe to completely replace the instruction list of the method. It would be more efficient, and cleaner. As for what to put in the new instruction list, here's what you need to do: if ((m.name.equals(targetMethodName) && m.desc.equals("(Ljava/lang/String;)Ljava/lang/String;"))) { System.out.println("********* Inside target method!"); InsnList toInject = new InsnList(); toInject.add(new VarInsnNode(ALOAD, 0)); toInject.add(new MethodInsnNode(INVOKESTATIC, "pickandcraftSkin/PlayerCustom", "getURLSkincustom", "(Ljava/lang/String;)Ljava/lang/String;")); toInject.add(new InsnNode(ARETURN)); // inject new instruction list into method instruction list m.instructions = toInject; System.out.println("Patching Complete!"); break; }
  6. Did you try debugging? Also make sure there is only one furnace.
  7. My only suggestion is to get into class transformation with core modding. It does require an enormous amount of effort to properly get into, but I find it to be extremely valuable for certain tasks, and it opens up vast amounts of possibilities. This is the tutorial that got me into it: http://www.minecraftforum.net/topic/1854988-/ In my mod, I replace both bedrock and coal ore with blocks of a new class to add new behaviour to them. Yes, they aren't items, but it's very much the same process with the same result. To do so, I edit the very code in net.minecraft.block.Block as it is loaded by the JVM. If you follow this method, you will be editing the code in net.minecraft.item.Item, which is very similar. The method you need to modify is the registerItems() method. Iterating through the bytecode instructions, you will be looking for the LDC instruction that loads a string equal to whatever the name of the item you are looking for is. The string name should be equal to the name that is used in net.minecraft.init.Items. You will use this string as an anchor to locate and modify the respective instructions. You should make sure that the string should only be found once, because it is not unusual to see the string two times while the item is being constructed. Say you wish to replace the vanilla feather by replacing the vanilla feather item with your custom ItemFeather item. You will be looking for the LDC instructions that loads the highlighed string below: itemRegistry.addObject(288, "feather", (new Item()).setUnlocalizedName("feather").setCreativeTab(CreativeTabs.tabMaterials).setTextureName("feather")); After your class transformation, it would programmatically be changed to this: itemRegistry.addObject(288, "feather", (new ItemFeather()).setUnlocalizedName("feather").setCreativeTab(CreativeTabs.tabMaterials).setTextureName("feather")); The instruction after the LDC would be a NEW instruction of type "net/minecraft/item/Item". You would have to change that to "package/package/etc/ItemFeather". The instruction after that would be a DUP instruction. Instructions after this one will vary. It depends on the amount of constructor parameters, but it usually takes only one instruction to load each parameter. The feather uses no constructor parameters, meaning the instruction after the DUP instruction will be INVOKESPECIAL, which is the constructor call. The owner of this would have to be changed to "package/package/etc/ItemFeather". To apply this example to other cases, here are some tips: If you want to override an item with a new class, make sure your new class extends the original class. The constructor of your new class should have the same parameters as well. This is how I replaced the two blocks in my mod: public byte[] patchClassBlock(byte[] data, boolean obfuscated) { String classBlock = obfuscated ? c.get("Block") : "net/minecraft/block/Block"; String methodRegisterBlocks = obfuscated ? "p" : "registerBlocks"; String methodSetHardness = obfuscated ? "c" : "setHardness"; ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(data); classReader.accept(classNode, 0); boolean bedrockFound = false; boolean coal_oreFound = false; for(int i = 0; i < classNode.methods.size(); i++) { MethodNode method = classNode.methods.get(i); if(method.name.equals(methodRegisterBlocks) && method.desc.equals("()V")) { for(int j = 0; j < method.instructions.size(); j++) { AbstractInsnNode instruction = method.instructions.get(j); if(instruction.getOpcode() == LDC) { LdcInsnNode ldcInstruction = (LdcInsnNode)instruction; if(ldcInstruction.cst.equals("bedrock")) { if(!bedrockFound) { ((TypeInsnNode)method.instructions.get(j + 1)).desc = "glenn/gases/BlockBedrock"; ((MethodInsnNode)method.instructions.get(j + 4)).owner = "glenn/gases/BlockBedrock"; } bedrockFound = true; } else if(ldcInstruction.cst.equals("coal_ore")) { if(!coal_oreFound) { ((TypeInsnNode)method.instructions.get(j + 1)).desc = "glenn/gases/BlockCoalOre"; ((MethodInsnNode)method.instructions.get(j + 3)).owner = "glenn/gases/BlockCoalOre"; } coal_oreFound = true; } } } } } ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); classNode.accept(writer); return writer.toByteArray(); } Have fun!
  8. Performance should not be a problem. A comma-separated array should work just fine. You could also have an NBT tag compound with the recipe name as the key, only storing simple booleans. To determine if something is unlocked, you would have to check if the NBT tag compound contains the key instead.
  9. It's generally beneficial for all modders since we're forcing the userbase to finally update to a newer minecraft version. Supporting extremely old versions is just plain boring. Modding in Minecraft just gets better and better with each version.
  10. Minecraft's particles are terribly hardcoded. The particle name you are looking for is "depthsuspend".
  11. Let me just suggest doing ASM anyway. It appears you already have experience with it, and the process is relatively simple if you just want to change 20 to 60. The aiArrowAttack field is initialized in a hidden method called <init>, which is called before a new object is constructed. We can agree that the EntityAIArrowAttack will only appear once in this method, so we can use this as a reference point to find the integer constant we wish to change. Iterate through the instructions in <init> and find a NEW instruction which has type 'EntityAIArrowAttack' (or obfuscated name respectively). Find the following instruction that is loading 20, and change it to 60.
  12. You could also consider using one block representing each quality.
  13. Minecraft uses a special class to render, the Tessellator. When the tessellator is used, it has to be started with tessellator.startDrawing(drawmode), where the drawmode is a specific way of drawing specified in OpenGL. When you send a coodinate (a vertex) to the tessellator, it is pushed into an array. This array will continue expanding until you do tessellator.draw(). At that point, the array of vertices is sent to your graphics processor so that it may render it. If tessellator.startDrawing(drawmode) is called while it is already collecting vertices, the "Already tessellating" exception is thrown. You get this problem because Forge's .obj renderer is designed to send its own vertices then draw them instantly. Therefore, it's calling tessellator.startDrawing(drawmode) and tessellator.draw() by itself, which must not be done during the block rendering phase. If you somehow were able to stop the model renderer from calling the suspected methods, there is still a potential problem. Blocks are rendered with the GL_QUADS drawmode, which means a square face will be drawn for every 4 vertices you send in. The model may not be rendered with this drawmode, which would completely mess up the rendering. The model renderer could even have several calls to both startDrawing and draw. Encasing your model.renderAll with Tessellator.instance.draw() above and Tessellator.instance.startDrawingQuads() below in BlockEggStandRenderer.renderWorldBlock is not a viable solution. Because of technical reasons, this can mess up the rendering of the blocks surrounding this one. It's fine to render your .obj model in renderInventoryBlock, but you need another solution for renderWorldBlock. You could try to render your block programmatically instead of using a model, or alternatively give the block a tile entity. Tile entity blocks can be rendered independently from other blocks, and their rendering does not suffer from the limitations of standard block rendering. Either solution should be covered by tutorials.
  14. You have apparently not done that correctly. Check the spelling on your folder names. As pointed out by Frost, code also helps.
  15. I highly recommend debugging. It has helped me so much with complicated block mechanisms, such as gas flow and gas piping.
  16. Textures must be placed in src/main/resources/assets/(insert the mod ID here)/textures/. For example, a block texture named "texture.png" for my mod with the ID "hammer" would be placed in src/main/resources/assets/hammer/textures/blocks/texture.png. To bind the texture to a block, I would use .setTextureName("hammer:texture").
  17. If you're doing this in such a large scale, consider using one of Minecraft's 3D perlin noise generators. Iterate through every block in the chunk, and check the perlin noise for each coordinate. If the block at the coordinate is stone, and the noise meets a certain condition (for example above 0.75), place your custom block at the coordinate.
  18. Whoa, whoa, whoa. This can be solved in a much simpler way. If you're just incrementing or decrementing a value, it would be very simple to use Block Events to solve the problem. Block events basically send information consisting of two integers to a specific tile. When a block event is sent, it is received both on client and server side, so you will have to take care of that. To send a block event, simply do world.addBlockEvent(x, y, z, BlockID, eventIndex, param); To catch a block event, add this method to the block class belonging to your tile entity: public boolean onBlockEventReceived(World world, int x, int y, int z, int eventIndex, param) They key to solving your problem is to use world.addBlockEvent each time the value is changed, and send the value along with it. You should add a switch for event indices in onBlockEventReceived, and give this specific event eventIndex 0. If eventIndex == 0, set value in tile entity to param.
  19. In an obfuscated version of Minecraft, namely outside any development environments, the field will not be called "currentPage". I would find the obfuscated field name right now, but my version of forge doesn't seem to have that field named. You should also note that if you are doing this in a core mod, the GuiAchievements class might not even exist at the time you're fetching the field.
  20. There probably is a block break event that I don't know about somewhere. I assume you are trying to fill in any broken blocks with your custom fluid. Alternatively, you could give your fluid a flowing mechanic so that it fills in any holes.
  21. Huh, I guess I am not alone with my obsession with gas and gas pipes. Rendering pipes is all about detecting which blocks adjacent to your pipe block are also pipes. Then it's just a matter or rendering it based on this data. Using a tessellator is the most efficient approach, but I guess it can be challenging to work with. Here's an example of how my pipes look: The pipes in my mod use this texture: The upper left corner is the texture of the actual pipe. The upper right corner is the texture of the pipe support (you can see them connected to the ground in the screenshot). The lower left corner is the texture used for the end of a pipe. You can't see it in the screenshot, but you can understand where it is. The rendering of the pipes isn't actually that advanced. The rendering is very similar to that of a normal block, except each side is indented by 6/16 of a block. I use the information of which sides to connect to the pipe to decide the corners of each indented face. I also apply faces for the ends of pipes where it is necessary. Here is the code used to render that: public class RenderBlockGasPipe implements ISimpleBlockRenderingHandler { private IIcon icon; private double uIconTranslate = 0.0F; private double vIconTranslate = 0.0F; private static final int[] xDirection = new int[]{ 0, 0, 1, -1, 0, 0 }; private static final int[] yDirection = new int[]{ -1, 1, 0, 0, 0, 0 }; private static final int[] zDirection = new int[]{ 0, 0, 0, 0, 1, -1 }; @Override public void renderInventoryBlock(Block block, int metadata, int modelID,RenderBlocks renderer) { Tessellator tessellator = Tessellator.instance; icon = renderer.hasOverrideBlockTexture() ? renderer.overrideBlockTexture : renderer.getBlockIcon(block); GL11.glRotatef(90.0F, 0.0F, 1.0F, 0.0F); GL11.glScalef(1.4F, 1.4F, 1.4F); GL11.glTranslatef(-0.5F, -0.5F, -0.5F); GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); GL11.glEnable(GL11.GL_ALPHA_TEST); double d1 = 6.0F / 16.0F; double d2 = 10.0F / 16.0F; tessellator.startDrawingQuads(); uIconTranslate = 0.0D; vIconTranslate = 0.0D; tessellator.setColorOpaque_F(1.0F, 1.0F, 1.0F); tessellator.setNormal(0.0F, 1.0F, 0.0F); tessellator.addVertexWithUV(0.0D, d2, 1.0D, u(0.0D), v(1.0D)); tessellator.addVertexWithUV(1.0D, d2, 1.0D, u(1.0D), v(1.0D)); tessellator.addVertexWithUV(1.0D, d2, 0.0D, u(1.0D), v(0.0D)); tessellator.addVertexWithUV(0.0D, d2, 0.0D, u(0.0D), v(0.0D)); //tessellator.setColorOpaque_F(0.6F, 0.6F, 0.6F); tessellator.setNormal(0.0F, -1.0F, 0.0F); tessellator.addVertexWithUV(0.0D, d1, 0.0D, u(0.0D), v(0.0D)); tessellator.addVertexWithUV(1.0D, d1, 0.0D, u(1.0D), v(0.0D)); tessellator.addVertexWithUV(1.0D, d1, 1.0D, u(1.0D), v(1.0D)); tessellator.addVertexWithUV(0.0D, d1, 1.0D, u(0.0D), v(1.0D)); //tessellator.setColorOpaque_F(0.8F, 0.8F, 0.8F); tessellator.setNormal(-1.0F, 0.0F, 0.0F); tessellator.addVertexWithUV(d1, 0.0D, 1.0D, u(0.0D), v(1.0D)); tessellator.addVertexWithUV(d1, 1.0D, 1.0D, u(1.0D), v(1.0D)); tessellator.addVertexWithUV(d1, 1.0D, 0.0D, u(1.0D), v(0.0D)); tessellator.addVertexWithUV(d1, 0.0D, 0.0D, u(0.0D), v(0.0D)); tessellator.setNormal(1.0F, 0.0F, 0.0F); tessellator.addVertexWithUV(d2, 0.0D, 0.0D, u(0.0D), v(0.0D)); tessellator.addVertexWithUV(d2, 1.0D, 0.0D, u(1.0D), v(0.0D)); tessellator.addVertexWithUV(d2, 1.0D, 1.0D, u(1.0D), v(1.0D)); tessellator.addVertexWithUV(d2, 0.0D, 1.0D, u(0.0D), v(1.0D)); tessellator.setNormal(0.0F, 0.0F, -1.0F); tessellator.addVertexWithUV(0.0D, 1.0D, d1, u(0.0D), v(1.0D)); tessellator.addVertexWithUV(1.0D, 1.0D, d1, u(1.0D), v(1.0D)); tessellator.addVertexWithUV(1.0D, 0.0D, d1, u(1.0D), v(0.0D)); tessellator.addVertexWithUV(0.0D, 0.0D, d1, u(0.0D), v(0.0D)); tessellator.setNormal(0.0F, 0.0F, 1.0F); tessellator.addVertexWithUV(0.0D, 0.0D, d2, u(0.0D), v(0.0D)); tessellator.addVertexWithUV(1.0D, 0.0D, d2, u(1.0D), v(0.0D)); tessellator.addVertexWithUV(1.0D, 1.0D, d2, u(1.0D), v(1.0D)); tessellator.addVertexWithUV(0.0D, 1.0D, d2, u(0.0D), v(1.0D)); vIconTranslate = 8.0D; //tessellator.setColorOpaque_F(1.0F, 1.0F, 1.0F); tessellator.setNormal(0.0F, 1.0F, 0.0F); tessellator.addVertexWithUV(0.0D, 1.0D, 1.0D, u(0.0D), v(1.0D)); tessellator.addVertexWithUV(1.0D, 1.0D, 1.0D, u(1.0D), v(1.0D)); tessellator.addVertexWithUV(1.0D, 1.0D, 0.0D, u(1.0D), v(0.0D)); tessellator.addVertexWithUV(0.0D, 1.0D, 0.0D, u(0.0D), v(0.0D)); //tessellator.setColorOpaque_F(0.6F, 0.6F, 0.6F); tessellator.setNormal(0.0F, -1.0F, 0.0F); tessellator.addVertexWithUV(0.0D, 0.0D, 0.0D, u(0.0D), v(0.0D)); tessellator.addVertexWithUV(1.0D, 0.0D, 0.0D, u(1.0D), v(0.0D)); tessellator.addVertexWithUV(1.0D, 0.0D, 1.0D, u(1.0D), v(1.0D)); tessellator.addVertexWithUV(0.0D, 0.0D, 1.0D, u(0.0D), v(1.0D)); //tessellator.setColorOpaque_F(0.8F, 0.8F, 0.8F); tessellator.setNormal(-1.0F, 0.0F, 0.0F); tessellator.addVertexWithUV(0.0D, 0.0D, 1.0D, u(0.0D), v(1.0D)); tessellator.addVertexWithUV(0.0D, 1.0D, 1.0D, u(1.0D), v(1.0D)); tessellator.addVertexWithUV(0.0D, 1.0D, 0.0D, u(1.0D), v(0.0D)); tessellator.addVertexWithUV(0.0D, 0.0D, 0.0D, u(0.0D), v(0.0D)); tessellator.setNormal(1.0F, 0.0F, 0.0F); tessellator.addVertexWithUV(1.0D, 0.0D, 0.0D, u(0.0D), v(0.0D)); tessellator.addVertexWithUV(1.0D, 1.0D, 0.0D, u(1.0D), v(0.0D)); tessellator.addVertexWithUV(1.0D, 1.0D, 1.0D, u(1.0D), v(1.0D)); tessellator.addVertexWithUV(1.0D, 0.0D, 1.0D, u(0.0D), v(1.0D)); tessellator.setNormal(0.0F, 0.0F, -1.0F); tessellator.addVertexWithUV(0.0D, 1.0D, 0.0D, u(0.0D), v(1.0D)); tessellator.addVertexWithUV(1.0D, 1.0D, 0.0D, u(1.0D), v(1.0D)); tessellator.addVertexWithUV(1.0D, 0.0D, 0.0D, u(1.0D), v(0.0D)); tessellator.addVertexWithUV(0.0D, 0.0D, 0.0D, u(0.0D), v(0.0D)); tessellator.setNormal(0.0F, 0.0F, 1.0F); tessellator.addVertexWithUV(0.0D, 0.0D, 1.0D, u(0.0D), v(0.0D)); tessellator.addVertexWithUV(1.0D, 0.0D, 1.0D, u(1.0D), v(0.0D)); tessellator.addVertexWithUV(1.0D, 1.0D, 1.0D, u(1.0D), v(1.0D)); tessellator.addVertexWithUV(0.0D, 1.0D, 1.0D, u(0.0D), v(1.0D)); tessellator.draw(); GL11.glTranslatef(0.5F, 0.5F, 0.5F); GL11.glDisable(GL11.GL_ALPHA_TEST); } @Override public boolean renderWorldBlock(IBlockAccess blockAccess, int x, int y, int z, Block bblock, int modelId, RenderBlocks renderer) { BlockGasPipe block = (BlockGasPipe)bblock; int brightness = block.getMixedBrightnessForBlock(blockAccess, x, y, z); icon = renderer.hasOverrideBlockTexture() ? renderer.overrideBlockTexture : renderer.getBlockIcon(block); Tessellator tessellator = Tessellator.instance; final boolean[] sidePipe = new boolean[6]; final boolean[] sideOpaque = new boolean[6]; for(int i = 0; i < 6; i++) { int x1 = x + xDirection[i]; int y1 = y + yDirection[i]; int z1 = z + zDirection[i]; Block directionBlock = blockAccess.getBlock(x1, y1, z1); if(directionBlock != Blocks.air) { sidePipe[i] = directionBlock instanceof BlockGasPipe || IGasReceptor.class.isAssignableFrom(directionBlock.getClass()); sideOpaque[i] = directionBlock.isOpaqueCube() & !sidePipe[i]; } } double d1 = 6.0F / 16.0F; double d2 = 10.0F / 16.0F; double d3 = 4.5F / 16.0F; double d4 = 11.5F / 16.0F; boolean collectionAll = sidePipe[0] || sidePipe[1] || sidePipe[2] || sidePipe[3] || sidePipe[4] || sidePipe[5]; boolean collectionY = sidePipe[2] || sidePipe[3] || sidePipe[4] || sidePipe[5]; boolean collectionX = sidePipe[0] || sidePipe[1] || sidePipe[4] || sidePipe[5]; boolean collectionZ = sidePipe[0] || sidePipe[1] || sidePipe[2] || sidePipe[3]; double minX = (sidePipe[3] | !collectionX) & collectionAll ? 0.0F : d1; double maxX = (sidePipe[2] | !collectionX) & collectionAll ? 1.0F : d2; double minY = (sidePipe[0] | !collectionY) & collectionAll ? 0.0F : d1; double maxY = (sidePipe[1] | !collectionY) & collectionAll ? 1.0F : d2; double minZ = (sidePipe[5] | !collectionZ) & collectionAll ? 0.0F : d1; double maxZ = (sidePipe[4] | !collectionZ) & collectionAll ? 1.0F : d2; /*double minX = sidePipe[2] ? 0.0F : 0.0F; double maxX = sidePipe[2] ? 1.0F : 1.0F; double minY = sidePipe[0] ? 0.0F : 0.0F; double maxY = sidePipe[1] ? 1.0F : 1.0F; double minZ = sidePipe[4] ? 0.0F : 0.0F; double maxZ = sidePipe[5] ? 1.0F : 1.0F;*/ tessellator.setBrightness(brightness); tessellator.addTranslation((float)x, (float)y, (float)z); uIconTranslate = 0.0D; vIconTranslate = 0.0D; tessellator.setColorOpaque_F(1.0F, 1.0F, 1.0F); if(collectionY | !collectionAll) { tessellator.setColorOpaque_F(0.6F, 0.6F, 0.6F); tessellator.setNormal(0.0F, -1.0F, 0.0F); tessellator.addVertexWithUV(minX, d1, minZ, u(minX), v(minZ)); tessellator.addVertexWithUV(maxX, d1, minZ, u(maxX), v(minZ)); tessellator.addVertexWithUV(maxX, d1, maxZ, u(maxX), v(maxZ)); tessellator.addVertexWithUV(minX, d1, maxZ, u(minX), v(maxZ)); tessellator.setColorOpaque_F(1.0F, 1.0F, 1.0F); tessellator.setNormal(0.0F, 1.0F, 0.0F); tessellator.addVertexWithUV(minX, d2, maxZ, u(minX), v(maxZ)); tessellator.addVertexWithUV(maxX, d2, maxZ, u(maxX), v(maxZ)); tessellator.addVertexWithUV(maxX, d2, minZ, u(maxX), v(minZ)); tessellator.addVertexWithUV(minX, d2, minZ, u(minX), v(minZ)); } if(collectionX | !collectionAll) { tessellator.setColorOpaque_F(0.8F, 0.8F, 0.8F); tessellator.setNormal(-1.0F, 0.0F, 0.0F); tessellator.addVertexWithUV(d1, minY, maxZ, u(minY), v(maxZ)); tessellator.addVertexWithUV(d1, maxY, maxZ, u(maxY), v(maxZ)); tessellator.addVertexWithUV(d1, maxY, minZ, u(maxY), v(minZ)); tessellator.addVertexWithUV(d1, minY, minZ, u(minY), v(minZ)); tessellator.setNormal(1.0F, 0.0F, 0.0F); tessellator.addVertexWithUV(d2, minY, minZ, u(minY), v(minZ)); tessellator.addVertexWithUV(d2, maxY, minZ, u(maxY), v(minZ)); tessellator.addVertexWithUV(d2, maxY, maxZ, u(maxY), v(maxZ)); tessellator.addVertexWithUV(d2, minY, maxZ, u(minY), v(maxZ)); } if(collectionZ | !collectionAll) { tessellator.setColorOpaque_F(0.8F, 0.8F, 0.8F); tessellator.setNormal(0.0F, 0.0F, -1.0F); tessellator.addVertexWithUV(minX, maxY, d1, u(minX), v(maxY)); tessellator.addVertexWithUV(maxX, maxY, d1, u(maxX), v(maxY)); tessellator.addVertexWithUV(maxX, minY, d1, u(maxX), v(minY)); tessellator.addVertexWithUV(minX, minY, d1, u(minX), v(minY)); tessellator.setNormal(0.0F, 0.0F, 1.0F); tessellator.addVertexWithUV(minX, minY, d2, u(minX), v(minY)); tessellator.addVertexWithUV(maxX, minY, d2, u(maxX), v(minY)); tessellator.addVertexWithUV(maxX, maxY, d2, u(maxX), v(maxY)); tessellator.addVertexWithUV(minX, maxY, d2, u(minX), v(maxY)); } if(collectionAll) { vIconTranslate = 8.0D; if(maxY == 1.0D) { tessellator.setColorOpaque_F(1.0F, 1.0F, 1.0F); tessellator.setNormal(0.0F, 1.0F, 0.0F); tessellator.addVertexWithUV(minX, maxY, maxZ, u(minX), v(maxZ)); tessellator.addVertexWithUV(maxX, maxY, maxZ, u(maxX), v(maxZ)); tessellator.addVertexWithUV(maxX, maxY, minZ, u(maxX), v(minZ)); tessellator.addVertexWithUV(minX, maxY, minZ, u(minX), v(minZ)); } if(minY == 0.0D) { tessellator.setColorOpaque_F(0.6F, 0.6F, 0.6F); tessellator.setNormal(0.0F, -1.0F, 0.0F); tessellator.addVertexWithUV(minX, minY, minZ, u(minX), v(minZ)); tessellator.addVertexWithUV(maxX, minY, minZ, u(maxX), v(minZ)); tessellator.addVertexWithUV(maxX, minY, maxZ, u(maxX), v(maxZ)); tessellator.addVertexWithUV(minX, minY, maxZ, u(minX), v(maxZ)); } tessellator.setColorOpaque_F(0.8F, 0.8F, 0.8F); if(minX == 0.0D) { tessellator.setNormal(-1.0F, 0.0F, 0.0F); tessellator.addVertexWithUV(minX, minY, maxZ, u(minY), v(maxZ)); tessellator.addVertexWithUV(minX, maxY, maxZ, u(maxY), v(maxZ)); tessellator.addVertexWithUV(minX, maxY, minZ, u(maxY), v(minZ)); tessellator.addVertexWithUV(minX, minY, minZ, u(minY), v(minZ)); } if(maxX == 1.0D) { tessellator.setNormal(1.0F, 0.0F, 0.0F); tessellator.addVertexWithUV(maxX, minY, minZ, u(minY), v(minZ)); tessellator.addVertexWithUV(maxX, maxY, minZ, u(maxY), v(minZ)); tessellator.addVertexWithUV(maxX, maxY, maxZ, u(maxY), v(maxZ)); tessellator.addVertexWithUV(maxX, minY, maxZ, u(minY), v(maxZ)); } tessellator.setColorOpaque_F(0.8F, 0.8F, 0.8F); if(minZ == 0.0D) { tessellator.setNormal(0.0F, 0.0F, -1.0F); tessellator.addVertexWithUV(minX, maxY, minZ, u(minX), v(maxY)); tessellator.addVertexWithUV(maxX, maxY, minZ, u(maxX), v(maxY)); tessellator.addVertexWithUV(maxX, minY, minZ, u(maxX), v(minY)); tessellator.addVertexWithUV(minX, minY, minZ, u(minX), v(minY)); } if(maxZ == 1.0D) { tessellator.setNormal(0.0F, 0.0F, 1.0F); tessellator.addVertexWithUV(minX, minY, maxZ, u(minX), v(minY)); tessellator.addVertexWithUV(maxX, minY, maxZ, u(maxX), v(minY)); tessellator.addVertexWithUV(maxX, maxY, maxZ, u(maxX), v(maxY)); tessellator.addVertexWithUV(minX, maxY, maxZ, u(minX), v(maxY)); } if(((x ^ y ^ z) & 1) > 0) { uIconTranslate = 8.0D; vIconTranslate = 0.0D; minX = sideOpaque[3] ? 0.0F : d1; maxX = sideOpaque[2] ? 1.0F : d2; minY = sideOpaque[0] ? 0.0F : d1; maxY = sideOpaque[1] ? 1.0F : d2; minZ = sideOpaque[5] ? 0.0F : d1; maxZ = sideOpaque[4] ? 1.0F : d2; if(sidePipe[0] | !collectionY) { tessellator.setColorOpaque_F(0.6F, 0.6F, 0.6F); tessellator.setNormal(0.0F, -1.0F, 0.0F); tessellator.addVertexWithUV(minX, d3, minZ, u(minX), v(minZ)); tessellator.addVertexWithUV(maxX, d3, minZ, u(maxX), v(minZ)); tessellator.addVertexWithUV(maxX, d3, maxZ, u(maxX), v(maxZ)); tessellator.addVertexWithUV(minX, d3, maxZ, u(minX), v(maxZ)); tessellator.setColorOpaque_F(1.0F, 1.0F, 1.0F); tessellator.setNormal(0.0F, 1.0F, 0.0F); tessellator.addVertexWithUV(minX, d3, maxZ, u(minX), v(maxZ)); tessellator.addVertexWithUV(maxX, d3, maxZ, u(maxX), v(maxZ)); tessellator.addVertexWithUV(maxX, d3, minZ, u(maxX), v(minZ)); tessellator.addVertexWithUV(minX, d3, minZ, u(minX), v(minZ)); } if(sidePipe[1] | !collectionY) { tessellator.setColorOpaque_F(0.6F, 0.6F, 0.6F); tessellator.setNormal(0.0F, -1.0F, 0.0F); tessellator.addVertexWithUV(minX, d4, minZ, u(minX), v(minZ)); tessellator.addVertexWithUV(maxX, d4, minZ, u(maxX), v(minZ)); tessellator.addVertexWithUV(maxX, d4, maxZ, u(maxX), v(maxZ)); tessellator.addVertexWithUV(minX, d4, maxZ, u(minX), v(maxZ)); tessellator.setColorOpaque_F(1.0F, 1.0F, 1.0F); tessellator.setNormal(0.0F, 1.0F, 0.0F); tessellator.addVertexWithUV(minX, d4, maxZ, u(minX), v(maxZ)); tessellator.addVertexWithUV(maxX, d4, maxZ, u(maxX), v(maxZ)); tessellator.addVertexWithUV(maxX, d4, minZ, u(maxX), v(minZ)); tessellator.addVertexWithUV(minX, d4, minZ, u(minX), v(minZ)); } if(sidePipe[2] | !collectionX) { tessellator.setColorOpaque_F(0.8F, 0.8F, 0.8F); tessellator.setNormal(-1.0F, 0.0F, 0.0F); tessellator.addVertexWithUV(d4, minY, maxZ, u(minY), v(maxZ)); tessellator.addVertexWithUV(d4, maxY, maxZ, u(maxY), v(maxZ)); tessellator.addVertexWithUV(d4, maxY, minZ, u(maxY), v(minZ)); tessellator.addVertexWithUV(d4, minY, minZ, u(minY), v(minZ)); tessellator.setNormal(1.0F, 0.0F, 0.0F); tessellator.addVertexWithUV(d4, minY, minZ, u(minY), v(minZ)); tessellator.addVertexWithUV(d4, maxY, minZ, u(maxY), v(minZ)); tessellator.addVertexWithUV(d4, maxY, maxZ, u(maxY), v(maxZ)); tessellator.addVertexWithUV(d4, minY, maxZ, u(minY), v(maxZ)); } if(sidePipe[3] | !collectionX) { tessellator.setColorOpaque_F(0.8F, 0.8F, 0.8F); tessellator.setNormal(-1.0F, 0.0F, 0.0F); tessellator.addVertexWithUV(d3, minY, maxZ, u(minY), v(maxZ)); tessellator.addVertexWithUV(d3, maxY, maxZ, u(maxY), v(maxZ)); tessellator.addVertexWithUV(d3, maxY, minZ, u(maxY), v(minZ)); tessellator.addVertexWithUV(d3, minY, minZ, u(minY), v(minZ)); tessellator.setNormal(1.0F, 0.0F, 0.0F); tessellator.addVertexWithUV(d3, minY, minZ, u(minY), v(minZ)); tessellator.addVertexWithUV(d3, maxY, minZ, u(maxY), v(minZ)); tessellator.addVertexWithUV(d3, maxY, maxZ, u(maxY), v(maxZ)); tessellator.addVertexWithUV(d3, minY, maxZ, u(minY), v(maxZ)); } if(sidePipe[4] | !collectionZ) { tessellator.setColorOpaque_F(0.8F, 0.8F, 0.8F); tessellator.setNormal(0.0F, 0.0F, -1.0F); tessellator.addVertexWithUV(minX, maxY, d4, u(minX), v(maxY)); tessellator.addVertexWithUV(maxX, maxY, d4, u(maxX), v(maxY)); tessellator.addVertexWithUV(maxX, minY, d4, u(maxX), v(minY)); tessellator.addVertexWithUV(minX, minY, d4, u(minX), v(minY)); tessellator.setNormal(0.0F, 0.0F, 1.0F); tessellator.addVertexWithUV(minX, minY, d4, u(minX), v(minY)); tessellator.addVertexWithUV(maxX, minY, d4, u(maxX), v(minY)); tessellator.addVertexWithUV(maxX, maxY, d4, u(maxX), v(maxY)); tessellator.addVertexWithUV(minX, maxY, d4, u(minX), v(maxY)); } if(sidePipe[5] | !collectionZ) { tessellator.setColorOpaque_F(0.8F, 0.8F, 0.8F); tessellator.setNormal(0.0F, 0.0F, -1.0F); tessellator.addVertexWithUV(minX, maxY, d3, u(minX), v(maxY)); tessellator.addVertexWithUV(maxX, maxY, d3, u(maxX), v(maxY)); tessellator.addVertexWithUV(maxX, minY, d3, u(maxX), v(minY)); tessellator.addVertexWithUV(minX, minY, d3, u(minX), v(minY)); tessellator.setNormal(0.0F, 0.0F, 1.0F); tessellator.addVertexWithUV(minX, minY, d3, u(minX), v(minY)); tessellator.addVertexWithUV(maxX, minY, d3, u(maxX), v(minY)); tessellator.addVertexWithUV(maxX, maxY, d3, u(maxX), v(maxY)); tessellator.addVertexWithUV(minX, maxY, d3, u(minX), v(maxY)); } } } tessellator.addTranslation((float)-x, (float)-y, (float)-z); return true; } private double u(double u) { return icon.getInterpolatedU(u * 8.0D + uIconTranslate); } private double v(double v) { return icon.getInterpolatedV(v * 8.0D + vIconTranslate); } @Override public boolean shouldRender3DInInventory(int i) { return true; } @Override public int getRenderId() { return GasesFramework.renderBlockGasPipeID; } } You could also consider adapting your mod to work with my Gases Framework. It would save you the work of creating gas pipes, and has some other features. The problem is that it probably brings in a few too many unnecessary features for your mod.
  22. The reason why it says the class "avc" or "Minecraft" doesn't exist is simple. It's the fact that something went wrong during the transformation of the class, so the class is improperly loaded. It would help a lot if you managed to get a print of the exception that is caught during the transformation. However, I advise you to not completely replace GuiMainMenu. I'm very sure Forge modifies this part of minecraft, either by doing what you are doing, or it's patching the vanilla class. You should also patch the vanilla class to avoid conflicts. If it turns out to be a forge class, patch that one instead.
  23. If that is what you intend to do, follow the instructions from this tutorial. It's pretty much the best resource on core modding around, but it could be better and perhaps go more in depth on how to patch with different situations. I might write a new tutorial dedicated purely to class transformation.
  24. Could it be that the entity is spawned on the client side but not the server side?
  25. If you're still interested in programmatically replacing the blocks, here's how I did it to replace the coal ore block and bedrock block. The following paste involves heavy use of ASM, so you have been warned. If you have no knowledge of class transforming or ASM, you can either read it up or simply ignore this. public byte[] patchClassBlock(byte[] data, boolean obfuscated) { String classBlock = obfuscated ? "ahu" : "net/minecraft/block/Block"; String methodRegisterBlocks = obfuscated ? "p" : "registerBlocks"; String methodSetHardness = obfuscated ? "c" : "setHardness"; ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(data); classReader.accept(classNode, 0); boolean bedrockFound = false; boolean coal_oreFound = false; for(int i = 0; i < classNode.methods.size(); i++) { MethodNode method = classNode.methods.get(i); if(method.name.equals(methodRegisterBlocks) && method.desc.equals("()V")) { for(int j = 0; j < method.instructions.size(); j++) { AbstractInsnNode instruction = method.instructions.get(j); if(instruction.getOpcode() == LDC) { LdcInsnNode ldcInstruction = (LdcInsnNode)instruction; if(ldcInstruction.cst.equals("bedrock")) { if(!bedrockFound) { ((TypeInsnNode)method.instructions.get(j + 1)).desc = "glenn/gases/BlockBedrock"; ((MethodInsnNode)method.instructions.get(j + 4)).owner = "glenn/gases/BlockBedrock"; } bedrockFound = true; } else if(ldcInstruction.cst.equals("coal_ore")) { if(!coal_oreFound) { ((TypeInsnNode)method.instructions.get(j + 1)).desc = "glenn/gases/BlockCoalOre"; ((MethodInsnNode)method.instructions.get(j + 3)).owner = "glenn/gases/BlockCoalOre"; ((MethodInsnNode)method.instructions.get(j + 5)).owner = "glenn/gases/BlockCoalOre"; } coal_oreFound = true; } } } } } ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); classNode.accept(writer); return writer.toByteArray(); } The solution works by simply replacing the initialization of the blocks in Block, which involves altering a NEW instruction and an INVOKESPECIAL (constructor call) instruction. It's important to note that this has to be adapted for certain situations, with factors such as constructor parameters and builder methods (setName, setHardness, setLightlevel, etc.). I had to change the owner of the setHardness() call in the coal ore block's initialization, because that's the way java is. It's pretty much programmatically changing this: Block b = (Block)new BlockSomething().setName("b").setHardness...etc; To this: Block b = (Block)new BlockSomethingElse().setName("b").setHardness...etc; I still recommend using events as much as you can, but we all know we can't cover everything without doing some core modding.
×
×
  • Create New...

Important Information

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