tutorial:armor
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:armor [2020/10/09 20:26] – [Creating Armor Items] sakira | tutorial:armor [2022/04/13 09:39] – map2fabricyarn daomephsta | ||
---|---|---|---|
Line 3: | Line 3: | ||
==== Introduction ==== | ==== Introduction ==== | ||
- | While Armor is a bit more complicated to add then a normal block/item, once you can understand it, it becomes simple to make. | + | While armor is a bit more complicated to implement than a normal block or item, once you understand it, it becomes simple to implement. To add armor, we'll first make a CustomArmorMaterial class, then register the items. We'll also take a look at how to texture them. There' |
- | To add Armor, we'll first make a CustomArmorMaterial class, then register the items. We'll also take a look at how to texture them. | + | |
- | There' | + | An example for this document can be found in [[https:// |
==== Creating an Armor Material class ==== | ==== Creating an Armor Material class ==== | ||
Line 11: | Line 11: | ||
Since new armor needs to be set with a new name (as well as extra things like armor points and durability), | Since new armor needs to be set with a new name (as well as extra things like armor points and durability), | ||
- | This class will implement | + | This class will implement |
- | <code java [enable_line_numbers=" | + | <yarncode |
- | public class CustomArmorMaterial implements | + | public class CustomArmorMaterial implements |
- | private static final int[] BASE_DURABILITY = new int[] {13, 15, 16, 11}; | + | private static final int[] BASE_DURABILITY = new int[] {13, 15, 16, 11}; |
- | private static final int[] PROTECTION_VALUES = new int[] {A, B, C, D}; | + | private static final int[] PROTECTION_VALUES = new int[] {A, B, C, D}; |
- | + | ||
- | // In which A is helmet, B chestplate, C leggings and D boots. | + | // In which A is helmet, B chestplate, C leggings and D boots. |
- | // For reference, Leather uses {1, 2, 3, 1}, and Diamond/ | + | // For reference, Leather uses {1, 2, 3, 1}, and Diamond/ |
} | } | ||
- | </code> | + | </yarncode> |
The next arguments are defined as follows (don't worry about the names, you'll see how we implement it below them): | The next arguments are defined as follows (don't worry about the names, you'll see how we implement it below them): | ||
- | - getDurability: how many hits can armor take before breaking. Uses the int we wrote on ' | + | - <yarn method_7696> |
- | - getPretectionAmount: calls for the ' | + | - <yarn method_7697> |
- | - getEnchantability: This will be how likely the armor can get high level or multiple enchantments in an enchantment book. | + | - <yarn method_7699> |
- | - SoundEvent getEquipSound: The standard used by vanilla armor is '' | + | - <yarn class_3414 method_7698> |
- | - Ingredient getRepairIngridient: what item are we gonna be using to repair the armor on an anvil. It can be either a vanilla item or one of your own. | + | - <yarn class_1856 method_7695> |
- | - String | + | - String |
- | - getToughness: This is a second protection value where the armor is more durable against high value attacks. Value goes as ' | + | - <yarn method_7700> |
And the new value introduced on 1.16 | And the new value introduced on 1.16 | ||
- | - getKnockbackResistance: leave this value at 0. If you want to implement it, write ' | + | - <yarn method_24355> |
I'll leave all variables written as X or A, B, C, D. With those arguments, it should now look something like this: | I'll leave all variables written as X or A, B, C, D. With those arguments, it should now look something like this: | ||
- | <code java [enable_line_numbers=" | + | <yarncode |
- | public class CustomArmorMaterial implements | + | public class CustomArmorMaterial implements |
- | private static final int[] BASE_DURABILITY = new int[] {13, 15, 16, 11}; | + | private static final int[] BASE_DURABILITY = new int[] {13, 15, 16, 11}; |
- | private static final int[] PROTECTION_VALUES = new int[] {A, B, C, D}; | + | private static final int[] PROTECTION_VALUES = new int[] {A, B, C, D}; |
- | | + | @Override |
- | public int getDurability(EquipmentSlot | + | public int method_7696(class_1304 |
- | return BASE_DURABILITY[slot.getEntitySlotId()] * X; | + | return BASE_DURABILITY[slot.method_5927()] * X; |
- | } | + | } |
- | | + | @Override |
- | public int getProtectionAmount(EquipmentSlot | + | public int method_7697(class_1304 |
- | return PROTECTION_VALUES[slot.getEntitySlotId()]; | + | return PROTECTION_VALUES[slot.method_5927()]; |
- | } | + | } |
- | | + | @Override |
- | public int getEnchantability() { | + | public int method_7699() { |
- | return X; | + | return X; |
- | } | + | } |
- | | + | @Override |
- | public | + | public |
- | return | + | return |
- | } | + | } |
- | | + | @Override |
- | public | + | public |
- | return | + | return |
- | } | + | } |
- | | + | @Override |
- | public String | + | public String |
- | return " | + | // Must be all lowercase |
- | } | + | return " |
+ | } | ||
- | | + | @Override |
- | public float getToughness() { | + | public float method_7700() { |
- | return X.0F; | + | return X.0F; |
- | } | + | } |
- | | + | @Override |
- | public float getKnockbackResistance() { | + | public float method_24355() { |
- | return 0.XF; | + | return 0.XF; |
- | } | + | } |
} | } | ||
- | </code> | + | </yarncode> |
Line 93: | Line 94: | ||
We're gonna make a new class called RegisterItems to implement your new armor pieces. This will also be the place to, for example, register tools, if you're making a new item like an ingot (We'll refer to this as a " | We're gonna make a new class called RegisterItems to implement your new armor pieces. This will also be the place to, for example, register tools, if you're making a new item like an ingot (We'll refer to this as a " | ||
- | The syntax of groups is //.group([Your mod name here].[YOUR_MOD_NAME_BUT_IN_CAPS]_GROUP)//. I'll be referring to it as ExampleMod: | + | The syntax of groups is //.<yarn method_7892> |
- | <code java [enable_line_numbers=" | + | <yarncode |
public class RegisterItems { | public class RegisterItems { | ||
- | public static final ArmorMaterial customArmorMaterial | + | |
- | | + | public static final class_1792 |
// If you made a new material, this is where you would note it. | // If you made a new material, this is where you would note it. | ||
- | public static final Item CUSTOM_MATERIAL_HELMET = new ArmorItem(CustomArmorMaterial, EquipmentSlot.HEAD, new Item.Settings().group(ExampleMod.EXAMPLE_MOD_GROUP)); | + | public static final class_1792 |
- | public static final Item CUSTOM_MATERIAL_CHESTPLATE = new ArmorItem(CustomArmorMaterial, EquipmentSlot.CHEST, new Item.Settings().group(ExampleMod.EXAMPLE_MOD_GROUP)); | + | public static final class_1792 |
- | public static final Item CUSTOM_MATERIAL_LEGGINGS = new ArmorItem(CustomArmorMaterial, EquipmentSlot.LEGS, new Item.Settings().group(ExampleMod.EXAMPLE_MOD_GROUP)); | + | public static final class_1792 |
- | public static final Item CUSTOM_MATERIAL_BOOTS = new ArmorItem(CustomArmorMaterial, EquipmentSlot.FEET, new Item.Settings().group(ExampleMod.EXAMPLE_MOD_GROUP)); | + | public static final class_1792 |
} | } | ||
- | </code> | + | </yarncode> |
- | Now that your items are properly created, | + | Now that your items are properly created, |
- | We'll be writing this right below your last ArmorItem. | + | We'll be writing this right below your last <yarn class_1738> |
- | <code java [enable_line_numbers=" | + | <yarncode |
- | | + | public static void register() { |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | } | + | } |
- | </code> | + | </yarncode> |
Your armor items are done. Now we'll just call the Registry on our main class (and annotate the new group). | Your armor items are done. Now we'll just call the Registry on our main class (and annotate the new group). | ||
- | <code java [enable_line_numbers=" | + | <yarncode |
- | public static final ItemGroup | + | public static final class_1761 |
- | new Identifier(" | + | new class_2960(" |
- | .icon(() -> new ItemStack(RegisterItems.CUSTOM_MATERIAL)) // This uses the model of the new material you created as an icon, but you can reference to whatever you like | + | .icon(() -> new class_1799(RegisterItems.CUSTOM_MATERIAL)) // This uses the model of the new material you created as an icon, but you can reference to whatever you like |
- | .build(); | + | .build(); |
@Override | @Override | ||
- | | + | public void onInitialize() { |
- | RegisterItems.register(); | + | RegisterItems.register(); |
- | } | + | } |
- | </code> | + | </yarncode> |
That's it! Your armor should now exist in game, untextured still, but present and able to be given with /give. | That's it! Your armor should now exist in game, untextured still, but present and able to be given with /give. | ||
Line 153: | Line 154: | ||
The following should be the same with all armor items, only changing which part are we using. We'll use helmet for our example. | The following should be the same with all armor items, only changing which part are we using. We'll use helmet for our example. | ||
- | < | + | < |
{ | { | ||
- | | + | " |
- | " | + | " |
- | " | + | " |
- | } | + | } |
} | } | ||
</ | </ | ||
Line 165: | Line 165: | ||
Repeat with all armor items. | Repeat with all armor items. | ||
- | To give your on-body armor a texture, | + | To give your on-body armor a texture, simply |
+ | |||
If you followed everything, you should now be able to have a full armor set! | If you followed everything, you should now be able to have a full armor set! | ||
+ | |||
+ | ====Adding Knockback Protection==== | ||
+ | |||
+ | And here comes the so very cursed! | ||
+ | |||
+ | Mojang decided that they were not only going to hardcode <yarn method_24355>, | ||
+ | |||
+ | To get around this, we're gonna make a mixin that goes into <yarn class_1738> | ||
+ | |||
+ | We'll make a class called ArmorItemMixin, | ||
+ | |||
+ | < | ||
+ | @Mixin (class_1738.class) | ||
+ | public abstract class ArmorItemMixin { | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | Now we have to make a @Shadow to modify knockbackResistance, | ||
+ | |||
+ | < | ||
+ | @Mixin (class_1738.class) | ||
+ | public abstract class ArmorItemMixin { | ||
+ | @Shadow @Final private static UUID[] MODIFIERS; | ||
+ | @Shadow @Final @Mutable private Multimap< | ||
+ | @Shadow @Final protected float knockbackResistance; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Next we @Inject our <yarn field_23718> | ||
+ | |||
+ | < | ||
+ | @Mixin (class_1738.class) | ||
+ | public abstract class ArmorItemMixin { | ||
+ | |||
+ | @Shadow @Final private static UUID[] MODIFIERS; | ||
+ | @Shadow @Final @Mutable private Multimap< | ||
+ | @Shadow @Final protected float knockbackResistance; | ||
+ | |||
+ | @Inject(method = "< | ||
+ | private void constructor(class_1741 material, class_1304 slot, class_1792.class_1793 settings, CallbackInfo ci) { | ||
+ | UUID uUID = MODIFIERS[slot.method_5927()]; | ||
+ | |||
+ | if (material == RegisterItems.CUSTOM_ARMOR_MATERIAL) { | ||
+ | ImmutableMultimap.Builder< | ||
+ | |||
+ | this.attributeModifiers.forEach(builder:: | ||
+ | |||
+ | builder.put( | ||
+ | class_5134.field_23718, | ||
+ | new class_1322(uUID, | ||
+ | "Armor knockback resistance", | ||
+ | this.knockbackResistance, | ||
+ | class_1322.class_1323.field_6328 | ||
+ | ) | ||
+ | ); | ||
+ | |||
+ | this.attributeModifiers = builder.build(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | Now your armor has the knockback resistance value you assigned to it back on CustomArmorMaterial. |
tutorial/armor.txt · Last modified: 2024/07/04 16:32 by mineblock11