tutorial:shield
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
tutorial:shield [2022/12/17 15:22] – Registry.ITEM -> Registries.ITEM miir | tutorial:shield [2023/12/22 08:20] – fixed bottom lang file, updated versions cringestar_boi | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | __**THIS PAGE SHOULD WORK FOR 1.17-1.19. THE 1.14-1.16 SECTIONS HAVE NOT BEEN TESTED IN A LONG TIME, SO THEY MAY NOT WORK.**__ | + | ====== Making a Custom Shield in Minecraft [1.19-1.20] ====== |
- | + | ||
- | ====== Making a Custom Shield in Minecraft [1.19-1.14] ====== | + | |
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.\\ | 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 source is available at https:// | Library source is available at https:// | ||
Line 15: | Line 13: | ||
**gradle.properties**\\ | **gradle.properties**\\ | ||
<code java> | <code java> | ||
- | fabric_shield_lib_version=1.6.0-1.19 | + | fabric_shield_lib_version=1.7.2-1.20.4 |
+ | midnightlib_version=1.5.2-fabric | ||
+ | mod_menu_version=9.0.0-pre.1 | ||
+ | fabricasm_version=2.3 | ||
</ | </ | ||
**build.gradle** (under dependencies)\\ | **build.gradle** (under dependencies)\\ | ||
<code java> | <code java> | ||
- | modImplementation " | + | 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.\\ \\ | + | modImplementation "com.terraformersmc: |
- | **build.gradle** (under repositories, | + | |
- | <code java> | + | |
- | maven | + | |
- | </ | + | |
- | __//**If you are doing this in Minecraft version 1.17 or higher or using FabricShieldLib version 1.5.0 or higher, add these things as well:**//__ | + | modImplementation "maven.modrinth:midnightlib: |
- | **gradle.properties**\\ | + | modImplementation "com.github.Chocohead: |
- | <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 | + | At the time of writing, latest project.fabric_shield_lib_version should be 1.7.2-1.20.4. This page will be updated |
- | + | **build.gradle** (inside repositories, | |
- | **build.gradle** (under dependencies)\\ | + | |
<code java> | <code java> | ||
- | + | maven | |
- | modApi(" | + | maven {url "https://maven.terraformersmc.com/ |
- | exclude(group: "net.fabricmc.fabric-api" | + | maven {url = "https://api.modrinth.com/maven"} |
- | } | + | |
- | include("me.shedaniel.cloth:cloth-config-fabric: | + | |
- | + | ||
- | modCompileOnly modRuntimeOnly ("com.terraformersmc: | + | |
- | exclude(group: | + | |
- | } | + | |
- | + | ||
- | modImplementation(" | + | |
- | exclude (group: "net.fabricmc.fabric-api") | + | |
- | } | + | |
- | include(" | + | |
</ | </ | ||
- | **build.gradle** (under repositories, | + | __//**Midnight Lib and FabricASM are included in FabricShieldLib release (.jar on Curseforge/ |
- | <code java> | + | |
- | maven { url " | + | |
- | maven { url " | + | |
- | </code> | + | |
===== 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!\\ \\ | 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 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: | If so, the first step to do is create a new instance of an Item like: | ||
<code java> | <code java> | ||
- | public static final Item NETHERITE_SHIELD = new FabricShieldItem(new FabricItemSettings().maxDamage(2500).group(ItemGroup.COMBAT), 10, 13, Items.NETHERITE_INGOT); | + | public static final Item NETHERITE_SHIELD = new FabricShieldItem(new FabricItemSettings().maxDamage(2500), |
</ | </ | ||
Line 79: | Line 54: | ||
</ | </ | ||
- | And our shield is done!\\ | + | If you want to add your shield to a creative tab, add this into your '' |
+ | <code java> | ||
+ | ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT).register(entries -> { | ||
+ | entries.add(NETHERITE_SHIELD); | ||
+ | }); | ||
+ | </ | ||
+ | |||
+ | And our shield is (code-wise) | ||
Now, we have to create the textures and models of the shield.\\ | 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 | + | For the texture, you can use anything. A good place to start is to look at Mojang's shield |
Now, for the models, we have to write a few .json files.\\ | Now, for the models, we have to write a few .json files.\\ | ||
- | For the model file without blocking, we use: \\ | + | |
+ | |||
+ | Inside '' | ||
<code javascript> | <code javascript> | ||
{ | { | ||
Line 100: | Line 85: | ||
} | } | ||
</ | </ | ||
- | Put it in '' | + | |
- | For the blocking model, use this: \\ | + | In the same folder, create another file, '' |
<code javascript> | <code javascript> | ||
{ | { | ||
- | " | + | " |
+ | " | ||
+ | " | ||
+ | } | ||
} | } | ||
</ | </ | ||
- | Plop it in resources/models/item/netherite_shield_blocking.json\\ | + | |
+ | Lastly, create a '' | ||
+ | <code javascript> | ||
+ | { | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ] | ||
+ | } | ||
+ | </ | ||
Don't forget to add it to **en_us.json** in '' | Don't forget to add it to **en_us.json** in '' | ||
<code javascript> | <code javascript> | ||
Line 114: | Line 112: | ||
} | } | ||
</ | </ | ||
- | And with that, your shield is done! | + | And with that, your non-decorateable |
+ | ===== Adding a custom shield with banner support ===== | ||
+ | If you want to make your shield accept banners and decorateable like a vanilla shield, the process is slightly different. | ||
- | ===== Adding banner support to your shield (1.17+) ===== | + | We still make the item in the same way, just make it a FabricBannerShieldItem: |
- | + | ||
- | If you are using 1.17/1.18 instead of 1.19, please change versions | + | |
<code java> | <code java> | ||
- | fabric_shield_lib_version=1.5.3-1.18 | + | public static final Item NETHERITE_BANNER_SHIELD |
- | 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 | + | |
</ | </ | ||
- | + | Then, we have to register | |
- | This is where mixins get involved. | + | |
- | + | ||
- | First thing you will want to do is to change // | + | |
<code java> | <code java> | ||
- | public static final Item NETHERITE_SHIELD = new FabricBannerShieldItem(new FabricItemSettings().maxDamage(2500).group(ItemGroup.COMBAT), 10, 13, Items.NETHERITE_INGOT); // FabricBannerShieldItem(settings.maxDamage(durability), | + | Registry.register(Registries.ITEM, new Identifier(" |
</ | </ | ||
- | Now, we have to register | + | If you want to add your shield |
- | + | ||
- | To create our '' | + | |
<code java> | <code java> | ||
- | public class ExampleModClient implements ClientModInitializer | + | ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT).register(entries -> { |
- | | + | entries.addAfter(Items.SHIELD, |
- | public void onInitializeClient() { | + | }); |
- | + | ||
- | } | + | |
- | } | + | |
</ | </ | ||
- | Before | + | Now the item is created, |
- | <code javascript> | ||
- | { | ||
- | [...] | ||
- | " | ||
- | " | ||
- | " | ||
- | ], | ||
- | " | ||
- | " | ||
- | ] | ||
- | } | ||
- | [...] | ||
- | } | ||
- | </ | ||
- | |||
- | Ok, so now that is done, we can work in our client initializer. | ||
First, we will need to create an '' | First, we will need to create an '' | ||
Line 181: | Line 142: | ||
public class ExampleModClient implements ClientModInitializer { | public class ExampleModClient implements ClientModInitializer { | ||
- | public static final EntityModelLayer | + | public static final EntityModelLayer |
@Override | @Override | ||
Line 199: | Line 160: | ||
@Override | @Override | ||
public void onInitializeClient() { | public void onInitializeClient() { | ||
- | | + | EntityModelLayerRegistry.registerModelLayer(netherite_banner_shield_model_layer, ShieldEntityModel:: |
} | } | ||
} | } | ||
</ | </ | ||
- | Then we will register | + | Then we will create |
<code java> | <code java> | ||
Line 210: | Line 171: | ||
public static final EntityModelLayer NETHERITE_SHIELD_MODEL_LAYER = new EntityModelLayer(new Identifier(" | public static final EntityModelLayer NETHERITE_SHIELD_MODEL_LAYER = new EntityModelLayer(new Identifier(" | ||
+ | | ||
+ | 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) | + | public class ExampleModClient implements ClientModInitializer |
- | public class RendererMixin | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | Then we will make the necessary '' | + | |
- | <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, | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | Next, we need to @Shadow the '' | + | |
- | <code java> | + | |
- | @Mixin (BuiltinModelItemRenderer.class) | + | |
- | public class RendererMixin { | + | |
- | 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, | + | |
- | + | ||
- | @Final | + | |
- | @Shadow | + | |
- | private EntityModelLoader entityModelLoader; | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | Now we will inject into the '' | + | |
- | <code java> | + | |
- | @Mixin (BuiltinModelItemRenderer.class) | + | |
- | 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){ | + | |
- | modelNetheriteShield = new ShieldEntityModel(this.entityModelLoader.getModelPart(ExampleModClient.NETHERITE_SHIELD_MODEL_LAYER)); | + | |
- | } | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | 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 static final SpriteIdentifier NETHERITE_SHIELD_BASE | + | |
- | private static final SpriteIdentifier NETHERITE_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("examplemod"," | + | |
- | + | ||
- | @Final | + | |
- | @Shadow | + | |
- | private EntityModelLoader entityModelLoader; | + | |
- | + | ||
- | + | ||
- | @Inject(method = " | + | |
- | private void setModelNetheriteShield(CallbackInfo ci){ | + | |
- | this.modelNetheriteShield = new ShieldEntityModel(this.entityModelLoader.getModelPart(ExampleModClient.NETHERITE_SHIELD_MODEL_LAYER)); | + | |
- | } | + | |
| | ||
- | | + | |
- | 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, '' | ||
- | |||
- | <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> | ||
- | fabric_shield_lib_version=1.4.5-1.16 | ||
- | </ | ||
- | \\ | ||
- | |||
- | 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 our '' | ||
- | |||
- | <code java> | ||
- | public class ExampleModClient implements ClientModInitializer { | ||
@Override | @Override | ||
public void onInitializeClient() { | public void onInitializeClient() { | ||
- | | + | EntityModelLayerRegistry.registerModelLayer(NETHERITE_SHIELD_MODEL_LAYER, |
+ | |||
+ | ShieldSetModelCallback.EVENT.register((loader) -> { | ||
+ | | ||
+ | return ActionResult.PASS; | ||
+ | }); | ||
} | } | ||
} | } | ||
</ | </ | ||
- | Before we do any work in our client mod initializer, we need to register its entrypoint in '' | + | Next, we have to create our two '' |
- | + | ||
- | <code javascript> | + | |
- | { | + | |
- | [...] | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | ], | + | |
- | " | + | |
- | " | + | |
- | ] | + | |
- | } | + | |
- | [...] | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | 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> | <code java> | ||
public class ExampleModClient implements ClientModInitializer { | public class ExampleModClient implements ClientModInitializer { | ||
- | @Override | + | public |
- | | + | |
- | 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. | + | public static ShieldEntityModel modelNetheriteShield; |
- | If this is your first time, [[tutorial: | + | public static final SpriteIdentifier NETHERITE_BANNER_SHIELD_BASE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, |
- | + | public static final SpriteIdentifier NETHERITE_BANNER_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, | |
- | We will make a class called '' | + | |
- | <code java> | + | |
- | @Mixin | + | |
- | public class RendererMixin { | + | |
+ | @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 | + | Finally, |
<code java> | <code java> | ||
- | @Mixin (BuiltinModelItemRenderer.class) | + | public class ExampleModClient implements ClientModInitializer |
- | 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, | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | 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 ''// | + | |
- | '' | + | |
- | } | + | |
- | } | + | |
- | + | public static final EntityModelLayer netherite_banner_shield_model_layer = new EntityModelLayer(new Identifier(" | |
- | } | + | |
- | </ | + | |
- | That is now all of the complicated things done! We now only need to change our existing model, add a '' | + | public static ShieldEntityModel modelNetheriteShield; |
- | In your shield model, '' | + | public static final SpriteIdentifier NETHERITE_BANNER_SHIELD_BASE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("examplemod", "entity/netherite_banner_shield_base")); |
- | <code javascript> | + | public static final SpriteIdentifier NETHERITE_BANNER_SHIELD_BASE_NO_PATTERN = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier("examplemod", "entity/netherite_banner_shield_base_nopattern")); |
- | { | + | |
- | | + | |
- | | + | |
- | { | + | |
- | " | + | |
- | " | + | |
- | }, | + | |
- | | + | |
- | } | + | |
- | ] | + | |
- | } | + | |
- | </ | + | |
- | You also have to change your blocking model for your shield, '' | + | @Override |
- | + | public void onInitializeClient() { | |
- | <code javascript> | + | EntityModelLayerRegistry.registerModelLayer(NETHERITE_SHIELD_MODEL_LAYER, ShieldEntityModel:: |
- | { | + | |
- | " | + | |
+ | modelNetheriteShield = new ShieldEntityModel(loader.getModelPart(netherite_banner_shield_model_layer)); | ||
+ | return ActionResult.PASS; | ||
+ | }); | ||
+ | |||
+ | BuiltinItemRendererRegistry.INSTANCE.register(ExampleMod.NETHERITE_BANNER_SHIELD, | ||
+ | renderBanner(stack, | ||
+ | | ||
+ | }); | ||
+ | } | ||
} | } | ||
- | </ | + | </ |
- | For this next step, you will add '' | + | That is all of our code done, we only have a few .json files to make. \\ |
- | Then, you will need to make a '' | + | |
- | Then, you will move both of these textures into '' | + | First, create a '' |
- | For one last thing, you will need to add names for each of your shield color variants in '' | + | Inside of it, you will have to list your '' |
<code javascript> | <code javascript> | ||
{ | { | ||
- | | + | |
- | | + | |
- | "item.examplemod.netherite_shield.orange": "Orange Netherite Shield", | + | "type": "single", |
- | "item.examplemod.netherite_shield.yellow": "Yellow Netherite Shield", | + | "resource": " |
- | "item.examplemod.netherite_shield.lime" | + | |
- | | + | |
- | | + | "type": "single", |
- | "item.examplemod.netherite_shield.cyan": "Cyan Netherite Shield", | + | "resource": " |
- | "item.examplemod.netherite_shield.blue": "Blue Netherite Shield", | + | |
- | "item.examplemod.netherite_shield.purple" | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | ===== 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 // | + | |
- | + | ||
- | <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 our '' | + | |
- | + | ||
- | <code java> | + | |
- | public class ExampleModClient implements ClientModInitializer { | + | |
- | @Override | + | |
- | public void onInitializeClient() { | + | |
- | | + | |
} | } | ||
+ | ] | ||
} | } | ||
</ | </ | ||
- | Before we do any work in our client mod initializer, we need to register its entrypoint in '' | + | Next, inside |
<code javascript> | <code javascript> | ||
{ | { | ||
- | | + | "parent":" |
- | | + | "overrides": [ |
- | "main": | + | { |
- | | + | "predicate": { |
- | ], | + | "blocking": 1 |
- | "client": [ | + | }, |
- | "net.fabricmc.ExampleModClient" | + | |
- | ] | + | |
- | } | + | |
- | [...] | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | 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 | + | |
- | public void onInitializeClient() | + | |
- | | + | |
- | registry.register(new Identifier("examplemod", "entity/ | + | |
- | registry.register(new Identifier(" | + | |
- | }); | + | |
} | } | ||
+ | ] | ||
} | } | ||
- | </ | + | </ |
- | + | ||
- | And now we get to the mixin. Don't worry, its an easy one. | + | |
- | + | ||
- | If this is your first time, [[tutorial: | + | |
- | + | ||
- | We will make a class called '' | + | |
- | <code java> | + | |
- | @Mixin (BuiltinModelItemRenderer.class) | + | |
- | public class RendererMixin { | + | |
- | + | ||
- | } | + | |
- | </ | + | |
- | + | ||
- | 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, | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | 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> | + | |
- | { | + | |
- | " | + | |
- | " | + | |
- | { | + | |
- | " | + | |
- | " | + | |
- | }, | + | |
- | " | + | |
- | } | + | |
- | ] | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | You also have to change your blocking model for your shield, '' | + | |
+ | In the same folder, create another file, '' | ||
<code javascript> | <code javascript> | ||
{ | { | ||
" | " | ||
} | } | ||
- | </ | + | </ |
- | 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 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 '' | + | Lastly, create a '' |
<code javascript> | <code javascript> | ||
{ | { | ||
- | | + | |
- | "item.examplemod.netherite_shield.red": | + | "values": |
- | "item.examplemod.netherite_shield.orange" | + | " |
- | " | + | ] |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
} | } | ||
- | </ | + | </ |
- | ===== Adding banner support to your shield (1.14) ===== | + | |
- | + | ||
- | 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.14 | + | |
- | </ | + | |
- | \\ | + | |
- | + | ||
- | 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), | + | |
- | </ | + | |
- | + | ||
- | The only thing we will need to do now is to add a simple mixin. | + | |
- | + | ||
- | If this is your first time, [[tutorial: | + | |
- | + | ||
- | We will make a class called '' | + | |
- | <code java> | + | |
- | @Mixin (BuiltinModelItemRenderer.class) | + | |
- | public class RendererMixin { | + | |
- | + | ||
- | } | + | |
- | </ | + | |
- | + | ||
- | Then we will make the necessary '' | + | |
- | <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(" | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | 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 // | + | |
- | + | ||
- | <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(); | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | + | ||
- | } | + | |
- | </ | + | |
- | + | ||
- | That is now all of the complicated things done! We now only need to change our existing model, add a '' | + | |
- | In your shield model, | + | Don't forget to add it to **en_us.json** in '' |
<code javascript> | <code javascript> | ||
{ | { | ||
- | "parent":" | + | "item.examplemod.netherite_banner_shield": "Netherite Banner Shield", |
- | "overrides": | + | " |
- | { | + | "item.examplemod.netherite_banner_shield.orange": |
- | "predicate": | + | "item.examplemod.netherite_banner_shield.yellow": |
- | "blocking": | + | " |
- | }, | + | "item.examplemod.netherite_banner_shield.green": |
- | "model": " | + | "item.examplemod.netherite_banner_shield.light_blue": |
- | } | + | " |
- | ] | + | "item.examplemod.netherite_banner_shield.blue": "Blue Netherite Banner Shield", |
+ | "item.examplemod.netherite_banner_shield.purple" | ||
+ | "item.examplemod.netherite_banner_shield.magenta": " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
} | } | ||
</ | </ | ||
- | |||
- | You also have to change your blocking model for your shield, '' | ||
- | |||
- | <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> | ||
- | { | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | } | ||
- | </ | ||
- | |||
- | Now your shield is done and has banner support! |
tutorial/shield.txt · Last modified: 2024/01/14 18:05 by cringestar_boi