Jump to content

TheGreyGhost

Members
  • Posts

    3280
  • Joined

  • Last visited

  • Days Won

    8

Everything posted by TheGreyGhost

  1. Hi Pls show your Main mod class and your CommonProxy class... The server is looking for your CommonProxy class constructor and it can't find it. Did you put @SideOnly(Side.CLIENT) or similar in front of your CommonProxy class declaration? -TGG
  2. Hi It's for sure possible. For each chunk in range, Vanilla compiles either a display list or a vertex buffer object (depending on the game settings). It keeps a list of the chunks which have been compiled and a list of the ones which are still outstanding. A bit of digging through the vanilla code should help you find the list and check whether the chunks you're interested in are still being compiled. I don't have access to my IDE at the moment, but a good place to start is to put a breakpoint in Block.getRenderLayer() and then see where it was called from; this method is used by the code which compiles the display list / VBO. A couple of things that might make it a bit harder. The list is probably private, so you will probably need to use Reflection to access it. Let us know if you need help with that - it's not difficult once you know how; for example here https://github.com/TheGreyGhost/SpeedyTools/blob/master/src/main/java/speedytools/clientside/userinput/KeyBindingInterceptor.java eg this one private static final Field keyCodeField = ReflectionHelper.findField(KeyBinding.class, "keyCode", "field_74512_d"); The second wrinkle is that the compiling of the display lists /VBOs takes place in multiple threads, so if you access the list of chunks being compiled, you have to do it in a thread-safe manner. The vanilla code should show you how. -TGG
  3. Hi TileEntities now need four methods to synchronise client<-->server For example // When the world loads from disk, the server needs to send the TileEntity information to the client // it uses getUpdatePacket(), getUpdateTag(), onDataPacket(), and handleUpdateTag() to do this: // getUpdatePacket() and onDataPacket() are used for one-at-a-time TileEntity updates // getUpdateTag() and handleUpdateTag() are used by vanilla to collate together into a single chunk update packet // Not really required for this example since we only use the timer on the client, but included anyway for illustration @Override @Nullable public SPacketUpdateTileEntity getUpdatePacket() { NBTTagCompound nbtTagCompound = new NBTTagCompound(); writeToNBT(nbtTagCompound); int metadata = getBlockMetadata(); return new SPacketUpdateTileEntity(this.pos, metadata, nbtTagCompound); } @Override public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) { readFromNBT(pkt.getNbtCompound()); } /* Creates a tag containing the TileEntity information, used by vanilla to transmit from server to client */ @Override public NBTTagCompound getUpdateTag() { NBTTagCompound nbtTagCompound = new NBTTagCompound(); writeToNBT(nbtTagCompound); return nbtTagCompound; } /* Populates this TileEntity with information from the tag, used by vanilla to transmit from server to client */ @Override public void handleUpdateTag(NBTTagCompound tag) { this.readFromNBT(tag); } That might be contributing to your problem. You can find a working example of TileEntities and GUI (Furnaces, chests) in this tutorial project https://github.com/TheGreyGhost/MinecraftByExample/tree/master see mbe20, mbe30, mbe31 -TGG
  4. Hi It looks to me like you've somehow managed to create an NBTTagCompound "A" which contains an element that has been set to itself (i.e. "A"). So when vanilla tries to copy your "A", it keeps trying to copy all the elements including the one that points to "A", i.e. a recursive loop. I'm not sure how you managed to do that. Personally I would follow hugo's advice and use your debugger to set a breakpoint at onItemTooltip and then check what is happening when you modify the tag. -TGG
  5. Hi That crash usually happens when you've tried to use WorldRenderer before .begin(). I'm not sure why that's happening in your case because I thought that EntityFX are always called with .begin() already set. It might be because you are calling tes.draw(), which EntityFX normally don't do in their render. -TGG PS an example of a custom EntityFX renderer is here; it might help to understand what the parameters for renderParticle mean. https://github.com/TheGreyGhost/MinecraftByExample/tree/1-8-9final Look at the "FlameFX" class in mbe50 package
  6. Hi You're right, you almost never need the server proxy. The only time I've ever used it was when I needed to get the path to the save game files. This is different on the dedicated server than on the combined client. Some folks don't even like the common proxy. Their Client-only code goes in the client proxy, the server proxy has nothing in it, and all the common code gets called directly from the mod class preInit(), init() etc. Personally I think that's a matter of taste, and it really doesn't matter which style you choose. -TGG
  7. Hi I think it shouldn't be too difficult. Just add a few custom methods to your Item class (not the ItemStack) and Item renderer to implement the effects of rotting. For example, instead of using the ItemStack durability bar to indicate rotting, draw a durability bar yourself when rendering the item; or alternatively change the item's appearance another way (eg its colour or a degraded texture). You can work around the ticking problem by storing a timestamp in the Item NBT (or perhaps - as a Capability). I.e. you have a master clock for the world, when an item is created, you copy the value of your master clock as "creation time". Later, whenever you render the item or do something with it, check the clock against the saved "creation time" and calculate the amount of rotting. -TGG
  8. Hi Ah yes, forgot that method existed (I need to go to sleep) . Also assuming that this is your armor this way. I have a vague recollection that method is client side only, i.e. it won't be any good for trampling farmland because that needs to occur on server side only. Worth testing out, should only take a few minutes to code up. Ah what the hell, I'll try it myself now. [00:06:16] [Client thread/INFO]: [minecraftbyexample.testingarea.ItemArmorTickTest:onArmorTick:20]: onArmorTick:client [00:06:16] [server thread/INFO]: [minecraftbyexample.testingarea.ItemArmorTickTest:onArmorTick:20]: onArmorTick:server [00:06:16] [Client thread/INFO]: [minecraftbyexample.testingarea.ItemArmorTickTest:onArmorTick:20]: onArmorTick:client [00:06:16] [server thread/INFO]: [minecraftbyexample.testingarea.ItemArmorTickTest:onArmorTick:20]: onArmorTick:server Guess I was mistaken... -TGG
  9. Hi This tutorial project has an example of Configuration (not just how to use the class, but also how to integrate it into the Forge mod "options" screen that users can change options with). https://github.com/TheGreyGhost/MinecraftByExample see mbe70 -TGG
  10. Hi I think the confusion is because the "TE_INVENTORY_SLOT_COUNT" offset is necessary for the player hotbar and the inventory - which is how the vanilla chest is set up (the GUI shows the player hotbar, the player inventory, and the chest contents). For your own TileEntity it will usually start from zero. // 0 - 8 = hotbar slots (which will map to the InventoryPlayer slot numbers 0 - // 9 - 35 = player inventory slots (which map to the InventoryPlayer slot numbers 9 - 35) // 36 - 44 = TileInventory slots, which map to our TileEntity slot numbers 0 - // Add the players hotbar to the gui - the [xpos, ypos] location of each item for (int x = 0; x < HOTBAR_SLOT_COUNT; x++) { int slotNumber = x; addSlotToContainer(new Slot(invPlayer, slotNumber, HOTBAR_XPOS + SLOT_X_SPACING * x, HOTBAR_YPOS)); } // Add the rest of the players inventory to the gui for (int y = 0; y < PLAYER_INVENTORY_ROW_COUNT; y++) { for (int x = 0; x < PLAYER_INVENTORY_COLUMN_COUNT; x++) { int slotNumber = HOTBAR_SLOT_COUNT + y * PLAYER_INVENTORY_COLUMN_COUNT + x; int xpos = PLAYER_INVENTORY_XPOS + x * SLOT_X_SPACING; int ypos = PLAYER_INVENTORY_YPOS + y * SLOT_Y_SPACING; addSlotToContainer(new Slot(invPlayer, slotNumber, xpos, ypos)); } } // Add the tile inventory container to the gui for (int x = 0; x < TE_INVENTORY_SLOT_COUNT; x++) { int slotNumber = x; addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber, TILE_INVENTORY_XPOS + SLOT_X_SPACING * x, TILE_INVENTORY_YPOS)); } -TGG
  11. Keen, you're welcome no I live in Australia which is a very long way away from both the US and the UK so I've never gone to a Minecon.... -TGG
  12. Hi That's much better I downloaded it and tested, the problem appears to be here, where you renamed a method but forgot to update all the calls to it. In IntelliJ and probably Eclipse as well, there's a rename command which lets you rename a method and will automatically update all code which calls the method as well. Stops you forgetting any. In this case, it was call the base class method which for some reason was causing one of the two tileentities to render single size, and the one next to it to render large. I don't quite understand why because I expected the base method to detect your GlistreChest as well as the chest, but anyway it appears to have fixed the problem. /** * Performs the check for adjacent chests to determine if this chest is double or not. */ public void checkForAdjacentChests() { if (!this.adjacentChestChecked) { this.adjacentChestChecked = true; this.adjacentChestXNeg = this.getAdjacentChest(EnumFacing.WEST); //changed this.adjacentChestXPos = this.getAdjacentChest(EnumFacing.EAST); //changed this.adjacentChestZNeg = this.getAdjacentChest(EnumFacing.NORTH); //changed this.adjacentChestZPos = this.getAdjacentChest(EnumFacing.SOUTH); //changed } } FYI there is another bug - double chests disappear when you look at them out of the corner of your eye. You need to override TileEntityGlistreChest:: @SideOnly(Side.CLIENT) public net.minecraft.util.AxisAlignedBB getRenderBoundingBox() { net.minecraft.util.AxisAlignedBB bb = INFINITE_EXTENT_AABB; Block type = getBlockType(); if (type == Blocks.enchanting_table) { bb = new net.minecraft.util.AxisAlignedBB(getPos(), getPos().add(1, 1, 1)); } else if (type == Blocks.chest || type == Blocks.trapped_chest) // only works for vanilla chests, you need to do similar for your chest { bb = new net.minecraft.util.AxisAlignedBB(getPos().add(-1, 0, -1), getPos().add(2, 2, 2)); } For example /** Return an appropriate bounding box enclosing the TESR * This method is used to control whether the TESR should be rendered or not, depending on where the player is looking. * The default is the AABB for the parent block, which might be too small if the TESR renders outside the borders of the * parent block. * If you get the boundary too small, the TESR may disappear when you aren't looking directly at it. * @return an appropriately size AABB for the TileEntity */ @SideOnly(Side.CLIENT) @Override public AxisAlignedBB getRenderBoundingBox() { // if your render should always be performed regardless of where the player is looking, use infinite AxisAlignedBB infiniteExample = INFINITE_EXTENT_AABB; // our gem will stay above the block, up to 1 block higher, so our bounding box is from [x,y,z] to [x+1, y+2, z+1] AxisAlignedBB aabb = new AxisAlignedBB(getPos(), getPos().add(1, 2, 1)); return aabb; } -TGG
  13. Hi BoneMeal is a dye, believe it or not... Have a look in ItemDye#applyBonemeal() -TGG
  14. Hi Nearly all the files are missing from the repo so I can't compile and run it. You need to put the entire project on GitHub, similar to this https://github.com/TheGreyGhost/MinecraftByExample If you're not already using GitHub or similar I recommend you spend a few hours learning about it because it will be a huge help to make sure your code is backed up and you have good control of different versions. IntelliJ in particular is very easy to integrate with GitHub. In the meantime you could zip your entire src and resources folders instead and add that, that would also be enough for me to work with. -TGG
  15. Because ITileEntityProvider is an outdated API. It will not give you the IBlockState , instead it will give you the raw metadata value, which is not very useful. So in other words, at some point in the future if Raycomms needs to know the IBlockState when creating his TileEntity, or if the ITileEntityProvider is removed, he will need to change it. To me that is a good reason to change it later, not now. Enough vanilla and forge stuff breaks at every upgrade that personally I don't think trying to get ahead of the curve is the best use of a developer's time. Having said that, I also agree that switching from ITileEntityProvider and overriding the two necessary methods in Block shouldn't break existing saves. @Draco I think you're probably right and @Override would show the problem @Override public TileEntity createTileEntity(World world, IBlockState state) @Override public boolean hasTileEntity(IBlockState state) -TGG
  16. Hi XFactHD Why do you say that? I think you're probably right that it's not necessary to implement ITileEntityProvider, but if Ray already has implemented it, why should (s)he change it? -TGG
  17. Hi > Thanks for the answer TGG, by the way, you have really nice tutorials from which I learned a lot Keen, glad you found them useful What I mean by 'stress test' is testing your code with difficult conditions - like high latency, complicated animation, high server CPU load, that sort of thing. Let me know how it goes? It sounds very interesting. -TGG
  18. Hi Could you put your code on GitHub? I'll fork it and see if I can recreate the problem. -TGG
  19. Hi I think your option 1 is the best bet for live action stuff and probably the most resistant to network lag. However if you're actually aiming for a machinima rendering that doesn't need to be in real time, you might be better off locking the ticks between client and server eg with a handshaking, to ensure there is never any desynchronisation. I don't think the update-tick-count resynchronise is likely to help much with lag / judder. If you are just dropping frames now and again, it might work if you can assume a fairly constant network latency that you can correct for. You could perhaps improve it by buffering ahead with timestamps, for example the server runs its ticks strictly according to the timestamps compared to the system clock, and the same on the client; but I think this would still rather sensitive to network delay. I think the best answer will probably depend on exactly what you want to achieve with the playback and probably the best way to find the answer is to code it a few different ways and stress test it. -TGG
  20. Hi You could try looking at this tutorial example, it does pretty much exactly what I think you're looking for (draws a base block and a renderer as well) https://github.com/TheGreyGhost/MinecraftByExample see mbe21 -TGG
  21. Oh, I mean- please post your Entity class and your Entity Renderer class. -TGG
  22. Hi The @SideOnly(Side.SERVER) probably aren't doing what you think they are. Side.Server means "load this class only when installed in a dedicated server". If you need these classes in a local server (when the user is doing single player) then they won't be there. Apart from that I don't see an obvious problem. What are the symptoms? I.e. you install your mod on the server, connect to it with a vanilla Forge client, and you get an error message? If so what is it? -TGG
  23. Hi Show your main mod class? -TGG
  24. Hi It sound to me like you have two TileEntities rendering instead of one: 1) the one you placed originally 2) the second one you placed First TileEntity renders a small chest. Second TileEntity renders a large chest over the top of the first one. I suggest putting something like System.out.println("render pos:" + te.getPos() + " size:" + (size ? "large" : "small")) into your code to see what's going on -TGG
  25. Thanks, that's useful to know. When did they change that? (added the ability to use previous version #, I mean)? Still using ye olde IRC interface I see -TGG
×
×
  • Create New...

Important Information

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