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

De-hardcode shears (again) #3477

Open
wants to merge 29 commits into
base: 1.20.4
Choose a base branch
from
Open

Conversation

AnAwesomGuy
Copy link

@AnAwesomGuy AnAwesomGuy commented Dec 21, 2023

Adds a boolean method to FabricItem and FabricItemStack, isShears. It functions as a stack-aware check that allows items to function as shears. By default, the method returns true if the item is either an instance of ShearsItem or in the fabric:shears tag.

If a stack isShears, it is able to shear pumpkins, de-arm tripwire, be enchanted with efficiency, have ShearsDispenserBehavior (if there isn't already a DispenserBehavior for the item registered), and shear snow golems, sheep, and mooshrooms.

This also mixes into MatchToolLootCondition and adds a custom predicate to it if its predicate contains shears. The custom predicate is a boolean value registered under fabric:allow_shears and defaults to true. If the value is false, the mixin will not add the custom predicate even if the predicate contains shears.

Supersedes/closes #1287 and closes #1226. Also depends on/includes #3493, so either merge that first or just merge this PR.

@modmuss50 modmuss50 added the enhancement New feature or request label Dec 21, 2023
@ZestyBlaze
Copy link

ZestyBlaze commented Dec 21, 2023

Aren't tags saved under c:shears not fabric:shears? You might want to ammend the comments to correct that if that's the case

@deirn
Copy link
Member

deirn commented Dec 21, 2023

Apply the license header with gradlew spotlessApply. You also need to fix the style issues.

@Juuxel
Copy link
Member

Juuxel commented Dec 21, 2023

@ZestyBlaze Generally, fabric tags are used for behaviour and c tags just for categorisation. (Compare with FAPI's mining level + mineable tags etc)

@AnAwesomGuy
Copy link
Author

AnAwesomGuy commented Dec 22, 2023

this works from 23w32a onwards (MatchToolLootCondition became a record with an optional in that version)

for below that, you would remove DirectRegistryEntryListAccessor<T> and replace MatchToolLootConditionMixin with something like this. that will work down until somewhere between 1.18.1 and 1.18.2, when TagKey<T>s were added

…lizer

also change the way all the shears are found
also change the way the mixins work
Copy link
Member

@deirn deirn left a comment

Choose a reason for hiding this comment

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

Not sure about modifying all loot tables, we should probably only do it for vanilla.

@AnAwesomGuy
Copy link
Author

AnAwesomGuy commented Dec 29, 2023

Not sure about modifying all loot tables, we should probably only do it for vanilla.

If someone could help me find a way to do that that would be amazing. Though it would be even harder now that we're moving towards making it stack-based, which means I'm mixing into MatchToolLootCondition#test, making it so there is basically no context about its creation.

I also don't really see why anyone would want to target only vanilla shears but ¯⁠\⁠_⁠(⁠ツ⁠)⁠_⁠/¯.

@deirn
Copy link
Member

deirn commented Dec 29, 2023

The way Forge does it is to just replace the loot tables with their own. Maybe we can move the modification into a datagen instead.

@AnAwesomGuy
Copy link
Author

Then it wouldn't be stack-based, and that seems like what modmuss and some others want.

@deirn deirn mentioned this pull request Dec 31, 2023
@deirn
Copy link
Member

deirn commented Dec 31, 2023

You can make a custom predicate that checks if the item is shears with #3493 😉

@AnAwesomGuy
Copy link
Author

That looks pretty good, but how would I make my PR depend on yours?
Should I just wait for it to get merged?

use custom codec impl
# Conflicts:
#	fabric-item-api-v1/src/main/java/net/fabricmc/fabric/api/item/v1/FabricItemStack.java
#	fabric-item-api-v1/src/main/resources/fabric-item-api-v1.mixins.json
#	fabric-item-api-v1/src/testmod/resources/fabric.mod.json
Comment on lines +29 to +40
/**
* Allows Fabric API to replace any occurrences of {@link net.minecraft.item.Items#SHEARS minecraft:shears} with a custom predicate for stack-aware shears. This is the default if {@link #DENY} is not specified.
*
* @see net.fabricmc.fabric.api.item.v1.FabricItem#isShears
*/
ALLOW,
/**
* Disallows Fabric API to replace any occurrences of {@link net.minecraft.item.Items#SHEARS minecraft:shears} with a custom predicate for stack-aware shears.
*
* @see net.fabricmc.fabric.api.item.v1.FabricItem#isShears
*/
DENY;
Copy link
Member

Choose a reason for hiding this comment

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

I'm a little confused by this, what's with the allow and deny? Why can't it be a boolean that checks if it is shears or not?

Copy link
Author

Choose a reason for hiding this comment

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

This also mixes into MatchToolLootCondition and adds a custom predicate to it if its predicate contains shears. The custom predicate is a boolean value registered under fabric:allow_shears and defaults to true. If the value is false, the mixin will not add the custom predicate even if the predicate contains shears.

true is ALLOW and false is DENY
this is made so mods can also target only shears using DENY if they want to for some reason

Copy link
Member

Choose a reason for hiding this comment

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

What I had in mind is a boolean predicate, maybe called fabric:is_shears and value && item.isShears() check that entirely replaces the vanilla items predicate. People who want to match strictly vanilla shears can do so like before without the deny shenanigans.

Comment on lines +53 to +63
if (predicate.items().isPresent() && predicate.items().get().contains(Items.SHEARS.getRegistryEntry())) {
CustomItemPredicate[] custom = predicate.custom().toArray(new CustomItemPredicate[0]);
ImmutableList.Builder<CustomItemPredicate> builder = ImmutableList.builderWithExpectedSize(custom.length + 1);

for (CustomItemPredicate customPredicate : custom) {
if (customPredicate == ShearsItemPredicate.DENY) return;
builder.add(custom);
}

((ItemPredicateExtensions) (Object) predicate).fabric_setCustom(builder.add(ShearsItemPredicate.ALLOW).build());
}
Copy link
Member

Choose a reason for hiding this comment

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

Does this make it replace all predicates with the ShearsItemPredicate.ALLOW by default? If anything, it should be defaults to deny.

Copy link
Author

Choose a reason for hiding this comment

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

yes it does
i chose to make it default to ALLOW cuz im lazy and dont want to datagen
also i doubt anyone should want to make it only work for shears so its opt-out

Copy link
Member

Choose a reason for hiding this comment

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

Can't you change the conditions at runtime with LootTableEvents.MODIFY? CC: @Juuxel

@cech12
Copy link

cech12 commented Apr 17, 2024

Thanks for all your work! I think it would be great if the changes were included as I own 2 mods that add shears to Minecraft. They would benefit greatly from this. Are there any plans to bring this PR to 1.20.5? What is needed to reach that? :)

@AnAwesomGuy
Copy link
Author

it should already work on 1.20.5, but this pr is kinda in a dead place rn

@cech12
Copy link

cech12 commented Apr 25, 2024

I think it needs a rework after #3493 was closed, because of the vanilla's sub predicate system.

@cech12
Copy link

cech12 commented Jun 7, 2024

For porting this to 1.20.6 I think it would be easier to add a new boolean component "IS_SHEARS" or something similar and add it to vanilla shears and also to custom shears. This component could be checked in all your mixins instead of adding a new tag, a new isShears method and the whole custom predicate logic. That should be much cleaner and easier to use.

Edit: and don't forget the newly added functionalities: shearable Bogged entity & Wolf armor shearing

@Patbox
Copy link

Patbox commented Jun 7, 2024

Adding new component would make fabric api incompatible with vanilla

@AnAwesomGuy
Copy link
Author

yes, that is why i havent ported this to 1.20.5+ yet
i could also go the old route and just add stuff to FabricItem (including the custom predicate) but i dont really know if thats the way to go yet

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Shears not completely de-hardcoded
9 participants