-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
898ca80
commit 116f24f
Showing
12 changed files
with
508 additions
and
11 deletions.
There are no files selected for viewing
88 changes: 88 additions & 0 deletions
88
docs/curios/Developing with Curios/APIs/renderer-interface.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
--- | ||
sidebar_position: 1 | ||
--- | ||
|
||
# `ICurioRenderer` | ||
|
||
## Methods | ||
|
||
* [Reference](#reference) | ||
* [render()](#render) | ||
* [static translateIfSneaking()](#static-translateifsneaking) | ||
* [static rotateIfSneaking()](#static-rotateifsneaking) | ||
* [static followHeadRotations()](#static-followheadrotations) | ||
* [static followBodyRotations()](#static-followbodyrotations) | ||
|
||
## Reference | ||
|
||
### `render()` | ||
--- | ||
Runs the rendering code when an associated item is equipped in a curio slot and the visibility of the rendering is | ||
enabled. An equipped cosmetic item will override the rendering of its related functional item. | ||
|
||
**Parameters:** | ||
|
||
|Name|Type|Description| | ||
|-----------|-----------|-----------| | ||
|`stack`|`ItemStack`|`ItemStack` being rendered| | ||
|`slotContext`|`SlotContext`|`SlotContext` for the slot with the `ItemStack` being rendered| | ||
|`poseStack`|`PoseStack`|`PoseStack` passed from the parent `RenderLayer`| | ||
|`renderLayerParent`|`RenderLayerParent`|`RenderLayerParent` passed from the parent `RenderLayer`| | ||
|`light`|integer|Light value| | ||
|`limbSwing`|float|Limb swing value| | ||
|`limbSwingAmount`|float|Limb swing amount value| | ||
|`partialTicks`|float|Partial ticks value| | ||
|`ageInTicks`|float|Age in ticks value| | ||
|`netHeadYaw`|float|Net head yaw value| | ||
|`headPitch`|float|Head pitch value| | ||
|
||
### `static translateIfSneaking()` | ||
--- | ||
Applies a translation to the given `PoseStack` if the given `LivingEntity` is crouching. This is called to have the | ||
render appropriately adjust its positioning up or down based on the crouching status of the entity. | ||
|
||
**Parameters:** | ||
|
||
|Name|Type|Description| | ||
|-----------|-----------|-----------| | ||
|`poseStack`|`PoseStack`|`PoseStack` passed from the parent `RenderLayer`| | ||
|`livingEntity`|`LivingEntity`|`LivingEntity` to check `isCrouching()`| | ||
|
||
### `static rotateIfSneaking()` | ||
--- | ||
Applies a rotation to the given `PoseStack` if the given `LivingEntity` is crouching. This is called to have the | ||
render appropriately adjust its rotations based on the crouching status of the entity. Specifically, these rotations | ||
are based on the body/torso rotations of the entity. | ||
|
||
**Parameters:** | ||
|
||
|Name|Type|Description| | ||
|-----------|-----------|-----------| | ||
|`poseStack`|`PoseStack`|`PoseStack` passed from the parent `RenderLayer`| | ||
|`livingEntity`|`LivingEntity`|`LivingEntity` to check `isCrouching()` and rotate around| | ||
|
||
### `static followHeadRotations()` | ||
--- | ||
Applies rotations to the given `ModelPart`s based on the given `LivingEntity` and its head rotations. This is called to | ||
render the model parts in alignment with the entity's head. This does nothing if the entity's renderer does not | ||
implement `LivingEntityRenderer` or if the model does not have a head inherited from the `HumanoidModel` class. | ||
|
||
**Parameters:** | ||
|
||
|Name|Type|Description| | ||
|-----------|-----------|-----------| | ||
|`livingEntity`|`LivingEntity`|`LivingEntity` to align the rotations around| | ||
|`modelParts`|`ModelPart...`|List of model parts to align to the head movement| | ||
|
||
### `static followBodyRotations()` | ||
--- | ||
Applies rotations to the given `HumanoidModel`s based on the given `LivingEntity` and its rotations. This is called to | ||
render the model parts in alignment with the entity's movements, such as their leg and arm movements when walking or | ||
interacting with objects. | ||
|
||
**Parameters:** | ||
|
||
|Name|Type|Description| | ||
|-----------|-----------|-----------| | ||
|`livingEntity`|`LivingEntity`|`LivingEntity` to align the rotations around| | ||
|`models`|`HumanoidModel...`|List of model parts to align to the body movement| |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
--- | ||
sidebar_position: 2 | ||
--- | ||
|
||
# Creating a Curio | ||
|
||
A tutorial on how to attach curio capabilities to your items. | ||
|
||
## Overview | ||
--- | ||
Curios comes with interfaces that you can attach to your items in order to define certain behaviors for those items when | ||
interacting with curios slots. This includes events such as ticking while in a curio slot or triggering certain actions | ||
when equipped or unequipped into a curio slot. | ||
|
||
There are three main ways to implement the capability on your item: directly attaching an `ICurio` implementation as a | ||
capability, extending the `ICurioItem` interface on your item, or registering an `ICurioItem` implementation to an item. | ||
|
||
Only **one** of these methods needs to be implemented for the curio item to work. | ||
|
||
## Attaching an `ICurio` capability | ||
--- | ||
This is recommended for mods that are Forge-oriented, due to the use of capabilities, and want to attach the | ||
capability optionally to their own items or another mod's items. | ||
|
||
To attach the capability to your own items, override the `IForgeItem#initCapabilities` method: | ||
```java | ||
@Override | ||
public ICapabilityProvider initCapabilities(ItemStack stack, CompoundTag unused) { | ||
return CuriosApi.createCurioProvider(new ICurio() { | ||
|
||
@Override | ||
public ItemStack getStack() { | ||
return stack; | ||
} | ||
|
||
@Override | ||
public void curioTick(SlotContext slotContext) { | ||
// ticking logic here | ||
} | ||
}); | ||
} | ||
``` | ||
The `ICurio` implementation in the example can be replaced or extended by your own custom implementation. The | ||
implementation can also exist in a separate class altogether as long as the instantiation is still done in the | ||
`IForgeItem#initCapabilities` method. | ||
|
||
To attach the capability to any item, including vanilla's and other mods', subscribe to the | ||
`AttachCapabilitiesEvent<ItemStack>` and use its methods: | ||
```java | ||
@SubscribeEvent | ||
public void attachCapabilities(AttachCapabilitiesEvent<ItemStack> evt) { | ||
ItemStack stack = evt.getObject(); | ||
Item item = stack.getItem(); | ||
evt.addCapability(CuriosCapability.ID_ITEM, CuriosApi.createCurioProvider(new ICurio() { | ||
|
||
@Override | ||
public ItemStack getStack() { | ||
return stack; | ||
} | ||
|
||
@Override | ||
public void curioTick(SlotContext slotContext) { | ||
// ticking logic here | ||
} | ||
})); | ||
} | ||
``` | ||
|
||
:::note | ||
You will need to pass in the `ItemStack` from the `IForgeItem#initCapabilities` argument or the | ||
`AttachCapabilitiesEvent#getObject` result to the return of `ICurio#getStack` as shown in the example. This makes sure | ||
that the implementation receives the correct `ItemStack` for further curios logic. Technically, `ICurio#getStack` can | ||
return any stack if proxies are needed, but the use-case for that is outside the scope of this documentation. | ||
::: | ||
|
||
## Implementing the `ICurioItem` interface | ||
--- | ||
This is recommended for mods that want the simplest and most straightforward method, do not mind having Curios as a | ||
required dependency, and are only working with their own items. | ||
|
||
To implement the `ICurioItem` interface, simply implement it on your item class: | ||
```java | ||
public class CurioItem extends Item implements ICurioItem { | ||
|
||
public CurioItem() { | ||
super(new Item.Properties().stacksTo(1).defaultDurability(0)); | ||
} | ||
|
||
@Override | ||
public void curioTick(SlotContext slotContext, ItemStack stack) { | ||
// ticking logic here | ||
} | ||
} | ||
``` | ||
|
||
## Registering an `ICurioItem` implementation | ||
--- | ||
This is recommended for multi-loader mods as a platform-agnostic method of registering Curios behavior to their own | ||
items or another mod's items that can be loaded optionally. | ||
|
||
To register an `ICurioItem` implementation, first create the implementation: | ||
```java | ||
public class CurioItem implements ICurioItem { | ||
|
||
@Override | ||
public void curioTick(SlotContext slotContext, ItemStack stack) { | ||
// ticking logic here | ||
} | ||
} | ||
``` | ||
|
||
And then register it by using `CurioApi#registerCurio`: | ||
```java | ||
CuriosApi.registerCurio(CurioModItems.MY_ITEM, new CurioItem()); | ||
``` | ||
|
||
Registration can occur at any time, but for simplicity can be called during the `FMLCommonSetupEvent` phase during mod | ||
loading: | ||
|
||
```java | ||
@Mod("CurioMod") | ||
public class CurioMod { | ||
|
||
public CurioMod() { | ||
final IEventBus eventBus = FMLJavaModLoadingContext.get().getModEventBus(); | ||
eventBus.addListener(this::setup); | ||
} | ||
|
||
private void setup(final FMLCommonSetupEvent evt) { | ||
CuriosApi.registerCurio(CurioModItems.MY_ITEM, new CurioItem()); | ||
} | ||
} | ||
``` | ||
|
||
## Priority | ||
--- | ||
In situations where multiple implementations are registered to the same item, there a few things to take note of: | ||
* Only one implementation will be used on any one item, any other implementations found will be ignored. | ||
* `ICurio` capabilities initialized through `IForgeItem#initCapabilities` will always be prioritized and other | ||
implementations will be ignored. | ||
* `ICurioItem` implementations registered through `CuriosApi#registerCurio` will be prioritized over `ICurioItem` | ||
implementations directly on the item class. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
--- | ||
sidebar_position: 1 | ||
--- | ||
|
||
# Setting Up the Development Environment | ||
|
||
A tutorial on how to set up your development workspace to work with Curios API interfaces and methods. | ||
|
||
## Set up your build script | ||
--- | ||
### Add repository | ||
|
||
First, add the repository hosting the Curios API files by adding the following to your build script's | ||
`repositories` block: | ||
|
||
```gradle | ||
repositories { | ||
maven { | ||
name = "Illusive Soulworks maven" | ||
url = "https://maven.theillusivec4.top/" | ||
} | ||
} | ||
``` | ||
|
||
### Add dependencies | ||
|
||
Secondly, add the Curios API dependencies to your build script's `dependencies` block: | ||
|
||
```gradle | ||
dependencies { | ||
// Compile against only the API artifact | ||
compileOnly(fg.deobf("top.theillusivec4.curios:curios-forge:${curios_version}:api")) | ||
// Use the full Curios API jar at runtime | ||
runtimeOnly(fg.deobf("top.theillusivec4.curios:curios-forge:${curios_version}")) | ||
} | ||
``` | ||
|
||
:::note | ||
**Why compile against only the API artifact?** | ||
|
||
Compiling against only the API artifact is recommended because the artifact only contains the public API packages, | ||
interfaces, and methods. These are all intended to be stable and will not break within the same major version if used. | ||
The same cannot be said about internal packages and methods, which may accidentally be used if the full jar is included | ||
during compile time. Including the full jar at runtime still means that testing can occur normally in development. | ||
|
||
If there is an internal package and or method you would like to use, please make a suggestion on the [issue tracker](https://github.com/TheIllusiveC4/Curios/issues) | ||
so that it may potentially be included in the public API. | ||
::: | ||
|
||
### Configure runs for mixin | ||
|
||
Finally, since Curios uses mixins, your run configurations will need to ensure that the remapping functions correctly: | ||
|
||
```gradle | ||
property 'mixin.env.remapRefMap', 'true' | ||
property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg" | ||
``` | ||
|
||
Add the above code block into each of the run configurations that you plan on using, for example: | ||
|
||
```gradle | ||
runs { | ||
client { | ||
property 'mixin.env.remapRefMap', 'true' | ||
property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg" | ||
} | ||
} | ||
``` | ||
|
||
Remember to regenerate the run configurations after changing the settings. | ||
|
||
## Select a version | ||
--- | ||
If you followed the steps above, `${curios_version}` should be defined so that it is replaced by the specific Curios API | ||
version that you want to use. This property can be set up by including a mapping in the `gradle.properties` file located | ||
in the same directory as the `build.gradle` file. | ||
|
||
Please see [CurseForge](https://www.curseforge.com/minecraft/mc-mods/curios/files), [Modrinth](https://modrinth.com/mod/curios/versions), | ||
or the [maven](https://maven.theillusivec4.top/top/theillusivec4/curios/curios-forge/) for possible versions. | ||
|
||
Example in `gradle.properties`: | ||
``` | ||
curios_version=5.3.1+1.20.1 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
--- | ||
sidebar_position: 8 | ||
--- | ||
|
||
# Rendering a Curio | ||
|
||
A tutorial on how to run rendering code when a specific curio item is equipped on an entity. | ||
|
||
## Create an `ICurioRenderer` | ||
--- | ||
In the `top.theillusivec4.curios.api.client` package, you'll find an interface called `ICurioRenderer`. This interface | ||
needs to be implemented on an object of your choice, as its `render` method is what will be called to run your rendering | ||
code later. | ||
|
||
For the full guide on the interface, see [here](APIs/renderer-interface.md). | ||
|
||
### Example | ||
```java | ||
public class MyCurioRenderer implements ICurioRenderer { | ||
|
||
@Override | ||
public <T extends LivingEntity, M extends EntityModel<T>> void render(ItemStack stack, | ||
SlotContext slotContext, | ||
PoseStack matrixStack, | ||
RenderLayerParent<T, M> renderLayerParent, | ||
MultiBufferSource renderTypeBuffer, | ||
int light, float limbSwing, | ||
float limbSwingAmount, | ||
float partialTicks, | ||
float ageInTicks, | ||
float netHeadYaw, | ||
float headPitch) { | ||
// Render code goes here | ||
} | ||
} | ||
``` | ||
|
||
## Register your renderer | ||
--- | ||
Once you have an implementation of `ICurioRenderer`, you need to register an instance of that to an item. This is done | ||
by calling the `register` method in `top.theillusivec4.curios.api.client.CuriosRendererRegistry` during the | ||
`FMLClientSetupEvent` in mod loading. | ||
|
||
### Example | ||
```java | ||
@Mod("CurioMod") | ||
public class CurioMod { | ||
|
||
public CurioMod() { | ||
final IEventBus eventBus = FMLJavaModLoadingContext.get().getModEventBus(); | ||
eventBus.addListener(this::clientSetup); | ||
} | ||
|
||
private void clientSetup(final FMLClientSetupEvent evt) { | ||
CuriosRendererRegistry.register(CurioModItems.MY_ITEM, () -> new MyCurioRenderer()); | ||
} | ||
} | ||
``` | ||
|
||
:::tip | ||
Multiple items are allowed to share a renderer instance or type. This can be handy if your `ICurioRenderer` | ||
implementation shares a lot of common code or if your items have very similar renders, in which case you may find it | ||
advantageous to simply register those items with a single renderer rather than multiple. | ||
::: |
Oops, something went wrong.