HT's TreeChop

HT's TreeChop

3M Downloads

Add support for tree with slimmer block size

strdsk opened this issue ยท 18 comments

commented

For example, Caupona added 2 trees which are fig tree and wolfberry. But, it's not using the size of a typical log block but a fence.

Perhaps add config or way for other mod to allow some log to start instead at N size of chopped blocks?

commented

I don't know about other mods but, some kind of notice about added compatibility like this one on TC curseforge page would be nice. End users will notify other mod developers to add integration.

@strdsk Agreed! I'll be sure to add better compatibility info on the curseforge page, for both users and devs

There should be a API that is able to set initial chops.

@khjxiaogu It's not released yet, but I've added an interface for this. In the simplest case, all that's needed is to override getUnchoppedRadius to return the radius of the log. Here's an example:

public class SkinnyLog extends Block implements ISimpleChoppableBlock {
public SkinnyLog(Properties properties) {
super(properties);
}
@Override
public int getUnchoppedRadius(BlockGetter blockGetter, BlockPos blockPos, BlockState blockState) {
return 4;
}
}

By default, skinnier logs can't be chopped as many times as full-size logs, so I've also made them require fewer chops to fell. This behavior can be overridden. If interested, see
https://github.com/hammertater/treechop/blob/main/shared/src/main/java/ht/treechop/api/IChoppableBlock.java
https://github.com/hammertater/treechop/blob/main/shared/src/main/java/ht/treechop/api/ISimpleChoppableBlock.java

Also, for now, chopping slim logs that are horizontally adjacent is wonky (treechop thinks they're connected). Fixing this shouldn't affect the API though.

Note that the API is split across the "fabric" and "shared" modules. Most of the stuff is in "shared". I'll be sure to add documentation for all this when it's released.

commented

It's not released yet, but I've added an interface for this. In the simplest case, all that's needed is to override getUnchoppedRadius to return the radius of the log. Here's an example:

Making mod blocks from other mod to implement your interface would cause a mess, as others may have to put this mod into dependency or use hacks. Why not make a map or recipe or datapack. This have a much higher compatibility and easier to add support by other mods.
Such as making a map Map<Block,ISimpleChoppableBlock>, and provide methods or events to add or remove handlers to this map. During game, other mods register handler to this map only if this mod is loaded. And this mod would get handler from this map if exist, and use that handler.

commented

Making mod blocks from other mod to implement your interface would cause a mess

Oh yikes, I had assumed implementing an interface would not create a required dependency (you're not using any of my code, just defining functions that match my definitions), but you're totally right. That was embarrassing...

Still, a super simple mixin removes the runtime dependency:
https://github.com/hammertater/treechop/blob/main/tests/fabric-tests/src/main/java/ht/treechoptests/mixin/HugeMushroomBlockMixin.java
With a super simple mixin plugin to check if treechop is loaded:
https://github.com/hammertater/treechop/blob/main/tests/fabric-tests/src/main/java/ht/treechoptests/TestsMixinPlugin.java#L13-L20

Why not make a map or recipe or datapack. This have a much higher compatibility and easier to add support by other mods.

Just trying to minimize how much stuff I have to support. I already use the interfaces internally, so making them part of the API is sort of a freebie. They're also much more performant and don't require any extra complexity/bookkeeping on my part, so less chance of breaking.

I can't imagine any other code-based approach would be much simpler than the mixin example. Thanks for the map example though, I'll be happy to give it a shot if you think there are issues with the mixin approach. I'll admit, I haven't been in the minecraft modding circle for very long, so I appreciate the pointers. If I have the time, I'll look into the recipe/datapack approaches too, I'm sure they'll help folks who use things like MCreator or are limited to making datapacks.

commented

Yeah, I'm happy to add some (API) support for slimmer trees. I'll try to get this done sometime next week.

Do either of you know of other mods that add slim/non-standard sized trees?

commented

Related issue: TeamMoegMC/Caupona#31

commented

There should be a API that is able to set initial chops.

commented

I don't know about other mods but, some kind of notice about added compatibility like this one on TC curseforge page would be nice. End users will notify other mod developers to add integration.

commented

@khjxiaogu Sorry for the wait. In 0.17.0 (only for 1.19.2 at the moment) I've added methods for registering block handlers, as you suggested. See examples here for retrieving a TreeChopAPI instance, and here for registering a handler to specify the radius of a block

commented

@khjxiaogu Sorry for the wait. In 0.17.0 (only for 1.19.2 at the moment) I've added methods for registering block handlers, as you suggested. See examples here for retrieving a TreeChopAPI instance, and here for registering a handler to specify the radius of a block

Good to hear. I would try that later.

commented

Another mod that adds a slimmer tree is the bamboo tree from Regions Unexplored

commented

Tested, It didn't work.
There are some problems:

  • The texture problem still exists when chopping, however I can use other vanilla texture and fix that.
  • Seems that getRadius is some sort of setting minimum radius instead of maximum radius.
  • getRadius returns 1 would cause the log unbreakable, as 1 is inclusive in documentation, and caupona trees actually only 1 radius.
  • getNumChops does not work.
    Here is my code, did I make anything wrong?
    @hammertater
commented

The texture problem still exists when chopping, however I can use other vanilla texture and fix that.

Yeah, right now it assumes the UVs are (0,0) to (1,1) (screenshots in #155). This should be fixed in the next TreeChop update.

Here is my code, did I make anything wrong?

Thanks for sharing, I'll look at it later tonight

commented

Seems that getRadius is some sort of setting minimum radius instead of maximum radius.

Weird, it should set the maximum radius. I'll try to test this in the next couple days.

getRadius returns 1 would cause the log unbreakable, as 1 is inclusive in documentation

Oh yeah, the lower limit should probably be 2. Each chop reduces the radius by 1, so it doesn't make sense to try to chop a block with radius 1, as it can't get any smaller. So, if getRadius returns 2, the block can be chopped one time down to the minimum radius of 1.

and caupona trees actually only 1 radius.

I'd expect getRadius to return half the width of the block's voxel shape. From this line:

https://github.com/TeamMoegMC/Caupona/blob/f56f6708dfb7d0fe51d757aba020199e5e184353/src/main/java/com/teammoeg/caupona/blocks/plants/BushLogBlock.java#L40

Looks like your blocks are 12 - 4 = 8 units across, so getRadius should return 4

getNumChops does not work.

Just have it return 0 for now, it's very unlikely you'll need to change that. It's only useful if you want to use a custom block instead of the default treechop:chopped_log for chopping. I'll add this to the documentation.

So, a basic handler for a slim log of radius 4 would just be this:

public class SlimTreeHandler implements ISimpleChoppableBlock {
    @Override
    public int getRadius(BlockGetter level, BlockPos blockPos, BlockState blockState) {
        return 4;
    }
}

and the other methods can use the default implementations for ISimpleChoppableBlock. Your IStrippableBlock workaround should work great until I can get the texture UVs fixed.

Thanks for trying this stuff out!

commented

So, a basic handler for a slim log of radius 4 would just be this:

I've tried to set from 1 to 8, neither take effect, but as I set higher the value, I find it take more time to chop, while initial radius unchanged. To conclude, minimum radius goes smaller as radius increases, but inital (or maximum) radius is not affected. So it is not the maximum radius, but the maximum chopping time.

Just have it return 0 for now, it's very unlikely you'll need to change that. It's only useful if you want to use a custom block instead of the default treechop:chopped_log for chopping. I'll add this to the documentation.

I guess if this returns the value from getRadius while getMaxChops returns constant 8, would fix this issue.
Because I tried to use in-game command to modify block data Chops, when it is set to 4, Its model looks correct. But changing getNumChops or getRadius does not modify this value, also I changed MaxChops data, whatever I set it to, it actually does not affect model.

commented

Tested all good.

commented

You're totally right, getRadius isn't working correctly. It seems to work on Fabric but not on Forge. I'll get it fixed asap

I guess if this returns the value from getRadius while getMaxChops returns constant 8, would fix this issue.

The problem with changing getNumChops from 0 is that it could really mess up the way chops are counted. Trees would always get felled with one chop, among other issues. So that method is only for really special use cases... it definitely needs some more documentation

commented

Ok, getRadius should be fixed in 0.17.3. So, just overriding getRadius to return 4 should work for you. The texture issue (#155) should be fixed too, but that won't matter much if you're setting the chopped texture manually using the IStrippableBlock interface. If you do decide to add stripped variants of your logs in the future, TreeChop should automatically detect them and use their textures for chopped logs.

commented

Glad to hear! Closing