diff --git a/docs/curios/Developing with Curios/APIs/renderer-interface.md b/docs/curios/Developing with Curios/APIs/renderer-interface.md new file mode 100644 index 0000000..1599bfd --- /dev/null +++ b/docs/curios/Developing with Curios/APIs/renderer-interface.md @@ -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| \ No newline at end of file diff --git a/docs/curios/Developing with Curios/curio-creation.md b/docs/curios/Developing with Curios/curio-creation.md new file mode 100644 index 0000000..2855cef --- /dev/null +++ b/docs/curios/Developing with Curios/curio-creation.md @@ -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` and use its methods: +```java +@SubscribeEvent +public void attachCapabilities(AttachCapabilitiesEvent 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. diff --git a/docs/curios/Developing with Curios/getting-started.md b/docs/curios/Developing with Curios/getting-started.md new file mode 100644 index 0000000..fd390f8 --- /dev/null +++ b/docs/curios/Developing with Curios/getting-started.md @@ -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 +``` diff --git a/docs/curios/Developing with Curios/rendering-registry.md b/docs/curios/Developing with Curios/rendering-registry.md new file mode 100644 index 0000000..717da68 --- /dev/null +++ b/docs/curios/Developing with Curios/rendering-registry.md @@ -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 > void render(ItemStack stack, + SlotContext slotContext, + PoseStack matrixStack, + RenderLayerParent 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. +::: diff --git a/docs/curios/commands.md b/docs/curios/commands.md new file mode 100644 index 0000000..a857c5d --- /dev/null +++ b/docs/curios/commands.md @@ -0,0 +1,114 @@ +--- +sidebar_position: 14 +--- + +# Commands + +A tutorial on the various commands available through Curios. + +## Command Guide +--- +|Syntax|Meaning| +|-----------|-----------| +|`plain text`|**Enter this literally**, exactly as shown.| +|``|An **argument** that should be replaced with an appropriate value.| +|`[entry]`|This entry is **optional**.| + +## Syntax +--- +All the commands begin with `curios` and have the following options: + +* `list` + * Outputs a list of slot identifiers, categorized by mod. +* `replace with [amount]` + * Places the specified item in the specified slot on the target player. +* `set [amount]` + * Sets a number of slots for the specified slot type on the target player. +* `add [amount]` + * Adds a number of slots for the specified slot type on the target player. +* `remove [amount]` + * Removes a number of slots for the specified slot type on the target player. +* `clear [slotId]` + * Clears the specified slot type of all its items. If no slot type is specified, all curios items will be cleared. +* `drop [slotId]` + * Drops all the items in the specified slot type. If no slot type is specified, all curios items will be dropped. +* `reset ` + * Resets the target player's curios inventory to its default slots, also clears all curios items. + +## Arguments +--- +* ``: [player](https://minecraft.fandom.com/wiki/Argument_types#minecraft:entity) + * Specifies the player to perform the command on. + * Must be a player name, a target selector, or a UUID. + +* ``: [int](https://minecraft.fandom.com/wiki/Argument_types#int) + * Specifies the quantity of slots or items. + * Must be a whole number greater than or equal to 1. + +* ``: [int](https://minecraft.fandom.com/wiki/Argument_types#int) + * Specifies the index within the slot type. + * Must be a whole number greater than or equal to 0. + +* ``: [slot_identifier](slot-register) + * Specifies a slot type. + * Must be an identifier of a registered slot type. + +## Examples +--- +* To add 3 `"ring"` slots to a player: + * `curios add ring Player123 1` + +* To place a `"minecraft:totem_of_undying"` item in the first `"charm"` slot found on a player: + * `curios replace charm 0 Player123 with minecraft:totem_of_undying 1` + +## Entity Selector Options +--- +Curios has a custom entity selector option to use with commands that target entities, such as @a or @p. + +The option starts with curios= and takes in a single **CompoundTag** as an argument. A blank tag would be `curios={}`. + +### Tag Format +The **CompoundTag** has the following fields: + +* `item` + * **required:** false + * **type:** **CompoundTag** + * **description:** Denotes an item to match in the target's curios inventory. + * **Example:** + * `curios={item:{id:"minecraft:glass_bottle"}}` + * This will search for a `minecraft:glass_bottle` in the target's curios inventory. + +* `slot` + * **required:** false + * **type:** string[] + * **description:** Denotes a slot type to search in the target's curios inventory. + * **Example:** + * `curios={slot:["ring"]}` + * This will search for `"ring"` slots in the target's curios inventory. + +* `index` + * **required:** false + * **type:** int[min, max] + * **description:** Denotes the indices in slots to search in the target's curios inventory. + * **Example:** + * `curios={index:[0,1]}` + * This will search for the first index of each slot type in the target's curios inventory. + +* `exclusive` + * **required:** false + * **type:** boolean + * **description:** Denotes whether the selector is searching for only one match. + * **Example:** + * `curios={slot:["ring"],exclusive:true}` + * This will search for `"ring"` slots in the target's curios inventory but will not return a match if any other slot type is found in the inventory as well. + +### Inverting + +The selector option also supports inverting. Placing a `!` before the **CompoundTag** will invert the search. +For example, `curios=!{slot:["ring"]}` will search for targets that do *not* have `"ring"` slots in their curios inventory. + +### Examples + +* To kill all players who have a `minecraft:glass_bottle` in a `"ring"` slot of the curios inventory: + * `/kill @a[curios={item:{id:"minecraft:glass_bottle"},slot:["ring"]}]` + \ No newline at end of file diff --git a/docs/curios/curios-nbt.md b/docs/curios/curios-nbt.md index 2ae9095..32fc0c7 100644 --- a/docs/curios/curios-nbt.md +++ b/docs/curios/curios-nbt.md @@ -2,11 +2,12 @@ sidebar_position: 12 --- -# Curio Item NBT +# Curios Attribute Modifiers (NBT) A tutorial on how to edit a curio item's NBT data to add attribute modifiers when the item is worn in a curio slot. ## Overview +--- Attribute modifiers used in item NBT for regular equipment slots will not work with curio slots. This is because the attribute modifiers are coded to work only in specific slots, and it will not recognize the custom curio slots. In order to grant this functionality, Curios adds its own method of adding NBT attribute modifiers in items. diff --git a/docs/curios/entity-register.md b/docs/curios/entity-register.md index d4a94f2..01d794e 100644 --- a/docs/curios/entity-register.md +++ b/docs/curios/entity-register.md @@ -2,11 +2,12 @@ sidebar_position: 3 --- -# Add a Slot Type to an Entity +# Adding Slot Types to Entities -A tutorial on how to add a registered slot type to an entity. +A tutorial on how to add registered slot types to entities. ## Overview +--- Beginning in 1.20, the recommended way to add a registered slot type to an entity is through a datapack. If you are unfamiliar with datapacks, it is recommended to read through the [wiki page](https://minecraft.fandom.com/wiki/Data_pack) in order to understand the concept and structure before proceeding to the rest of this page. diff --git a/docs/curios/preset-slots.md b/docs/curios/preset-slots.md index a959d9d..8da5e59 100644 --- a/docs/curios/preset-slots.md +++ b/docs/curios/preset-slots.md @@ -7,7 +7,7 @@ sidebar_position: 10 A list of commonly used slot types that are already defined in Curios for developers to use. ## Overview - +--- One of the benefits of using Curios is that multiple developers can share slot types between each other, allowing mechanics and items to cooperate seamlessly. As long as the `identifier` for the slot type is the same, the slot types will be merged together upon registration. To reduce the need for redundant code and data, Curios provides a preset diff --git a/docs/curios/slot-register.md b/docs/curios/slot-register.md index 8a95e04..002e23e 100644 --- a/docs/curios/slot-register.md +++ b/docs/curios/slot-register.md @@ -2,11 +2,12 @@ sidebar_position: 1 --- -# Register a Slot Type +# Registering Slot Types -A tutorial on how to register a slot type that is recognized by Curios. +A tutorial on how to register slot types that are recognized by Curios. ## Overview +--- Beginning in 1.20, the recommended way to register a slot type is through a datapack. If you are unfamiliar with datapacks, it is recommended to read through the [wiki page](https://minecraft.fandom.com/wiki/Data_pack) in order to understand the concept and structure before proceeding to the rest of this page. diff --git a/docs/curios/slot-textures.md b/docs/curios/slot-textures.md index 78980bd..0020633 100644 --- a/docs/curios/slot-textures.md +++ b/docs/curios/slot-textures.md @@ -2,16 +2,17 @@ sidebar_position: 5 --- -# Adding a Custom Slot Texture +# Adding Custom Slot Textures -A tutorial on how to add a custom slot texture to a slot type. +A tutorial on how to add custom slot textures to slot types. ## Overview +--- Registering a new custom slot texture can be done through a resource pack. If you are unfamiliar with resource packs, it is recommended to read through the [wiki page](https://minecraft.fandom.com/wiki/Resource_pack) in order to understand the concept and structure before proceeding to the rest of this page. -# Registering a Slot Texture +## Registering a Slot Texture --- Create a new resource directory `assets/(namespace)/textures/slot` and place any `.png` file in the `slot` folder. @@ -27,7 +28,7 @@ part of a mod, the namespace is usually the mod ID. If this is part of a user-de can be anything that is lowercased with no special characters. ::: -# Using a Slot Texture +## Using a Slot Texture --- When entering the fields of the `.json` slot registration files as described in [Register a Slot Type](./slot-register), diff --git a/docusaurus.config.js b/docusaurus.config.js index 5fdbddf..df2ba87 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -91,6 +91,7 @@ const config = { copyright: `Copyright © ${new Date().getFullYear()} Illusive Soulworks, Built with Docusaurus.`, }, prism: { + additionalLanguages: ['java', 'gradle'], theme: lightCodeTheme, darkTheme: darkCodeTheme, }, diff --git a/versioned_docs/version-1.18.x/champions/commands.md b/versioned_docs/version-1.18.x/champions/commands.md index 87a16ca..89ac6fe 100644 --- a/versioned_docs/version-1.18.x/champions/commands.md +++ b/versioned_docs/version-1.18.x/champions/commands.md @@ -4,7 +4,7 @@ sidebar_position: 6 # Commands -All of the Champions commands are available through `/champions`. +All the Champions commands are available through `/champions`. ## Command Guide |Syntax|Meaning|