Jump to content

Reika

Members
  • Posts

    228
  • Joined

  • Last visited

Everything posted by Reika

  1. First thing to check - is it being placed on both server and client, or client only (which would cause the behavior you describe)?
  2. It is getIcon. My code (which works) to prove it: @Override public Icon getIcon(int s, int meta) { return this.icons[meta][s]; } @Override public void registerIcons(IconRegister par1IconRegister) { for (int i = 0; i < 6; i++) for (int j = 0; j < 4; j++) this.icons[j][i] = par1IconRegister.registerIcon("RotaryCraft:steel"); icons[0][4] = par1IconRegister.registerIcon("RotaryCraft:borer_front"); icons[1][5] = par1IconRegister.registerIcon("RotaryCraft:borer_front"); icons[3][2] = par1IconRegister.registerIcon("RotaryCraft:borer_front"); icons[2][3] = par1IconRegister.registerIcon("RotaryCraft:borer_front"); icons[0][5] = par1IconRegister.registerIcon("RotaryCraft:borer_back"); icons[1][4] = par1IconRegister.registerIcon("RotaryCraft:borer_back"); icons[3][3] = par1IconRegister.registerIcon("RotaryCraft:borer_back"); icons[2][2] = par1IconRegister.registerIcon("RotaryCraft:borer_back"); }
  3. This is entirely correct. You are aware of what static does in Java, yes? Blocks behave as if every variable was static. So if you set a variable property with a method, all blocks have their instance change to the "last written value". As a rather amusing test, you can try registering a TileEntity with Block ID 1 (so that when the game loads, all stone is given a TE). Do this with Task Manager open to the performance tab and watch your RAM usage go up faster than gas prices for Christmas break.
  4. Did you try the method I use in the packetHandler (where I get both world and ws)?
  5. Is there a way to lock the game controls (at the very least, all mouse controls, including "move-to-look", on demand, without using coremods/ASM?
  6. Containers are only loaded server-side, so how I could get a disparity within itself is beyond me. But the GUI is client side! (And the tile entity is on both) The GUI works fine. The item slots (that is, what index slots correlate to what index in inventory[]) are controlled by the Container alone.
  7. You need a packet handler; the Forge tutorials have one such tutorial. Basically, from the "source" you need to send a 132TileEntityData packet, and your packetHandler needs to act accordingly. Here is how I do it (this is a GUI controlling a TE variable, but the principle is the same). Also note you need to make your mod "listen" to a channel at the top of your main mod class, like this: channels={"RotaryCraftData"}, packetHandler = PacketHandler.class) GUI: public void sendPacket(int a) { ByteArrayOutputStream bos = new ByteArrayOutputStream(20); // 5 ints DataOutputStream outputStream = new DataOutputStream(bos); try { //ModLoader.getMinecraftInstance().thePlayer.addChatMessage(String.valueOf(drops)); outputStream.writeInt(a); if (a == 19) outputStream.writeInt(omega); if (a == 20) outputStream.writeInt(torque); outputStream.writeInt(coil.xCoord); outputStream.writeInt(coil.yCoord); outputStream.writeInt(coil.zCoord); } catch (Exception ex) { ex.printStackTrace(); } Packet250CustomPayload packet = new Packet250CustomPayload(); packet.channel = "RotaryCraftData"; packet.data = bos.toByteArray(); packet.length = bos.size(); Side side = FMLCommonHandler.instance().getEffectiveSide(); if (side == Side.SERVER) { // We are on the server side. EntityPlayerMP player2 = (EntityPlayerMP) player; } else if (side == Side.CLIENT) { // We are on the client side. EntityClientPlayerMP player2 = (EntityClientPlayerMP) player; PacketDispatcher.sendPacketToServer(packet); } else { // We are on the Bukkit server. } } Corresponding sections of the packetHandler: [...] private TileEntityAdvancedGear adv; private TileEntityAdvancedGear clientadv; @Override public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player) { ep = (EntityPlayer) player; if (packet.channel.equals("RotaryCraftData")) { this.handleData(packet); } } private void handleData(Packet250CustomPayload packet) { DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(packet.data)); int control; boolean drops; int len; int[] data; long longdata = 0; int x,y,z; boolean readinglong = false; //System.out.print(packet.length); try { control = inputStream.readInt(); pack = EnumPackets.getEnum(control); len = pack.getNumberDataInts(); data = new int[len]; readinglong = pack.isLongPacket(); if (!readinglong) { for (int i = 0; i < len; i++) data[i] = inputStream.readInt(); } else longdata = inputStream.readLong(); x = inputStream.readInt(); y = inputStream.readInt(); z = inputStream.readInt(); } catch (IOException e) { e.printStackTrace(); return; } World world = ModLoader.getMinecraftInstance().theWorld; Minecraft m = Minecraft.getMinecraft(); WorldServer ws = m.getIntegratedServer().worldServerForDimension(m.thePlayer.dimension); switch (pack) { [...] case COIL: adv = (TileEntityAdvancedGear)ws.getBlockTileEntity(x, y, z); clientadv = (TileEntityAdvancedGear)world.getBlockTileEntity(x, y, z); if (control == 19) { adv.releaseOmega = data[0]; clientadv.releaseOmega = data[0]; } if (control == 20) { adv.releaseTorque = data[0]; clientadv.releaseTorque = data[0]; } break; [...] } }
  8. There is a method called something like isValidSpawn() in Entity. Use that (override it) and use the world to check the time of day.
  9. For now, forget the tutorial entirely and try to do this by understanding the function of the code itself. Have a look in ContainerChest (or whatever its name may be). See how it is making the slot IDs correspond to their positions, as a function of row and column (i and j)? Referring back to the table I put in my previous post, try to work out how that little piece of code creates such an arrangement. Maybe even try experimenting. As for the IndexOutOfBounds exception, that is what happens when you try to access slots beyond your inventory's size. So if your size was, say, 54, and you used i+16*j, you would crash as soon as you reached i = 6, j = 3, as 3*16+6 = 54, which is invalid. (I assume you understand array function).
  10. Containers are only loaded server-side, so how I could get a disparity within itself is beyond me.
  11. The returned ItemStack is what you are left holding after the method is processed. To decrement a stack, just use ItemStack.stackSize-- and return the new stack (checking for if the new size is zero and nulling if necessary). To remove it entirely, return null.
  12. Use the HashMap. The current key format is likely a pair of numbers (ID and metadata). Change that to use a few (dependent on ingredient count) ItemStacks instead, and then use Map.put((ItemStack arguments), ItemStack output).
  13. You can also fake it pretty well by setting the block bounds dynamically (so that it connects to itself, at least visually). Sample code: @Override public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int x, int y, int z) { this.setBlockBounds(0.33F, 0.2F, 0.33F, 0.67F, 0.53F, 0.67F); float minx = (float)this.minX; float maxx = (float)this.maxX; float miny = (float)this.minY; float maxy = (float)this.maxY; float minz = (float)this.minZ; float maxz = (float)this.maxZ; if (par1IBlockAccess.getBlockId(x-1, y, z) == this.blockID) minx = 0; if (par1IBlockAccess.getBlockId(x+1, y, z) == this.blockID) maxx = 1; if (par1IBlockAccess.getBlockId(x, y-1, z) == this.blockID) miny = 0; if (par1IBlockAccess.getBlockId(x, y+1, z) == this.blockID) maxy = 1; if (par1IBlockAccess.getBlockId(x, y, z-1) == this.blockID) minz = 0; if (par1IBlockAccess.getBlockId(x, y, z+1) == this.blockID) maxz = 1; this.setBlockBounds(minx, miny, minz, maxx, maxy, maxz); }
  14. The problem is in your container file. Note the second argument in the constructor of Slot(). That is the ID of the slot, which corresponds to the array index in the TE inventory. Your current implementation of i+j is neither linear nor unique. That is to say, there are multiple times you will find the same value of i+j (for example 2+4 and 3+3), and as such what you are actually seeing is one slot being represented in multiple GUI instances. Additionally, the diagonal arrangement is because the IDs are not counting as, say, a chest does: 000102030405060708 091010111314151617 181920212223242526 You are instead getting this: 000102030405060708 010203040506070809 020304050607080910 Normally, I would provide the exact code, but this one is so easy and so important to understand that I want you to try to work it out on your own first.
  15. Worth noting before I start is that I have never seen the class MaskForgeRecipes before and if it uses a different structural layout than I am familiar with, my advice may be somewhat inaccurate. Anyways, a hashmap is just a list of objects with a given "key", that is an address. For example, if you declared HashMap map = new HashMap() then added map.put(new ItemStack(Item.diamond.itemID, 1, 0), Block.dirt.blockID), then there would be an object (in this case the ID of a dirt block) stored with the key of a diamond item ID. So if you were to call map.get(Item.diamond.itemID), you would get Block.dirt.blockID. What the hashmap in your recipes file is doing is storing a more complicated structure of this, using a list (are you familiar with Java lists?) of Items as the key, and the output as the object (also a pair of objects, one float experience value and one itemstack).
  16. You hardcode your recipes directly into the Recipes class, in the constructor. Basically call addSmelting a bunch of times, with arguments you choose and design. If you use ItemStacks, like addSmelting(is1, is2...), you can fetch IDs, metadata, and NBT as needed. You see where the canSmelt checks if recipe(inputs) != null? That is how it knows if it is a valid recipe.
  17. I have a related question. Is there a way I can have MCP obfuscate my code and classes as well?
  18. If you use ItemStack arguments in the addSmelting, you can use the metadata property in them. As for containers, they are rather simple. Have a look in the container for the vanilla furnace. Most of that you can ignore for now - just copy and paste it. Now, see where, in the constructor, it has entries addSlotToContainer? That is where it adds the actual slots (the part of the GUI that makes the items "snap" in place). The arguments are the relevant inventory (player or furnace), id (corresponding to the index in the inventory of the TileEntity (eg inventory[6] -> addSlot(--, 6, --, --)), and x and y 2D coordinates. Simply add as many of these as you like wherever you like.
  19. That much becomes clear from my code...did you not see disableLightMap()?
  20. Okay, just use second part of that. int l = world.getLightBrightnessForSkyBlocks(i, j, k, 0); int l1 = l % 65536; int l2 = l / 65536; OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)l1, (float)l2); Also, you can write Tessellator tessellator = Tessellator.instance; and still use your OGL renderer. And as renderer updates frequently, you will have dynamic lighting. Trust me. Again: [*]The tessellator slows everything down when you need to render 40000 points [*]I want no lighting at all - permanent full brightness no matter what [*]My problem is not lighting that is controlled by the environment, but that which seems controlled by camera relative angle and position alone Also, as above, SAP's solution seems to be working.
  21. That works as long as the value is a valid float, but I do not recommend it - it will crash with non-numeric input and is very prone to decimal point errors.
  22. All of that goes in your TileEntity, yes. As for allowing lots of recipes, it is easier to use a Recipes file, much like the default Furnace does. In your TileEntity's smelt function, use the following line to determine the output ItemStack: ItemStack itemstack = RecipesClass.smelting().getSmeltingResult(inventory[0].itemID, inventory[1].itemID); With whatever parameters you see fit (as per number of input items and metadata sensitivity). Here I assume no metadata and two ingredients. And to test whether you have the right recipe, you can largely copy and paste code from the furnace, but the critical thing is this bit: ItemStack itemstack = RecipesGrinder.smelting().getSmeltingResult(inventory[0].itemID, inventory[1].itemID); if (itemstack == null) return false; This checks the result of the ingredients against the recipe file. If the result is null (no matching entry) it returns out and stops the smelting process from occurring. You can largely copy the recipes file itself, but change the constructor (private RecipesClass() {}) to include your own recipes. You may need to change the number or type of parameters on the addSmelting method; using an ItemStack list is the best as it is dynamically sized. Also, did you need aid in Container interface?
  23. Use config.get(category, key, defaultValue) with arguments String, string, double.
  24. [continued] Now for IInventory. That is an interface you implement (notice how the TileEntityFurnace extends TileEntity implements IInventory), which will force you to include a few methods. The names of these are rather self-explanatory, names like getStackInSlot(int i), which gets the ItemStack in slot i of your inventory, and setStackInSlot(int i, ItemStack itemstack), which sets the stack in slot i to itemstack, overwriting its original contents. Others are similarly clear. You can simply copy-and-paste these methods from the Furnace code if you like. Now, notice how the furnace also has updateEntity(). This is called every tick (50 ms), and in the furnace is used to evaluate the contents of the inventory and act appropriately. What you do next depends on what you plan to do with your furnace. If you only plan on having a few recipes for this furnace, you can do is iterate through your inventory, and set a bunch of booleans depending on whether you come across various ingredient items (using getStackInSlot and loops). If all of them come out true (or if the right combination do), then you can call a smelt() method which uses setStackInSlot() as needed, adding to the output and subtracting from the input. If you want a lot of different recipes, there is a shortcut, but it is a bit more complex. If you do intend to do this, I will explain it. Also, you will need to interface with a container and a GUI if you want to use any nonstandard slot layout. Do you need assistance with this as well? Also, to any admins: I apologize for making this two posts, but the forum system was not letting me post one long one.
×
×
  • Create New...

Important Information

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