Nous allons voir comment créer une armure.
La classe principale
Dans la classe principale créez 4 items qui correspondrons aux éléments de votre armure.
| public static final Item tuto_helmet = new TutorielArmor(EntityEquipmentSlot.HEAD).setRegistryName("tuto_helmet").setUnlocalizedName("tuto_helmet"); |
| public static final Item tuto_chestplate = new TutorielArmor(EntityEquipmentSlot.CHEST).setRegistryName("tuto_chestplate").setUnlocalizedName("tuto_chestplate"); |
| public static final Item tuto_leggings = new TutorielArmor(EntityEquipmentSlot.LEGS).setRegistryName("tuto_leggings").setUnlocalizedName("tuto_leggings"); |
| public static final Item tuto_boots = new TutorielArmor(EntityEquipmentSlot.FEET).setRegistryName("tuto_boots").setUnlocalizedName("tuto_boots"); |
La classe TutorielArmor n’existe pas, nous allons la créer après.
Enregistrez les items dans la fonction fonction preInit(FMLPreInitialization event) de votre mod
| GameRegistry.register(tuto_helmet); |
| GameRegistry.register(tuto_chestplate); |
| GameRegistry.register(tuto_leggings); |
| GameRegistry.register(tuto_boots); |
Passons à la classe de l’armure.
La classe de l’armure :
Créez la classe de l’armure, je l’ai appelé TutorielArmor comme nous l’avons vu. Faites hériter cette classe de la classe ItemArmor.
Et mettez le constructeur suivant :
| |
| public TutorielArmor(EntityEquipmentSlot equipmentSlotIn) { |
| super(material, 0, equipmentSlotIn); |
| } |
| |
Le premier argument est le matériau de votre armure, nous allons le créer après. Le second argument est un id de rendu, mais c’est utiliser pour les
classes de minecraft, ça ne change rien ici. Le troisième argument est le slot d’armure dans lequel l’objet sera.
Vous allez créer une variable de classe nommée material de type ArmorMaterial de la façon suivante.
| |
| public static final ArmorMaterial material = EnumHelper.addArmorMaterial("armortuto", ModTutoriel.MODID + ":armortuto", 500, new int[]{4, 6, 7, 3}, 17, SoundEvents.ITEM_ARMOR_EQUIP_DIAMOND, 0.0F); |
| |
Ici nous utilisons une classe implémentée par forge afin de créer un matériau d’armure qui estEnumHelper), le premier argument est le nom du matériau, le second est
le nom de la texture, vous devez mettre sous la forme modid:nomTex, et le jeu ira chercher vos textures (oui il en faut 2) dans
assets.modid.textures.models.armor.nomTex_layer_1 et assets.modid.textures.models.armor.nomTex_layer_2. Le layer 1 contient tout les éléments
de l’armure sauf le pantalon, et le layer 2 contient le pantalon. Ensuite vient le troisième argument, c’est la durabilité de l’armure.
Le tableau d’entier correspond à l’absortion de chaque pièce (bottes, pantalons, plastron, casque), l’argument d’après est le son à jouer lorsqu’on équipe l’armure
Le dernier argument correspond à la dureté de l’armure, c’est une autre réduction de dégâts.
Pour préciser quel objet doit être utilisé pour réparer votre armure rajoutez un bloc static en dessous de la déclaration de votre matériau avec le code suivant.
material.customCraftingMaterial = Items.APPLE;
Ici on réparera l’armure avec une pomme.
On obtient alors :
| public class TutorielArmor extends ItemArmor { |
| |
| public static final ArmorMaterial material = EnumHelper.addArmorMaterial("armortuto", ModTutoriel.MODID + ":armortuto", 500, new int[]{4, 6, 7, 3}, 17, SoundEvents.ITEM_ARMOR_EQUIP_DIAMOND, 0.0F); |
| static { |
| material.customCraftingMaterial = Items.APPLE; |
| } |
| |
| public TutorielArmor(EntityEquipmentSlot equipmentSlotIn) { |
| super(material, 0, equipmentSlotIn); |
| } |
| } |
Les textures
Enregistrez les textures d’inventaire comme si c’était des objets normaux, pour le rendu sur le joueur il faut donc, comme dit précédemment,
placer les textures dans le package assets.modid.textures.models.armor, ce qui me donne :
assets.modid.textures.models.armor.armortuto_layer_1.png et assets.modid.textures.models.armor.armortuto_layer_2, voici les layers :


Vous allez vite vous rendre compte que vos armures sont capables de vous rendre invicible et cela en augmentant un peu la résistance du matériau.
Ici nous allons voir comment personnaliser la résistance de votre armure.
Dans la classe de votre armure, implémentez l’interface ISpecialArmor
Cette interface contient 3 fonctions:
- public ArmorProperties getProperties(EntityLivingBase player, ItemStack armor, DamageSource source, double damage, int slot)
- public int getArmorDisplay(EntityPlayer player, ItemStack armor, int slot)
- public void damageArmor(EntityLivingBase entity, ItemStack stack, DamageSource source, int damage, int slot)
La première renvoie la propriété de résistance pour les paramètres passés, pour les slots, il vont de 0 à 3 dans l’ordre boots, leggings, chestplate, helmet.
La seconde renvoie le nombre de demi-morceau d’armure à afficher pour les paramètres passés.
La troisième doit endommager la pièce d’armure donnée en fonction des paramètres passés.
Nous allons commencer avec la première :
| @Override |
| public ArmorProperties getProperties(EntityLivingBase player, ItemStack armor, DamageSource source, double damage, int slot) { |
| |
| } |
Nous allons d’abord créer un switch suivant le slot donné
| @Override |
| public ArmorProperties getProperties(EntityLivingBase player, ItemStack armor, DamageSource source, double damage, int slot) { |
| switch(slot) { |
| case 3: |
| return null; |
| case 2: |
| return null; |
| case 1: |
| return null; |
| case 0: |
| return null; |
| default: |
| return null; |
| } |
| } |
Voilà nous avons le switch, maintenant il faut créer les ArmorProperties à retourner, regardons d’abord le constructeur de ce dernier.
ArmorProperties(int priority, double ratio, int max)
Bon, ici nous avons des variables qui sont utilisée pour le calcul de réduction des dégâts, il faut d’abord que je vous explique comment va être calculé
la réduction.
Pour faire simple, tout les objets avec une priorité égale à 0 vont additionner leur ratio, puis la réduction sera calculée de la façon suivante :
| reduction = damage * totalRatio; |
| |
| damage -= damage * totalRatio; |
Je vous rappelle que totalRatio est l’addition de tout les ratios de priorité 0.
Le code est fait de façon à ce que le ratio total ne dépasse pas 1, on ne peut pas infliger des dégâts négatifs.
Le processus est répété pour toutes les priorités dans l’ordre croissant, le ratio est remis à 0 entre chaque priorité.
Si durant le processus, les dégâts sont réduits de telle sorte qu’ils deviennent nuls les éléments d’armure suivants ne réduiront pas les dégâts et ne seront
donc pas endommagés. Donc les pièces d’armure avec la priorité la plus haute seront endommagés en dernières.
La réduction des dégâts d’une pièce d’armure ne peux pas être supérieur à la variable max que vous rentrez dans les paramètres du constructeur d’AmorProperties
Ainsi :
- priority : permet de définir l’ordre de réduction des dégâts
- ratio : ratio de réduction des dégâts (entre 0 et 1)
- max : réduction maximum des dégâts par la pièce d’armure (en demi-coeur)
Grâce à la fonction getProperties on va pouvoir faire pleins de trucs, ici je vais réduire les dégâts de noyade seulement avec le casque,
les dégâts de chute seulement avec les bottes et sinon je réduirai avec l’armure entière.
| @Override |
| public ArmorProperties getProperties(EntityLivingBase entity, ItemStack armor, DamageSource source, double damage, int slot) { |
| if(source == DamageSource.drown) { |
| return slot == 3 ? new ArmorProperties(0, 0.2, 10) : new ArmorProperties(0, 0, 0); |
| } |
| if(source == DamageSource.fall) { |
| return slot == 0 ? new ArmorProperties(0, 0.5, 10) : new ArmorProperties(0, 0, 0); |
| } |
| switch(slot) { |
| case 3: |
| return new ArmorProperties(1, 0.05, 10); |
| case 2: |
| return new ArmorProperties(0, 0.2, 15); |
| case 1: |
| return new ArmorProperties(0, 0.3, 18); |
| case 0: |
| return new ArmorProperties(1, 0.04, 6); |
| default: |
| return new ArmorProperties(0, 0, 0); |
| } |
| } |
Les possibilités sont nombreuses, comme nous venons de le voir une pièce de l’armure peut être très resistante à une certaine source
de dégât et moins à une autre. Si l’entité est dans le nether, l’armure peut protéger contre les dégâts de feu, mais si l’entité est dans l’overworld
l’armure ne protège plus contre les dégâts de feu.
Les résistances que vous définissez ici annulent celles données par le matériau.
La seconde fonction permet de définir le nombre le demi-plastron à affiché, je ne vais pas passer une heure dessus :
| @Override |
| public int getArmorDisplay(EntityPlayer player, ItemStack armor, int slot) { |
| switch(slot) { |
| case 0: |
| return 4; |
| case 1: |
| return 6; |
| case 2: |
| return 7; |
| case 3: |
| return 3; |
| default: |
| return 0; |
| } |
| } |
La dernière est appelée pour endommager l’armure, ici je vais décider d’endommager l’armure de seulement la moitié des dégâts qu’elle absorbe
| @Override |
| public void damageArmor(EntityLivingBase entity, ItemStack stack, DamageSource source, int damage, int slot) { |
| stack.damageItem(damage / 2, entity); |
| if(stack.getItemDamage() >= stack.getMaxDamage()) { |
| stack.stackSize--; |
| } |
| } |
On a donc en classe finale :
| public class TutorielArmor extends ItemArmor implements ISpecialArmor { |
| |
| public static final ArmorMaterial material = EnumHelper.addArmorMaterial("armortuto", ModTutoriel.MODID + ":armortuto", 500, new int[]{4, 6, 7, 3}, 17, SoundEvents.ITEM_ARMOR_EQUIP_DIAMOND, 0.0F); |
| static { |
| material.customCraftingMaterial = Items.APPLE; |
| } |
| |
| public TutorielArmor(EntityEquipmentSlot equipmentSlotIn) { |
| super(material, 0, equipmentSlotIn); |
| } |
| |
| @Override |
| public ArmorProperties getProperties(EntityLivingBase player, ItemStack armor, DamageSource source, double damage, int slot) { |
| if(source == DamageSource.drown) { |
| return slot == 3 ? new ArmorProperties(0, 0.2, 10) : new ArmorProperties(0, 0, 0); |
| } |
| if(source == DamageSource.fall) { |
| return slot == 0 ? new ArmorProperties(0, 0.5, 10) : new ArmorProperties(0, 0, 0); |
| } |
| switch(slot) { |
| case 3: |
| return new ArmorProperties(1, 0.05, 10); |
| case 2: |
| return new ArmorProperties(0, 0.2, 15); |
| case 1: |
| return new ArmorProperties(0, 0.3, 18); |
| case 0: |
| return new ArmorProperties(1, 0.04, 6); |
| default: |
| return new ArmorProperties(0, 0, 0); |
| } |
| } |
| |
| @Override |
| public int getArmorDisplay(EntityPlayer player, ItemStack armor, int slot) { |
| switch(slot) { |
| case 0: |
| return 4; |
| case 1: |
| return 6; |
| case 2: |
| return 7; |
| case 3: |
| return 3; |
| default: |
| return 0; |
| } |
| } |
| |
| @Override |
| public void damageArmor(EntityLivingBase entity, ItemStack stack, DamageSource source, int damage, int slot) { |
| stack.damageItem(damage / 2, entity); |
| if(stack.getItemDamage() >= stack.getMaxDamage()) { |
| stack.stackSize--; |
| } |
| } |
| } |
Voici le rendu en jeu :


Voir le commit sur GitHub