tutorial:shield
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| tutorial:shield [2023/09/26 00:09] – added warning cringestar_boi | tutorial:shield [2025/11/13 23:28] (current) – Updated to 1.21.5 and added and added a section on the conditional model format needed to make the shield work bouncingelf10 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | __**!!OUTDATED AND BEING WORKED ON !!**__ | + | ====== Making a Custom Shield in Minecraft [1.19-1.21.5] ====== |
| + | :!: The tutorial depends on third-party libraries. | ||
| - | ====== Making a Custom Shield | + | Congrats! You just learned how to create your custom tools in the last tutorial! Now imagine you want to shield yourself from that sword if your friend got it. If you made it too op, a regular shield won't do. So we will see how to make a custom shield. |
| - | Congrats! You just learned how to create your custom sword in the last tutorial! Now imagine you want to shield yourself from that sword if your friend got it. If you made it too op, a regular shield won't do. So we will see how to make a custom shield.\\ | + | Luckily, |
| - | Luckily, | + | |
| - | Library | + | The library |
| Library compiled as a jar is available at https:// | Library compiled as a jar is available at https:// | ||
| Line 12: | Line 12: | ||
| ===== Adding the library to your project ===== | ===== Adding the library to your project ===== | ||
| - | Add the following code to the files mentioned:\\ \\ | + | Add the following code to the files mentioned: |
| - | **gradle.properties**\\ | + | |
| - | <code java> | + | |
| - | fabric_shield_lib_version=1.6.0-1.19 | + | |
| - | </ | + | |
| - | **build.gradle** (under dependencies)\\ | + | |
| - | <code java> | + | |
| - | modImplementation " | + | |
| - | </ | + | |
| - | At the time of writing, latest project.fabric_shield_lib_version should be 1.6.0-1.19. This page will be updated whenever a new update comes out.\\ \\ | + | |
| - | **build.gradle** (under repositories, | + | |
| - | <code java> | + | |
| - | maven { url = ' | + | |
| - | </ | + | |
| - | __//**If you are doing this in Minecraft version | + | **gradle.properties** |
| + | <file properties gradle.properties> | ||
| + | fabric_shield_lib_version=1.8.3-1.21.5 | ||
| + | mod_menu_version=14.0.0 | ||
| + | midnightlib_version=1.7.3+1.21.4-fabric | ||
| + | fabricasm_version=2.3 | ||
| + | </file> | ||
| - | **gradle.properties**\\ | + | Find the corresponding mod versions for your Minecraft version |
| - | <code java> | + | |
| - | fabric_asm_version=2.3 | + | |
| - | cloth_version=8.1.77 | + | |
| - | mod_menu_version=4.0.6 | + | |
| - | crowdlin_version=1.4+1.19 | + | |
| - | </ | + | |
| - | **(These versions will be updated in this wiki alongside the mod version)** | + | **build.gradle** (under '' |
| + | <file groovy build.gradle> | ||
| + | modImplementation " | ||
| + | modImplementation " | ||
| + | modImplementation " | ||
| + | modImplementation " | ||
| + | </ | ||
| - | **build.gradle** (under dependencies)\\ | + | At the time of writing, these are the most up-to-date FabricShieldLib versions: |
| - | <code java> | + | |
| + | * **1.21.4** ('' | ||
| + | * **1.21.2** - **1.21.3** ('' | ||
| + | * **1.21** - **1.21.1** ('' | ||
| + | * **1.20.5** - **1.20.6** ('' | ||
| + | * **1.20.2** - **1.20.4** ('' | ||
| + | * **1.20** - **1.20.1** ('' | ||
| + | * **1.19.3** - **1.19.4** ('' | ||
| + | * **1.19** - **1.19.2** ('' | ||
| + | * **1.18.2** ('' | ||
| + | * **1.17.1** ('' | ||
| + | **build.gradle** (inside '' | ||
| + | <file groovy build.gradle> | ||
| + | maven {url = ' | ||
| + | maven {url " | ||
| + | maven {url = " | ||
| + | </ | ||
| - | modApi("me.shedaniel.cloth: | + | __// |
| - | exclude(group: | + | |
| - | } | + | |
| - | include(" | + | |
| - | modCompileOnly modRuntimeOnly (" | + | ===== Adding a custom shield ===== |
| - | exclude(group: | + | **If you want your shield to support banner decoration on your shield, please skip to the next section** |
| - | } | + | |
| - | modImplementation(" | + | On to the non-boring steps! We will now make a custom shield! |
| - | exclude (group: " | + | |
| - | } | + | |
| - | include(" | + | |
| - | </ | + | If you have followed the above steps correctly and refreshed the project, then you will have the FabricShieldLib installed. |
| - | **build.gradle** (under repositories, | + | If so, the first step to do is create a new instance of an '' |
| - | <code java> | + | <code java TutorialItems> |
| - | maven { url " | + | public final class TutorialItems { |
| - | maven { url " | + | // ... |
| - | </ | + | |
| - | + | | |
| - | ===== Adding a custom shield ===== | + | // ... |
| - | **If you want your shield to support banner decoration, there are extra steps that will be covered after the main creation.**\\ | + | } |
| - | On to the non-boring steps! We will now make a custom shield!\\ \\ | + | |
| - | If you have followed the above steps correctly and refreshed the project, then you will have the fabric shield api installed.\\ | + | |
| - | If so, the first step to do is create a new instance of an Item like: | + | |
| - | <code java> | + | |
| - | public static final Item NETHERITE_SHIELD = new FabricShieldItem(new | + | |
| </ | </ | ||
| - | Then, we have to register it, like so: | + | If you want to add your shield to a [[itemgroup|item groups]], for example, the "Combat" |
| - | + | ||
| - | <code java> | + | |
| - | Registry.register(Registries.ITEM, new Identifier("examplemod", | + | |
| - | </ | + | |
| - | And our shield is done!\\ | + | < |
| - | Now, we have to create the textures and models of the shield.\\ | + | public class ExampleMod implements ModInitializer { |
| - | For the texture, you can use anything. A good place to start is looking at mojang' | + | ... |
| - | Now, for the models, we have to write a few .json files.\\ | + | |
| - | For the model file without blocking, we use: \\ | + | |
| - | <code javascript> | + | |
| - | { | + | |
| - | | + | |
| - | | + | }); |
| - | | + | ... |
| - | }, | + | } |
| - | " | + | |
| - | { | + | |
| - | | + | |
| - | " | + | |
| - | | + | |
| - | " | + | |
| - | } | + | |
| - | | + | |
| } | } | ||
| - | </code>\\ | + | </yarncode> |
| - | Put it in '' | + | |
| - | For the blocking model, use this: \\ | + | |
| - | <code javascript> | + | |
| - | { | + | |
| - | " | + | |
| - | } | + | |
| - | </ | + | |
| - | Plop it in resources/ | + | |
| - | Don't forget to add it to **en_us.json** in '' | + | |
| - | <code javascript> | + | |
| - | { | + | |
| - | " | + | |
| - | } | + | |
| - | </ | + | |
| - | And with that, your shield is done! | + | |
| + | And our shield is (code-wise) done! | ||
| - | ===== Adding banner support | + | Now, we have to create the textures and models of the shield. |
| - | If you are using 1.17/1.18 instead of 1.19, please change versions | + | For the texture, |
| - | <code java> | + | |
| - | fabric_shield_lib_version=1.5.3-1.18 | + | |
| - | fabric_asm_version=2.3 | + | |
| - | cloth_version=6.2.57 | + | |
| - | mod_menu_version=3.0.1 | + | |
| - | crowdlin_version=1.4+1.18 | + | |
| - | </code> | + | |
| - | or | + | |
| - | <code java> | + | |
| - | fabric_shield_lib_version=1.5.3-1.17 | + | |
| - | fabric_asm_version=2.3 | + | |
| - | cloth_version=5.3.63 | + | |
| - | mod_menu_version=2.0.15 | + | |
| - | crowdlin_version=1.3+1.17 | + | |
| - | </ | + | |
| + | Now, for the models, we have to write a few .json files. | ||
| - | This is where mixins get involved. | + | Inside '' |
| - | First thing you will want to do is to change | + | <file javascript resources/assets/tutorial/models/item/netherite_shield.json> |
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </file> | ||
| - | <code java> | + | In the same folder, create another file, '' |
| - | public static final Item NETHERITE_SHIELD = new FabricBannerShieldItem(new FabricItemSettings().maxDamage(2500).group(ItemGroup.COMBAT), 10, 13, Items.NETHERITE_INGOT); | + | <file javascript resources/assets/tutorial/ |
| - | </code> | + | { |
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </file> | ||
| - | Now, we have to register a few things in our '' | + | Assuming you've made the Item correctly, you should' |
| + | <file javascript resources/ | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | }, | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| - | To create | + | Then, as a [[tags|conventional tag]], |
| + | <code javascript resources/ | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | ] | ||
| + | } | ||
| + | </ | ||
| - | < | + | Lastly, to make it enchantable, |
| - | public class ExampleModClient implements ClientModInitializer | + | < |
| - | | + | { |
| - | | + | " |
| - | + | " | |
| - | } | + | |
| + | ] | ||
| } | } | ||
| </ | </ | ||
| - | Before we do any work in our client mod initializer, | + | Don't forget |
| - | + | <code javascript | |
| - | <code javascript> | + | |
| { | { | ||
| - | | + | "item.tutorial.netherite_shield": "Netherite Shield" |
| - | | + | |
| - | " | + | |
| - | "net.fabricmc.ExampleMod" | + | |
| - | ], | + | |
| - | " | + | |
| - | | + | |
| - | ] | + | |
| - | } | + | |
| - | [...] | + | |
| } | } | ||
| + | </ | ||
| + | And with that, your non-decorateable shield is done! | ||
| + | |||
| + | ===== Adding a custom shield with banner support ===== | ||
| + | The process is slightly different if you want to make your shield accept banners and decorateable like a vanilla shield. | ||
| + | |||
| + | We still make the item in the same way, just make it a '' | ||
| + | <code java TutorialItems> | ||
| + | public static final Item NETHERITE_BANNER_SHIELD = register(" | ||
| </ | </ | ||
| + | If you want to add your shield to a [[itemgroup|item groups]], for example, the " | ||
| + | |||
| + | < | ||
| + | public class ExampleMod implements ModInitializer { | ||
| + | @Override | ||
| + | public void onInitialize() { | ||
| + | ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT).register(entries -> { | ||
| + | // ... | ||
| + | entries.add(NETHERITE_BANNER_SHIELD); | ||
| + | }); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| - | Ok, so now that is done, we can work in our client initializer. | + | Now the item is created, we need to set up its rendering. For these steps, we are going to be working |
| First, we will need to create an '' | First, we will need to create an '' | ||
| <code java> | <code java> | ||
| + | @Environment(EnvType.CLIENT) | ||
| public class ExampleModClient implements ClientModInitializer { | public class ExampleModClient implements ClientModInitializer { | ||
| - | + | | |
| - | | + | |
| @Override | @Override | ||
| Line 193: | Line 201: | ||
| <code java> | <code java> | ||
| + | @Environment(EnvType.CLIENT) | ||
| public class ExampleModClient implements ClientModInitializer { | public class ExampleModClient implements ClientModInitializer { | ||
| - | public static final EntityModelLayer NETHERITE_SHIELD_MODEL_LAYER = new EntityModelLayer(new Identifier(" | + | public static final EntityModelLayer NETHERITE_SHIELD_MODEL_LAYER = new EntityModelLayer(Identifier.of("tutorial", " |
| @Override | @Override | ||
| public void onInitializeClient() { | public void onInitializeClient() { | ||
| - | | + | EntityModelLayerRegistry.registerModelLayer(NETHERITE_BANNER_SHILED_MODEL_LAYER, ShieldEntityModel:: |
| } | } | ||
| } | } | ||
| </ | </ | ||
| - | Then we will register | + | Then we will create |
| <code java> | <code java> | ||
| + | @Environment(EnvType.CLIENT) | ||
| public class ExampleModClient implements ClientModInitializer { | public class ExampleModClient implements ClientModInitializer { | ||
| - | + | | |
| - | | + | |
| + | public static ShieldEntityModel modelNetheriteShield; | ||
| @Override | @Override | ||
| public void onInitializeClient() { | public void onInitializeClient() { | ||
| EntityModelLayerRegistry.registerModelLayer(NETHERITE_SHIELD_MODEL_LAYER, | EntityModelLayerRegistry.registerModelLayer(NETHERITE_SHIELD_MODEL_LAYER, | ||
| - | ClientSpriteRegistryCallback.event(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE).register((atlasTexture, | ||
| - | registry.register(new Identifier(" | ||
| - | registry.register(new Identifier(" | ||
| - | }); | ||
| } | } | ||
| } | } | ||
| </ | </ | ||
| - | And now we get to the mixin. Don't worry, its an easy one. | + | And then register that shield model, |
| - | If this is your first time, [[tutorial: | ||
| - | |||
| - | We will make a class called '' | ||
| <code java> | <code java> | ||
| - | @Mixin (BuiltinModelItemRenderer.class) | + | @Environment(EnvType.CLIENT) |
| - | public class RendererMixin | + | public class ExampleModClient implements ClientModInitializer |
| + | public static final EntityModelLayer NETHERITE_SHIELD_MODEL_LAYER = new EntityModelLayer(Identifier.of(" | ||
| + | |||
| + | public static ShieldEntityModel modelNetheriteShield; | ||
| + | @Override | ||
| + | public void onInitializeClient() { | ||
| + | EntityModelLayerRegistry.registerModelLayer(NETHERITE_SHIELD_MODEL_LAYER, | ||
| + | | ||
| + | ShieldSetModelCallback.EVENT.register((loader) -> { | ||
| + | modelNetheriteShield = new ShieldEntityModel(loader.getModelPart(netherite_banner_shield_model_layer)); | ||
| + | return ActionResult.PASS; | ||
| + | }); | ||
| + | } | ||
| } | } | ||
| </ | </ | ||
| - | Then we will make the necessary | + | Next, we have to create our two '' |
| <code java> | <code java> | ||
| - | @Mixin (BuiltinModelItemRenderer.class) | + | @Environment(EnvType.CLIENT) |
| - | public class RendererMixin | + | public class ExampleModClient implements ClientModInitializer |
| - | private ShieldEntityModel modelNetheriteShield; | + | |
| - | private static final SpriteIdentifier NETHERITE_SHIELD_BASE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, | + | |
| - | private static final SpriteIdentifier NETHERITE_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, | + | |
| - | } | + | |
| - | </ | + | |
| - | Next, we need to @Shadow the '' | + | public static final EntityModelLayer netherite_banner_shield_model_layer |
| - | <code java> | + | |
| - | @Mixin (BuiltinModelItemRenderer.class) | + | |
| - | public | + | |
| - | private ShieldEntityModel modelNetheriteShield; | + | |
| - | private | + | |
| - | private static final SpriteIdentifier NETHERITE_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("examplemod"," | + | |
| - | @Final | + | public static ShieldEntityModel modelNetheriteShield; |
| - | @Shadow | + | |
| - | private EntityModelLoader entityModelLoader; | + | |
| - | } | + | |
| - | </ | + | |
| - | Now we will inject into the '' | + | public static final SpriteIdentifier |
| - | <code java> | + | public |
| - | @Mixin (BuiltinModelItemRenderer.class) | + | |
| - | public | + | |
| - | | + | |
| - | private | + | |
| - | | + | |
| - | | + | @Override |
| - | | + | public |
| - | private EntityModelLoader entityModelLoader; | + | |
| - | + | ||
| - | + | | |
| - | @Inject(method = " | + | |
| - | private | + | return ActionResult.PASS; |
| - | | + | }); |
| - | } | + | } |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | Now we get to the most important part of the mixin. We will inject a method to render a banner on our shield. | + | |
| - | + | ||
| - | <code java> | + | |
| - | @Mixin | + | |
| - | public class RendererMixin { | + | |
| - | | + | |
| - | private static final SpriteIdentifier NETHERITE_SHIELD_BASE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, | + | |
| - | private static final SpriteIdentifier NETHERITE_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, | + | |
| - | + | ||
| - | @Final | + | |
| - | @Shadow | + | |
| - | private EntityModelLoader entityModelLoader; | + | |
| - | + | ||
| - | + | ||
| - | @Inject(method = " | + | |
| - | private void setModelNetheriteShield(CallbackInfo ci){ | + | |
| - | this.modelNetheriteShield = new ShieldEntityModel(this.entityModelLoader.getModelPart(ExampleModClient.NETHERITE_SHIELD_MODEL_LAYER)); | + | |
| - | } | + | |
| - | + | ||
| - | @Inject(method = " | + | |
| - | private void mainRender(ItemStack stack, ModelTransformation.Mode mode, MatrixStack matrices, VertexConsumerProvider vertexConsumers, | + | |
| - | if (stack.isOf(ExampleMod.NETHERITE_SHIELD)) { | + | |
| - | FabricShieldLibClient.renderBanner(stack, | + | |
| - | //The first five parameters are taken from the method, while the last 3 you provide yourself. You will provide the model, and then your 2 sprite identifiers in the order of ''// | + | |
| - | '' | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | + | ||
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | That is now all of the complicated things done! We now only need to change our existing model, add a '' | + | |
| - | + | ||
| - | In your shield model, '' | + | |
| - | <code javascript> | + | |
| - | { | + | |
| - | " | + | |
| - | " | + | |
| - | { | + | |
| - | " | + | |
| - | " | + | |
| - | | + | |
| - | " | + | |
| - | | + | |
| - | ] | + | |
| } | } | ||
| </ | </ | ||
| - | You also have to change your blocking model for your shield, '' | + | Finally, we will want to go back to our item and add a component to it to store its model information like so: |
| - | <code javascript> | ||
| - | { | ||
| - | " | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | For this next step, you will add '' | ||
| - | Then, you will need to make a '' | ||
| - | |||
| - | Then, you will move both of these textures into '' | ||
| - | |||
| - | For one last thing, you will need to add names for each of your shield color variants in '' | ||
| - | <code javascript> | ||
| - | { | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | ===== Adding banner support to your shield (1.16) ===== | ||
| - | |||
| - | This is where mixins get involved. | ||
| - | |||
| - | First, change the fabric_shield_lib in **gradle.properties** | ||
| - | \\ | ||
| <code java> | <code java> | ||
| - | fabric_shield_lib_version=1.4.5-1.16 | + | public static final Item NETHERITE_BANNER_SHIELD |
| - | </code> | + | settings -> new FabricBannerShieldItem(settings, |
| - | \\ | + | new Item.Settings().maxDamage(2500).component(FabricShieldLib.MODEL_COMPONENT, |
| + | new FabricShieldModelComponent( | ||
| + | ExampleModClient.NETHERITE_BANNER_SHIELD_BASE.getTextureId(), | ||
| + | ExampleModClient.NETHERITE_BANNER_SHIELD_BASE_NO_PATTERN.getTextureId(), | ||
| + | ExampleModClient.netherite_banner_shield_model_layer.toString() // Your model layer, from the client initializer | ||
| + | ))); | ||
| - | Next thing you will want to do is to change // | ||
| - | |||
| - | <code java> | ||
| - | public static final Item NETHERITE_SHIELD = new FabricBannerShieldItem(new FabricItemSettings().maxDamage(2500).group(ItemGroup.COMBAT), | ||
| </ | </ | ||
| - | Now, we have to register a few things in our '' | ||
| - | To create | + | That is all of our code done, we only have a few json files to make. |
| - | <code java> | + | First, create a '' |
| - | public class ExampleModClient implements ClientModInitializer { | + | <code javascript |
| - | @Override | + | |
| - | public void onInitializeClient() { | + | |
| - | + | ||
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | Before we do any work in our client mod initializer, we need to register its entrypoint in '' | + | |
| - | + | ||
| - | <code javascript> | + | |
| { | { | ||
| - | | + | "sources": |
| - | | + | |
| - | "main": | + | "type": "single", |
| - | | + | "resource": "tutorial: |
| - | ], | + | }, |
| - | "client": | + | { |
| - | | + | "type": "single", |
| - | | + | "resource": "tutorial:entity/netherite_banner_shield_base_nopattern" |
| - | | + | |
| - | [...] | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | Ok, so now that is done, we can work in our client initializer. | + | |
| - | + | ||
| - | The only thing that we will need to do is register our 2 '' | + | |
| - | + | ||
| - | <code java> | + | |
| - | public class ExampleModClient implements ClientModInitializer { | + | |
| - | + | ||
| - | @Override | + | |
| - | | + | |
| - | | + | |
| - | registry.register(new Identifier("examplemod", "entity/ | + | |
| - | | + | |
| - | }); | + | |
| } | } | ||
| + | ] | ||
| } | } | ||
| </ | </ | ||
| - | And now we get to the mixin. Don't worry, its an easy one. | + | Next, inside |
| - | + | < | |
| - | If this is your first time, [[tutorial: | + | |
| - | + | ||
| - | We will make a class called '' | + | |
| - | <code java> | + | |
| - | @Mixin (BuiltinModelItemRenderer.class) | + | |
| - | public class RendererMixin { | + | |
| - | + | ||
| - | } | + | |
| - | </code> | + | |
| - | + | ||
| - | Then we will make the necessary | + | |
| - | < | + | |
| - | @Mixin (BuiltinModelItemRenderer.class) | + | |
| - | public class RendererMixin { | + | |
| - | private ShieldEntityModel modelNetheriteShield = new ShieldEntityModel; | + | |
| - | private static final SpriteIdentifier NETHERITE_SHIELD_BASE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, | + | |
| - | private static final SpriteIdentifier NETHERITE_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, | + | |
| - | } | + | |
| - | </code> | + | |
| - | + | ||
| - | Now we get to the most important part of the mixin. We will inject a method to render a banner on our shield. | + | |
| - | + | ||
| - | <code java> | + | |
| - | @Mixin (BuiltinModelItemRenderer.class) | + | |
| - | public class RendererMixin { | + | |
| - | private ShieldEntityModel modelNetheriteShield = new ShieldEntityModel; | + | |
| - | private static final SpriteIdentifier NETHERITE_SHIELD_BASE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, | + | |
| - | private static final SpriteIdentifier NETHERITE_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, | + | |
| - | + | ||
| - | @Inject(method = " | + | |
| - | private void mainRender(ItemStack stack, MatrixStack matrix, VertexConsumerProvider vertexConsumerProvider, | + | |
| - | if (stack.getItem() == ExampleMod.NETHERITE_SHIELD)) { | + | |
| - | FabricShieldLibClient.renderBanner(stack, | + | |
| - | //The first five parameters are taken from the method, while the last 3 you provide yourself. You will provide the model, and then your 2 sprite identifiers in the order of ''// | + | |
| - | '' | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | + | ||
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | That is now all of the complicated things done! We now only need to change our existing model, add a '' | + | |
| - | + | ||
| - | In your shield model, '' | + | |
| - | <code javascript> | + | |
| { | { | ||
| - | " | + | " |
| - | " | + | |
| - | { | + | |
| - | " | + | |
| - | " | + | |
| - | }, | + | |
| - | " | + | |
| - | } | + | |
| - | ] | + | |
| } | } | ||
| </ | </ | ||
| - | You also have to change your blocking model for your shield, '' | + | In the same folder, create another file, '' |
| - | + | <code javascript | |
| - | <code javascript> | + | |
| { | { | ||
| " | " | ||
| Line 497: | Line 321: | ||
| </ | </ | ||
| - | For this next step, you will add '' | + | For this next step, you will add a '' |
| - | Then, you will need to make a '' | + | |
| Then, you will move both of these textures into '' | Then, you will move both of these textures into '' | ||
| - | For one last thing, you will need to add names for each of your shield color variants in '' | + | Next, create a '' |
| - | <code javascript> | + | <code javascript |
| { | { | ||
| - | | + | |
| - | "item.examplemod.netherite_shield.red": | + | "values": |
| - | "item.examplemod.netherite_shield.orange" | + | "tutorial:netherite_banner_shield" |
| - | " | + | ] |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| } | } | ||
| - | </ | ||
| - | |||
| - | ===== Adding banner support to your shield (1.15) ===== | ||
| - | |||
| - | This is where mixins get involved. | ||
| - | |||
| - | First, change the fabric_shield_lib in **gradle.properties** | ||
| - | \\ | ||
| - | <code java> | ||
| - | fabric_shield_lib_version=1.4.5-1.15 | ||
| </ | </ | ||
| - | \\ | ||
| - | Next thing you will want to do is to change | + | Finally create a '' |
| - | + | < | |
| - | < | + | { |
| - | public static final Item NETHERITE_SHIELD = new FabricBannerShieldItem(new FabricItemSettings().maxDamage(2500).group(ItemGroup.COMBAT), | + | " |
| - | </ | + | " |
| - | + | | |
| - | Now, we have to register a few things in our '' | + | ] |
| - | + | ||
| - | To create our '' | + | |
| - | + | ||
| - | <code java> | + | |
| - | public class ExampleModClient implements ClientModInitializer | + | |
| - | | + | |
| - | | + | |
| - | + | ||
| - | } | + | |
| } | } | ||
| </ | </ | ||
| - | Before we do any work in our client mod initializer, | + | Don't forget |
| <code javascript> | <code javascript> | ||
| { | { | ||
| - | | + | |
| - | "entrypoints": | + | "item.tutorial.netherite_banner_shield.red": |
| - | "main": | + | "item.tutorial.netherite_banner_shield.orange": |
| - | "net.fabricmc.ExampleMod" | + | "item.tutorial.netherite_banner_shield.yellow": |
| - | ], | + | "item.tutorial.netherite_banner_shield.lime": "Lime Netherite Banner Shield", |
| - | "client": | + | " |
| - | "net.fabricmc.ExampleModClient" | + | "item.tutorial.netherite_banner_shield.light_blue": |
| - | ] | + | "item.tutorial.netherite_banner_shield.cyan": "Cyan Netherite Banner Shield", |
| - | | + | " |
| - | | + | |
| + | | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| } | } | ||
| </ | </ | ||
| - | Ok, so now that is done, we can work in our client initializer. | + | And now your shield |
| + | ===== Changes for 1.21.3 ===== | ||
| + | If you are working | ||
| + | |||
| + | <file properties gradle.properties> | ||
| + | mod_menu_version=12.0.0-beta.1 | ||
| + | midnightlib_version=1.6.4-fabric | ||
| + | </ | ||
| - | The only thing that we will need to do is register | + | Next, remove the '' |
| <code java> | <code java> | ||
| + | ... | ||
| + | import static com.github.crimsondawn45.fabricshieldlib.initializers.FabricShieldLibClient.renderBanner; | ||
| + | ... | ||
| public class ExampleModClient implements ClientModInitializer { | public class ExampleModClient implements ClientModInitializer { | ||
| - | + | ... | |
| - | @Override | + | @Override |
| - | public void onInitializeClient() { | + | public void onInitializeClient() { |
| - | | + | ... |
| - | | + | BuiltinItemRendererRegistry.INSTANCE.register(ExampleMod.NETHERITE_BANNER_SHIELD, |
| - | | + | renderBanner(stack, matrices, vertexConsumers, |
| - | }); | + | //The first five parameters are taken from the method, while the last 3 you provide yourself. |
| - | } | + | //You will provide the model, and then your 2 sprite identifiers in the order of SHIELD_NAME_BASE and then SHIELD_NAME_BASE_NOPATTERN. |
| + | }); | ||
| + | ... | ||
| + | } | ||
| + | ... | ||
| } | } | ||
| </ | </ | ||
| - | And now we get to the mixin. Don't worry, its an easy one. | + | Finally, change the following models |
| - | If this is your first time, [[tutorial: | + | <file javascript resources/assets/tutorial/models/item/ |
| - | + | ||
| - | We will make a class called '' | + | |
| - | <code java> | + | |
| - | @Mixin (BuiltinModelItemRenderer.class) | + | |
| - | public class RendererMixin { | + | |
| - | + | ||
| - | } | + | |
| - | </code> | + | |
| - | + | ||
| - | Then we will make the necessary '' | + | |
| - | <code java> | + | |
| - | @Mixin (BuiltinModelItemRenderer.class) | + | |
| - | public class RendererMixin { | + | |
| - | private ShieldEntityModel modelNetheriteShield = new ShieldEntityModel; | + | |
| - | private static final SpriteIdentifier NETHERITE_SHIELD_BASE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX, | + | |
| - | private static final SpriteIdentifier NETHERITE_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX, | + | |
| - | } | + | |
| - | </code> | + | |
| - | + | ||
| - | Now we get to the most important part of the mixin. We will inject a method to render a banner on our shield. | + | |
| - | + | ||
| - | <code java> | + | |
| - | @Mixin (BuiltinModelItemRenderer.class) | + | |
| - | public class RendererMixin { | + | |
| - | private ShieldEntityModel modelNetheriteShield = new ShieldEntityModel; | + | |
| - | private static final SpriteIdentifier NETHERITE_SHIELD_BASE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX, | + | |
| - | private static final SpriteIdentifier NETHERITE_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX, | + | |
| - | + | ||
| - | @Inject(method = " | + | |
| - | private void mainRender(ItemStack stack, ModelTransformation.Mode mode, MatrixStack matrices, VertexConsumerProvider vertexConsumers, | + | |
| - | if (stack.getItem() == ExampleMod.NETHERITE_SHIELD)) { | + | |
| - | FabricShieldLibClient.renderBanner(stack, | + | |
| - | //The first five parameters are taken from the method, while the last 3 you provide yourself. You will provide the model, and then your 2 sprite identifiers in the order of ''// | + | |
| - | '' | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | + | ||
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | That is now all of the complicated things done! We now only need to change our existing model, add a '' | + | |
| - | + | ||
| - | In your shield model, '' | + | |
| - | <code javascript> | + | |
| { | { | ||
| - | | + | |
| + | " | ||
| + | " | ||
| + | }, | ||
| " | " | ||
| { | { | ||
| Line 645: | Line 413: | ||
| " | " | ||
| }, | }, | ||
| - | " | + | " |
| } | } | ||
| ] | ] | ||
| } | } | ||
| - | </code> | + | </file> |
| - | You also have to change your blocking model for your shield, '' | + | <code javascript |
| - | + | ||
| - | <code javascript> | + | |
| { | { | ||
| - | " | + | " |
| + | " | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | }, | ||
| + | " | ||
| + | } | ||
| + | ] | ||
| } | } | ||
| </ | </ | ||
| - | For this next step, you will add '' | + | <code javascript |
| - | Then, you will need to make a '' | + | |
| - | + | ||
| - | Then, you will move both of these textures into '' | + | |
| - | + | ||
| - | For one last thing, you will need to add names for each of your shield color variants in '' | + | |
| - | <code javascript> | + | |
| { | { | ||
| - | | + | |
| - | " | + | "textures":{ |
| - | "item.examplemod.netherite_shield.orange": | + | "shield":" |
| - | "item.examplemod.netherite_shield.yellow": | + | } |
| - | "item.examplemod.netherite_shield.lime": "Lime Netherite Shield", | + | |
| - | " | + | |
| - | "item.examplemod.netherite_shield.light_blue": "Light Blue Netherite Shield", | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| } | } | ||
| - | </ | + | </ |
| - | ===== Adding banner support to your shield (1.14) ===== | + | |
| - | This is where mixins get involved. | + | ===== Changes for 1.21.1 ===== |
| + | If you are working in 1.21.1, **follow the changes for all higher versions first**, then change the FabricShieldLib and FAPI versions accordingly and change your other dependencies to these versions:\\ | ||
| - | First, change the fabric_shield_lib in **gradle.properties** | + | <file properties |
| - | \\ | + | mod_menu_version=11.0.1 |
| - | <code java> | + | midnightlib_version=1.5.8-fabric |
| - | fabric_shield_lib_version=1.4.5-1.14 | + | </file> |
| - | </code> | + | |
| - | \\ | + | |
| - | Next thing you will want to do is to change // | + | Then, update your Item registries |
| <code java> | <code java> | ||
| - | public static final Item NETHERITE_SHIELD = new FabricBannerShieldItem(new FabricItemSettings().maxDamage(2500).group(ItemGroup.COMBAT), 10, 13, Items.NETHERITE_INGOT); | + | public static final Item NETHERITE_SHIELD = register(new FabricShieldItem(new Item.Settings().maxDamage(2500), |
| + | </code> | ||
| + | or | ||
| + | <code java> | ||
| + | public static final Item NETHERITE_BANNER_SHIELD = register(new | ||
| </ | </ | ||
| - | The only thing we will need to do now is to add a simple mixin. | + | ===== Changes for 1.20.6 ===== |
| + | If you are working in 1.20.6, **follow the changes for all higher versions first**, then change the FabricShieldLib and FAPI versions accordingly and change your other dependencies to these versions:\\ | ||
| - | If this is your first time, [[tutorial: | + | <file properties gradle.properties> |
| + | mod_menu_version=10.0.0-beta.1 | ||
| + | midnightlib_version=1.5.5-fabric | ||
| + | </file> | ||
| - | We will make a class called | + | Next, change all instances of '' |
| - | <code java> | + | |
| - | @Mixin (BuiltinModelItemRenderer.class) | + | |
| - | public class RendererMixin { | + | |
| - | } | + | Then, change your '' |
| - | </code> | + | |
| - | Then we will make the necessary | + | Finally, move your '' |
| - | <code java> | + | |
| - | @Mixin (BuiltinModelItemRenderer.class) | + | |
| - | public class RendererMixin { | + | |
| - | private static final Identifier NETHERITE_SHIELD_BASE = new Identifier(" | + | |
| - | private static final Identifier NETHERITE_SHIELD_BASE_NO_PATTERN = new Identifier(" | + | |
| - | } | + | |
| - | </code> | + | |
| - | + | ||
| - | Now we get to the most important part of the mixin. We will inject a method to render a banner on our shield. **Do not forget to mark the inject with //cancellable = true//** | + | |
| - | + | ||
| - | <code java> | + | |
| - | @Mixin (BuiltinModelItemRenderer.class) | + | |
| - | public class RendererMixin { | + | |
| - | private static final Identifier NETHERITE_SHIELD_BASE = new Identifier(" | + | |
| - | private static final Identifier NETHERITE_SHIELD_BASE_NO_PATTERN = new Identifier(" | + | |
| - | + | ||
| - | @Inject(method = " | + | |
| - | private void mainRender(ItemStack stack, CallbackInfo callbackInfo) { | + | |
| - | if (stack.getItem() == ExampleMod.NETHERITE_SHIELD)) { | + | |
| - | //The first parameter is taken from the method, while you will provide your 2 identifiers in the order of ''// | + | |
| - | FabricShieldBannerRendering.render(stack, | + | |
| - | callbackInfo.cancel(); | + | |
| - | } | + | |
| - | } | + | |
| - | | + | ===== Changes for 1.20.4 ===== |
| - | } | + | If you are working in 1.20.4, **follow the changes for all higher versions first**, then change the FabricShieldLib and FAPI versions accordingly and change your other dependencies to these versions:\\ |
| - | </ | + | |
| - | That is now all of the complicated things done! We now only need to change our existing model, add a '' | + | **gradle.properties** |
| + | <file properties gradle.properties> | ||
| + | midnightlib_version=1.5.2-fabric | ||
| + | mod_menu_version=9.0.0-pre.1 | ||
| + | </ | ||
| - | In your shield model, '' | + | Additionally, **remove the** '' |
| - | <code javascript> | + | |
| - | { | + | |
| - | " | + | |
| - | " | + | |
| - | { | + | |
| - | " | + | |
| - | " | + | |
| - | }, | + | |
| - | " | + | |
| - | } | + | |
| - | ] | + | |
| - | } | + | |
| - | </ | + | |
| - | You also have to change your blocking model for your shield, '' | + | ===== Changes |
| + | If you are working in 1.20.1, **follow the changes | ||
| - | <code javascript> | + | **gradle.properties** |
| - | { | + | <file properties gradle.properties> |
| - | " | + | midnightlib_version=1.4.1-fabric |
| - | } | + | mod_menu_version=7.1.0 |
| - | </code> | + | </file> |
| - | For this next step, you will add '' | + | ===== Changes for 1.19 ===== |
| - | Then, you will need to make a '' | + | If you are working in 1.19, **follow the changes |
| - | Then, you will move both of these textures into '' | + | **gradle.properties** |
| - | + | <file properties gradle.properties> | |
| - | For one last thing, you will need to add names for each of your shield color variants in '' | + | midnightlib_version=1.0.0-fabric |
| - | <code javascript> | + | mod_menu_version=4.2.0-beta.2 |
| - | { | + | </file> |
| - | "item.examplemod.netherite_shield": | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | " | + | |
| - | } | + | |
| - | </code> | + | |
| - | Now your shield is done and has banner support! | ||
tutorial/shield.1695686944.txt.gz · Last modified: 2023/09/26 00:09 by cringestar_boi