Uploaded image for project: 'Spigot'
  1. Spigot
  2. SPIGOT-4820

Villager.getType() and villager.setType()

XMLWordPrintable

    • Icon: New Feature New Feature
    • Resolution: Fixed
    • Icon: Minor Minor
    • None
    • None
    • This server is running CraftBukkit version git-Spigot-e4be9b0-5736cdc (MC: 1.14) (Implementing API version 1.14-R0.1-SNAPSHOT)
    • Yes

      It is currently possible to manage a Villager's profession using Villager.getProfession​() and Villager.setProfession​(Villager.Profession). It is however not possible to set a Villager's Type (NBT VillagerData > type). Therefore it is not possible using the API to set a Villager to use any of the available skins - see "Outfits" under https://minecraft.gamepedia.com/Villager#Professions

      Similarly to Profession, it would probably be an enum named something like Villager.Type and contain DESERT, JUNGLE, PLAINS, SAVANNA, SNOWY, SWAMP, and TAIGA.

      As also noted in comments in SPIGOT-4766, something like Villager.setLevel() would also be required to get the profession to retain.

      Edit:

      A possible name other than "Villager.Type" could be "Villager.Outfit", "Villager.OutfitType", "Villager.Biome", "Villager.BiomeOutfit", or "Villager.BiomeType". The first is more consistent to what they're called in the NBT, but outfit type is more appropriate to what it's referring to. Villager.getType() is already used by Entity.getType(), so would have to be a different name I think.

      Edit 2:

      This seems like it should be relatively easy to implement.

      Adding something like this to org.bukkit.entity.Villager:

      // Internally the VillagerData constructor ensures this is not lesser than 1.
      public int getLevel();
      
      // Should this throw an exception if level is set to lesser than 1? Or just silently let the VillagerData constructor reset it to 1?
      public void setLevel(int level);
      
      // Not sure about name yet
      @NotNull
      public OutfitType getOutfitType();
      
      // Not sure about name yet
      public void setOutfitType(@NotNull OutfitType outfitType);
      
      // Not sure about the name yet. Type? Outfit? OutfitType? Other?
      public enum OutfitType {
          DESERT,
          JUNGLE,
          PLAINS,
          SAVANNA,
          SNOWY,
          SWAMP,
          TAIGA;
      }
      

      And then in org.bukkit.craftbukkit.entity.CraftVillager:

      @Override
      public int getLevel() {
          return getHandle().getVillagerData().getLevel();
      }
      
      @Override
      public void setLevel(int level) {
          getHandler().setVillagerData(getHandle().getVillagerData().withLevel(level));
      }
      
      @Override
      public OutfitType getOutfitType() {
          return OutfitType.valueOf(IRegistry.VILLAGER_TYPE.getKey(getHandle().getVillagerData().getType()).getKey().toUpperCase(Locale.ROOT));
      }
      
      @Override
      public void setOutfitType(OutfitType outfitType) {
          Validate.notNull(outfitType);
          getHandle().setVillagerData(getHandle().getVillagerData().withType(IRegistry.VILLAGER_TYPE.get(new MinecraftKey(outfitType.name().toLowerCase(Locale.ROOT)))));
      }
      

      Obviously, this would need javadocs as well and some other tweaks. Might not compile as is either, I haven't tested it. I tried doing basically this but with NMS and it seems to work just fine. I'll consider trying to create a pull request but I have never contributed to Spigot before so it's pretty daunting. I don't really know how to compile Spigot after making changes so can't test it atm. I wouldn't know what to name the VillagerType things anyways. They're "getType()" in VillagerData but "getType()" is already used in the Villager interface.

            Unassigned Unassigned
            VapidLinus Linus Närkling
            Votes:
            2 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: