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. http://www.minecraftforge.net/forum/index.php/topic,34201.msg180147.html
  2. Is it vanilla or Forge that allows for custom sprite loaders? Want to report to the right people, for now I am assuming Forge inserts that as part of its patch (because why the hell would vanilla assume custom loaders!). The custom sprite load method is not passed a number of mipmap levels and TextureMap.mipmapLevels is a private field. This value is passed to loadSprite , albeit indirectly as the length of a buffered image array. This makes correctly instantiating the framesTextureData 2D arrays difficult: the sprite MUST assume the maximum number of mipmaps possible for its own size (for 16x16 default resources, this is 4) which could lead to problems if the number that the system goes to generate exceeds this value (unlikely, but possible) and under lower mipmap settings just wastes RAM. Or it forces the modder to use Reflection in order to get access to the private field. Either this method would need to include that integer value or TextureMap.mipmapLevels needs a getter method via IResourceManager .
  3. You'd do #2 sort of, except that you would manually interface with the tessellator to draw your camera-facing quad. Take a look at how nametags are drawn.
  4. 4) You could declare new Random() but I would do it at the event handler class level, not inside the function.
  5. Sorry, my mistake. I saw damage.getSourceOfDamage() instanceof EntityPlayer and it looked wrong, but I was away from Eclipse and on my tablet.
  6. Look at the DamageSource class more closely.
  7. You don't need IEEP for this. The living drops event should include that damage source.
  8. That's likely the best you're going to get. 1.8's rendering is weird and annoying due to the multiple levels of wrappers.
  9. I'm not familiar with 1.8, unfortunately. You'll have to dig around to figure out how Minecraft's renderer (RenderGlobal?) figures that out. The whole json thing irks me, TBH. I mean, I get why it exists, so that resource packs can alter the shapes of blocks as well as the texture, but the implementation lost something in the process.
  10. Item item = stack.getItem(); Block block = Block.getBlockFromItem(item); block.getIcon(side, meta); Note that I didn't attempt to check for null, etc.
  11. That should be the stitched texture sheet, yes. You'll still need to bind the texture (making sure that OGL is drawing with the right texture) and get the UV coordinates from the block's IIcon (to draw the correct portion).
  12. All of those // TODO Auto-generated method stub might be the problem.
  13. Block bounds are not affected by rotation because they are axis aligned.
  14. You so not need the other mod's files.
  15. https://github.com/Draco18s/Artifacts/tree/master/main/java/com/draco18s/artifacts http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/1291999-unique-artifacts-powerful-randomly-generated-items I don't do any world saved data there, though.
  16. (Was this really back from April? Wow. No wonder it took me a while to locate the thread.) Woo, I got a block texture that's pre-computed! It takes two icon registration strings and reads the files directly, doing alpha-multiplication. Not bad for 1 day's work. package com.draco18s.texturetest.client; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; import javax.imageio.ImageIO; import com.draco18s.texturetest.TextureTestMain; import com.google.common.collect.Lists; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.DynamicTexture; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.renderer.texture.TextureUtil; import net.minecraft.client.resources.IResourceManager; import net.minecraft.client.resources.data.AnimationMetadataSection; import net.minecraft.util.IIcon; import net.minecraft.util.ResourceLocation; public class TextureAtlasDynamic extends TextureAtlasSprite { protected String textureBase; protected String textureOverlay; public TextureAtlasDynamic(String p_i1282_1_, String base, String overlay) { super(p_i1282_1_); textureBase = base; textureOverlay = overlay; } @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.setFramesTextureData(Lists.newArrayList()); this.frameCounter = 0; this.tickCounter = 0; //int [] rawTexture = icon.getTextureData(); //IResourceManager manager = Minecraft.getMinecraft().getResourceManager(); try { ResourceLocation resource1 = new ResourceLocation(textureBase); ResourceLocation resource2 = new ResourceLocation(textureOverlay); 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()); width = buff.getWidth(); height = buff.getHeight(); 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); int r1,g1,b1; int r2,g2,b2; float a1,a2,a3; for(int p=0; p<rawBase.length;p++) { //perform alpha blending Color c1 = new Color(rawBase[p],true); Color c2 = new Color(rawOverlay[p],true); 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(); //rawBase[p] = (rawBase[p] + rawOverlay[p])/2; } 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(); } return false; } /** Scale the larger icon to the same size as the smaller, using no interpolation. This is "good enough" to accommodate most resource packs. * Alternatively could scale up in the same manner. * width and min should be multiples (dividing evenly) due to the power-of-2 rule. */ private 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; } /** Wrapper to access the TextureMap private method. */ private ResourceLocation completeResourceLocation(TextureMap map, ResourceLocation loc, int c) { try { return (ResourceLocation)TextureTestMain.proxy.resourceLocation.invoke(map, loc, c); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } } There's a bit of reflection necessary to turn "modid:texture" into a proper directory listing, which I do in the client proxy. This finds and saves a reference to the private completeResourceLocation method of TextureMap. 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 block registration: @Override @SideOnly(Side.CLIENT) public void registerBlockIcons(IIconRegister iconRegister) { if(iconRegister instanceof TextureMap) { TextureMap map = (TextureMap)iconRegister; map.setTextureEntry("texturetest:test", new TextureAtlasDynamic("texturetest:test",Blocks.stone.getIcon(0, 0).getIconName(),"texturetest:stone_overlay_13")); blockIcon = map.getTextureExtry("texturetest:test"); } } http://s12.postimg.org/pks9kuty5/2015_10_13_22_58_48.png[/img] No more transparent particles! Left is the custom block, right is vanilla cobblestone.
  17. Mmmmm. Magic numbers
  18. Yes, that's why the gui class has properties like xSize and ySize.
  19. You're on the wrong forum for that kind of help.
  20. That's totally fair. Vanilla uses a hash, and comparing to the furnace is easy to say, "Hey, look at this."

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.