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

Add Support for Custom Item Settings #1359

Open
wants to merge 20 commits into
base: 1.16
Choose a base branch
from

Conversation

Haven-King
Copy link

Currently, if a mod wants to pass custom settings for items, the best way is to subclass either Item.Settings or FabricItemSettings and add the behavior there yourself. An example of this is in The Aether, where custom item settings are used for a custom rarity and enchantment glint color. If another mod, however, adds an item setting for their items via the same method, there's no way for one item to share both properties.

This pull request solves that by allowing mods to attach arbitrary data to item settings. As part of this change, both the EquipmentSlotProvider and CustomDamageHandler have been migrated to use this system. Their public-facing API's remain unchanged.

This pull request also fixes a small bug in the testmod, wherein one of the test entrypoints would fail to launch.

@LambdAurora LambdAurora added enhancement New feature or request priority:low Low priority PRs that don't immediately need to be resolved labels Mar 11, 2021
@LambdAurora LambdAurora requested a review from a team March 11, 2021 09:13
@liach
Copy link
Contributor

liach commented Mar 11, 2021

Pretty good. I assume these settings are all used by other vanilla items in modified bytecode, right? If those are exclusively used by mods mods should just add extra constructor parameters.

… the item in question so that mods don't need to add mixins/accessor interfaces to access their settings on items.
@Haven-King
Copy link
Author

Pretty good. I assume these settings are all used by other vanilla items in modified bytecode, right? If those are exclusively used by mods mods should just add extra constructor parameters.

Adding constructor parameters isn't an elegant solution when you want to be able to add settings to a wide range of item types, potentially from different mods, or if you want to ensure a large group of items have the same settings.

Copy link
Contributor

@liach liach left a comment

Choose a reason for hiding this comment

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

@liach liach requested a review from a team March 11, 2021 21:38
@liach liach requested a review from a team March 11, 2021 21:46
@liach liach added the reviews needed This PR needs more reviews label Mar 11, 2021
@LambdAurora LambdAurora requested a review from a team March 12, 2021 12:57
@Technici4n
Copy link
Member

So I thought of another way of doing this, based on one of Lambda's idea.

Let's say we add .then(Consumer<Item>... itemConsumers) to FabricItemSettings that registers consumers to be invoked at the end of the item constructor, then we could achieve exactly the same thing, and we could replace ExtraData with List<Consumer> basically.

For example

public FabricItemSettings equipmentSlot(EquipmentSlotProvider equipmentSlotProvider) {
    FabricItemInternals.computeExtraData(this).equipmentSlot(equipmentSlotProvider);
}

becomes

public FabricItemSettings equipmentSlot(EquipmentSlotProvider equipmentSlotProvider) {
    return then(item -> ((ItemExtensions) item).fabric_setEquipmentSlotProvider(equipmentSlotProvider);
}

By separating the Consumer<Item> from the item settings, this can then be trivially expanded upon by other mods, for example:

public static Consumer<Item> fuel(int burnTicks) {
    return item -> FuelRegistry.add(item, burnTicks);
}

// used like this:
.then(fuel(42))

The only downside is that it's not possible to get the current setting as it's stored within the lambda, but the current PR doesn't provide that option either.

@LambdAurora
Copy link
Contributor

LambdAurora commented Mar 12, 2021

@Technici4n imo, the consumers being executed at the end of the constructor and not after item registration is a bit painful as it would prevent calling anything that relies on the item to be in the register.
Other issue is fake items stuff, it's possible to instantiate an item without registering it, not recommended but the consumers being executed at constructor end would very likely cause issues in that case.

@Technici4n
Copy link
Member

If you register a then() for your own fake Item then that's not my problem. ^^

@Haven-King
Copy link
Author

Haven-King commented Mar 12, 2021

I agree that .then would be a good feature, but I don't see how it relates directly to this PR. I suppose it could replace the intermediary step of copying the map in the constructor, but that has its own issues. The most important issue I see is that when then is fired you expect the item to be fully initialized, which might not be the case if custom item settings are being copied via the same method.

@LambdAurora
Copy link
Contributor

If you register a then() for your own fake Item then that's not my problem. ^^

Can't wait to have to strip every consumers from the re-usable settings for the fake item :|

Plus it's mutable and there's no way to copy an item settings properly so really not happy about that.

Copy link
Contributor

@i509VCB i509VCB left a comment

Choose a reason for hiding this comment

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

With regards to new item settings added by fabric api, those should still recieve dedicated setting methods.

@Haven-King Haven-King requested a review from LambdAurora March 12, 2021 22:25
@Technici4n Technici4n requested a review from a team March 13, 2021 00:18
@LambdAurora
Copy link
Contributor

Uh... The usual rule of thumb in Fabric API is that parameters shouldn't be null unless @Nullable is specified, we don't really use @NotNull annotations here.

@liach
Copy link
Contributor

liach commented Mar 26, 2021

Also I meant to add Objects.requireNonNull calls than @NotNull annotations.

@Technici4n Technici4n requested review from Technici4n and Juuxel March 26, 2021 17:27
@@ -39,8 +39,7 @@
* @return this builder
*/
public FabricItemSettings equipmentSlot(EquipmentSlotProvider equipmentSlotProvider) {
FabricItemInternals.computeExtraData(this).equipmentSlot(equipmentSlotProvider);
return this;
return custom(CustomItemSettingImpl.EQUIPMENT_SLOT_PROVIDER, equipmentSlotProvider);

This comment was marked as resolved.

Copy link
Contributor

@sfPlayer1 sfPlayer1 left a comment

Choose a reason for hiding this comment

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

The is an overlap with the api-lookup api that needs further invesigation.

This PR handles both a) transporting the data from Item.Settings.custom(data) to the constructor and b) holding and retrieving said data externally with any item instance. The latter is what api-api does as well, although significantly less conveniently.

@sfPlayer1
Copy link
Contributor

I forgot to mention there that adding such a mechanism would imply doing the same for blocks. I don't really want to clutter the interface with a generic arg for block vs item, so some code duplication is in order. Not sure how much the impl can be shared.

@Haven-King
Copy link
Author

I do plan on adding a similar mechanism for block settings. I want to get this PR merged as a precedent for how I will handle blocks.

- Adds another create method to CustomItemSetting
- Code and JavaDoc cleanup
@PseudoDistant
Copy link

PseudoDistant commented Apr 30, 2022

@sfPlayer1 was something like this ever finished?

I could pick it up if needbe.

@liach
Copy link
Contributor

liach commented Apr 30, 2022

Can probably be replaced by #2172

@PseudoDistant
Copy link

Ah, maybe.

@Technici4n
Copy link
Member

@liach No, this PR is for immutable data that's stored in the Item and set at creation time. #2172 is for mutable data that is attached to many game objects (worlds, chunks, entities, block entities) and can be updated / persisted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request priority:low Low priority PRs that don't immediately need to be resolved reviews needed This PR needs more reviews
Projects
None yet
Development

Successfully merging this pull request may close these issues.