Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Draco18s

Members
  • Joined

  • Last visited

Everything posted by Draco18s

  1. You missed an important line: icons[o] = map.getTextureExtry(regname); You need to get the IIcon back out and save it to a field in the block, which is then returned via getIcon(...)
  2. Here's a custom TextureAtlasSprite that does pretty much what you're looking for. It takes in two textures and combines them. You'll have to modify it to combine them in the way you want, however. http://www.minecraftforge.net/forum/index.php/topic,35760.0.html
  3. I do not know. You may have to write your own ISimpleBlockRenderingHandler. Its pretty straight forward.
  4. AH HAHAHAHA HEHEHE Ha ha ha heeee..... oooh boy. This is going to be tough as balls as it has to be done client side and anything done client side has to be assumed to be inherently insecure. That is: someone clever enough can decompile your mod, strip out the checking code (or make it always return, "Yep! No X-Ray!") and recompile it and you would never know. That said, the only way I know how to get access to the pixel data of a given texture would be the method I talk about over here. You'd just have to rewrite some of the functions and then do Dirty Tricks as part of the processing (that is: violate the implied agreement that the texture loading code is there to load textures and not cause side effects, though no one will ever check to see that that is true). You'd still have to register a new texture icon to get the code to execute, but it could report back to Somewhere Else its findings.
  5. Because the input to the getRotation method is the rotation axis, that is, the bit that doesn't move.
  6. Have fun with that. Having done chunk-level saved data myself, there are a lot of pitfalls.
  7. Show your icon registration method in your block class.
  8. Not all mods do, so knowing about JD-GUI is still a boon.
  9. That was the second choice block I'd including putting the field in the common proxy.
  10. IIRC, you want to override getCollisionBoundingBoxFromPool() .
  11. Note that items inside inventories that themselves don't tick (chests, actually most TileEntities, item frames) items don't get updates.
  12. JD-GUI may be in order.
  13. Redstone dust is super complicated to follow. It was hellish trying to disect the code enough to make redstone fences. Alright, starting to look at this block's problems. #1! The metadata used is 2,3,4,5 consistent with 0 and 1 being down and up. But! The isProvidingPower method uses bitwise &3 so the values don't arrayoutofbounds on Direction[], this is why you use ForgeDirection! #2! A bridge has one primary direction specified by metadata (that's fine) however, the crosswise direction can go either left to right or right to left. There's room in the metadata to handle this, but this means the blocks needs a way to know whether it is right handed or left handed (mirror images, not rotations). #3! Something is going on with figuring out that a neighboring block is providing power. I even duplicated all of the functionality in the repeater and still don't get the output I want (at best, it takes input directly from a redstone wire--and only wire--which I suppose would be fine). Correction, it takes direct power only, none of that "through a solid block" stuff (e.g. comparators and repeaters work too). That said, I have a working block!
  14. Here we go. There are a few important parts, and a few unimportant ones. Important: - hasCustomLoader() - load() Unimportant: - colorize() which handles color multiplication (I used it to colorize the overlay image but not the base). - anything dealing with invert (this was special case handling I wanted so that my grayscale overlays could be inverted white-to-black so that they could be used equally well on a dark base (such as basalt) or a light base (such as marble). scaleToSmaller() should be rewritten to be "scaleToLarger()" but it was easy to write and lets the overlay handle resource packs changing resolution size of only one texture without breaking horribly. It may not generate a good result, but it will generate a valid result. public class TextureAtlasDynamic extends TextureAtlasSprite { protected String textureBase; protected String textureOverlay; protected Color colorMulti; protected boolean invert; public TextureAtlasDynamic(String p_i1282_1_, String base, String overlay, Color color, boolean inv) { super(p_i1282_1_); textureBase = base; textureOverlay = overlay; colorMulti = color; invert = inv; } @Override public void updateAnimation() { TextureUtil.uploadTextureMipmap((int[][])this.framesTextureData.get(0), this.width, this.height, this.originX, this.originY, false, false); } @Override public boolean hasCustomLoader(IResourceManager manager, ResourceLocation location) { return true; } @Override public boolean load(IResourceManager manager, ResourceLocation location) { framesTextureData.clear(); this.frameCounter = 0; this.tickCounter = 0; ResourceLocation resource1 = new ResourceLocation(textureBase); ResourceLocation resource2 = new ResourceLocation(textureOverlay); try { TextureMap map = Minecraft.getMinecraft().getTextureMapBlocks(); resource1 = this.completeResourceLocation(map, resource1, 0); resource2 = this.completeResourceLocation(map, resource2, 0); BufferedImage buff = ImageIO.read(manager.getResource(resource1).getInputStream()); BufferedImage buff2 = ImageIO.read(manager.getResource(resource2).getInputStream()); int[] rawBase = new int[buff.getWidth()*buff.getHeight()]; int[] rawOverlay = new int[buff2.getWidth()*buff2.getHeight()]; buff.getRGB(0, 0, buff.getWidth(), buff.getHeight(), rawBase, 0, buff.getWidth()); buff2.getRGB(0, 0, buff2.getWidth(), buff2.getHeight(), rawOverlay, 0, buff2.getWidth()); int min = Math.min(buff.getWidth(),buff2.getWidth()); rawBase = scaleToSmaller(rawBase, buff.getWidth(), min); rawOverlay = scaleToSmaller(rawOverlay, buff2.getWidth(), min); width = min; height = min; int r1,g1,b1; int r2,g2,b2; float a1,a2,a3; for(int p=0; p<rawBase.length;p++) { Color c1 = new Color(rawBase[p],true); Color c2 = new Color(rawOverlay[p],true); c2 = colorize(colorMulti,c2,invert); a1 = c1.getAlpha()/255f; r1 = c1.getRed(); g1 = c1.getGreen(); b1 = c1.getBlue(); a2 = c2.getAlpha()/255f; r2 = c2.getRed(); g2 = c2.getGreen(); b2 = c2.getBlue(); a3 = a2+a1*(1-a2); if(a3 > 0) { r1 = Math.round(((r2*a2)+(r1*a1*(1-a2)))/a3); g1 = Math.round(((g2*a2)+(g1*a1*(1-a2)))/a3); b1 = Math.round(((b2*a2)+(b1*a1*(1-a2)))/a3); } else { r1 = g1 = b1 = 0; } Color c3 = new Color(r1,g1,b1,Math.round(a3*255)); rawBase[p] = c3.getRGB(); } int[][] aint = new int[1 + MathHelper.calculateLogBaseTwo(min)][]; for (int k = 0; k < aint.length; ++k) { aint[k] = rawBase; } this.framesTextureData.add(aint); } catch (IOException e) { e.printStackTrace(); int[][] aint = new int[1][]; for (int k = 0; k < 1; ++k) { aint[k] = new int[16*16]; for(int l=0; l<aint[k].length;l++) { aint[k][l] = 0xFFFFFFFF; } } width = 16; height = 16; this.framesTextureData.add(aint); } return false; } private static int[] scaleToSmaller(int[] data, int width, int min) { if(width == min) { return data; } int scale = width / min; int[] output = new int[min*min]; int j = 0; for(int i = 0; i < output.length; i++) { if(i%min == 0) { j += width; } output[i] = data[i*scale+j]; } return output; } private static ResourceLocation completeResourceLocation(TextureMap map, ResourceLocation loc, int c) { try { return (ResourceLocation)HardLib.proxy.resourceLocation.invoke(map, loc, c); //see below } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } private static Color colorize(Color cm, Color c2, boolean invert) { float[] pix = new float[3]; float[] mul = new float[3]; Color.RGBtoHSB(c2.getRed(), c2.getGreen(), c2.getBlue(),pix); Color.RGBtoHSB(cm.getRed(), cm.getGreen(), cm.getBlue(), mul); float v = (invert?1-pix[2]:pix[2]); Color c3 = new Color(Color.HSBtoRGB(mul[0], mul[1], v)); return new Color(c3.getRed(),c3.getGreen(),c3.getBlue(),c2.getAlpha()); } } The only bit that is external is the reflection which I did in my common proxy. It could have been static. public class ClientProxy extends CommonProxy { //public Method resourceLocation; in CommonProxy public void init() { Class clz = TextureMap.class; Method[] meths = clz.getDeclaredMethods(); for(Method m : meths) { if(m.getReturnType() == ResourceLocation.class) { m.setAccessible(true); resourceLocation = m; } } } And finally, registering the TextureAtlasSprite without needing events: (I had an array of 12 used for the same block) @Override @SideOnly(Side.CLIENT) public void registerBlockIcons(IIconRegister iconRegister) { this.icons = new IIcon[12]; if(iconRegister instanceof TextureMap) { //instanceof check, TextureMap should be the only thing that implements IIconRegister TextureMap map = (TextureMap)iconRegister; for(int o = 0; o < 12; o++) { String overlayName = "hazards:stone_overlay_"+o; String baseName = this.getTextureName(); //passed via block constructor from the block its "cloning" String regname = "hazards:"+this.getUnlocalizedName()+"_"+o; //the overlay texture map.setTextureEntry(regname, new TextureAtlasDynamic(regname,baseName,overlayName,new Color(color),inv)); icons[o] = map.getTextureExtry(regname); } } }
  15. Specifically because knowing the seed is a cheat: you could easily make a clone of the world and examine it with 3rd party tools to find minerals. That said, there IS a client side mod that can save the chunk data anyway (it can't save chest and other inventory content unless the container is opened, but that's pretty minor).
  16. Oh man are you in for a fun time tonight. Short answer: yes, two ways. 1) render the block twice 2) custom TextureAtlasSprite loading 1 is easier and found via Google ("two pass blocks"), 2 is muuuch more complicated and will need to wait for me to be at my desktop again. There's a copy on the forum here somewhere, check my user profile for threads started on the last couple of months.
  17. I think the OP wants his TileEntity to update. I've forgotten the name of the method, but it should be easy to find. Is something like doesRequireUpdates , returns a boolean and the default implementation returns false (and does nothing else).
  18. I'm sure I could code it, but you'd have to wait a few days. I'm kind of tied up.
  19. Mm. Wasn't sure if that's what that was or not. I was just falling asleep and remembered that weird little fact about how getPower works.
  20. Code you have showed contains no Keyboard.isKeyDown code.
  21. This is (almost certainly) a Forge bug. Is it the most recent version for 1.7.10? If so, report it as a bug. Try also checking the actually most latest (1.8. as well. Lex hates people who use 1.7.10 still.
  22. You have a lot of debug statements in there. When you mine a block and it doesn't drop the right thing, what does the console say? (Also, what is the name of your enchantment? This is for purposes unrelated to your bug. e.g. whatever you pass to setName() in your enchantment constructor).
  23. Don't rotate opposite. The getPower methods checks the block west and sends "west" as the side parameter. Your code thinks that "east" is where its input is when passed "west," so it asks the block east of it if it is powered, but that block asked your block, and so on. That is: the side parameter passed is not the side of YOUR block the request is coming from, but the side the REQUESTOR is checking.
  24. Because 1) Minecraft totally has that behavior natively (hint: item stack NBT is used for hardly nothing: enchantments and nametags and that's about it). 2) That's totally how code works: reading arbitrary data tags and knowing what the fuck to do with them.
  25. Is it possible? Yes. Will you have to write a whole lot of custom handling code so that you can display a youtube video inside an application that has never before needed that capability? Also yes.

Important Information

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.