-
Posts
37 -
Joined
-
Last visited
Converted
-
Gender
Male
-
Personal Text
I am here.
Glenn's Achievements

Tree Puncher (2/8)
8
Reputation
-
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.
-
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.
-
[1.7.2] Animated texture from resource packs in my blocks
Glenn replied to ColdFox's topic in Modder Support
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. -
Try making the whole texture semi-transparent. Also, I believe you have to move all the rendering to the second render pass.
-
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; }
-
Did you try debugging? Also make sure there is only one furnace.
-
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!
-
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.
-
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.
-
Making a Block Spawn Void Particles (Or Any Particle)
Glenn replied to BungeeTheCookie's topic in Modder Support
Minecraft's particles are terribly hardcoded. The particle name you are looking for is "depthsuspend". -
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.
-
You could also consider using one block representing each quality.
-
[Unsolved] "Already tesselating!" crash with custom block model
Glenn replied to bdkuhman's topic in Modder Support
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. -
[1.6.4] my textures are not loaded by minecraft
Glenn replied to terschegget's topic in Modder Support
You have apparently not done that correctly. Check the spelling on your folder names. As pointed out by Frost, code also helps. -
I highly recommend debugging. It has helped me so much with complicated block mechanisms, such as gas flow and gas piping.