Items
Note
These docs will only take care about polymer-related part of creation of items. You might want to see official Fabric Wiki for more in depth look into how to create items. You can skip some client side specific things, as it won't take effect server side (excluding item groups, as they can be used by other mods)
Creation of items
Creation of items is mostly the same as vanilla. Only real difference is that your items need to
implement Polymer's PolymerItem
interface. It exposes few defaulted methods for manipulation
of client side visuals.
Default implementation
For most basic uses, there are default implementation of PolymerItem
:
SimplePolymerItem
- Same as vanillaItem
,PolymerSpawnEggItem
- Same as vanillaSpawnEggItem
,PolymerBlockItem
- Same as vanillaBlockItem
,PolymerHeadBlockItem
- Similar toPolymerBlockItem
, but for Blocks implementingPolymerHeadBlock
interface.
Selecting visual item type.
To select visual item type, you need to implement this method
* Item getPolymerItem(ItemStack itemStack, @Nullable ServerPlayerEntity player)
They can't return nulls. They can also point to other PolymerItem instance, but keep in mind to make validation if it's configurable by user!
Example use:
Changing client-side item to diamond
@Override
public Item getPolymerItem(ItemStack itemStack, @Nullable ServerPlayerEntity player) {
return itemStack.getCount() > 32 ? Items.DIAMOND_BLOCK : Items.DIAMOND;
}
Manipulation of client side ItemStack
Sometimes it's useful to manipulate entire ItemStack, as it allows achieving better effects.
To do so, you need to override the ItemStack getPolymerItemStack(ItemStack itemStack, TooltipContext context, @Nullable ServerPlayerEntity player)
method. However, keep in mind that making nbt incorrect might create some issues (for example
breaking items in creative mode)!
Ideally you should modify output of PolymerItem.super.getPolymerItemStack(itemStack, context, player)
,
PolymerItemUtils.createItemStack(itemStack, player)
or PolymerItemUtils.createMinimalItemStack(itemStack, player)
, as they contain all required NBT.
Example use:
Adding enchanting glint to item.
@Override
public ItemStack getPolymerItemStack(ItemStack itemStack, TooltipContext context, ServerPlayerEntity player) {
ItemStack out = PolymerItemUtils.createItemStack(itemStack, context, player);
out.addEnchantment(Enchantments.LURE, 0);
return out;
}
Support of models/CustomModelData
You can change custom model data of virtual model by simple
overriding int getPolymerCustomModelData(ItemStack itemStack, @Nullable ServerPlayerEntity player)
.
You can return -1 to disable it, or any number above it to set value of it.
Ideally you should return value created with polymer's resource pack utils, but nothing blocks you from using any other ones.
Example usage:
Changing client-side item CustomModelData to previously stored value.
@Override
public int getPolymerCustomModelData(ItemStack itemStack, @Nullable ServerPlayerEntity player) {
// Instance of PolymerModelData, see info above
return this.cmd.value();
}
Item Groups support
You can create server side Item Groups, which will be later synced with Polymer-compatible clients.
They also allow you to create server side Creative categories, that are accessible via /polymer creative
command.
To create, it, you just need to call one of provided PolymerItemGroupUtils.builder(Identifier)
static method.
Then you can create it just like regular ItemGroup.
Manipulation of non-polymer items
Sometimes, you might want to manipulate other vanilla/modded items without implementing
PolymerItem
on them. You can do it by using few events from PolymerItemUtils
.
Forcing items to go through Polymer
To force items to go through polymer's client side item creation, you need to register
event handler for PolymerItemUtils.ITEM_CHECK
event. You can register it by using
PolymerItemUtils.ITEM_CHECK.register(ItemStack -> boolean)
lambda.
Example use:
Making every item with string NBT tag of "Test" go through polymer
PolymerItemUtils.ITEM_CHECK.register(
(itemStack) -> {
return itemStack.hasNbt() && itemStack.getNbt().contains("Test", NbtElement.STRING_TYPE);
}
);
Modification of Client side item
After getting vanilla (or for any PolymerItem by default) you can modify any client side item
with PolymerItemUtils.ITEM_MODIFICATION_EVENT
event. Just keep in mind doing it incorrectly
can cause issues (mostly around creative mode, but also in case you modify original item).
You change the client side item by either directly modifying client ItemStack
or creating new one and returning it. Ideally you should also keep previous nbt,
just so it can work nicely, You can register this event by using
PolymerItemUtils.ITEM_MODIFICATION_EVENT.register(((ItemStack original, ItemStack client, ServerPlayerEntity player) -> ItemStack)
lambda.
Example use:
Hiding enchantment glint for items with HideEnchantments: 1b
nbt tag
PolymerItemUtils.ITEM_MODIFICATION_EVENT.register(
(original, client, player) -> {
if (original.hasNbt() && original.getNbt().getBoolean("HideEnchantments")) {
client.getNbt().remove("Enchantments");
}
return client;
}
);
Replacing look/name of ItemStack with "Test" NBT tag
PolymerItemUtils.ITEM_MODIFICATION_EVENT.register(
(original, client, player) -> {
if (original.hasNbt() && original.getNbt().contains("Test", NbtElement.STRING_TYPE)) {
ItemStack out = new ItemStack(Items.DIAMOND_SWORD, client.getCount());
out.setNbt(client.getNbt());
out.setCustomName(new LiteralText("TEST VALUE: " + original.getNbt().getString("Test")).formatted(Formatting.WHITE));
return out;
}
return client;
}
);
Making items mining calculated on server side
You can also force item's mining speed to be calculated server side (which happens by default to every PolymerItem).
Only thing you need to do is just listening to BlockHelper.SERVER_SIDE_MINING_CHECK
event.
Example use:
PolymerBlockUtils.SERVER_SIDE_MINING_CHECK.register(
(player, pos, blockState) -> {
var itemStack = player.getMainHandStack();
return EnchantmentHelper.getLevel(MyEnchanments.SLOW_MINING, itemStack) > 0;
}
);
Enchantments
The only thing to make your enchantment fully server side is implementation of PolymerSyncedObject
or PolymerEnchantment
interface.
You also might want to manipulate some things from Polymer Block/Item events.