
Reika
Members-
Posts
228 -
Joined
-
Last visited
Everything posted by Reika
-
From what I can contribute: The reason the no-dual-layer-transparency glitch (eg not seeing water through ice) is a bug in OpenGL (MC's rendering engine) itself - it cannot understand alpha in the traditional manner, so what it is essentially doing is recoloring areas accordingly as you add new render passes with semitransparent textures. Since it automatically also performs culling (not rendering things that are behind others and rendered at the same time, no matter what), that means having two semitransparent things on the same pass will cause only the latter one to be visible. Also, does anyone know if Optifine adds extra render passes like MCPatcher? Finally, yes, the render-on-both-passes trick works - I use it for my TileEntities which are partly transparent and partly opaque, and use "MinecraftForgeClient.getRenderPass() == 1" in the Render files (passing arguments into the Model class' renderAll(...)).
-
Hello, as you can probably tell from the infobox <----- Over there, I am Reika. I am writing the machinery mod "RotaryCraft" (link), and have other mods planned, and would like the Modder status. Given how small my mods are, I do not need a subforum, not for now.
-
I have two items (not blocks) that I want to be able to be crafted together and swap their metadata values (damage values). The problem is, this relies on two abilities I am not sure exist within the recipe system: One, it must have two output items - neither can be consumed (I am fine with destroying one and recreating it, but I do not want to have to do things like edit the player's inventory directly, as that will lead to bugs). Two, and more ominously, it must be simultaneously metadata-independent (works for every combination of values), yet still determine the outputs from said metadata values. This may seem like a simple problem, solvable with a two-layer for loop, but seeing as each item can have metadata up to the limit - 65535 - I do not want to add 4 billion recipes to the game. How would I accomplish this, or is it impossible?
-
My render code is in my TileEntity file. Tessellator var5 = Tessellator.instance; var5.setColorOpaque(255, 0, 0); var5.startDrawing(GL11.GL_LINE_LOOP); var5.addVertex(x, y+1, z); var5.addVertex(x+1, y+1, z); var5.addVertex(x+1, y+1, z+1); var5.addVertex(x, y+1, z+1); var5.draw(); It crashes no matter what combination of start() and Draw() I have - both and only one (and either one).
-
Strange Item Rendering Glitch - Dark Blocks in Inventory
Reika replied to Reika's topic in Modder Support
OK, I have fixed it, but in a very weird way - by making the GL11.glDisable(GL12.GL_RESCALE_NORMAL); line dependent on (par1TileEntity.worldObj != null) (do not stop rescaling normals when in inventory rendering). ...Why does this fix it? -
Strange Item Rendering Glitch - Dark Blocks in Inventory
Reika replied to Reika's topic in Modder Support
So ... does it fix the problem or not If it does, disable the lighting when rendering and enable it when you exit the scope. That is what I did. Also, it does not fix blocks that are "under the cursor" (being moved between slots). -
Strange Item Rendering Glitch - Dark Blocks in Inventory
Reika replied to Reika's topic in Modder Support
After some messing around, using Lighting Disable will fix the problem, but it also makes the blocks look completely wrong (they do not render the shading correctly, and look "overexposed"). -
This has been with Minecraft since 1.2, and they say it will be fixed in 1.5. It is not your mod.
-
Strange Item Rendering Glitch - Dark Blocks in Inventory
Reika replied to Reika's topic in Modder Support
OK, it built and ran without error, but it also had no effect. Sample code: public class RenderHRay extends TileEntitySpecialRenderer { /** The normal small chest model. */ private ModelHRay HRayModel = new ModelHRay(); /** * Renders the TileEntity for the position. */ public void renderTileEntityHeatRayAt(TileEntityHeatRay par1TileEntity, double par2, double par4, double par6, float par8) { int var9; if (par1TileEntity.worldObj == null) { var9 = 0; } else { Block var10 = par1TileEntity.getBlockType(); var9 = par1TileEntity.getBlockMetadata(); if (var10 != null && var9 == 0) { //((BlockHRayBlock1)var10).unifyAdjacentChests(par1TileEntity.worldObj, par1TileEntity.xCoord, par1TileEntity.yCoord, par1TileEntity.zCoord); var9 = par1TileEntity.getBlockMetadata(); } } if (true) { ModelHRay var14; if (true) { var14 = this.HRayModel; this.bindTextureByName("/Reika/RotaryCraft/HRay.png"); } GL11.glPushMatrix(); GL11.glEnable(GL12.GL_RESCALE_NORMAL); GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); GL11.glTranslatef((float)par2, (float)par4 + 2.0F, (float)par6 + 1.0F); GL11.glScalef(1.0F, -1.0F, -1.0F); GL11.glTranslatef(0.5F, 0.5F, 0.5F); int var11 = 0; //used to rotate the model about metadata if (par1TileEntity.worldObj != null) { switch(par1TileEntity.getBlockMetadata()) { case 0: var11 = 0; break; case 1: var11 = 180; break; case 2: var11 = 270; break; case 3: var11 = 90; break; } GL11.glRotatef((float)var11+90, 0.0F, 1.0F, 0.0F); } else { GL11.glEnable(GL11.GL_LIGHTING); } //GL11.glTranslatef(-0.5F, -0.5F, -0.5F); //float var12 = par1TileEntity.prevLidAngle + (par1TileEntity.lidAngle - par1TileEntity.prevLidAngle) * par8; float var13;/* var12 = 1.0F - var12; var12 = 1.0F - var12 * var12 * var12;*/ var14.renderAll(); GL11.glDisable(GL12.GL_RESCALE_NORMAL); GL11.glPopMatrix(); GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); } } public void renderTileEntityAt(TileEntity par1TileEntity, double par2, double par4, double par6, float par8) { this.renderTileEntityHeatRayAt((TileEntityHeatRay)par1TileEntity, par2, par4, par6, par8); } } -
AutoStoring ItemDrops in TileEntity Inventory - Duplication Glitch
Reika replied to Reika's topic in Modder Support
Really? Well, that is interesting. Which leaves me at an even greater loss for an explanation. -
But light value is not metadata-sensitive. It, of all things, should be "static".
-
I tried that before posting here, and the result was no render where I told it to be, and "rays" of corrupted rendering projecting from where I told it to render, corrupting every render in their path: Also, I was plagued with crashes - the tessellator appears to have the following logic within it: *call tess.startDrawing(GL.LINE_LOOP)* *crash from "already tesellating!"* and *do not call start* *add Vertex* *crash from "not tesselating!"*
-
AutoStoring ItemDrops in TileEntity Inventory - Duplication Glitch
Reika replied to Reika's topic in Modder Support
My best guess is that the 2+ TEs are running the absorb code simultaneously, so all get a copy of the entityitem. This makes sense, as they would all detect the item simultaneously, but I have no idea how to fix it. -
Yes, I am sure. If you used TileEntities thats something else. TileEntities exist multiple times. Only the Block exists once. Then explain how I was able to make the same block have different light values dependent on its metadata (multiple values in the world at once) - using vanilla code - and no Tile Entities...
-
Strange Item Rendering Glitch - Dark Blocks in Inventory
Reika replied to Reika's topic in Modder Support
I tried your suggestion: "GL_LIGHTING can not be resolved to a variable". -
AutoStoring ItemDrops in TileEntity Inventory - Duplication Glitch
Reika replied to Reika's topic in Modder Support
package Reika.RotaryCraft; import java.util.List; import java.util.Random; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.src.ModLoader; import net.minecraft.util.AxisAlignedBB; import net.minecraft.world.World; import Reika.DragonAPI.ReikaMathLibrary; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; public class TileEntityVacuum extends TileEntityPowerReceiver implements IInventory { public static final int MINPOWER = 32768; public static final int MAXRANGE = RotaryConfig.maxvacuumrange; public ItemStack[] inventory = new ItemStack[54]; private int tickcount = 0; public Random par5Random = new Random(); public boolean canUpdate() { return true; } public void updateEntity() { if (this.worldObj.isRemote) return; this.getPower4Sided(); this.power = this.torque*this.omega; tickcount++; if (this.power < MINPOWER) return; if (tickcount < 2) return; tickcount = 0; this.suck(this.worldObj, this.xCoord, this.yCoord, this.zCoord); this.absorb(this.worldObj, this.xCoord, this.yCoord, this.zCoord); } public void suck(World world, int x, int y, int z) { AxisAlignedBB box = this.getBox(world, x, y, z); List inbox = world.getEntitiesWithinAABB(EntityItem.class, box); for (int i = 0; i < inbox.size(); i++) { EntityItem ent = (EntityItem)inbox.get(i); double dd = 8.0D; double dx = (this.xCoord - ent.posX) / dd; double dy = (this.yCoord - ent.posY) / dd; double dz = (this.zCoord - ent.posZ) / dd; double ddt = ReikaMathLibrary.py3d(dx, dy, dz); double dd1 = 1.0D - ddt; if (dd1 > 0.0D) { dd1 *= dd1; ent.motionX += dx / ddt * dd1 * 0.2D; ent.motionY += dy / ddt * dd1 * 0.2D; ent.motionZ += dz / ddt * dd1 * 0.2D; if (!world.isRemote) ent.velocityChanged = true; } } } public void absorb(World world, int x, int y, int z) { if (world.isRemote) return; AxisAlignedBB close = AxisAlignedBB.getBoundingBox(this.xCoord, this.yCoord, this.zCoord, this.xCoord+1, this.yCoord+1, this.zCoord+1).expand(0.25D, 0.25D, 0.25D); List closeitems = world.getEntitiesWithinAABB(EntityItem.class, close); //ModLoader.getMinecraftInstance().thePlayer.addChatMessage(String.format("%d", closeitems.size())); for (int i = 0; i < closeitems.size(); i++) { EntityItem ent = (EntityItem)closeitems.get(i); if (ent.delayBeforeCanPickup <= 0) { ItemStack is = ent.getEntityItem(); int targetslot = this.checkForStack(is); // Keep note: the checkForStack may not decr the size of the "real" stack, just // the projected copy inside itself - watch to see if "extra" items appearing if (targetslot != -1) { if (this.inventory[targetslot] == null) this.inventory[targetslot] = new ItemStack(is.itemID, is.stackSize, is.getItemDamage()); else this.inventory[targetslot].stackSize += is.stackSize; } else { return; } //ModLoader.getMinecraftInstance().thePlayer.addChatMessage(String.format("%f", par5Random.nextFloat())); ent.setDead(); //ModLoader.getMinecraftInstance().thePlayer.addChatMessage(String.valueOf(FMLCommonHandler.instance().getEffectiveSide())); //if (FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) { world.playSoundEffect(x+0.5, y+0.5, z+0.5, "random.pop", 0.1F+0.5F*par5Random.nextFloat(), par5Random.nextFloat()); //ModLoader.getMinecraftInstance().thePlayer.addChatMessage("FD2"); //} } } } public int checkForStack(ItemStack is) { int target = -1; int id = is.itemID; int meta = is.getItemDamage(); int size = is.stackSize; int firstempty = -1; for (int k = 0; k < this.inventory.length; k++) { //Find first empty slot if (inventory[k] == null) { firstempty = k; k = inventory.length; } } for (int j = 0; j < this.inventory.length; j++) { if (inventory[j] != null) { if (inventory[j].itemID == id && inventory[j].getItemDamage() == meta) { if (inventory[j].stackSize+size <= is.getMaxStackSize()) { target = j; j = inventory.length; } else { int diff = is.getMaxStackSize() - inventory[j].stackSize; inventory[j].stackSize += diff; is.stackSize -= diff; } } } } if (target == -1) target = firstempty; return target; } public AxisAlignedBB getBox(World world, int x, int y, int z) { int expand = ReikaMathLibrary.extrema((int)(this.power/MINPOWER), MAXRANGE, "min"); AxisAlignedBB box = AxisAlignedBB.getBoundingBox(this.xCoord, this.yCoord, this.zCoord, this.xCoord+1, this.yCoord+1, this.zCoord+1).expand(expand, expand, expand); return box; } /** * Returns the number of slots in the inventory. */ public int getSizeInventory() { return inventory.length; } public static boolean func_52005_b(ItemStack par0ItemStack) { return true; } /** * Returns the stack in slot i */ public ItemStack getStackInSlot(int par1) { return inventory[par1]; } /** * Decrease the size of the stack in slot (first int arg) by the amount of the second int arg. Returns the new * stack. */ public ItemStack decrStackSize(int par1, int par2) { if (inventory[par1] != null) { if (inventory[par1].stackSize <= par2) { ItemStack itemstack = inventory[par1]; inventory[par1] = null; return itemstack; } ItemStack itemstack1 = inventory[par1].splitStack(par2); if (inventory[par1].stackSize == 0) { inventory[par1] = null; } return itemstack1; } else { return null; } } /** * When some containers are closed they call this on each slot, then drop whatever it returns as an EntityItem - * like when you close a workbench GUI. */ public ItemStack getStackInSlotOnClosing(int par1) { if (inventory[par1] != null) { ItemStack itemstack = inventory[par1]; inventory[par1] = null; return itemstack; } else { return null; } } /** * Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections). */ public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { inventory[par1] = par2ItemStack; if (par2ItemStack != null && par2ItemStack.stackSize > getInventoryStackLimit()) { par2ItemStack.stackSize = getInventoryStackLimit(); } } /** * Returns the name of the inventory. */ public String getInvName() { return "Item Vacuum"; } /** * Reads a tile entity from NBT. */ public void readFromNBT(NBTTagCompound par1NBTTagCompound) { super.readFromNBT(par1NBTTagCompound); NBTTagList nbttaglist = par1NBTTagCompound.getTagList("Items"); inventory = new ItemStack[getSizeInventory()]; for (int i = 0; i < nbttaglist.tagCount(); i++) { NBTTagCompound nbttagcompound = (NBTTagCompound)nbttaglist.tagAt(i); byte byte0 = nbttagcompound.getByte("Slot"); if (byte0 >= 0 && byte0 < inventory.length) { inventory[byte0] = ItemStack.loadItemStackFromNBT(nbttagcompound); } } this.torque = par1NBTTagCompound.getInteger("torque"); this.omega = par1NBTTagCompound.getInteger("omega"); } /** * Writes a tile entity to NBT. */ public void writeToNBT(NBTTagCompound par1NBTTagCompound) { super.writeToNBT(par1NBTTagCompound); par1NBTTagCompound.setInteger("torque", this.torque); par1NBTTagCompound.setInteger("omega", this.omega); NBTTagList nbttaglist = new NBTTagList(); for (int i = 0; i < inventory.length; i++) { if (inventory[i] != null) { NBTTagCompound nbttagcompound = new NBTTagCompound(); nbttagcompound.setByte("Slot", (byte)i); inventory[i].writeToNBT(nbttagcompound); nbttaglist.appendTag(nbttagcompound); } } par1NBTTagCompound.setTag("Items", nbttaglist); } /** * Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't * this more of a set than a get?* */ public int getInventoryStackLimit() { return 64; } public void openChest() { } public void closeChest() { } public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { if (worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) != this) return false; return par1EntityPlayer.getDistanceSq((double)xCoord + 0.5D, (double)yCoord + 0.5D, (double)zCoord + 0.5D) <= 64D; } } -
AutoStoring ItemDrops in TileEntity Inventory - Duplication Glitch
Reika replied to Reika's topic in Modder Support
It did not help - duplication is still occurring. That said, this technique is going to fix some glitches with the Fan and PileDriver. -
AutoStoring ItemDrops in TileEntity Inventory - Duplication Glitch
Reika replied to Reika's topic in Modder Support
Sure, it's not slow, but its not the most effective way That seems odd to me. Are you sure your whole updateEntity method only execute on the server? I tried making it server-only, but then the drops, from the player's point of view, just disappear then appear inside the internal inventory. I want the player to see the items being literally sucked into the machine. -
AutoStoring ItemDrops in TileEntity Inventory - Duplication Glitch
Reika replied to Reika's topic in Modder Support
That is odd - I have used that last one a few times and had no problems with it. Then again, I am not doing anything major with it. Also, Server checking and adding entityitem.delayBeforeCanPickup = 10 did help, but it did not completely eliminate the glitch. Also, with multiple vacuums in close proximity, they fight over the drops (expected) but often each one will get a "copy" and this will result in massive duplication. -
AutoStoring ItemDrops in TileEntity Inventory - Duplication Glitch
Reika replied to Reika's topic in Modder Support
This explains the NoSuchMethodError crashes I often get when using it. This stands in direct contradiction of what I have been told - that in 1.3+, it ALWAYS returns true... EDIT: Adding your suggestion has mitigated the problem - ordinary operation no longer duplicates items, but breaking and placing the machine will duplicate or delete items, with greater probability and greater numbers as you do it more rapidly. I am using default furnace drop-on-break code: public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { TileEntityVacuum tileentityVacuum = (TileEntityVacuum)par1World.getBlockTileEntity(par2, par3, par4); if (tileentityVacuum != null) { label0: for (int i = 0; i < tileentityVacuum.getSizeInventory(); i++) { ItemStack itemstack = tileentityVacuum.getStackInSlot(i); if (itemstack == null) { continue; } float f = par5Random.nextFloat() * 0.8F + 0.1F; float f1 = par5Random.nextFloat() * 0.8F + 0.1F; float f2 = par5Random.nextFloat() * 0.8F + 0.1F; do { if (itemstack.stackSize <= 0) { continue label0; } int j = par5Random.nextInt(21) + 10; if (j > itemstack.stackSize) { j = itemstack.stackSize; } itemstack.stackSize -= j; EntityItem entityitem = new EntityItem(par1World, (float)par2 + f, (float)par3 + f1, (float)par4 + f2, new ItemStack(itemstack.itemID, j, itemstack.getItemDamage())); if (itemstack.hasTagCompound()) { entityitem.getEntityItem().setTagCompound((NBTTagCompound)itemstack.getTagCompound().copy()); } float f3 = 0.05F; entityitem.motionX = (float)par5Random.nextGaussian() * f3; entityitem.motionY = (float)par5Random.nextGaussian() * f3 + 0.2F; entityitem.motionZ = (float)par5Random.nextGaussian() * f3; par1World.spawnEntityInWorld(entityitem); } while (true); } } super.breakBlock(par1World, par2, par3, par4, par5, par6); } I added the check-for-item-ready-to-be-picked-up code since writing the original post - that may be causing some of the duplication. Time shall tell. EDIT 2: It did help, but it did not completely eliminate it (adding entityitem.delayBeforeCanPickup = 10). Also, with multiple vacuums in close proximity, they fight over the drops (expected) but often each one will get a "copy" and this will result in massive duplication. -
AutoStoring ItemDrops in TileEntity Inventory - Duplication Glitch
Reika replied to Reika's topic in Modder Support
The code is exactly the same as posted, with the only change being the addition of @SideOnly(Side.SERVER) before absorb(). Also, the motion is not for animation - it is to actually move the items physically closer; there are two bounding boxes - a large "Area of Effect" one and a small "absorb within" one. -
I wish to know this as well - and one step further, how to render a full block from GL11 wireframe tools... Attached is a picture of what I have in mind.
-
Are you sure? I have had my blocks have variables store internal data (like "int dropmeta") which was unique to each block.
-
That would be wasteful. Try adding the onBlockAdded(World, x, y, z) method. This is called whenever the block is added to the world (placed, oregen, setBlockWithNotify...). From there, set 3 variables - x, y, and z. Then, in the blockDestroyedByPlayer (or whatever it is called), you can use those variables.
-
Strange Item Rendering Glitch - Dark Blocks in Inventory
Reika replied to Reika's topic in Modder Support
Will that not affect their renders in-world, though...? And how would that affect rendering of vanilla blocks...?