
Reika
Members-
Posts
228 -
Joined
-
Last visited
Everything posted by Reika
-
OK. We shall start with arrays since those are fundamental Java and will be useful to you pretty much forever. An array is basically a collection of variables organized into an ordered structure. Imagine it as a row of "slots" (not unlike inventory slots) and each slot can hold one variable of the appropriate type. For example, an array of 21 double values (declared as double[] array = new double[21]; ) would store 21 doubles, accessed via their positions, called indices (singular: index). Worth noting is that the indices start at zero and progress up to (size-1), for a total of (size) slots. So if you tried accessing slot 21 (or greater) out of the above example (with a line like double b = array[21]; ) you would crash with an "Array Index out of Bounds" exception. Similarly, negative numbers for indices will crash with the same error. Inventories in a TileEntity are treated as an array of ItemStacks. Notice in the furnace code (near the top), something like ItemStack[] furnaceItemStacks = new ItemStack[3];? That is declaring the ItemStack array of size 3 (indices 0-2), with each corresponding to a slot, in this case ingredient, fuel, output. Similarly, a chest has a size 27 array for its 27 slots. [continued]
-
Rendering sometimes too dark, changes with camera angle
Reika replied to Reika's topic in Modder Support
Looking through it, it is simply 4 GL calls. Yes, that makes sense. I just wish Mojang/MCP would name methods as per their functions. -
I can walk you through it. Here are the things you will need to understand: Arrays ItemStacks IInventory and Slot Operations (set and get) Which of those is currently causing you trouble?
-
I have a chest whose inventory size changes depending on the variables in the TileEntity. While it runs perfectly at "open time", the container only ever gets that one chance to calculate the number of slots to draw. Trying to reload the container failed horribly (Java.lang.ArrayIndexOutOfBounds with Index = NaN) and I know of no way to "refresh" it, seeing as all calculations are called from the constructor. Is there a way to do what I want to do, without simply forcing the GUI to closeGui (which is annoying and impractical)? My Container: public ContainerScaleChest(IInventory par1IInventory, TileEntityScaleableChest par2IInventory) { lowerScaleChestInventory = par2IInventory; chest = par2IInventory; size = par2IInventory.getSizeInventory(); par2IInventory.openChest(); this.setSlots(par1IInventory, par2IInventory); } private void setSlots(IInventory par1IInventory, TileEntityScaleableChest te) { int var3 = 0; int var4 = 8; int var5 = 18; int page = chest.page; int rowsize = size; if (rowsize > chest.MAXROWS*9) rowsize = chest.MAXROWS*9; if (page == chest.getMaxPage()) { rowsize = size-(page*9*chest.MAXROWS); } int rows = (int)Math.ceil(rowsize/9D); int x = 0; int y = 0; //ReikaJavaLibrary.pConsole(size); //ReikaJavaLibrary.pConsole(rowsize); //ReikaJavaLibrary.pConsole(page); for (var3 = 0; var3 < rowsize; var3++) { y = var5+var3/9*18; x = var4+18*(var3%9); //ReikaJavaLibrary.pConsole(var3+" -> "+x+", "+y); this.addSlotToContainer(new Slot(te, var3+page*9*chest.MAXROWS, x, y)); } var5 = chest.MAXROWS*18+31;//rows*18+31; //var4 = 44+18*(rows-1); int k; for (k = 0; k < 3; ++k) { for (int m = 0; m < 9; ++m) { var3 = m+9*k; y = var5+k*18; x = var4+18*m; this.addSlotToContainer(new Slot(par1IInventory, m + k * 9 + 9, x, y)); } } var5 += 58; for (k = 0; k < 9; ++k) { y = var5; x = var4+18*k; this.addSlotToContainer(new Slot(par1IInventory, k, x, y)); } } public void reset(IInventory par1IInventory, TileEntityScaleableChest te) { //inventorySlots.clear(); //this.func_94533_d(); //this.setSlots(par1IInventory, te); }
-
Rendering sometimes too dark, changes with camera angle
Reika replied to Reika's topic in Modder Support
@Naitenne: That code assumes I am using the Tessellator, which I am not (due to overhead reasons). I am using OpenGL directly. Also, I want full brightness all the time, not one calculated based on other lighting. Did you already try RenderHelper.disableStandardItemLighting(); before you render your stuff? I used disableEntityLighting as the render code is found in my TileEntity render file, but disabling Item Lighting as well seems to have fixed the problem. Why would item lighting be relevant when rendering a TileEntity? Thank you for helping me nonetheless. -
I recommend forgoing using furnace code entirely and coding it yourself. Use the ItemStack[] array to hold the ingredients. Compare that against possible recipes (if you want it shapeless, use either a list or simple check-for-item algorithms). If it has all the ingredients and all other conditions are met, call make() (or whatever you want to call it) and produce the product by setStackInSlot(). Sample code (do not copy and paste it, as it will not work for you): public void make() { boolean consume = (this.par5Random.nextInt(16) == 0); if (consume) { for (int i = 0; i < ingredients.length; i++) { ReikaInventoryHelper.decrStack(i, this.inv); } } this.fuel++; //this.fuel += par5Random.nextInt(11)+5; if (this.fuel > this.CAPACITY) this.fuel = this.CAPACITY; } public boolean process() { if (this.fuel >= CAPACITY) return false; boolean allitems = this.getAllIngredients(); if (this.inv[ingredients.length] == null) return false; if (this.inv[ingredients.length].itemID != Item.ghastTear.itemID) //need a ghast tear as fuel solvent return false; return allitems; } public boolean getAllIngredients() { for (int k = 0; k < ingredients.length; k++) if (this.inv[k] == null) return false; for (int i = 0; i < ingredients.length; i++) { if (!ReikaInventoryHelper.checkForItemStack(ingredients[i].itemID, ingredients[i].getItemDamage(), this.inv)) return false; } return true; }
-
Rendering sometimes too dark, changes with camera angle
Reika replied to Reika's topic in Modder Support
No replies, and less than 20 views, even after 3 days? Does noone have any ideas? -
Or I may just say "Screw it" and decide to render through the terrain instead...
-
How do i Check for block neighbor that is for example 5 blocks away
Reika replied to Silverkill95's topic in Modder Support
Thank you. I am writing a (non-base-class-modifying) API that has a lot of such functions; you can certainly use it in your own mods as a dependency if you want. It has no "mod class", so forge does not recognize it as a true mod, but it is accessible if referenced correctly. It also has functionality to use the old spritesheet system (which Optifine sadly breaks on blocks, though items work beautifully) and some file I/O (including PNG and MIDI files). -
I do far larger things on every tick, and even my so-slow-it-takes-longer-to-boot-than-the-battery-lasts laptop is not strongly affected. And I mean something like 400 lines of code - per TileEntity - with half a dozen method calls, including this monstrosity: public int[] findSourceBlock(World world, int x, int y, int z) { int[] loc = {x,y-1,z}; int tries = 0; boolean found = false; //ModLoader.getMinecraftInstance().ingameGUI.addChatMessage(String.format("%d", world.getBlockId(x, y-1, z))); while (!this.isSource(world, loc[0], loc[1], loc[2]) && tries < 200 && !found) { //ModLoader.getMinecraftInstance().ingameGUI.addChatMessage(String.format("%d %d %d %d", loc[0], loc[1], loc[2], world.getBlockId(loc[0], loc[1], loc[2]))); loc[0] += -1 + par5Random.nextInt(3); loc[1] = y -6 + par5Random.nextInt(7); loc[2] += -1 + par5Random.nextInt(3); tries++; // to prevent 1fps if (ReikaMathLibrary.py3d(loc[0]-x, 0, loc[2]-z) > 16) { loc[0] = x; loc[2] = z; } } //ModLoader.getMinecraftInstance().ingameGUI.addChatMessage(String.format("%d %d %d %d", loc[0], loc[1], loc[2], world.getBlockId(loc[0], loc[1], loc[2]))); return loc; } How would one open a separate thread (I am not a coremod)?
-
Changing the texture on a TileEntity without changing the block
Reika replied to Yagoki's topic in Modder Support
The easiest way is to create a custom Renderer and use a switch() based on TileEntity.variable. Sample code: switch(par1TileEntity.type) { case 0: this.bindTextureByName("/Reika/RotaryCraft/Textures/TileEntityTex/shafttexw.png"); break; case 1: this.bindTextureByName("/Reika/RotaryCraft/Textures/TileEntityTex/shafttexs.png"); break; case 2: this.bindTextureByName("/Reika/RotaryCraft/Textures/TileEntityTex/shafttex.png"); break; case 3: this.bindTextureByName("/Reika/RotaryCraft/Textures/TileEntityTex/shafttexd.png"); break; case 4: this.bindTextureByName("/Reika/RotaryCraft/Textures/TileEntityTex/shafttexb.png"); break; } -
How do i Check for block neighbor that is for example 5 blocks away
Reika replied to Silverkill95's topic in Modder Support
If you want to get really advanced you could use line-of-sight algorithms like this (do not simply copy-paste the code, as it will not work for you): for (float i = 0; i <= range; i += 0.25) { Vec3 vec2 = ReikaVectorHelper.getVec2Pt(x+a, y+b, z+c, x0, y0, z0).normalize(); vec2.xCoord *= i; vec2.yCoord *= i; vec2.zCoord *= i; vec2.xCoord += x0; vec2.yCoord += y0; vec2.zCoord += z0; //ReikaGuiAPI.write(String.format("%f --> %.3f, %.3f, %.3f", i, vec2.xCoord, vec2.yCoord, vec2.zCoord)); int id = world.getBlockId((int)vec2.xCoord, (int)vec2.yCoord, (int)vec2.zCoord); if ((int)vec2.xCoord == x && (int)vec2.yCoord == y && (int)vec2.zCoord == z) { //ReikaGuiAPI.writeCoords(world, (int)vec2.xCoord, (int)vec2.yCoord, (int)vec2.zCoord); return true; } else if (id != 0 && (isCollideable(world, (int)vec2.xCoord, (int)vec2.yCoord, (int)vec2.zCoord) && !softBlocks(id))) { i = (float)(range + 1); } } -
A little bit of a hack-y workaround you could use is to just monitor changes with updateEntity(). Store the inventory contents each tick (or as often as you want to evaluate) and then compare with the last contents (ItemStack[]).
-
Again both of these seem beyond my capability. Are these very advanced topics?
-
You will need to explain that in more depth - what is ASM? And you say "insert "if(MyMod.doRenderBlocks)" to wrap ... in WorldRenderer" - does that not mean editing base classes? Also, what if I need it done non-statically, i.e., controlled by object variables? Like the above, I need elaboration. What do you mean by "subscribe to"?
-
When I render things with OpenGL directly, sometimes they render too dark, like my GLcolor command was set to about 70% the given values. It is a function of the camera angle and position, and if I move carefully, I can reproduce it on demand once discovering a "trigger angle". Is this related to how sometimes my TileEntities render as if they were in full blackness, often controlled by the same thing? For what it is worth, disabling GLBlend makes it ALWAYS too dark. My code: ModLoader.getMinecraftInstance().entityRenderer.disableLightmap(1); GL11.glPushMatrix(); GL11.glTranslated(p2, p4+2, p6+1); GL11.glScalef(1.0F, -1.0F, -1.0F); GL11.glTranslatef(0.5F, 0.5F, 0.5F); GL11.glPopMatrix(); GL11.glDisable(GL11.GL_LIGHTING); GL11.glEnable(GL11.GL_BLEND); GL11.glDisable(GL11.GL_TEXTURE_2D); GL11.glDisable(GL12.GL_RESCALE_NORMAL); GL11.glEnable(GL11.GL_CULL_FACE); GL11.glDisable(GL11.GL_DEPTH_TEST); GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); //GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); GL11.glPointSize(2F); GL11.glBegin(GL11.GL_POINTS); double[] color = new double[3]; int sc = 16; int a = Math.abs(i); int b = Math.abs(j); int c = Math.abs(k); //ReikaJavaLibrary.pConsole(i+" "+j+" "+k); color[0] = (a%sc)/(double)sc; color[1] = (b%sc)/(double)sc; color[2] = (c%sc)/(double)sc; if (ReikaArrayHelper.sumArray(color) < 0.25) { color[0] *= 4; color[1] *= 4; color[2] *= 4; } if (ReikaArrayHelper.sumArray(color) < 0.5) { color[0] *= 2; color[1] *= 2; color[2] *= 2; } GL11.glColor3d(color[0], color[1], color[2]); GL11.glVertex3d(p2+i, p4+j, p6+k); double spread = 0*0.03125/8; if (spread > 0) { for (double m = -spread; m <= spread; m+= spread/2D) { for (double l = -spread; l <= spread; l+= spread/2D) { for (double n = -spread; n <= spread; n+= spread/2D) { GL11.glVertex3d(p2+i+m, p4+j+l, p6+k+n); } } } } GL11.glEnd(); GL11.glEnable(GL11.GL_TEXTURE_2D); GL11.glEnable(GL11.GL_DEPTH_TEST); ModLoader.getMinecraftInstance().entityRenderer.enableLightmap(1); Desired Colors: Dark rendering (notice the slight turn to the right):
-
I am making a machine that needs to fundamentally change the way the world is rendered, from the normal textured quads to my own system. All of it is done except one last part - I need to disable the default system on demand, without editing base classes. Digging through Minecraft, WorldRenderer, RenderGlobal, and RenderBlocks provide no insight. How would I go about disabling the rendering of blocks on command? Clarification: I want absolute, total nothingness in terms of block rendering, but still want entity, particle, and sky rendering. I need it to look like this (white points are my own):
-
Do what I do and use an item to place the blocks (look at ItemBlock or ItemRedstone). Use the item damage value in a switch() statement and place the block you want accordingly. This also allows you to set metadata and TileEntity data as needed. Sample code (do not simply copy and paste it, as it uses some of my own functions from my API): public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int x, int y, int z, int side, float par8, float par9, float par10) { if (!ReikaWorldHelper.softBlocks(par3World.getBlockId(x, y, z)) && par3World.getBlockMaterial(x, y, z) != Material.water && par3World.getBlockMaterial(x, y, z) != Material.lava) { if (side == 0) --y; if (side == 1) ++y; if (side == 2) --z; if (side == 3) ++z; if (side == 4) --x; if (side == 5) ++x; if (!ReikaWorldHelper.softBlocks(par3World.getBlockId(x, y, z)) && par3World.getBlockMaterial(x, y, z) != Material.water && par3World.getBlockMaterial(x, y, z) != Material.lava) return false; } AxisAlignedBB box = AxisAlignedBB.getBoundingBox(x, y, z, x+1, y+1, z+1); List inblock = par3World.getEntitiesWithinAABB(EntityLiving.class, box); if (inblock.size() > 0) return false; if (!par2EntityPlayer.canPlayerEdit(x, y, z, 0, par1ItemStack)) return false; else { if (!par2EntityPlayer.capabilities.isCreativeMode) --par1ItemStack.stackSize; ReikaWorldHelper.legacySetBlockWithNotify(par3World, x, y, z, mod_RotaryCraft.engine.blockID); TileEntityEngine eng = (TileEntityEngine)par3World.getBlockTileEntity(x, y, z); if (eng != null) { par3World.playSoundEffect(x+0.5, y+0.5, z+0.5, "step.stone", 1F, 1.5F); eng.type = EnumEngineType.setType(par1ItemStack.getItemDamage()); } } int i = MathHelper.floor_double((double)((par2EntityPlayer.rotationYaw * 4F) / 360F) + 0.5D); while (i > 3) i -= 4; while (i < 0) i += 4; switch (i) { case 0: ReikaWorldHelper.legacySetBlockMetadataWithNotify(par3World, x, y, z, 2); break; case 1: ReikaWorldHelper.legacySetBlockMetadataWithNotify(par3World, x, y, z, 1); break; case 2: ReikaWorldHelper.legacySetBlockMetadataWithNotify(par3World, x, y, z, 3); break; case 3: ReikaWorldHelper.legacySetBlockMetadataWithNotify(par3World, x, y, z, 0); break; } return true; }
-
Do what I do and use an item to place the blocks (look at ItemBlock or ItemRedstone). Use the item damage value in a switch() statement and place the block you want accordingly. This also allows you to set metadata and TileEntity data as needed. Sample code (do not simply copy and paste it, as it uses some of my own functions from my API): public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int x, int y, int z, int side, float par8, float par9, float par10) { if (!ReikaWorldHelper.softBlocks(par3World.getBlockId(x, y, z)) && par3World.getBlockMaterial(x, y, z) != Material.water && par3World.getBlockMaterial(x, y, z) != Material.lava) { if (side == 0) --y; if (side == 1) ++y; if (side == 2) --z; if (side == 3) ++z; if (side == 4) --x; if (side == 5) ++x; if (!ReikaWorldHelper.softBlocks(par3World.getBlockId(x, y, z)) && par3World.getBlockMaterial(x, y, z) != Material.water && par3World.getBlockMaterial(x, y, z) != Material.lava) return false; } AxisAlignedBB box = AxisAlignedBB.getBoundingBox(x, y, z, x+1, y+1, z+1); List inblock = par3World.getEntitiesWithinAABB(EntityLiving.class, box); if (inblock.size() > 0) return false; if (!par2EntityPlayer.canPlayerEdit(x, y, z, 0, par1ItemStack)) return false; else { if (!par2EntityPlayer.capabilities.isCreativeMode) --par1ItemStack.stackSize; ReikaWorldHelper.legacySetBlockWithNotify(par3World, x, y, z, mod_RotaryCraft.engine.blockID); TileEntityEngine eng = (TileEntityEngine)par3World.getBlockTileEntity(x, y, z); if (eng != null) { par3World.playSoundEffect(x+0.5, y+0.5, z+0.5, "step.stone", 1F, 1.5F); eng.type = EnumEngineType.setType(par1ItemStack.getItemDamage()); } } int i = MathHelper.floor_double((double)((par2EntityPlayer.rotationYaw * 4F) / 360F) + 0.5D); while (i > 3) i -= 4; while (i < 0) i += 4; switch (i) { case 0: ReikaWorldHelper.legacySetBlockMetadataWithNotify(par3World, x, y, z, 2); break; case 1: ReikaWorldHelper.legacySetBlockMetadataWithNotify(par3World, x, y, z, 1); break; case 2: ReikaWorldHelper.legacySetBlockMetadataWithNotify(par3World, x, y, z, 3); break; case 3: ReikaWorldHelper.legacySetBlockMetadataWithNotify(par3World, x, y, z, 0); break; } return true; }
-
That only works on block updates.
-
That only works on block updates.
-
Try a TileEntity and using its updateEntity().
-
Crazy crafting recipe request - two outputs, 4 billion combinations
Reika replied to Reika's topic in Modder Support
...How does that help me here? -
Crazy crafting recipe request - two outputs, 4 billion combinations
Reika replied to Reika's topic in Modder Support
I would need someone to teach me how to do that. I assume you're using eclipse. In your project explorer right-click, select new->Class. Under Interfaces add IRecipe. That will create a class for you. Then you can register it with GameRegistry.addRecipe(new YourRecipe()); The method names in IRecipe are pretty self-explanatory. Every other time I have seen someone mention implementing IRecipe, they actually meant writing my own version. That is why I thought this was harder than it is. Also, how to modify the metadata of (and not consume) the other item? -
Crazy crafting recipe request - two outputs, 4 billion combinations
Reika replied to Reika's topic in Modder Support
I would need someone to teach me how to do that.