Jump to content

JimiIT92

Members
  • Posts

    866
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by JimiIT92

  1. I have a new type of chiseled bookshelf made out of spruce wood, and I want to craft it like regular chiseled bookshelf but with spruce planks and slabs instead. So I've created the crafting recipe like so
     

    {
      "type": "minecraft:crafting_shaped",
      "category": "building",
      "key": {
        "#": {
          "item": "minecraft:spruce_planks"
        },
        "X": {
          "item": "minecraft:spruce_slab"
        }
      },
      "pattern": [
        "###",
        "XXX",
        "###"
      ],
      "result": {
        "item": "mineworld:spruce_chiseled_bookshelf"
      },
      "show_notification": true
    }

    hovewer when I try the crafting the regular chiseled bookshelf is crafted instead. Looking at the assemble method from the recipe the crafting is matching the recipe that takes the planks and slabs tags instead, thus the result.
    Now, I don't want to completely override the recipe, as it is bad practice. The generic recipe should still work for mod compatibility, I just want to craft anotehr item when using some more specific planks and slabs. So how can I force the game to use this more specific recipe instead?

    EDIT:
    I should point out that in the mods.toml file the Forge dependecy ordering is set to AFTER, as pointed out in another similar thread

  2. In my mod I'm dealing with some custom chests and, for the item rendering, I came across the BlockEntityWithoutLevelRenderer to render the item model of the chest inside the inventory.
    Now, everything works, but I've noticed that I have to call an instance of this class in the custom chest item, like so
     

    @Override
    public void initializeClient(final @NotNull Consumer<IClientItemExtensions> consumer) {
      consumer.accept(new IClientItemExtensions() {
        @Override
          public BlockEntityWithoutLevelRenderer getCustomRenderer() {
          return MineWorld.getItemsRenderer();
        }
      });
    }

    where the MineWorld.getItemsRenderer is a method that returns a new instance of my custom BEWLR class, or an existing one if it has been already initialized.
    What got my attention is that if I want to add another item with a custom model I have to add this same method in that item class as well. Is this the optimal approach or there's a better, centralized one? Maybe one that would also prevent me from registering a custom item for the chest, and instead checks for the actual chest block item?

  3. Yeah I've tried doing a custom block that extends LecternBlock and creates a custom LecternBlockEntity, but unfortunately the LecternBlockEntity hardwires the BlockEntityType.LECTERN into the constructor :/ If I do that I can surely solve the issue, as I can link the custom block entity to the LecternRederer class using BlockEntityRenderers, is just that I'm wondering if I can avoid duplicating the class, since it would be harder to mantain in future due to changes.

    As for the book I've already hooked it up on the RightClickBlock event and using the static tryPlaceBook method on the block class itself, so that's not really an issue

    EDIT:
    Ok, I got it, and I feel so dumb to not thought about this earlier. Turns out that all I needed to do is to override the getType method inside the custom block entity

     

    public class MWLecternBlockEntity extends LecternBlockEntity {
    
        public MWLecternBlockEntity(final BlockPos blockPos, final BlockState blockState) {
            super(blockPos, blockState);
        }
    
        @Override
        public @NotNull BlockEntityType<?> getType() {
            return MWBlockEntityTypes.SPRUCE_LECTERN.get();
        }
    }

    And inside the custom block I now instantiate this block entity instead
     

    @Override
            public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
                return new MWLecternBlockEntity(blockPos, blockState);
            }

    This way I don't need to copy the vanilla class and can hook up my custom block entity type to the vanilla render
     

  4. I'm trying to create some lectern blocks, and so far the block itself works. However the rendering of the book doesn't, and by looking at the debugger it seems that the renderer class doesn't get linked to the custom block, even thou I'm not using a custom block class. So I've tried to instead create my own lectern block entity, however the LecternBlockEntity constructor doesn't allow to change the blockentitytype (is hardcoded into the constructor itself), so if I had to do this I'd have to basically clone the entire class, which is something I want to avoid.

    This is how I register the block
     

    public static final RegistryObject<Block> SPRUCE_LECTERN = RegisterHelper.registerBlock("spruce_lectern", () -> new LecternBlock(PropertyHelper.copyFromBlock(Blocks.LECTERN)));

    You can see the full implementation here to check what the helper methods does: https://github.com/JimiIT92/MineWorld/blob/master/src/main/java/org/mineworld/core/MWBlocks.java#L1183

    I've also already created the block entity and the rendering like so
     

    public static final RegistryObject<BlockEntityType<LecternBlockEntity>> SPRUCE_LECTERN = RegisterHelper.registerBlockEntity("spruce_lectern", LecternBlockEntity::new, MWBlocks.SPRUCE_LECTERN);
    
    //rendering
    BlockEntityRenderers.register(SPRUCE_LECTERN.get(), LecternRenderer::new);

    You can also see this here: https://github.com/JimiIT92/MineWorld/blob/master/src/main/java/org/mineworld/core/MWBlockEntityTypes.java#L19

     

    So how can I attach the vanilla block entity to my custom block? Or at least make so that the custom lectern block will use the custom block entity type, but without copy/pasting the entire class, if is even possible?

  5. If you mean the CreativeModeTabEvent.Register event, to register your own tab, you need to create a listener on the mod bus

    @Mod.EventBusSubscriber(modid = "your_mod_id", bus = Mod.EventBusSubscriber.Bus.MOD)
    public class CreativeTabEvents {
      
      @SubscribeEvent
      public static void onRegisterCreativeTabs(final CreativeModeTabEvent.Register event) {
    
    	event.registerCreativeModeTab(new ResourceLocation("your_mod_id", "tab_name"),
                    builder -> builder
                            .icon(() -> new ItemStack(MyModItems.MyItem))
                            .title(Component.translatable("itemGroup." + "your_mod_id" + "." + name)) //you are not forced to this syntax, but it's pretty common
                            .build());
      }
    }

    Assuming that MyModItems.MyItem is an item in a class of your mod that has all the items (of course you can set it to whatever item or block you want, even vanilla ones).

    If, instead, you want to add items to your creative tab, you need to listen to the CreativeModeTabEvent.BuildContents event, in a similar way. In here you want to check which tab is being populated (event.getTab()) and, if is your tab, add as many item stacks as you want using event.acceptAll(itemStacks) method
     

    @SubscribeEvent
      public static void onTabBuildContents(final CreativeModeTabEvent.BuildContents event) {
    	final CreativeModeTab tab = event.getTab();
      	if(tab.equals(MY_CREATIVE_TAB)) {
          	event.acceptAll(List.of(
          		new ItemStack(MyModItems.MyItem),
            	new ItemStack(MyModItems.MySecondItem)
            	...
          ));
        }
      }

    Of course you need to have reference to your tab, so when you register it during the CreativeModeTabEvent.Register event make sure to store the registered tab into a variable so you can use it later on to add items to it.

    You can see how I handle my tabs here to get an idea: https://github.com/JimiIT92/MineWorld/blob/master/src/main/java/org/mineworld/core/MWTabs.java

  6. In my mod I'm making so that if the player tries to place some glass panes while sneaking it will be placed another block (a horizontal glass pane). To do so I'm listening to the block place game event and so far everything works. However for a split fraction you can see the vanilla glass pane before it gets replaced by the mod block. Is there any way to prevent this and instead just straight forward place the mod block without placing the vanilla block and then the modded one?

    You can see how I replace the block here:
    https://github.com/JimiIT92/MineWorld/blob/master/src/main/java/org/mineworld/event/GameEventListener.java#L40


    By the way I've also tried listening to the BlockEvent.EntityPlaceEvent, cancelling and then set my own block, but that didn't worked at all (and not cancelling the event would produce the same result where you can see the placed block before is replaced) 

  7. I think I figured out what the problem is: the leash knot entity type has the noSave() attribute set
     

    public static final EntityType<LeashFenceKnotEntity> LEASH_KNOT = register("leash_knot", EntityType.Builder.<LeashFenceKnotEntity>of(LeashFenceKnotEntity::new, MobCategory.MISC).noSave().sized(0.375F, 0.5F).clientTrackingRange(10).updateInterval(Integer.MAX_VALUE));

    What I've tried is to create a custom entity that extends the LeashFenceKnotEntity class and when registering it I removed the noSave attribute, and sure enough it worked: the leash stayed through world reloads.
    But that raises another question: can I remove this attribute from the vanilla entity? Since having to create a custom entity imply that I have to replace all vanilla leash knots with custom ones when they are added (which is not optimal I guess)

  8. First thing first: don't be rude to others just because they just told you a basic simple rule, that is even written in the top section of every page: **1.12, and every version prior to 1.18, is no longer supported**. That means that is very unlikely that some would come to help, simply because the version is too old and many things has changed, so to give a correct answer someone should remember how things works in 1.12.2, which is something typically none would do.

    Second: use the appropriate formatting tools when writing posts.
    Third: if you really want to get some help you need to provide more context/source to your answer. And for the code part use something like GitHub so it's way easier to look at your code and identify the actual problem. You've also mentioned a video, so it would also be helpful to link the video you mentioned to see if it is even correct in the first place.

    All that being said, you should have an error in the debugger console pointing out why your block isn't loading (maybe there's an error in some of the files? The mod id is wrong?). Post that error (using the spoiler tag) so we can actually see what the error is (I'm not going to setup a 1.12.2 dev env just for this...) 

  9. I want to make the player be able to attach a leash to a fence without a mob leashed to it.

    So essentially have a fence persisting like this
    t9GOX83.png

    However when I realod the world the leash knot is gone, and I don't understand why (I know it's a vanilla feature, but even looking at the entity code I can't find out why it breaks so I can override it).

    What I've tried so far is to intercept the EntityLeaveLevelEvent, but that seems to not be firing when reloading the world and removing the entity.
    So what is actually been fired when the lead disappear, so I can prevent it? Where should I look into?

  10. I'm making some stained glass slabs, and by doing so, in the blockstates file, I reference the minecraft full block model for the double slab variant

    {
      "variants": {
        "type=bottom": {
          "model": "mineworld:block/pink_stained_glass_slab"
        },
        "type=double": {
          "model": "minecraft:block/pink_stained_glass"
        },
        "type=top": {
          "model": "mineworld:block/pink_stained_glass_slab_top"
        }
      }
    }

    however the double slab renders as a solid cube in game (while the bottom and top slabs renders correctly since I added the render_type: translucent inside the model JSON file

    SqBVHdo.png

    For reference this is how I create the slab block (nothing too crazy)

    new SlabBlock(BlockBehaviour.Properties.copy(Blocks.PINK_STAINED_GLASS)).requiresCorrectToolForDrops())

    You can also see the full source here: https://github.com/JimiIT92/MineWorld/blob/master/src/main/java/org/mineworld/core/MWBlocks.java#L1039

    So what am I missing here that causes this incorrect rendering?

  11. I got this when trying to launch my mod in IntelliJ. Looks like the gradle plugin has temporarly (I hope) gone

    org.gradle.api.plugins.UnknownPluginException: Plugin [id: 'net.minecraftforge.gradle', version: '5.1.+'] was not found


    EDIT:

    From the Forge discord

     

    Our maven server (https://maven.minecraftforge.net/) which hosts all project files and downloads, is currently experiencing a fault leading to a Gateway Timeout.
    
    We are aware of the issue, and are currently working to fix it.
    
    Please stand by.
    
    In the meantime, you can enable Gradle Offline mode (https://www.baeldung.com/gradle-offline-mode) to use artifacts cached without hitting the maven.

    These messages were sent around 2 hours ago, so I guess we'll just wait or work in offline mode if you really need

  12. On 4/18/2023 at 1:43 AM, warjort said:

    It looks like you can create your own FeatureFlagRegistry with its own "universe".

    That was exactly what I was looking into, but can't seem to make it work properly at all. Even trying to register a Feature Flag using a different "universe" than main completely brokes the game. So yeah, I guess config file is the way to go

  13. I'm wondering if it is possible (or is planned for 1.20) for a mod to create their own custom feature flags. I know that config files are a thing and should probably be used, but it would also be cool if you can have some features of your mod under a feature flag, allowing the player to choose which ones to have inside a world (just like vanilla feature flags).

    I've tried using the vanilla implementation
     

    public static final FeatureFlag MY_FEATURE_FLAG = new FeatureFlagRegistry.Builder("main").create(new ResourceLocation("modid", "my_feature_flag"));

    and providing the feature flag to the block properties inside the requiredFeatures method, but unfortunately the game crashes as soon as it loads up with the following error

    Exception caught during firing event: Mismatched feature universe, expected 'main', but got 'main'

    Full crash report here: https://pastebin.com/1NtaAeeM

    And you can see where I create a Feature Flag here: https://github.com/JimiIT92/MineWorld/blob/master/src/main/java/org/mineworld/core/MWFeatureFlags.java

    So I don't know if I'm actually doing something wrong or is just something that is currently impossible to do

  14. I'm trying to make some copper block variants and I want them to act like regular blocks, so over time they oxidize, they can be waxed with honeycomb and can be scraped with an axe.
    Now, doing the blocks and making them work this way isn't really a problem (you can see a WIP implementation here: https://github.com/JimiIT92/MineWorld/blob/master/src/main/java/org/mineworld/block/IMWWeatheringBlock.java), however

    as you might guess I've duplicated the WeatheringCopper interface from vanilla Minecraft and added my own logic to make it work with my custom block.

    That's because what I've originally tried is to add values to the NEXT_BY_BLOCK map inside the FMLCommonSetupEvent, however that is an Immutable Map, and as such I can't add values to it (I get an UnsupportedOperationException if I try to do that).
    In a similar way I've also tried to add the waxed variants to the HoneycombItem#WAXABLES map, but again that is immutable.

    So, is there a way to actually modify these maps so you don't have to rewrite the same logic?

  15. 10 minutes ago, warjort said:

    Neither of these has the requiresCorrectToolForDrops() property set.

    In Blocks.java you can see that the Iron door has the requireCorrectToolForDrops() property set
     

    public static final Block IRON_DOOR = register("iron_door", new DoorBlock(BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).requiresCorrectToolForDrops().strength(5.0F).noOcclusion(), BlockSetType.IRON));

    By the way I've also tried to manually set the property myself, so doing like this
     

    BlockBehaviour.Properties.copy(Blocks.IRON_DOOR).requiresCorrectToolForDrops()

    but doesn't work as well.

    The only difference is that vanilla doors doesn't have a tier set, but that doesn't explain why if you add them or a block with the same properties under that requirement it gets ignored

  16. What do you mean about bushes generation? You can always look at vanilla files to see how they works, one thing that comes to my mind when talking about bushes is regarding the jungle patches of leaves that you can find in jungle biomes. You can look at the files for these and copy/edit them to suit your needs

    • Like 1
  17. Tags will be your goto for mod compatiblity. Of course the other mods must know about your tag and should add values to them.

    What you need to do is to create your custom tag using the Forge documentation
    https://docs.minecraftforge.net/en/1.19.2/resources/server/tags/

    Then, when you need to check for a block (I'm assuming you want to see if a block falls inside a list of detectable blocks) you need to use the BlockState#is method.

    For example, let's say you create your tag "mymodid:detectable_blocks" and inside it you have specified the iron_ores or the diamond_ores (by the way you can also reference other tags in it, so if you reference the #forge:ores/iron tag you'll match also modded iron ores).
    When you want to check if a block is part of that tag you need to use the following statement 
     

    blockstate.is(MyTags.DETECTABLE_BLOCKS)

    Assuming that somehwer in your code you have a class called MyTags and inside that class you have your tag defined as DETECTABLE_BLOCKS. 

    Tags might look complicated but in reality they are really easy to use and deal with and of course are the recommended approach to maximimze mod compatibility

    • Thanks 1
×
×
  • Create New...

Important Information

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