diff --git a/api/src/main/java/lol/pyr/znpcsplus/api/entity/EntityProperty.java b/api/src/main/java/lol/pyr/znpcsplus/api/entity/EntityProperty.java index 7ae66cb..69db24e 100644 --- a/api/src/main/java/lol/pyr/znpcsplus/api/entity/EntityProperty.java +++ b/api/src/main/java/lol/pyr/znpcsplus/api/entity/EntityProperty.java @@ -3,4 +3,5 @@ package lol.pyr.znpcsplus.api.entity; public interface EntityProperty { T getDefaultValue(); String getName(); + boolean isPlayerModifiable(); } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/commands/property/PropertyRemoveCommand.java b/plugin/src/main/java/lol/pyr/znpcsplus/commands/property/PropertyRemoveCommand.java index 0fc8b23..b517d74 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/commands/property/PropertyRemoveCommand.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/commands/property/PropertyRemoveCommand.java @@ -28,6 +28,7 @@ public class PropertyRemoveCommand implements CommandHandler { NpcImpl npc = entry.getNpc(); EntityPropertyImpl property = context.parse(EntityPropertyImpl.class); if (!npc.hasProperty(property)) context.halt(Component.text("This npc doesn't have the " + property.getName() + " property set", NamedTextColor.RED)); + if (!property.isPlayerModifiable()) context.halt(Component.text("This property is not modifiable by players", NamedTextColor.RED)); npc.setProperty(property, null); context.send(Component.text("Removed property " + property.getName() + " from NPC " + entry.getId(), NamedTextColor.GREEN)); } @@ -36,7 +37,7 @@ public class PropertyRemoveCommand implements CommandHandler { public List suggest(CommandContext context) throws CommandExecutionException { if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds()); if (context.argSize() == 2) return context.suggestStream(context.suggestionParse(0, NpcEntryImpl.class) - .getNpc().getAppliedProperties().stream().map(EntityProperty::getName)); + .getNpc().getAppliedProperties().stream().filter(EntityProperty::isPlayerModifiable).map(EntityProperty::getName)); return Collections.emptyList(); } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/DataImporterRegistry.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/DataImporterRegistry.java index 5a286ae..55d1012 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/DataImporterRegistry.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/DataImporterRegistry.java @@ -1,6 +1,7 @@ package lol.pyr.znpcsplus.conversion; import lol.pyr.znpcsplus.config.ConfigManager; +import lol.pyr.znpcsplus.conversion.citizens.CitizensImporter; import lol.pyr.znpcsplus.conversion.znpcs.ZNpcImporter; import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl; import lol.pyr.znpcsplus.npc.NpcTypeRegistryImpl; @@ -30,8 +31,8 @@ public class DataImporterRegistry { packetFactory, textSerializer, typeRegistry, propertyRegistry, skinCache, new File(pluginsFolder, "ServersNPC/data.json")))); register("znpcsplus_legacy", LazyLoader.of(() -> new ZNpcImporter(configManager, adventure, bungeeConnector, taskScheduler, packetFactory, textSerializer, typeRegistry, propertyRegistry, skinCache, new File(pluginsFolder, "ZNPCsPlusLegacy/data.json")))); - /* register("citizens", LazyLoader.of(() -> new CitizensImporter(configManager, adventure, bungeeConnector, taskScheduler, - packetFactory, textSerializer, typeRegistry, propertyRegistry, skinCache, new File(pluginsFolder, "Citizens/saves.yml")))); */ + register("citizens", LazyLoader.of(() -> new CitizensImporter(configManager, adventure, bungeeConnector, taskScheduler, + packetFactory, textSerializer, typeRegistry, propertyRegistry, skinCache, new File(pluginsFolder, "Citizens/saves.yml")))); } private void register(String id, LazyLoader loader) { diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/CitizensImporter.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/CitizensImporter.java index 3005864..39b3deb 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/CitizensImporter.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/CitizensImporter.java @@ -1,21 +1,30 @@ package lol.pyr.znpcsplus.conversion.citizens; +import lol.pyr.znpcsplus.api.NpcApiProvider; import lol.pyr.znpcsplus.config.ConfigManager; import lol.pyr.znpcsplus.conversion.DataImporter; +import lol.pyr.znpcsplus.conversion.citizens.model.CitizensTrait; +import lol.pyr.znpcsplus.conversion.citizens.model.CitizensTraitsRegistry; import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl; import lol.pyr.znpcsplus.npc.NpcEntryImpl; +import lol.pyr.znpcsplus.npc.NpcImpl; import lol.pyr.znpcsplus.npc.NpcTypeRegistryImpl; import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.scheduling.TaskScheduler; import lol.pyr.znpcsplus.skin.cache.MojangSkinCache; import lol.pyr.znpcsplus.util.BungeeConnector; +import lol.pyr.znpcsplus.util.NpcLocation; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import org.bukkit.Bukkit; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import java.io.File; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.UUID; @SuppressWarnings("FieldCanBeLocal") public class CitizensImporter implements DataImporter { @@ -29,6 +38,7 @@ public class CitizensImporter implements DataImporter { private final EntityPropertyRegistryImpl propertyRegistry; private final MojangSkinCache skinCache; private final File dataFile; + private final CitizensTraitsRegistry traitsRegistry; public CitizensImporter(ConfigManager configManager, BukkitAudiences adventure, BungeeConnector bungeeConnector, TaskScheduler taskScheduler, PacketFactory packetFactory, LegacyComponentSerializer textSerializer, @@ -44,13 +54,54 @@ public class CitizensImporter implements DataImporter { this.propertyRegistry = propertyRegistry; this.skinCache = skinCache; this.dataFile = dataFile; + this.traitsRegistry = new CitizensTraitsRegistry(typeRegistry, propertyRegistry, skinCache); } @Override public Collection importData() { YamlConfiguration config = YamlConfiguration.loadConfiguration(dataFile); - // TODO - return Collections.emptyList(); + ConfigurationSection npcsSection = config.getConfigurationSection("npc"); + if (npcsSection == null) { + return Collections.emptyList(); + } + ArrayList entries = new ArrayList<>(); + npcsSection.getKeys(false).forEach(key -> { + ConfigurationSection npcSection = npcsSection.getConfigurationSection(key); + if (npcSection == null) { + return; + } + String name = npcSection.getString("name", "Citizens NPC"); + UUID uuid; + try { + uuid = UUID.fromString(npcSection.getString("uuid")); + } catch (IllegalArgumentException e) { + uuid = UUID.randomUUID(); + } + String world = npcSection.getString("traits.location.world"); + if (world == null) { + world = Bukkit.getWorlds().get(0).getName(); + } + NpcImpl npc = new NpcImpl(uuid, propertyRegistry, configManager, packetFactory, textSerializer, world, typeRegistry.getByName("armor_stand"), new NpcLocation(0, 0, 0, 0, 0)); + npc.getHologram().addLineComponent(textSerializer.deserialize(name)); + ConfigurationSection traits = npcSection.getConfigurationSection("traits"); + if (traits != null) { + for (String traitName : traits.getKeys(false)) { + Object trait = traits.get(traitName); + CitizensTrait citizensTrait = traitsRegistry.getByName(traitName); + if (citizensTrait != null) { + npc = citizensTrait.apply(npc, trait); + } + } + } + String id = key.toLowerCase(); + while (NpcApiProvider.get().getNpcRegistry().getById(id) != null) { + id += "_"; + } + NpcEntryImpl entry = new NpcEntryImpl(id, npc); + entry.enableEverything(); + entries.add(entry); + }); + return entries; } @Override diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/CitizensTrait.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/CitizensTrait.java new file mode 100644 index 0000000..0811589 --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/CitizensTrait.java @@ -0,0 +1,19 @@ +package lol.pyr.znpcsplus.conversion.citizens.model; + +import lol.pyr.znpcsplus.npc.NpcImpl; +import org.jetbrains.annotations.NotNull; + +public abstract class CitizensTrait { + private final String identifier; + + public CitizensTrait(String identifier) { + this.identifier = identifier; + } + + public String getIdentifier() { + return identifier; + } + + public abstract @NotNull NpcImpl apply(NpcImpl npc, Object value); + +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/CitizensTraitsRegistry.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/CitizensTraitsRegistry.java new file mode 100644 index 0000000..ba3ba89 --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/CitizensTraitsRegistry.java @@ -0,0 +1,31 @@ +package lol.pyr.znpcsplus.conversion.citizens.model; + +import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry; +import lol.pyr.znpcsplus.api.npc.NpcTypeRegistry; +import lol.pyr.znpcsplus.conversion.citizens.model.traits.*; +import lol.pyr.znpcsplus.skin.cache.MojangSkinCache; + +import java.util.HashMap; + +public class CitizensTraitsRegistry { + private final HashMap traitMap = new HashMap<>(); + + public CitizensTraitsRegistry(NpcTypeRegistry typeRegistry, EntityPropertyRegistry propertyRegistry, MojangSkinCache skinCache) { + register(new LocationTrait()); + register(new TypeTrait(typeRegistry)); + register(new ProfessionTrait(propertyRegistry)); + register(new VillagerTrait(propertyRegistry)); + register(new SkinTrait(propertyRegistry)); + register(new MirrorTrait(propertyRegistry, skinCache)); + register(new SkinLayersTrait(propertyRegistry)); + register(new LookTrait(propertyRegistry)); + } + + public CitizensTrait getByName(String name) { + return traitMap.get(name); + } + + public void register(CitizensTrait trait) { + traitMap.put(trait.getIdentifier(), trait); + } +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/SectionCitizensTrait.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/SectionCitizensTrait.java new file mode 100644 index 0000000..123eca5 --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/SectionCitizensTrait.java @@ -0,0 +1,19 @@ +package lol.pyr.znpcsplus.conversion.citizens.model; + +import lol.pyr.znpcsplus.npc.NpcImpl; +import org.bukkit.configuration.ConfigurationSection; +import org.jetbrains.annotations.NotNull; + +public abstract class SectionCitizensTrait extends CitizensTrait { + public SectionCitizensTrait(String identifier) { + super(identifier); + } + + @Override + public @NotNull NpcImpl apply(NpcImpl npc, Object value) { + if (!(value instanceof ConfigurationSection)) return npc; + return apply(npc, (ConfigurationSection) value); + } + + public abstract @NotNull NpcImpl apply(NpcImpl npc, ConfigurationSection section); +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/StringCitizensTrait.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/StringCitizensTrait.java new file mode 100644 index 0000000..58199a4 --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/StringCitizensTrait.java @@ -0,0 +1,18 @@ +package lol.pyr.znpcsplus.conversion.citizens.model; + +import lol.pyr.znpcsplus.npc.NpcImpl; +import org.jetbrains.annotations.NotNull; + +public abstract class StringCitizensTrait extends CitizensTrait { + public StringCitizensTrait(String identifier) { + super(identifier); + } + + @Override + public @NotNull NpcImpl apply(NpcImpl npc, Object value) { + if (!(value instanceof String)) return npc; + return apply(npc, (String) value); + } + + public abstract @NotNull NpcImpl apply(NpcImpl npc, String string); +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/LocationTrait.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/LocationTrait.java new file mode 100644 index 0000000..c56793c --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/LocationTrait.java @@ -0,0 +1,25 @@ +package lol.pyr.znpcsplus.conversion.citizens.model.traits; + +import lol.pyr.znpcsplus.conversion.citizens.model.SectionCitizensTrait; +import lol.pyr.znpcsplus.npc.NpcImpl; +import lol.pyr.znpcsplus.util.NpcLocation; +import org.bukkit.configuration.ConfigurationSection; +import org.jetbrains.annotations.NotNull; + +public class LocationTrait extends SectionCitizensTrait { + public LocationTrait() { + super("location"); + } + + @Override + public @NotNull NpcImpl apply(NpcImpl npc, ConfigurationSection section) { + double x = Double.parseDouble(section.getString("x")); + double y = Double.parseDouble(section.getString("y")); + double z = Double.parseDouble(section.getString("z")); + float yaw = Float.parseFloat(section.getString("yaw")); + float pitch = Float.parseFloat(section.getString("pitch")); + NpcLocation location = new NpcLocation(x, y, z, yaw, pitch); + npc.setLocation(location); + return npc; + } +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/LookTrait.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/LookTrait.java new file mode 100644 index 0000000..0854124 --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/LookTrait.java @@ -0,0 +1,22 @@ +package lol.pyr.znpcsplus.conversion.citizens.model.traits; + +import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry; +import lol.pyr.znpcsplus.conversion.citizens.model.SectionCitizensTrait; +import lol.pyr.znpcsplus.npc.NpcImpl; +import org.bukkit.configuration.ConfigurationSection; +import org.jetbrains.annotations.NotNull; + +public class LookTrait extends SectionCitizensTrait { + private final EntityPropertyRegistry registry; + + public LookTrait(EntityPropertyRegistry registry) { + super("lookclose"); + this.registry = registry; + } + + @Override + public @NotNull NpcImpl apply(NpcImpl npc, ConfigurationSection section) { + if (section.getBoolean("enabled")) npc.setProperty(registry.getByName("look", Boolean.class), true); + return npc; + } +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/MirrorTrait.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/MirrorTrait.java new file mode 100644 index 0000000..19360bf --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/MirrorTrait.java @@ -0,0 +1,27 @@ +package lol.pyr.znpcsplus.conversion.citizens.model.traits; + +import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry; +import lol.pyr.znpcsplus.api.skin.SkinDescriptor; +import lol.pyr.znpcsplus.conversion.citizens.model.SectionCitizensTrait; +import lol.pyr.znpcsplus.npc.NpcImpl; +import lol.pyr.znpcsplus.skin.cache.MojangSkinCache; +import lol.pyr.znpcsplus.skin.descriptor.MirrorDescriptor; +import org.bukkit.configuration.ConfigurationSection; +import org.jetbrains.annotations.NotNull; + +public class MirrorTrait extends SectionCitizensTrait { + private final EntityPropertyRegistry registry; + private final MojangSkinCache skinCache; + + public MirrorTrait(EntityPropertyRegistry registry, MojangSkinCache skinCache) { + super("mirrortrait"); + this.registry = registry; + this.skinCache = skinCache; + } + + @Override + public @NotNull NpcImpl apply(NpcImpl npc, ConfigurationSection section) { + if (section.getBoolean("enabled")) npc.setProperty(registry.getByName("skin", SkinDescriptor.class), new MirrorDescriptor(skinCache)); + return npc; + } +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/ProfessionTrait.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/ProfessionTrait.java new file mode 100644 index 0000000..551d9a8 --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/ProfessionTrait.java @@ -0,0 +1,28 @@ +package lol.pyr.znpcsplus.conversion.citizens.model.traits; + +import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry; +import lol.pyr.znpcsplus.conversion.citizens.model.StringCitizensTrait; +import lol.pyr.znpcsplus.npc.NpcImpl; +import lol.pyr.znpcsplus.util.VillagerProfession; +import org.jetbrains.annotations.NotNull; + +public class ProfessionTrait extends StringCitizensTrait { + private final EntityPropertyRegistry registry; + + public ProfessionTrait(EntityPropertyRegistry registry) { + super("profession"); + this.registry = registry; + } + + @Override + public @NotNull NpcImpl apply(NpcImpl npc, String string) { + VillagerProfession profession; + try { + profession = VillagerProfession.valueOf(string.toUpperCase()); + } catch (IllegalArgumentException ignored) { + profession = VillagerProfession.NONE; + } + npc.setProperty(registry.getByName("villager_profession", VillagerProfession.class), profession); + return npc; + } +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/SkinLayersTrait.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/SkinLayersTrait.java new file mode 100644 index 0000000..f2d7ed0 --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/SkinLayersTrait.java @@ -0,0 +1,38 @@ +package lol.pyr.znpcsplus.conversion.citizens.model.traits; + +import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry; +import lol.pyr.znpcsplus.conversion.citizens.model.SectionCitizensTrait; +import lol.pyr.znpcsplus.npc.NpcImpl; +import org.bukkit.configuration.ConfigurationSection; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; + +public class SkinLayersTrait extends SectionCitizensTrait { + private final EntityPropertyRegistry registry; + private final Map skinLayers; + + public SkinLayersTrait(EntityPropertyRegistry registry) { + super("skinlayers"); + this.registry = registry; + this.skinLayers = new HashMap<>(); + this.skinLayers.put("cape", "skin_cape"); + this.skinLayers.put("hat", "skin_hat"); + this.skinLayers.put("jacket", "skin_jacket"); + this.skinLayers.put("left_sleeve", "skin_left_sleeve"); + this.skinLayers.put("left_pants", "skin_left_leg"); + this.skinLayers.put("right_sleeve", "skin_right_sleeve"); + this.skinLayers.put("right_pants", "skin_right_leg"); + } + + @Override + public @NotNull NpcImpl apply(NpcImpl npc, ConfigurationSection section) { + for (Map.Entry entry : this.skinLayers.entrySet()) { + String key = entry.getKey(); + String property = entry.getValue(); + if (section.contains(key)) npc.setProperty(registry.getByName(property, Boolean.class), section.getBoolean(key)); + } + return npc; + } +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/SkinTrait.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/SkinTrait.java new file mode 100644 index 0000000..439c9ff --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/SkinTrait.java @@ -0,0 +1,27 @@ +package lol.pyr.znpcsplus.conversion.citizens.model.traits; + +import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry; +import lol.pyr.znpcsplus.api.skin.SkinDescriptor; +import lol.pyr.znpcsplus.conversion.citizens.model.SectionCitizensTrait; +import lol.pyr.znpcsplus.npc.NpcImpl; +import lol.pyr.znpcsplus.skin.Skin; +import lol.pyr.znpcsplus.skin.descriptor.PrefetchedDescriptor; +import org.bukkit.configuration.ConfigurationSection; +import org.jetbrains.annotations.NotNull; + +public class SkinTrait extends SectionCitizensTrait { + private final EntityPropertyRegistry registry; + + public SkinTrait(EntityPropertyRegistry registry) { + super("skintrait"); + this.registry = registry; + } + + @Override + public @NotNull NpcImpl apply(NpcImpl npc, ConfigurationSection section) { + String texture = section.getString("textureRaw"); + String signature = section.getString("signature"); + if (texture != null && signature != null) npc.setProperty(registry.getByName("skin", SkinDescriptor.class), new PrefetchedDescriptor(new Skin(texture, signature))); + return npc; + } +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/TypeTrait.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/TypeTrait.java new file mode 100644 index 0000000..6af1d85 --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/TypeTrait.java @@ -0,0 +1,31 @@ +package lol.pyr.znpcsplus.conversion.citizens.model.traits; + +import lol.pyr.znpcsplus.api.npc.NpcTypeRegistry; +import lol.pyr.znpcsplus.conversion.citizens.model.StringCitizensTrait; +import lol.pyr.znpcsplus.npc.NpcImpl; +import lol.pyr.znpcsplus.npc.NpcTypeImpl; +import org.jetbrains.annotations.NotNull; + +public class TypeTrait extends StringCitizensTrait { + private final NpcTypeRegistry registry; + + public TypeTrait(NpcTypeRegistry registry) { + super("type"); + this.registry = registry; + } + + @Override + public @NotNull NpcImpl apply(NpcImpl npc, String string) { + NpcTypeImpl type = warpNpcType(string); + if (type == null) return npc; + npc.setType(type); + return npc; + } + + private NpcTypeImpl warpNpcType(String name) { + name = name.toLowerCase(); +// if (name.equals("player")) name = "human"; +// else if (name.equals("zombievillager")) name = "zombie_villager"; + return (NpcTypeImpl) registry.getByName(name); + } +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/VillagerTrait.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/VillagerTrait.java new file mode 100644 index 0000000..4998f78 --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/VillagerTrait.java @@ -0,0 +1,39 @@ +package lol.pyr.znpcsplus.conversion.citizens.model.traits; + +import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry; +import lol.pyr.znpcsplus.conversion.citizens.model.SectionCitizensTrait; +import lol.pyr.znpcsplus.npc.NpcImpl; +import lol.pyr.znpcsplus.util.VillagerLevel; +import lol.pyr.znpcsplus.util.VillagerType; +import org.bukkit.configuration.ConfigurationSection; +import org.jetbrains.annotations.NotNull; + +public class VillagerTrait extends SectionCitizensTrait { + private final EntityPropertyRegistry registry; + + public VillagerTrait(EntityPropertyRegistry registry) { + super("villagertrait"); + this.registry = registry; + } + + @Override + public @NotNull NpcImpl apply(NpcImpl npc, ConfigurationSection section) { + int level = section.getInt("level"); + String type = section.getString("type", "plains"); + VillagerLevel villagerLevel; + try { + villagerLevel = VillagerLevel.values()[level]; + } catch (ArrayIndexOutOfBoundsException ignored) { + villagerLevel = VillagerLevel.STONE; + } + VillagerType villagerType; + try { + villagerType = VillagerType.valueOf(type.toUpperCase()); + } catch (IllegalArgumentException ignored) { + villagerType = VillagerType.PLAINS; + } + npc.setProperty(registry.getByName("villager_level", VillagerLevel.class), villagerLevel); + npc.setProperty(registry.getByName("villager_type", VillagerType.class), villagerType); + return npc; + } +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyImpl.java index 9842fbb..53b4392 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyImpl.java @@ -15,6 +15,7 @@ public abstract class EntityPropertyImpl implements EntityProperty { private final T defaultValue; private final Class clazz; private final List> dependencies = new ArrayList<>(); + private boolean playerModifiable = true; protected EntityPropertyImpl(String name, T defaultValue, Class clazz) { this.name = name.toLowerCase(); @@ -32,6 +33,15 @@ public abstract class EntityPropertyImpl implements EntityProperty { return defaultValue; } + @Override + public boolean isPlayerModifiable() { + return playerModifiable; + } + + public void setPlayerModifiable(boolean playerModifiable) { + this.playerModifiable = playerModifiable; + } + public Class getType() { return clazz; } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java index b8a33f5..bea8614 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java @@ -249,7 +249,7 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { register(new NameProperty()); register(new DummyProperty<>("look", false)); - register(new DummyProperty<>("skin", SkinDescriptor.class)); + register(new DummyProperty<>("skin", SkinDescriptor.class, false)); register(new GlowProperty(packetFactory)); register(new EffectsProperty("fire", 0x01)); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/DummyProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/DummyProperty.java index 9e1306e..eba69a5 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/DummyProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/DummyProperty.java @@ -8,13 +8,23 @@ import org.bukkit.entity.Player; import java.util.Map; public class DummyProperty extends EntityPropertyImpl { - @SuppressWarnings("unchecked") public DummyProperty(String name, T defaultValue) { - super(name, defaultValue, (Class) defaultValue.getClass()); + this(name, defaultValue, true); } public DummyProperty(String name, Class clazz) { + this(name, clazz, true); + } + + @SuppressWarnings("unchecked") + public DummyProperty(String name, T defaultValue, boolean playerModifiable) { + super(name, defaultValue, (Class) defaultValue.getClass()); + setPlayerModifiable(playerModifiable); + } + + public DummyProperty(String name, Class clazz, boolean playerModifiable) { super(name, null, clazz); + setPlayerModifiable(playerModifiable); } @Override diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java index 619083f..573aea4 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java @@ -142,6 +142,7 @@ public class NpcImpl extends Viewable implements Npc { } public void setProperty(EntityPropertyImpl key, T value) { + if (key == null) return; if (value == null || value.equals(key.getDefaultValue())) propertyMap.remove(key); else propertyMap.put(key, value); UNSAFE_refreshProperty(key);