tutorial:shield
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
tutorial:shield [2022/01/01 08:55] – update mc version in header redgrapefruit | tutorial:shield [2025/06/21 18:39] (current) – updated to 1.21.4 cringestar_boi | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Making a Custom Shield in Minecraft [1.18] ====== | + | ====== Making a Custom Shield in Minecraft [1.19-1.21.4] ====== |
+ | :!: The tutorial depends on third-party libraries. | ||
- | Congrats! You just learned how to create your custom | + | Congrats! You just learned how to create your custom |
- | Luckily, CrimsonDawn45 has already made a library to help with this! If he didn' | + | |
- | Library | + | Luckily, StellarWind22 has already made a library to help with this! If she didn' |
+ | |||
+ | The library | ||
Library compiled as a jar is available at https:// | Library compiled as a jar is available at https:// | ||
Line 10: | 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> | + | **gradle.properties** |
- | fabric_shield_lib_version=1.4.5-1.18 | + | <file properties gradle.properties> |
- | </code>\\ | + | fabric_shield_lib_version=1.8.0-1.21.4 |
- | **build.gradle** (under dependencies)\\ | + | mod_menu_version=13.0.0 |
- | <code java> | + | midnightlib_version=1.6.6-fabric |
- | modImplementation " | + | fabricasm_version=2.3 |
- | </code>\\ | + | </file> |
- | At the time of writing, | + | |
- | **build.gradle** (under repositories)\\ | + | **build.gradle** (under |
- | <code java> | + | <file groovy build.gradle> |
- | allprojects { repositories { maven { url ' | + | modImplementation " |
- | </code> | + | modImplementation " |
+ | modImplementation " | ||
+ | modImplementation " | ||
+ | </file> | ||
+ | |||
+ | At the time of writing, | ||
+ | * **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 = " | ||
+ | </file> | ||
+ | |||
+ | __// | ||
===== Adding a custom shield ===== | ===== Adding a custom shield ===== | ||
- | **If you want your shield to support banner decoration, | + | **If you want your shield to support banner decoration |
- | 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.\\ | + | On to the non-boring steps! We will now make a custom shield! |
- | If so, the first step to do is create a new instance of an Item like: | + | |
- | <code java> | + | If you have followed the above steps correctly and refreshed the project, then you will have the FabricShieldLib |
- | public static final Item NETHERITE_SHIELD = new FabricShieldItem(new FabricItemSettings().maxDamage(2500).group(ItemGroup.COMBAT), | + | |
- | </ | + | |
- | Then, we have to register it, like so: | + | If so, the first step to do is create a new instance of an '' |
- | + | <code java TutorialItems> | |
- | <code java> | + | public final class TutorialItems { |
- | Registry.register(Registry.ITEM, new Identifier(" | + | // ... |
+ | public static final Item NETHERITE_SHIELD = register(" | ||
+ | //The constructor for the item takes in the following values: FabricBannerShieldItem(settings.maxDamage(durability), | ||
+ | // ... | ||
+ | } | ||
</ | </ | ||
- | And our shield is done!\\ | + | If you want to add your shield to a [[itemgroup|item groups]], for example, the " |
- | Now, we have to create the textures and models of the shield.\\ | + | |
- | For the texture, you can use anything. A good place to start is looking at mojang' | + | <yarncode java ExampleMod> |
- | Now, for the models, we have to write a few .json files.\\ | + | public class ExampleMod implements ModInitializer |
- | For the model file without blocking, we use: \\ | + | |
- | <code javascript> | + | |
- | { | + | public void onInitialize() |
- | | + | |
- | | + | |
- | | + | |
- | }, | + | }); |
- | " | + | ... |
- | { | + | } |
- | | + | |
- | " | + | |
- | | + | |
- | " | + | |
- | } | + | |
- | | + | |
} | } | ||
- | </code>\\ | + | </yarncode> |
- | Put it in resources/ | + | |
- | For the blocking model, use this: \\ | + | |
- | <code javascript> | + | |
- | { | + | |
- | " | + | |
- | } | + | |
- | </ | + | |
- | Plop it in resources/ | + | |
- | Don't forget to add it to **en_us.json**\\ | + | |
- | <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 instead of 1.18, please | + | For the texture, |
- | <code java> | + | |
- | fabric_shield_lib_version=1.4.5-1.17 | + | |
- | </code> | + | |
- | This is where mixins get involved. | + | Now, for the models, we have to write a few .json files. |
- | First thing you will want to do is to change | + | Inside '' |
- | <code java> | + | <file javascript resources/assets/tutorial/ |
- | public static final Item NETHERITE_SHIELD = new FabricBannerShieldItem(new FabricItemSettings().maxDamage(2500).group(ItemGroup.COMBAT), | + | { |
- | </code> | + | " |
+ | " | ||
+ | " | ||
+ | } | ||
+ | } | ||
+ | </file> | ||
- | Now, we have to register a few things in our '' | + | In the same folder, create another file, '' |
+ | <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 141: | Line 180: | ||
<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> | + | |
- | </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 446: | Line 300: | ||
</ | </ | ||
- | 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> | + | |
- | </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 595: | Line 392: | ||
" | " | ||
}, | }, | ||
- | " | + | " |
} | } | ||
] | ] | ||
} | } | ||
- | </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.1641027357.txt.gz · Last modified: 2022/01/01 08:55 by redgrapefruit