tutorial:armor
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionLast revisionBoth sides next revision | ||
tutorial:armor [2021/01/11 21:43] – typo florens | tutorial:armor [2022/12/16 00:26] – should use tutorial namespace solidblock | ||
---|---|---|---|
Line 5: | Line 5: | ||
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' | 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' | ||
- | An example for this document can be found in [[https:// | + | 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 | + | // In which A is boots, B leggings, C chestplate, |
// 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 | @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 | @Override | ||
- | public int getProtectionAmount(EquipmentSlot | + | public int method_7697(class_1304 |
- | return PROTECTION_VALUES[slot.getEntitySlotId()]; | + | return PROTECTION_VALUES[slot.method_5927()]; |
} | } | ||
@Override | @Override | ||
- | public int getEnchantability() { | + | public int method_7699() { |
return X; | return X; | ||
} | } | ||
@Override | @Override | ||
- | public | + | public |
- | return | + | return |
} | } | ||
@Override | @Override | ||
- | public | + | public |
- | return | + | return |
} | } | ||
@Override | @Override | ||
- | public String | + | public String |
+ | // Must be all lowercase | ||
return " | return " | ||
} | } | ||
@Override | @Override | ||
- | public float getToughness() { | + | public float method_7700() { |
return X.0F; | return X.0F; | ||
} | } | ||
@Override | @Override | ||
- | public float getKnockbackResistance() { | + | public float method_24355() { |
return 0.XF; | return 0.XF; | ||
} | } | ||
} | } | ||
- | </code> | + | </yarncode> |
Line 91: | Line 92: | ||
==== Creating Armor Items ==== | ==== Creating Armor Items ==== | ||
- | 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 // | + | <yarncode |
- | + | ||
- | <code java [enable_line_numbers=" | + | |
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() { | public static void register() { | ||
- | Registry.register(Registry.ITEM, new Identifier("examplemod", " | + | class_2378.method_10230(class_7923.field_41178, new class_2960("tutorial", " |
- | Registry.register(Registry.ITEM, new Identifier("examplemod", " | + | |
- | Registry.register(Registry.ITEM, new Identifier("examplemod", " | + | |
- | Registry.register(Registry.ITEM, new Identifier("examplemod", " | + | |
- | Registry.register(Registry.ITEM, new Identifier("examplemod", " | + | |
} | } | ||
- | </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("examplemod", " | + | new class_2960("tutorial", " |
- | .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 152: | ||
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. | ||
- | <code JSON resources/ | + | <code JSON resources/ |
{ | { | ||
" | " | ||
" | " | ||
- | " | + | " |
} | } | ||
} | } | ||
Line 164: | Line 163: | ||
Repeat with all armor items. | Repeat with all armor items. | ||
- | To give your on-body armor a texture, | + | Generally, mod textures go under resources/ |
+ | To give your on-body armor a texture, | ||
- | 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! | + | If you followed everything, you should now be able to have a full armor set! |
- | + | ||
- | Mojang decided that they were not only going to hardcode getKnockbackResistance, | + | |
- | + | ||
- | To get around this, we're gonna make a mixin that goes into ArmorItem. | + | |
- | + | ||
- | We'll make a class called ArmorItemMixin, | + | |
- | + | ||
- | <code java [enable_line_numbers:" | + | |
- | @Mixin (ArmorItem.class) | + | |
- | public abstract class ArmorItemMixin { | + | |
- | + | ||
- | } | + | |
- | </ | + | |
- | + | ||
- | Now we have to make a @Shadow to modify knockbackResistance, | + | |
- | + | ||
- | <code java [enable_line_numbers:" | + | |
- | @Mixin (ArmorItem.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 GENERIC_KNOCKBACK_RESISTANCE into the ArmorMaterial constructor. | + | |
- | + | ||
- | <code java [enable_line_numbers:" | + | |
- | @Mixin (ArmorItem.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(ArmorMaterial material, EquipmentSlot slot, Item.Settings settings, CallbackInfo ci) { | + | |
- | UUID uUID = MODIFIERS[slot.getEntitySlotId()]; | + | |
- | + | ||
- | if (material == RegisterItems.customArmorMaterial) { | + | |
- | ImmutableMultimap.Builder< | + | |
- | + | ||
- | this.attributeModifiers.forEach(builder:: | + | |
- | + | ||
- | builder.put( | + | |
- | EntityAttributes.GENERIC_KNOCKBACK_RESISTANCE, | + | |
- | new EntityAttributeModifier(uUID, | + | |
- | "Armor knockback resistance", | + | |
- | this.knockbackResistance, | + | |
- | EntityAttributeModifier.Operation.ADDITION | + | |
- | ) | + | |
- | ); | + | |
- | + | ||
- | this.attributeModifiers = builder.build(); | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | } | + | |
- | </ | + | |
- | + | ||
- | Now your armor has the knockback resistance value you assigned to it back on CustomArmorMaterial. | + |
tutorial/armor.txt · Last modified: 2023/08/20 10:19 by wjz_p