Skip to content

Commit

Permalink
Update docs a bit
Browse files Browse the repository at this point in the history
  • Loading branch information
Patbox committed Dec 12, 2024
1 parent 18ba37f commit c88b3cf
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 104 deletions.
29 changes: 11 additions & 18 deletions docs/polymer-core/blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,15 @@ For most basic uses, there are default implementation of `PolymerBlock`:
* `SimplePolymerBlock` - Same as vanilla `Block`.

### Selecting base polymer block type.
To change base block, you need to override `Block getPolymerBlock(BlockState state)` method.

You can also override `Block getPolymerBlock(ServerPlayerEntity player, BlockState state)` to replace blocks per player,
however keep in mind they should ideally have same collisions.
To change base block, you need to override `Block getPolymerBlock(BlockState state, PacketContext context)` method.

Both of these methods can't return null. They can also point to other PolymerBlock instances, but keep
in mind to make validation if it's configurable by user!

Example use:

Making block look like a diamond
```
@Override
public Block getPolymerBlock(BlockState state) {
public Block getPolymerBlock(BlockState state, PacketContext context) {
return Blocks.BARRIER;
}
Expand All @@ -42,10 +37,8 @@ public Block getPolymerBlock(ServerPlayerEntity player, BlockState state) {
```

### Changing client-side and collision BlockStates
If you want to change what BlockState will be used for server side collision
and client side you need to override `BlockState getPolymerBlockState(BlockState state)` method.
You can also override `BlockState getPolymerBlockState(BlockState state, ServerPlayerEntity player)` for player context,
similar to `getPolymerBlock`.
To change the blockstate visible on client and used for server side collisions, you need to override
`BlockState getPolymerBlockState(BlockState state, PacketContext context)` method.
You can return other BlockState of PolymerBlock, but keep in mind you can only nest them
up to 32!

Expand All @@ -54,7 +47,7 @@ Example use:
Changing BlockState to furnace with the same facing, but inverted "lit" BlockState property
```
@Override
public BlockState getPolymerBlockState(BlockState state) {
public BlockState getPolymerBlockState(BlockState state, PacketContext context) {
return Blocks.FURNACE.getDefaultState()
.with(AbstractFurnaceBlock.FACING, state.get(AbstractFurnaceBlock.FACING))
.with(AbstractFurnaceBlock.LIT, !state.get(AbstractFurnaceBlock.LIT));
Expand All @@ -63,35 +56,35 @@ public BlockState getPolymerBlockState(BlockState state) {

### Sending additional data (signs/heads or even custom)
In case if you want to send additional (to more customize look on client for signs/heads
or additional data for companion mod), you need to override `onPolymerBlockSend(BlockState blockState, BlockPos.Mutable pos, ServerPlayerEntity player)`.
or additional data for companion mod), you need to override `onPolymerBlockSend(BlockState blockState, BlockPos.Mutable pos, PacketContext.NotNullWithPlayer context)`.
Technically you can do anything there, but ideally it should be only used for packets.

Example use:

Sending data required to render player head with skin
```
@Override
public void onPolymerBlockSend(BlockState blockState, BlockPos.Mutable pos, ServerPlayerEntity player) {
public void onPolymerBlockSend(BlockState blockState, BlockPos.Mutable pos, PacketContext.NotNullWithPlayer context) {
player.networkHandler.sendPacket(this.getPolymerHeadPacket(blockState, pos.toImmutable()));
}
```

### Using PolymerHeadBlock
`PolymerHeadBlock` is an interface extending PolymerBlock with methods prepared for
usage of player heads as a block. To modify texture, you just need to override
`String getPolymerSkinValue(BlockState state, BlockPos pos, ServerPlayerEntity entity)` which should return texture value.
`String getPolymerSkinValue(BlockState state, BlockPos pos, PacketContext.NotNullWithPlayer context)` which should return texture value.

To generate it you can use websites like https://mineskin.org/.

Additionally, you can override `BlockState getPolymerBlockState(BlockState state)`
Additionally, you can override `BlockState getPolymerBlockState(BlockState state, PacketContext context)`
to change rotation of Player Head Block.

Example use:

Setting skin value for PolymerHeadBlock
```
@Override
public String getPolymerSkinValue(BlockState state, BlockPos pos, ServerPlayerEntity entity) {
public String getPolymerSkinValue(BlockState state, BlockPos pos, PacketContext.NotNullWithPlayer context) {
return "ewogICJ0aW1lc3RhbXAiIDogMTYxNzk3NjcxOTAzNSwKICAicHJvZmlsZUlkIiA6ICJlZDUzZGQ4MTRmOWQ0YTNjYjRlYjY1MWRjYmE3N2U2NiIsCiAgInByb2ZpbGVOYW1lIiA6ICI0MTQxNDE0MWgiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNTczNTE0YTIzMjQ1ZjE1ZGJhZDVmYjRlNjIyMTYzMDIwODY0Y2NlNGMxNWQ1NmRlM2FkYjkwZmE1YTcxMzdmZCIKICAgIH0KICB9Cn0";
}
```
Expand All @@ -104,7 +97,7 @@ The only thing you need to do to remove BlockEntity from being sent to client is

## Getting Polymer Blocks client representation
If you want to get client-friendly representation of block, you need to call
`PolymerBlockUtils.getBlockStateSafely(PolymerBlock block, BlockState blockState)`
`PolymerBlockUtils.getBlockStateSafely(PolymerBlock block, BlockState blockState, PacketContext context)`
method. It should return block safe to use (or air in case of failure).

## Limitations
Expand Down
2 changes: 1 addition & 1 deletion docs/polymer-core/client-side.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ You can do that by registering packets for which you should check [Polymer Netwo

After that you can just validate if player supports it with this check it like this
```
SomeObject getPolymerX(ServerPlayerEntity player) {
SomeObject getPolymerX(PacketContext context) {
if (PolymerServerNetworking.getSupportedVersion(player.networkHandler, PACKET_ID) > 0) {
// Client state for modded
return this;
Expand Down
4 changes: 2 additions & 2 deletions docs/polymer-core/entities.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ You also need to register your entity type as virtual,
by using `PolymerEntityUtils.registerType(EntityType... types)`.

### Changing client side entity.
To select visual entity type, you just need to override `EntityType<?> getPolymerEntityType(ServerPlayerEntity player)`
To select visual entity type, you just need to override `EntityType<?> getPolymerEntityType(PacketContext context)`

This method can't return null or another EntityType that points to other virtual entity, as it won't work.

Expand All @@ -23,7 +23,7 @@ Example use:
Displaying entity as zombie
```
@Override
public EntityType<?> getPolymerEntityType(ServerPlayerEntity player) {
public EntityType<?> getPolymerEntityType(PacketContext context) {
return EntityType.ZOMBIE;
}
```
Expand Down
71 changes: 21 additions & 50 deletions docs/polymer-core/items.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,63 +20,38 @@ For most basic uses, there are default implementation of `PolymerItem`:
* `PolymerBlockItem` - Same as vanilla `BlockItem`,
* `PolymerHeadBlockItem` - Similar to `PolymerBlockItem`, but for Blocks implementing `PolymerHeadBlock` interface.

### Selecting visual item type.
To select visual item type, you need to implement this method
* `Item getPolymerItem(ItemStack itemStack, @Nullable ServerPlayerEntity player)`
### Selecting base item type.
To select base item type, you need to implement this method
* `Item getPolymerItem(ItemStack itemStack, PacketContext context)`

They can't return nulls. They can also point to other PolymerItem instance, but keep
It 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) {
public Item getPolymerItem(ItemStack itemStack, PacketContext context) {
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;
}
```
### Changing item model
By default, Polymer will use whatever the `item_model` component is set for the item, which is equal to the value
you provided in Item.Settings, as long as ItemStack doesn't override it.

### 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.
For better control over it, you can override `Identifier getPolymerItemModel(ItemStack itemStack, PacketContext context)`
method.

Ideally you should return value created with [polymer's resource pack utils](/resource-packs/basics),
but nothing blocks you from using any other ones.
### 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 `void modifyBasePolymerItemStack(ItemStack out, ItemStack stack, PacketContext context)`
method. You can only modify the `out` item stack, as it's item that gets sent to the client.
The `stack` item is what server sends by default and should never be modified.

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();
}
```
If you need more control, you can also override `ItemStack getPolymerItemStack(ItemStack itemStack, TooltipType type, PacketContext context)`,
however doing it incorrectly will result in items converting to vanilla ones in creative and desyncing in inventory.

## Item Groups support
You can create server side Item Groups, which will be later synced with Polymer-compatible clients.
Expand Down Expand Up @@ -113,14 +88,14 @@ can cause issues (mostly around creative mode, but also in case you modify origi
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.
`PolymerItemUtils.ITEM_MODIFICATION_EVENT.register(((ItemStack original, ItemStack client, PacketContext context) -> ItemStack)` lambda.

Example use:

Hiding enchantment glint for items with `HideEnchantments: 1b` nbt tag
```
PolymerItemUtils.ITEM_MODIFICATION_EVENT.register(
(original, client, player) -> {
(original, client, context) -> {
if (original.hasNbt() && original.getNbt().getBoolean("HideEnchantments")) {
client.getNbt().remove("Enchantments");
Expand All @@ -133,7 +108,7 @@ PolymerItemUtils.ITEM_MODIFICATION_EVENT.register(
Replacing look/name of ItemStack with "Test" NBT tag
```
PolymerItemUtils.ITEM_MODIFICATION_EVENT.register(
(original, client, player) -> {
(original, client, context) -> {
if (original.hasNbt() && original.getNbt().contains("Test", NbtElement.STRING_TYPE)) {
ItemStack out = new ItemStack(Items.DIAMOND_SWORD, client.getCount());
out.setNbt(client.getNbt());
Expand All @@ -159,8 +134,4 @@ PolymerBlockUtils.SERVER_SIDE_MINING_CHECK.register(
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.
```
2 changes: 1 addition & 1 deletion docs/polymer-core/other.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ Then you can use it just like vanilla ones.
## StatusEffects

To create custom, server side status effects, you just need to implement PolymerStatusEffect on your
custom StatusEffect class. You can also override `StatusEffect getPolymerReplacement(ServerPlayerEntity player)` to display it
custom StatusEffect class. You can also override `StatusEffect getPolymerReplacement(PacketContext context)` to display it
as vanilla one or null to make it invisible (default).

34 changes: 2 additions & 32 deletions docs/polymer-resource-pack/basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,6 @@ Additionally, you can add assets manually by calling `ResourcePackBuilder.addDat
You can get instance of it by listening to `PolymerResourcePackUtils.RESOURCE_PACK_CREATION_EVENT`.
Just keep in minds that new one will be created every time resource pack is generated.

### Requesting model for item
After that you can register your models by calling
`PolymerModelData PolymerResourcePackUtils.requestModel(Item vanillaItem, Identifier modelPath)`.
It returns `PolymerModelData` with contains all information you need for applying custom model data
to your items. You need to keep in mind, that modelPath needs to contain main directory (in similar way
to vanilla models). While model is created, all it's overrides are copied and applied, so you don't need to
request them manually (useful for bows).

You can execute this function before making your mod an asset source, but it should be run before
resource pack is build.

Example use:

```
PolymerModelData modelData = PolymerResourcePackUtils.requestModel(Items.IRON_SWORD, Identifier.of("mymod", "item/silver_sword"));
```

### Requesting armor textures
Polymer supports custom armor textures thanks to usage of [Ancientkingg's fancyPants resource pack](https://github.com/Ancientkingg/fancyPants).

To request it you need to use `PolymerResourcePackUtils.requestArmor(Identifier)`.
It will automatically create variant of every armor peace, however you aren't
required to use/define them all.

To apply it to your armor, you need to set your client side item to leather armor peace.
Then you need to override `PolymerItem.getPolymerArmorColor()` method and return used color.

```
PolymerArmorModel armorModel = PolymerResourcePackUtils.requestArmor(Identifier.of("mymod", "silver"));
```

## Checking players
Checking if player has resource pack is quite simple.
You just need to call `boolean PolymerResourcePackUtils.hasPack(ServerPlayerEntity player)`.
Expand All @@ -71,4 +40,5 @@ One exception is resource pack on client, which will get effected by that.
I also recommend you to keep it optional if it's possible.

## Building resource pack
To create resource pack you only need to execute `/polymer generate-pack` command. Resource pack will be located in your server folder as `polymer-resourcepack.zip`.
To create resource pack you only need to execute `/polymer generate-pack` command.
Resource pack will be located in your server folder as `polymer/resourcepack.zip`.

0 comments on commit c88b3cf

Please sign in to comment.