Jump to content

Choonster

Moderators
  • Posts

    5123
  • Joined

  • Last visited

  • Days Won

    76

Posts posted by Choonster

  1. I'd be curious to know what the proper way to handle records is. I've just realised that my record item hasn't worked since I switched to instantiating registry entries in registry events; because the SoundEvent passed to the constructor doesn't yet exist when RegistryEvent.Register<Item> is fired.

     

    It's possible to override ItemRecord#getSound to return the SoundEvent directly (ignoring the ItemRecord#sound field), but this requires adding the record to the ItemRecord.RECORDS map manually so that Minecraft will display the record name above the hotbar when it's played.

     

    Is there a better way to do this?

  2. I think I know what's going on now. The missing recipe IDs warning isn't from Forge loading the IDs saved with the world, it's from Forge loading the server's IDs into the client's registries.

     

    This means that the server has several recipes that the client doesn't know about, which is probably due to the client and server having different versions of Thermal Foundation installed.

  3. It looks like Forge is complaining because there are recipe IDs saved in your world that no longer exist in Thermal Foundation. The strange thing is, the recipe registry is explicitly configured to not be saved to the disk; so there shouldn't be any saved recipe IDs in the first place (and there aren't in any of my worlds).

     

    Are you using any mods apart from Thermal Foundation/OTG?

     

    Could you please post your world's level.dat file?

  4. 24 minutes ago, anothertime said:

    Thank you!

     

    So, if my MissingMappings  handler chose to remove the old mapping I wan't be able to see it in the data fixer?

     

    Looking at the event and the code around it more closely, I'm not sure you can remove the mapping. I haven't confirmed this, but it looks like the old name and ID remain in the registry even if you choose remap the missing entry. Remapping adds an alias from the old name to the new one that the modder-facing IForgeRegistry methods appear to respect; but the internal ForgeRegistry#getID methods don't appear to.

     

    You may want to confirm this yourself.

  5. I've actually just implemented a DataFixer for this myself, see this commit of TestMod3.

     

    It uses a list of flattening definitions that specify the old registry name and metadata to look for, a function to get the replacement state and a function to modify or remove the saved TileEntity. It then iterates through each block in the chunk NBT looking for ones that match a flattening definition before running the state/TileEntity functions and updating the block.

     

    I also have a separate class (Remapper) that handles the MissingMappings event and tells FML to leave the missing IDs in the save, allowing them to be accessed in the DataFixer.

     

    There might be better ways to do this, but I'm fairly confident that it works.

  6. 1 hour ago, Frontear said:

    I'm curious then, what is the purpose of EntityPlayerMP in the super constructor? I see that EntityPlayerSP is your player, EntityOtherPlayerMP is everyone else on a multiplayer/server connection. What's EntityPlayerMP purpose? Additionally, when should a side check be used?

     

    • EntityPlayerMP is used for all players on the server side.
    • EntityPlayerSP is used for the controlling player on the client side.
    • EntityOtherPlayerMP is used for all other players on the client side.
    • Like 1
  7. This field has been named hasCrashed in the latest MCP mappings, so you should update your mappings to stable_39 (the final mappings version for 1.12). The MCPBot website you linked earlier explains what you need to change in your build.gradle to do this (click on the stable_39 dropdown button and then click "Use in ForgeGradle").

     

    There's no wiki that explains what each field/method does, the closest thing would be the Javadocs of Vanilla fields/methods provided by MCP. These are included in the source code attached to the forgeSrc dependency when you run setupDecompWorkspace. Like field/method names, Javadocs are contributed by the community using MCPBot; so they may not always be 100% accurate or up-to-date.

  8. 3 minutes ago, theishiopian said:

    @Choonster OK, I've got most of it set up, but I have one more question: How does the server know which player sent the packet? Do I have to specify somehow, or will the server somehow be able to tell? Currently, I have an event handler listening for PlayerInteract.LeftClickEmpty, which then sends an empty packet to the server like so:

     

    Core.INSTANCE.sendToServer(new DeflectPacket());

     

    (I defined the networkwrapper instance in the core mod class temporarily, I'll move it to somewhere else later)

     

    The server maintains a network connection for each connected client along with a reference to the server-side player entity. When a packet is received on this connection, the server knows which player sent it and you can access the player through the NetworkContext.

    • Like 1
  9. 8 minutes ago, theishiopian said:

    @Choonster would using the entityID work for players? I need the server to know when a player is left clicking, but the left click event is clientside only, hence the need for packets.

     

    The entity ID should work for players, but it's not actually needed here. The player who sent the packet is available on the server side through the MessageContext, see this example in the documentation for more details.

  10. It looks like the RightClickItem docs are incorrect, since the RightClickBlock docs explicitly mention that the client will try RightClickItem unless the result is SUCCESS:

        /**
         * This event is fired on both sides whenever the player right clicks while targeting a block.
         * This event controls which of {@link net.minecraft.block.Block#onBlockActivated} and/or {@link net.minecraft.item.Item#onItemUse}
         * will be called after {@link net.minecraft.item.Item#onItemUseFirst} is called.
         * Canceling the event will cause none of the above three to be called
         *
         * Let result be a return value of the above three methods, or {@link #cancellationResult} if the event is cancelled.
         * If we are on the client and result is not {@link EnumActionResult#SUCCESS}, the client will then try {@link RightClickItem}.
         *
         * There are various results to this event, see the getters below.
         * Note that handling things differently on the client vs server may cause desynchronizations!
         */

     

    If you perform some action, you should set the event's cancellation result to EnumActionResult.SUCCESS and then cancel the event. This will stop the Vanilla methods from being called and the other event from being fired.

     

    That said, there's no need to use events to handle the right click behaviour of your own Item; just override the appropriate methods in the Item class instead.

    • Like 1
  11. 17 minutes ago, TheRPGAdventurer said:

    Like this

     

    
    	@Override
    	public void fromBytes(ByteBuf buf) {
    		if(buf instanceof PacketBuffer) {
    	    	PacketBuffer packetBuf = (PacketBuffer) buf;
    	    	dragonId = packetBuf.readUniqueId();
    		}
    		controlState = buf.readByte();
    	}
    
    	@Override
    	public void toBytes(ByteBuf buf) {
    		if(buf instanceof PacketBuffer) {
    		  PacketBuffer packetBuf = (PacketBuffer) buf;
    		  packetBuf.writeUniqueId(dragonId);
    		}
    		buf.writeByte(controlState);
    
    	}

     

     

    No. As I said, those ByteBufs aren't PacketBuffers; so that code will never send the unique IDs.

     

    When I say "create a new instance", I mean "use the new operator".

    • Thanks 1
  12. 13 minutes ago, TheRPGAdventurer said:

    Like this? but it crashes, with a classexception

    
    	@Override
    	public void fromBytes(ByteBuf buf) {
    		PacketBuffer packetBuf = (PacketBuffer) buf;
    		dragonId = packetBuf.readUniqueId();
    		controlState = buf.readByte();
    	}
    
    	@Override
    	public void toBytes(ByteBuf buf) {
    		PacketBuffer packetBuf = (PacketBuffer) buf;
    		packetBuf.writeUniqueId(dragonId);
    		buf.writeByte(controlState);
    
    	}

     

     

    The ByteBuf passed to those methods isn't an instance of PacketBuffer, you need to create a new instance of PacketBuffer and pass the ByteBuf to the constructor.

  13. Minecraft normally uses the entity ID (Entity#getEntityId) rather than the unique ID in networking situations (and this is its main purpose). This reduces unnecessary network traffic as the entity ID is a single 32-bit integer (that's actually compressed further) rather than a UUID that's sent as a pair of 64-bit integers.

     

    If you absolutely need to send a UUID, you can wrap the ByteBuf in a PacketBuffer and use PacketBuffer#readUniqueId/PacketBuffer#writeUniqueId to read/write UUIDs.

  14. Are your RGB values actually being synced to the client? I suspect that they're always 0 on the client, so the block is being rendered black.

     

    There's no need for a TESR here at all. If you register a standard JSON model with a tint index (see the wiki), you can then register an IBlockColor that reads the RGB value from the TileEntity and returns it.

  15. HarvestDropsEvent can be called for any block in the game, 99% of which won't have the BlockOldLeaf.VARIANT property in their block state. As you've seen, calling IBlockState#getValue with an invalid property throws an exception.

     

    You need to check the Block itself first, use IBlockState#getBlock to get it and then check that it's equal to Blocks.LEAVES/Blocks.LEAVES2.

     

    16 minutes ago, UM3 F0R TH3 W1N said:

    if(event.getState().getBlock() == Blocks.LEAVES.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.OAK))

    IBlockState#getBlock returns a Block, which will never be equal to an IBlockState. You need to check the Block and the properties in two separate expressions within the if condition.

     

    Edit: It looks like @diesieben07 already explained most of this in your previous threads. Please stop creating new threads for the same topic.

  16. ItemBlock itself isn't suitable for blocks with variants, you need to use a subclass that overrides Item#getMetadata(int) to convert the item metadata to block metadata and calls Item#setHasSubtypes to mark the item as having variants/subtypes. ItemCloth does these and also overrides Item#getTranslationKey(ItemStack) to add the stack's colour as a suffix to the translation key (unlocalised name) so that each colour can have its own translation.

  17. 3 minutes ago, Siqhter said:

    On placing the block, it should be 1 of 16 different dye colors. Also the items in the creative menu should each be their own dye color.

     

    It's not a model issue, because they render when placed, just not with the correct color (they only render in white, which is the first color in the blockstates colors variants). Also the blocks work fine when applied with dyes (the blocks change to their respective color), so it's probably something in a method that I'm not adding. Below are my Block and TileEntity classes, as well as the blockstate file.

     

    This sounds like an issue with the ItemBlock and/or the model registration for the ItemBlock. Please post the code where you instantiate and register the ItemBlock and the code where you register the models for the ItemBlock(or create a repository so that we can see all of your code).

×
×
  • Create New...

Important Information

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