Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

Override Vanilla Blocks class


CaptainDoge
 Share

Recommended Posts

1 hour ago, CaptainDoge said:

What is the best method for overriding a vanilla blocks class? Is there a way to modify a vanilla class to add or change functionality?

Overriding a vanilla block class...? Most vanilla blocks are instances of Block, and those with special functionality use a subclass of Block with the required methods.

Do you mean changing the functionality of a vanilla block? I know nothing about this. Maybe the "reflection" I've been hearing so much about may be useful to you.

Link to comment
Share on other sites

Yes I do mean changing the functionality of a vanilla block by changing this \/ to my own block class

                            "public static final Block STONE = register("stone", new Block(Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(1.5F, 6.0F)));"

Link to comment
Share on other sites

No that is not what you're wanting to do.

You just need to use registry replacements.

Just register your block, using vanilla's name. And it'll be overriden in the game.

  • Like 2

I do Forge for free, however the servers to run it arn't free, so anything is appreciated.
Patreon: http://www.patreon.com/lexmanos
Paypal: http://paypal.me/LexManos

BitCoin: 1Q8rWvUNMM2T1ZfDaFeeYQyVXtYoeT6tTn

Link to comment
Share on other sites

13 minutes ago, CaptainDoge said:

Does my block class have to share the same name as the vanilla class?

No, but it should (must? Not sure if Forge type-checks) extend the original's class, or Bad Things will happen.

Edited by Draco18s

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Because you haveRegistryObject there, then you're using DeferredRegister. Please check if the second parameter to the DeferredRegister constructor is correct. If you intend to replace "minecraft:oak_leaves", the modid to be passed to that constructor should be "minecraft".

 

If you're replacing vanilla blocks and registering your own custom blocks, I suggest either:

  • making two DeferredRegister objects and naming them seperately (preferrably in seperate classes); or
  • registering your vanilla replacements in RegistryEvent.Register (see the docs or a tutorial), and your own blocks in DeferredRegister.
Link to comment
Share on other sites

import com.blocks.exampletest;

import net.minecraft.block.Block;

import net.minecraft.block.SoundType;

import net.minecraft.block.material.Material;

import net.minecraftforge.event.RegistryEvent;

import net.minecraftforge.eventbus.api.SubscribeEvent;

import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber(modid = "minecraft", bus = Mod.EventBusSubscriber.Bus.FORGE)

public class OverrideRegistryHandler

{

     @SubscribeEvent

     public void registerBlocks(RegistryEvent.Register<Block> event)

     {

          event.getRegistry().registerAll 

          ( 

               new exampletest(Block.Properties.create(Material.ANVIL).hardnessAndResistance(0.2F).tickRandomly().sound(SoundType.PLANT).notSolid()) 

          );

     }

}

I tried this syntax. this is what I interpret the docs to be saying is correct, but I don't see how to convey the name of the block I intend to replace

Link to comment
Share on other sites

event.getRegistry().registerAll( 
           new LeafReplacementBlock(Block.Properties.create(Material.LEAVES)).setRegistryName("minecraft:oak_leaves")
      );

You need to call setRegistryName with the registry name of the block you want to replace.

I suggest assigning the new LeafReplacementBlock(...) to a public static field in your class, and then caliing registerAll.

Link to comment
Share on other sites

6 hours ago, sciwhiz12 said:

I suggest assigning the new LeafReplacementBlock(...) to a public static field in your class, and then caliing registerAll.

Do not do this. Do not create registry entities in a static location.

You want a static field referencing a block?
Use @ObjectHolder.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

package com.dev.examplemod.util;

import com.blocks.exampletest;
import com.dev.examplemod.ExampleMod;
import net.minecraft.block.Block;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber(modid = ExampleMod.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE)
public class OverrideRegistryHandler
{

    public Block OAK_LEAVES = new exampletest(Block.Properties.create(Material.ANVIL).hardnessAndResistance(0.2F).tickRandomly().sound(SoundType.ANVIL).notSolid());

    @SubscribeEvent
    public void registerBlocks(RegistryEvent.Register<Block> event)
    {
        event.getRegistry().registerAll
        (
            OAK_LEAVES.setRegistryName("minecraft","oak_leaves")

        );
    }

}

I have read the docs and these posts as thoroughly as my reading comprehension will allow, this code is the result of that. Yet my leaves don't sound like anvils, my only guesses for what the issue might be is the EventBusSubscriber that I copied and pasted from another class. I am not sure what changes I would have to make to the event structure to fire off of the correct event. exampletest extends LeavesBlock and that is all it does I'm not sure if this is important information

Link to comment
Share on other sites

2 hours ago, Draco18s said:

Do not do this. Do not create registry entities in a static location.

You want a static field referencing a block?
Use @ObjectHolder.

Woops. Forgot about @ObjectHolder. Won't happen again.

 

To @CaptainDoge,

  • Your class is registering to the wrong bus; use Bus.MOD.
    • RegistryEvents are fired on the mod-specific event bus.
  • Change your event handling method to static.
    • 6 minutes ago, diesieben07 said:

      @EventBusSubscriber registers the Class object to the event bus, meaning only static subscriber methods will be registered.

       

  • Move the code constructing the Block into the event registerAll, and make a public static final field annotated with @ObjectHolder.
    • Never put your block constructor in an instance field on your event handling class with @EventBusSubscriber. Since you're using @EventBusSubscriber, you'll never get the instance containing your registered block, and any further created instances will make additional, unregistered, and useless instances of your block.

Corrected code:

Spoiler

@Mod.EventBusSubscriber(modid = ExampleMod.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
public class OverrideRegistryHandler
{
    @ObjectHolder("minecraft:oak_leaves")
    public static final Block OAK_LEAVES = null;

    @SubscribeEvent
    public static void registerBlocks(RegistryEvent.Register<Block> event)
    {
        event.getRegistry().registerAll
        (
            new exampletest(Block.Properties.create(Material.ANVIL).hardnessAndResistance(0.2F).tickRandomly().sound(SoundType.ANVIL).notSolid()).setRegistryName("minecraft:oak_leaves")
        );
    }
}

 

 

  • Like 1
Link to comment
Share on other sites

1 minute ago, sciwhiz12 said:

@ObjectHolder("minecraft:oak_leaves")

public static final Block OAK_LEAVES = null;

This is fine, just pointing out that Blocks.OAK_LEAVES will contain the same value, so it isn't really necessary.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

I have implemented these fixes and applied the same logic to registering items and everything seems to work fine until I grow a tree. This suggests to me that the Block is not fully overridden by this method, unless there is a strange exception in the Tree or foliage placer class.

Link to comment
Share on other sites

I have been experimenting a bit and replaced grass_blocks an stone and it causes strange errors

STONE: stone generates fine but caves don't spawn inside the stone

GRASS: grass blocks don't generate instead there is just a lighting glitch and when updated spawns a non-textured block that behaves like grass yet the block still shows up in the creative tab and can be placed like normal

LEAVES: behaves normally when placed by player but will not be generated by growing trees

 

this is the method I am using to register these blocks

 

@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD)
public class RegistryEvents
{
    @ObjectHolder("minecraft:stone")
    public static final Block STONE_BLOCK = null;

    @ObjectHolder("minecraft:grass_block")
    public static final Block GRASS_BLOCK = null;

    @SubscribeEvent
    public static void onBlocksRegistry(final RegistryEvent.Register<Block> blockRegistryEvent)
    {
        blockRegistryEvent.getRegistry().registerAll
        (
            new Block(Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(5.0f, 6.0F).sound(SoundType.STONE)).setRegistryName("minecraft:stone"),
            new GrassBlock(Block.Properties.create(Material.ORGANIC).tickRandomly().hardnessAndResistance(1.5F).sound(SoundType.PLANT)).setRegistryName("minecraft:grass_block")
        );
    }

    @ObjectHolder("minecraft:stone")
    public static final Item STONE_ITEM = null;

    @ObjectHolder("minecraft:grass_block")
    public static final Block GRASS_ITEM = null;

    @SubscribeEvent
    public static void registerItems(RegistryEvent.Register<Item> event)
    {
        event.getRegistry().registerAll
        (
            new BlockItemBase(STONE_BLOCK, ItemGroup.BUILDING_BLOCKS).setRegistryName("minecraft:stone"),
            new BlockItemBase(GRASS_BLOCK, ItemGroup.BUILDING_BLOCKS).setRegistryName("minecraft:grass_block")
        );
    }
}

This is the  definition of BlockItemBase

package com.Blocks;

import net.minecraft.block.Block;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;

public class BlockItemBase extends BlockItem
{
    public BlockItemBase( Block blockIn, ItemGroup itemGroupIn)
    {
        super(blockIn, new Item.Properties().group(itemGroupIn));
    }
}

 

It seems to me that there is another step in registration that I am missing, unless minecraft's generation code surrounding these blocks is inflexible which I hop isn't the case

Link to comment
Share on other sites

1. Don't use bases. They are an abuse of inheritance.

2. Try replacing the constant values of items and block in Items and Blocks class respectively with your custom instances. I haven't met this exact problem before, but I guess it is caused by vanilla's still trying to use the original values from those two classes.

Some tips:

Spoiler

Modder Support:

Spoiler

1. Do not follow tutorials on YouTube, especially TechnoVision (previously called Loremaster) and HarryTalks, due to their promotion of bad practice and usage of outdated code.

2. Always post your code.

3. Never copy and paste code. You won't learn anything from doing that.

4. 

Quote

Programming via Eclipse's hotfixes will get you nowhere

5. Learn to use your IDE, especially the debugger.

6.

Quote

The "picture that's worth 1000 words" only works if there's an obvious problem or a freehand red circle around it.

Support & Bug Reports:

Spoiler

1. Read the EAQ before asking for help. Remember to provide the appropriate log(s).

2. Versions below 1.11 are no longer supported due to their age. Update to a modern version of Minecraft to receive support.

 

 

Link to comment
Share on other sites

Just to be sure this

Spoiler

    public static final Block GRASS_BLOCK = new GrassBlock(Block.Properties.create(Material.ORGANIC).tickRandomly().hardnessAndResistance(1.5F).sound(SoundType.PLANT)).setRegistryName("minecraft:grass_block");

 

is what is meant by 

6 hours ago, DavidM said:

replacing the constant values of items and block in Items and Blocks class respectively with your custom instances

either way didn't seem to make a difference

 

I have removed the use of base classes, this \/ is what I have replaced it with I am not sure if this is correct but the items seem to behave properly

Spoiler

            new BlockItem(STONE, new Item.Properties().group(ItemGroup.BUILDING_BLOCKS)).setRegistryName("minecraft:stone"),

 

Despite all these changes I am still getting the same behavior, after some experimentation I have found that some world gen works properly

 

World gen that works:

Lakes-Lava and water above and under ground

Mine shafts

normal stone world gen

all ores

dirt, gravel, andesite, diorite, granite patches

 

World gen that doesn't work:

caves in stone 

grass blocks

sand

 

Attached picture displays strange behavior 

ToGrassOrNotToGrass.png

Link to comment
Share on other sites

7 hours ago, CaptainDoge said:

Just to be sure this

  Hide contents


    public static final Block GRASS_BLOCK = new GrassBlock(Block.Properties.create(Material.ORGANIC).tickRandomly().hardnessAndResistance(1.5F).sound(SoundType.PLANT)).setRegistryName("minecraft:grass_block");

 

is what is meant by 

either way didn't seem to make a difference

 

I have removed the use of base classes, this \/ is what I have replaced it with I am not sure if this is correct but the items seem to behave properly

  Reveal hidden contents


            new BlockItem(STONE, new Item.Properties().group(ItemGroup.BUILDING_BLOCKS)).setRegistryName("minecraft:stone"),

 

Despite all these changes I am still getting the same behavior, after some experimentation I have found that some world gen works properly

 

World gen that works:

Lakes-Lava and water above and under ground

Mine shafts

normal stone world gen

all ores

dirt, gravel, andesite, diorite, granite patches

 

World gen that doesn't work:

caves in stone 

grass blocks

sand

 

Attached picture displays strange behavior 

ToGrassOrNotToGrass.png

(I can't seem to partially quote a post on mobile)

 

That is not what I meant. You'll have to replace the constants in Blocks class via reflection.

Some tips:

Spoiler

Modder Support:

Spoiler

1. Do not follow tutorials on YouTube, especially TechnoVision (previously called Loremaster) and HarryTalks, due to their promotion of bad practice and usage of outdated code.

2. Always post your code.

3. Never copy and paste code. You won't learn anything from doing that.

4. 

Quote

Programming via Eclipse's hotfixes will get you nowhere

5. Learn to use your IDE, especially the debugger.

6.

Quote

The "picture that's worth 1000 words" only works if there's an obvious problem or a freehand red circle around it.

Support & Bug Reports:

Spoiler

1. Read the EAQ before asking for help. Remember to provide the appropriate log(s).

2. Versions below 1.11 are no longer supported due to their age. Update to a modern version of Minecraft to receive support.

 

 

Link to comment
Share on other sites

Still won't work David, Mojang's generators cache their blocks.

What are you changing about stone and grass?

This is my Forum Signature, I am currently attempting to transform it into a small guide for fixing easier issues using spoiler blocks to keep things tidy.

 

As the most common issue I feel I should put this outside the main bulk:

The only official source for Forge is https://files.minecraftforge.net, and the only site I trust for getting mods is CurseForge.

If you use any site other than these, please take a look at the StopModReposts project and install their browser extension, I would also advise running a virus scan.

 

For players asking for assistance with Forge please expand the spoiler below and read the appropriate section(s) in its/their entirety.

Spoiler

Logs (Most issues require logs to diagnose):

Spoiler

Please post logs using one of the following sites (Thank you Lumber Wizard for the list):

https://gist.github.com/100MB Requires member (Free)

https://pastebin.com/: 512KB as guest, 10MB as Pro ($$$)

https://hastebin.com/: 400KB

Do NOT use sites like Mediafire, Dropbox, OneDrive, Google Drive, or a site that has a countdown before offering downloads.

 

What to provide:

...for Crashes and Runtime issues:

Minecraft 1.14.4 and newer:

Post debug.log

Older versions:

Please update...

 

...for Installer Issues:

Post your installer log, found in the same place you ran the installer

This log will be called either installer.log or named the same as the installer but with .log on the end

Note for Windows users:

Windows hides file extensions by default so the installer may appear without the .jar extension then when the .log is added the log will appear with the .jar extension

 

Where to get it:

Mojang Launcher: When using the Mojang launcher debug.log is found in .minecraft\logs.

 

Curse/Overwolf: If you are using the Curse Launcher, their configurations break Forge's log settings, fortunately there is an easier workaround than I originally thought, this works even with Curse's installation of the Minecraft launcher as long as it is not launched THROUGH Twitch:

Spoiler
  1. Make sure you have the correct version of Forge installed (some packs are heavily dependent on one specific build of Forge)
  2. Make a launcher profile targeting this version of Forge.
  3. Set the launcher profile's GameDir property to the pack's instance folder (not the instances folder, the folder that has the pack's name on it).
  4. Now launch the pack through that profile and follow the "Mojang Launcher" instructions above.

Video:

Spoiler

 

 

 

or alternately, 

 

Fallback ("No logs are generated"):

If you don't see logs generated in the usual place, provide the launcher_log.txt from .minecraft

 

Server Not Starting:

Spoiler

If your server does not start or a command window appears and immediately goes away, run the jar manually and provide the output.

 

Reporting Illegal/Inappropriate Adfocus Ads:

Spoiler

Get a screenshot of the URL bar or copy/paste the whole URL into a thread on the General Discussion board with a description of the Ad.

Lex will need the Ad ID contained in that URL to report it to Adfocus' support team.

 

Posting your mod as a GitHub Repo:

Spoiler

When you have an issue with your mod the most helpful thing you can do when asking for help is to provide your code to those helping you. The most convenient way to do this is via GitHub or another source control hub.

When setting up a GitHub Repo it might seem easy to just upload everything, however this method has the potential for mistakes that could lead to trouble later on, it is recommended to use a Git client or to get comfortable with the Git command line. The following instructions will use the Git Command Line and as such they assume you already have it installed and that you have created a repository.

 

  1. Open a command prompt (CMD, Powershell, Terminal, etc).
  2. Navigate to the folder you extracted Forge’s MDK to (the one that had all the licenses in).
  3. Run the following commands:
    1. git init
    2. git remote add origin [Your Repository's URL]
      • In the case of GitHub it should look like: https://GitHub.com/[Your Username]/[Repo Name].git
    3. git fetch
    4. git checkout --track origin/master
    5. git stage *
    6. git commit -m "[Your commit message]"
    7. git push
  4. Navigate to GitHub and you should now see most of the files.
    • note that it is intentional that some are not synced with GitHub and this is done with the (hidden) .gitignore file that Forge’s MDK has provided (hence the strictness on which folder git init is run from)
  5. Now you can share your GitHub link with those who you are asking for help.

[Workaround line, please ignore]

 

Link to comment
Share on other sites

1 hour ago, DaemonUmbra said:

Still won't work David, Mojang's generators cache their blocks.

Oh oops. I thought they would use the constants in the Blocks class (since the access time is constant anyways) instead of caching. What is the reason for doing so on Mojang's side?

Some tips:

Spoiler

Modder Support:

Spoiler

1. Do not follow tutorials on YouTube, especially TechnoVision (previously called Loremaster) and HarryTalks, due to their promotion of bad practice and usage of outdated code.

2. Always post your code.

3. Never copy and paste code. You won't learn anything from doing that.

4. 

Quote

Programming via Eclipse's hotfixes will get you nowhere

5. Learn to use your IDE, especially the debugger.

6.

Quote

The "picture that's worth 1000 words" only works if there's an obvious problem or a freehand red circle around it.

Support & Bug Reports:

Spoiler

1. Read the EAQ before asking for help. Remember to provide the appropriate log(s).

2. Versions below 1.11 are no longer supported due to their age. Update to a modern version of Minecraft to receive support.

 

 

Link to comment
Share on other sites

20 hours ago, LexManos said:

Why the hell are you replacing stone/grass?

 

15 hours ago, DaemonUmbra said:

What are you changing about stone and grass?

 

I am replacing stone and grass to change their hardness and resistance (I wouldn't be surprised if their was a better way). But I also wanted to change oak leaves to add my own features which I accomplished but I couldn't get trees to spawn my new leaves

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share



  • Recently Browsing

    No registered users viewing this page.

  • Posts

    • I want to debug in intellij but when i click the debug icon it runs like normal, and if you go to top right(Gradle icon), normally i use runClient but if i try runServer minecraft doesnt open, or runServer with debug(https://imgur.com/a/KuSUqwt), (the eula.txt file has eula=true just in case) before minecraft window open it close with no errors, like if i closed it on purpose
    • By looking at the log output for command 'gradlew --debug runData', it appears that the Standard Library jars get passed to Forge via the '-cp' command line parameter correctly in both versions. Trying to create a workaround earlier revealed that the module resolver is aware of the Standard Library's exports, and therefore conflicts with any attempt to manually copy stdlib over to 'build/classes/kotlin/main'. This means I cannot create a workaround that way. I have also switched to 1.18, and this issue still persists. This is most likely an issue regarding JVM options, which I do not have enough knowledge about. The build.gradle snippets shown above (remember switching jvmTarget in kotlinOptions to 17 when building for 1.18), alongside with the following piece of code for a mod class, should be enough to reproduce: File: src/main/kotlin/com/example/examplemod/ExampleMod.kt package com.example.examplemod import net.minecraftforge.fml.common.Mod import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.Logger @Mod("examplemod") class ExampleMod { init { LOGGER.info("Hello World!") } companion object { private val LOGGER: Logger = LogManager.getLogger() } } Note that removing the explicit type Logger (so it becomes 'private val LOGGER = LogManager.getLogger()') loads successfully, because when there is no explicit type specified, Koltin implicitly infers a so-called platform type, shown in IDE as 'Logger!' (note the exclamation mark). This platform type is not null checked by default, so there are no references to 'kotlin.jvm.internal.Intrinsics' for null checks. Specifying the type explicitly as not null however creates a null check under the hood, because in Kotlin, for a type to be nullable, it has to be suffixed with a question mark (Logger?). Otherwise it is guaranteed to be not null. Explanation for those not knowing Kotlin: The 'init' block is essentially a constructor block. The Java equivalent would be 'public ExampleMod() { LOGGER.info("Hello World!"); }'. Declarations inside 'companion object' basically behave like static declarations, so the Java equivalent would be 'private static Logger LOGGER = LogManager.getLogger();'. Looking forward to a fix! Thank you for your time.
    • affter a bit of time this worked: @SubscribeEvent public static void renderPlayerPre(RenderPlayerEvent.Pre event) { //here i was canceling the pre event so... event.getRenderer().getEntityModel().bipedLeftArm.showModel = false; } @SubscribeEvent public static void renderPlayerPost(RenderPlayerEvent.Post event) { PlayerEntity player = event.getPlayer(); PlayerModel<AbstractClientPlayerEntity> model = event.getRenderer().getEntityModel(); ModelRenderer rightArm = model.bipedLeftArm; rightArm.showModel = true; rightArm.render( event.getMatrixStack(), event.getBuffers().getBuffer(RenderType.getEntitySolid(((AbstractClientPlayerEntity)player).getLocationSkin())), Minecraft.getInstance().getRenderManager().getPackedLight(player, 1f), OverlayTexture.NO_OVERLAY); } But just one more thing, i promess no more questions..., the hand is like this: https://imgur.com/a/KTVudC3, and there is no offsetX, Y, or Z, do i need arm.rotationPointSOMETHING to move the hand wherever i want?
    • 1.12 is no longer supported on this forum. Please update to a modern version of Minecraft to receive support.
    • I get this error when i start up forge sever for 1.12.2 :https://pastebin.com/Hz1dGb4P
  • Topics

  • Who's Online (See full list)

×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.