Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace PlantType system with SpecialPlantable interface and canSustainPlant block method #971

Merged
merged 72 commits into from
Jun 26, 2024

Conversation

TelepathicGrunt
Copy link
Contributor

@TelepathicGrunt TelepathicGrunt commented May 17, 2024

It is well known the old PlantType system used in past is quite clunky and broken in many areas. It does not even cover some important vanilla plants such as Cocoa.

Basically, it tried to be many things at once and failed at all of them. It tried to allow for blocks to define what plant it can keep as well as control what modded crops villagers can place.

This PR splits the two goals into separate systems.

  1. SpecialPlantable interface (any suggestions of different name?)

    • This replaces the IPlantable interface and instead of being on blocks, you would put the SpecialPlantable interface on your own custom item classes.
    • The interface will force you to define canPlacePlantAtPosition and spawnPlantAtPosition methods. villagerCanPlantItem is optional to override.
    • Other mods will instanceof check for the interface on an item and if present, will call these two methods to check if the item can place a plant at a spot and if so, call the other method to spawn the plant. This allows for the item to spawn larger or more complex plants through mod interactions instead of just a normal BlockItem.
    • Vanilla items are untouched as they are BlockItems. Mods can still find those crop items by checking if in ItemTags.VILLAGER_PLANTABLE_SEEDS tag and then call the BlockItem's method for placing the crop. Again, the interface is for crops that are more complex than a BlockItem.
    • If an item has this interface and has overridden villagerCanPlantItem to return true, Villagers can pick up this item and put it into the Villager's inventory. Then the Villager will now be able to plant this item on nearby block that extend FarmBlock!
    • Thoughts? Any way to improve this interface? Or is it not a good idea?
  2. Changed canSustainPlant to return a Tristate and patched it into more blocks

    • Modded soil blocks will override canSustainPlant and return TRUE, FALSE, or DEFAULT enum. If DEFAULT, the plant block will continue to run it's normal logic for checking survivability. If TRUE or FALSE is returned, it will override the plant's survivability checks to what the soil block wants.
    • Modded plant blocks that override canSurvive method should call canSustainPlant on the block the plant is attaching to and respect the enum result that comes out. Basically, modded plants will have to "opt-in" into this system. If the pklant overrides mayPlace method, they will still respect canSustainPlant because the patches tries to target the canSurvive methods where-ever it makes sense
    • The patches to the vanilla blocks to support canSustainPlant are in places where vanilla is doing block type checks or light checks. Any check for block shape was ignored to keep patch size down and because those kinds of plants technically support any block as long as the block's shape is good for supporting the plant.
    • CropBlock's getGrowthSpeed method had its first parameter changed from Block to BlockStatein order to pass in the correct crop block's blockstate to canSustainPlant. No idea why mojang passed only the Block in but this is an annoying breaking change to a vanilla method param type I ended up doing. Any suggestions around this?
    • Support far more vanilla blocks than the old PlantType system did. It includes Cocoa, Chorus Plant, and more! Even Hanging Mangrove Propagule! Let me know if there's any specific plant that needs the hook.
  3. Added GameTests for all kinds of plants

    • I added gametests for each kind of plant to make sure there's no regression on logic in future and catch missed patches much easier.
    • Note: I was not able to make gametest that test the plant's survivability in the dark because the lighting engine is too problematic to handle during gametests. Darkness survivability checking will have to be done manually for Red/Brown mushroom blocks on non-myclium and making sure crops cannot be planted in the dark.
  4. Added neoforge:villager_farmlands block tag

  • This will be added alongside the two instanceof FarmBlock checks. Modders should add to this tag instead to be fully supported by Villagers. This means mods can tag their non-farmland block as trackable and plantable with crops by farmer villagers. other mods can use this tag to know if a block is supposed to be farmland like

Feed back welcomed as there's a lot of improvements that can be done to this PR.

@TelepathicGrunt TelepathicGrunt added enhancement New (or improvement to existing) feature or request breaking change Breaks binary compatibility request for comments For gathering opinions on some topic or subject 1.20.6 Targeted at Minecraft 1.20.6 labels May 17, 2024
@TelepathicGrunt TelepathicGrunt self-assigned this May 17, 2024
@neoforged-pr-publishing
Copy link

neoforged-pr-publishing bot commented May 17, 2024

  • Publish PR to GitHub Packages

Last commit published: 0a7b1d1bb2e685443705713488c639a62eecf767.

PR Publishing

The artifacts published by this PR:

Repository Declaration

In order to use the artifacts published by the PR, add the following repository to your buildscript:

repositories {
    maven {
        name 'Maven for PR #971' // https://github.com/neoforged/NeoForge/pull/971
        url 'https://prmaven.neoforged.net/NeoForge/pr971'
        content {
            includeModule('net.neoforged', 'neoforge')
            includeModule('net.neoforged', 'testframework')
        }
    }
}

MDK installation

In order to setup a MDK using the latest PR version, run the following commands in a terminal.
The script works on both *nix and Windows as long as you have the JDK bin folder on the path.
The script will clone the MDK in a folder named NeoForge-pr971.
On Powershell you will need to remove the -L flag from the curl invocation.

mkdir NeoForge-pr971
cd NeoForge-pr971
curl -L https://prmaven.neoforged.net/NeoForge/pr971/net/neoforged/neoforge/21.0.111-beta-pr-971-PlantTypeRefactor/mdk-pr971.zip -o mdk.zip
jar xf mdk.zip
rm mdk.zip || del mdk.zip

To test a production environment, you can download the installer from here.

@Spinoscythe
Copy link
Contributor

Spinoscythe commented May 17, 2024

@TelepathicGrunt canPlacePlantAtSpot -> canPlacePlantAtPosition maybe? More inline with Minecraft imo..

@Spinoscythe
Copy link
Contributor

Spinoscythe commented May 17, 2024

@TelepathicGrunt SpecialPlantable -> BasePlantable?

@TelepathicGrunt
Copy link
Contributor Author

TelepathicGrunt commented May 19, 2024

@TelepathicGrunt SpecialPlantable -> BasePlantable?

BasePlantable sounds like it is for vanilla plantable items too. But the interface is better suited for special plantable blocks that aren't simple vanilla villager plantable tagged BlockItems. (And that we can't patch vanilla items to have the interface as they are using the BlockItem class directly)

@TelepathicGrunt TelepathicGrunt marked this pull request as ready for review May 20, 2024 22:16
XFactHD
XFactHD previously approved these changes Jun 22, 2024
XFactHD
XFactHD previously approved these changes Jun 24, 2024
Copy link
Member

@XFactHD XFactHD left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would still like a second pair of eyes on this

@pupnewfster pupnewfster self-requested a review June 26, 2024 04:22
pupnewfster
pupnewfster previously approved these changes Jun 26, 2024
@neoforged-compatibility-checks
Copy link

neoforged-compatibility-checks bot commented Jun 26, 2024

@TelepathicGrunt, this PR introduces breaking changes.
Fortunately, this project is currently accepting breaking changes, but if they are not intentional, please revert them.
Last checked commit: 0a7b1d1bb2e685443705713488c639a62eecf767.

Compatibility checks

neoforge (:neoforge)

  • net/minecraft/world/level/block/WitherRoseBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/BeetrootBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/TallGrassBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/DeadBushBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/TallSeagrassBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/WaterlilyBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/CropBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
    • getGrowthSpeed(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)F: ❗ API method was removed
  • net/minecraft/world/level/block/SeagrassBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/FlowerBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/neoforged/neoforge/common/extensions/IBlockExtension
    • canSustainPlant(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/Direction;Lnet/neoforged/neoforge/common/IPlantable;)Z: ❗ API method was removed
  • net/minecraft/world/level/block/SaplingBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/SugarCaneBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
    • getPlantType(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Lnet/neoforged/neoforge/common/PlantType;: ❗ API method was removed
    • getPlant(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;: ❗ API method was removed
  • net/minecraft/world/level/block/MangrovePropaguleBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/PinkPetalsBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/RootsBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/PotatoBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/BushBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
    • getPlant(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;: ❗ API method was removed
  • net/minecraft/world/level/block/Block
    • canSustainPlant(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/Direction;Lnet/neoforged/neoforge/common/IPlantable;)Z: ❗ API method was removed
  • net/minecraft/world/level/block/NetherSproutsBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/AzaleaBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/neoforged/neoforge/common/extensions/IBlockStateExtension
    • canSustainPlant(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/Direction;Lnet/neoforged/neoforge/common/IPlantable;)Z: ❗ API method was removed
  • net/minecraft/world/level/block/SeaPickleBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/PitcherCropBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/CarrotBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/neoforged/neoforge/common/PlantType
    • ❗ API class no longer exists
  • net/minecraft/world/level/block/BambooStalkBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
    • getPlant(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;: ❗ API method was removed
  • net/minecraft/world/level/block/MushroomBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/AttachedStemBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/SweetBerryBushBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/SmallDripleafBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/TorchflowerCropBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/DoublePlantBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/CactusBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
    • getPlantType(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Lnet/neoforged/neoforge/common/PlantType;: ❗ API method was removed
    • getPlant(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;: ❗ API method was removed
  • net/minecraft/world/level/block/FungusBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/minecraft/world/level/block/TallFlowerBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
  • net/neoforged/neoforge/common/IPlantable
    • ❗ API class no longer exists
  • net/minecraft/world/level/block/StemBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable
    • getPlantType(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Lnet/neoforged/neoforge/common/PlantType;: ❗ API method was removed
  • net/minecraft/world/level/block/NetherWartBlock
    • ❗ Class missing interface: net/neoforged/neoforge/common/IPlantable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1.21 Targeted at Minecraft 1.21 breaking change Breaks binary compatibility enhancement New (or improvement to existing) feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants