Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Choonster

Moderators
  • Joined

  • Last visited

Everything posted by Choonster

  1. ITickable s have to be registered for Minecraft to tick them. This is done automatically for TileEntities , but you can register other tickables using MinecraftServer#registerTickable . [nobbc]Like this[/nobbc]
  2. If you have a single canvas Block and store the IBlockState it's imitating in the TileEntity , you need to override Block#getExtendedState to return an extended state with the PAINTED_BLOCK property set to the imitated IBlockState (retrieved from the TileEntity at that position). If you have one canvas Block per IBlockState , you don't need the extended state at all; just get the imitated IBlockState directly from the canvas Block . In CanvasBlockModelFactory#handleBlockState , retrieve the imitated IBlockState from the extended state or from the Block and create the model using it.
  3. Create a ResourceLocation or ModelResourceLocation with the new operator like you would any other object. A ResourceLocation consists of a resource domain and a resource path. There are two public constructors: One that takes a single string in the format "<domain>:<path>" One that takes the domain and path as two separate strings ModelResourceLocation extends ResourceLocation and adds a variant. There are three public constructors: One that takes a single string in the format "<domain>:<path>#<variant>" (the variant is optional and defaults to normal ) One that takes a ResourceLocation for the domain and path and a string for the variant One that takes a string in the format "<domain>:<path>" for the domain and path and a string for the variant The domain is the name of the assets folder to look in, usually your mod ID (i.e. the domain minecraft maps to assets/minecraft). If you don't specify a domain, it defaults to minecraft . ModelBakery.registerVariantNames tells Minecraft to load the specified models. It expects <path> to be the name of your model, which either maps to the item model assets/<domain>/models/item/<path>.json (this is the first priority) or the model specified by the variant with name <variant> in the blockstates file assets/<domain>/blockstates/<path>.json (this is added by Forge and only used when the item model wasn't found). If you provide a ResourceLocation , the variant will be inventory . The model will be stored using the provided ModelResourceLocation as the key. ModelLoader.setCustomModelResourceLocation and ModelLoader.setCustomMeshDefinition tell Minecraft which model to use for the Item , using the provided ModelResourceLocation as the key.
  4. Use ModelLoader.setCustomModelResourceLocation or ModelLoader.setCustomMeshDefinition in preInit instead of ItemModelMesher#register in init. ModelBakery.registerVariantNames takes arguments in the same format as ModelBakery.addVariantName ( "modid:modelName" ), but expects either ResourceLocation s or ModelResourceLocation s instead of String s.
  5. If you use ItemColored for the block's item form, Item#getColorFromItemStack is overridden to call Block#getRenderColor with the state corresponding to the item metadata.
  6. World#setBlockState and World#getBlockState only operate on property values that are stored in metadata. If you want to store more than 16 unique value combinations, you need to store the data in a TileEntity (or derive it from the location, e.g. neighbouring blocks) and then retrieve it in Block#getExtendedState / Block#getActualState .
  7. You're returning true (item is valid for slot) when there's already an item of that type in the inventory and false (item isn't valid for slot) when there isn't.
  8. Use ModelLoader.setCustomModelResourceLocation / ModelLoader.setCustomMeshDefinition in preInit to set the model used by an Item . This can either be an existing model like minecraft:diamond_sword or your own model that uses the same textures as the existing one ( minecraft:items/diamond_sword ).
  9. ItemStack#getIsItemStackEqual is client-only, using it in common code will crash the dedicated server. If you only care about the Item , use ItemStack#getItem and compare the Item s directly. If you care about the Item and metadata, use ItemStack.areItemsEqual . If you care about the Item , metadata and NBT, use ItemStack.areItemStacksEqual . Nope http://pastebin.com/HkrTfcia That is a NullPointerException .
  10. If you look at assets/minecraft/models/block/grass.json, you'll see that it sets the "tintindex" property for the "up" face of the first element (the base cube) and all faces of the second element (the side overlay). This allows the textures of those faces to be coloured and is passed as the renderPass argument of Block#colorMultiplier(IBlockAccess, BlockPos, int) .
  11. Vanilla handles the FOV modification for the bow in AbstractClientPlayer#getFovModifier , this also fires FOVUpdateEvent .
  12. Do you have missing texture errors in the log? Your model's texture paths don't have a resource prefix, so it's trying to load them from the minecraft domain.
  13. You need to subscribe to FOVUpdateEvent to modify the FOV like the vanilla bow does if the player is using your bow. You can see how I do this here.
  14. Ah, that makes things trickier. You may be able to use ISmartItemModel to render the bar, but I don't know enough about rendering or the model system to help you any further.
  15. Use SlotItemHandler instead of Slot .
  16. For BlockLiquid , metadata 0 is a source block. Forge's Fluid system doesn't specify that fluids must have a source block ( BlockFluidClassic does, but BlockFluidFinite doesn't) , but IFluidBlock#drain should return a FluidStack with FluidContainerRegistry.BUCKET_VOLUME as the amount if a bucket can be filled from the block. Make sure you call IFluidBlock#canDrain first and call IFluidBlock#drain with false as the doDrain argument.
  17. Override Item#showDurabilityBar to return true when the current RF is less than the maximum and Item#getDurabilityForDisplay to return the percentage of the durability bar to fill (i.e. (maxRF - currentRF) / maxRF ).
  18. WorldSavedData is loaded on demand and should be available as soon as the World has been constructed, but TileEntity#readFromNBT is called before the TileEntity exists in any World .
  19. Yes, it's called by Chunk#setBlockIDWithMetadata , which is called by World#setBlock . This is used to place blocks in the world by everything except the initial terrain generation ( BiomeGenBase#genTerrainBlocks ), which deals with raw Block and metadata arrays that later become an actual Chunk . No, the TileEntity is only created after Block#onBlockAdded is called. If you use per-dimension WorldSavedData , you can store the positions of each block instead of the TileEntity objects.
  20. No. That's a static method that takes three arguments and does absolutely nothing. You need to call the getX , getY and getZ methods on the BlockPos you get from the MovingObjectPosition . Calling methods is a very basic concept in Java. If the ray trace doesn't hit anything, the returned MovingObjectPosition will be null . If it hits an entity instead of a block, the BlockPos will be null . This means that you need to check that the MovingObjectPositon isn't null and that it hit a block (the MovingObjectPosition#typeOfHit field is MovingObjectPosition.MovingObjectType.BLOCK ) before you try to get the BlockPos from it.
  21. getBlockPos returning null wouldn't cause an error on that line. The error is happening because the value you're calling getBlockPos on ( objectMouseOver ) is null .
  22. You can probably take a similar approach to the one I recommended in this thread.
  23. Do you understand why that's causing an error and how you can solve this? That's definitely not right. I didn't tell you to copy-paste the methods and fields into your own class, I told you to call the existing methods.
  24. This is a NullPointerException , which I explained in a previous post. How about you read that and figure out for yourself what's causing the error? We can't do all of your debugging for you.
  25. That's one of the methods you need to call, yes.

Important Information

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.