New item type, manager update & introduction of categories

This commit is contained in:
Roch Blonndiaux 2023-02-24 14:27:50 +01:00
parent 8768f1b9fe
commit 78fb3c94c9
11 changed files with 323 additions and 416 deletions

View File

@ -0,0 +1,64 @@
package net.Indyuce.mmoitems.api.item.category;
import net.Indyuce.mmoitems.api.item.type.MMOItemType;
import net.Indyuce.mmoitems.stat.type.ItemStat;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* mmoitems
* 24/02/2023
*
* @author Roch Blondiaux (Kiwix).
*/
public class MMOTypeCategory {
private final String id;
private final String name;
private final ItemStack item;
private final String loreFormat;
private final List<ItemStat<?, ?>> stats;
public MMOTypeCategory(String id, String name, ItemStack item, String loreFormat, List<ItemStat<?, ?>> stats) {
this.id = id;
this.name = name;
this.item = item;
this.loreFormat = loreFormat;
this.stats = stats;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public ItemStack getItem() {
return item;
}
public String getLoreFormat() {
return loreFormat;
}
public List<ItemStat<?, ?>> getStats() {
return stats;
}
public static MMOTypeCategory load(@NotNull ConfigurationSection section) {
final String id = section.getName();
final String name = section.getString("name");
final ItemStack item = MMOItemType.read(section.getString("display", Material.STONE.toString()));
final String loreFormat = section.getString("lore-format");
final List<ItemStat<?, ?>> stats = new ArrayList<>();
return new MMOTypeCategory(id, name, item, loreFormat, stats);
}
}

View File

@ -1,61 +1,157 @@
package net.Indyuce.mmoitems.api.item.type; package net.Indyuce.mmoitems.api.item.type;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.api.item.NBTItem; import io.lumine.mythic.lib.api.item.NBTItem;
import io.lumine.mythic.lib.player.modifier.ModifierSource; import io.lumine.mythic.lib.player.modifier.ModifierSource;
import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.ConfigFile; import net.Indyuce.mmoitems.api.ConfigFile;
import net.Indyuce.mmoitems.api.Type; import net.Indyuce.mmoitems.api.item.category.MMOTypeCategory;
import net.Indyuce.mmoitems.api.item.type.set.MMOTypeSet;
import net.Indyuce.mmoitems.api.item.util.identify.UnidentifiedItem; import net.Indyuce.mmoitems.api.item.util.identify.UnidentifiedItem;
import net.Indyuce.mmoitems.manager.TypeManager;
import net.Indyuce.mmoitems.stat.type.ItemStat; import net.Indyuce.mmoitems.stat.type.ItemStat;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
/** /**
* mmoitems * mmoitems
* 20/02/2023 * 24/02/2023
* *
* @author Roch Blondiaux (Kiwix). * @author Roch Blondiaux (Kiwix).
*/ */
public interface MMOItemType { public class MMOItemType {
@NotNull private final String id;
String getId(); private final String name;
private final ModifierSource modifierSource;
private final boolean weapon;
private final String loreFormat;
private final MMOTypeCategory category;
private final ItemStack item;
private final UnidentifiedItem unidentifiedTemplate;
private final List<ItemStat<?, ?>> stats;
@NotNull private MMOItemType(String id, String name, ModifierSource modifierSource, boolean weapon, String loreFormat, MMOTypeCategory category, ItemStack item, List<ItemStat<?, ?>> stats) {
String getName(); this.id = id;
this.name = name;
this.modifierSource = modifierSource;
this.weapon = weapon;
this.loreFormat = loreFormat;
this.category = category;
this.item = item;
this.unidentifiedTemplate = new UnidentifiedItem(this);
this.stats = stats;
}
boolean isWeapon(); public String getId() {
return id;
}
ModifierSource getModifierSource(); public String getName() {
return name;
}
ItemStack toItemStack(); public ModifierSource getModifierSource() {
return modifierSource;
}
boolean isFourGUIMode(); public boolean isWeapon() {
return weapon;
}
String getLoreFormat(); public String getLoreFormat() {
return loreFormat;
}
List<ItemStat<?, ?>> getAvailableStats(); public MMOTypeCategory getCategory() {
return category;
}
ConfigFile getConfiguration(); public ItemStack getItem() {
return item;
}
UnidentifiedItem getUnidentifiedItem(); public UnidentifiedItem getUnidentifiedTemplate() {
return unidentifiedTemplate;
}
void load(ConfigurationSection config); public List<ItemStat<?, ?>> getStats() {
return stats;
}
/** public boolean isFourGUIMode() {
* Used in command executors and completions for easier manipulation return this.modifierSource == ModifierSource.ARMOR;
* }
* @param id The type id
* @return If a registered type with this ID could be found public ConfigFile getConfigFile() {
*/ return new ConfigFile("/item", getId().toLowerCase());
static boolean isValid(@Nullable String id) { }
return id != null && MMOItems.plugin.getTypes().has(id.toUpperCase().replace("-", "_").replace(" ", "_"));
public static MMOItemType load(@NotNull TypeManager manager, @NotNull ConfigurationSection section) {
final String id = section.getName();
final String name = section.getString("name");
final ModifierSource modifierSource = ModifierSource.valueOf(section.getString("modifier-source"));
final boolean weapon = section.getBoolean("weapon");
final String loreFormat = section.getString("lore-format");
final ItemStack item = read(section.getString("display", Material.STONE.toString()));
// TODO: Load the category
final String categoryId = section.getString("category");
final MMOTypeCategory category = manager.getCategories()
.stream()
.filter(mmoTypeCategory -> mmoTypeCategory.getId().equalsIgnoreCase(categoryId))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(String.format("Category %s does not exist.", categoryId)));
// TODO: Load the stats
final List<ItemStat<?, ?>> stats = new ArrayList<>();
MMOItemType type = new MMOItemType(id, name, modifierSource, weapon, loreFormat, category, item, stats);
type.getUnidentifiedTemplate().update(section.getConfigurationSection("unident-item"));
return type;
}
public static ItemStack read(String str) {
Validate.notNull(str, "Input must not be null");
String[] split = str.split(":");
Material material = Material.valueOf(split[0]);
return split.length > 1 ? MythicLib.plugin.getVersion().getWrapper().textureItem(material, Integer.parseInt(split[1])) : new ItemStack(material);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MMOItemType type = (MMOItemType) o;
return id.equals(type.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
@Override
public String toString() {
return "MMOItemType{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", modifierSource=" + modifierSource +
", weapon=" + weapon +
", loreFormat='" + loreFormat + '\'' +
", category=" + category +
'}';
} }
/** /**
@ -66,7 +162,8 @@ public interface MMOItemType {
*/ */
@Nullable @Nullable
@Contract("null -> null") @Contract("null -> null")
static MMOTypeSet get(@Nullable ItemStack item) { public static MMOItemType get(@Nullable ItemStack item) {
if (item == null) return null;
return get(NBTItem.get(item).getType()); return get(NBTItem.get(item).getType());
} }
@ -78,8 +175,19 @@ public interface MMOItemType {
*/ */
@Nullable @Nullable
@Contract("null -> null") @Contract("null -> null")
static MMOTypeSet get(@Nullable String id) { public static MMOItemType get(@Nullable String id) {
if (id == null) return null;
String format = id.toUpperCase().replace("-", "_").replace(" ", "_"); String format = id.toUpperCase().replace("-", "_").replace(" ", "_");
return MMOItems.plugin.getTypes().has(format) ? MMOItems.plugin.getTypes().get(format) : null; return MMOItems.plugin.getTypes().has(format) ? MMOItems.plugin.getTypes().get(format) : null;
} }
/**
* Used in command executors and completions for easier manipulation
*
* @param id The type id
* @return If a registered type with this ID could be found
*/
public static boolean isValid(@Nullable String id) {
return id != null && MMOItems.plugin.getTypes().has(id.toUpperCase().replace("-", "_").replace(" ", "_"));
}
} }

View File

@ -1,165 +0,0 @@
package net.Indyuce.mmoitems.api.item.type;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.player.modifier.ModifierSource;
import net.Indyuce.mmoitems.api.ConfigFile;
import net.Indyuce.mmoitems.api.TypeSet;
import net.Indyuce.mmoitems.api.item.type.set.MMOTypeSet;
import net.Indyuce.mmoitems.api.item.util.identify.UnidentifiedItem;
import net.Indyuce.mmoitems.manager.TypeManager;
import net.Indyuce.mmoitems.stat.type.ItemStat;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* mmoitems
* 20/02/2023
*
* @author Roch Blondiaux (Kiwix).
*/
public class MMOPredefinedType implements MMOItemType {
private final String id;
private final MMOTypeSet set;
private final ModifierSource modifierSource;
private final boolean weapon;
// Configurable
private String name;
@Nullable
private String loreFormat;
/**
* Used to display the item in the item explorer and in the item recipes
* list in the advanced workbench. can also be edited using the config
* files.
*/
private ItemStack item;
private UnidentifiedItem unidentifiedTemplate;
/**
* List of stats which can be applied onto an item which has this type. This
* improves performance when generating an item by a significant amount.
*/
private final List<ItemStat<?, ?>> stats = new ArrayList<>();
public MMOPredefinedType(String id, boolean weapon, ModifierSource modSource) {
this.id = id.toUpperCase().replace("-", "_").replace(" ", "_");
this.modifierSource = modSource;
this.weapon = weapon;
this.loreFormat = null;
}
public MMOPredefinedType(@NotNull TypeManager manager, @NotNull ConfigurationSection config) {
id = config.getName().toUpperCase().replace("-", "_").replace(" ", "_");
parent = manager.get(config.getString("parent", "").toUpperCase().replace("-", "_").replace(" ", "_"));
set = (parent != null ? parent.set : TypeSet.EXTRA);
weapon = (parent != null && parent.weapon);
modifierSource = (parent != null ? parent.modifierSource : ModifierSource.OTHER);
this.loreFormat = config.getString("LoreFormat", (parent != null ? parent.loreFormat : null));
}
@NotNull
@Override
public String getId() {
return this.id;
}
@NotNull
@Override
public String getName() {
return this.name;
}
@Override
public boolean isWeapon() {
return this.weapon;
}
@Override
public ModifierSource getModifierSource() {
return this.modifierSource;
}
@Override
public ItemStack toItemStack() {
return this.item.clone();
}
@Override
public boolean isFourGUIMode() {
}
@Override
public String getLoreFormat() {
return this.loreFormat;
}
@Override
public List<ItemStat<?, ?>> getAvailableStats() {
return this.stats;
}
@Override
public ConfigFile getConfiguration() {
return new ConfigFile("/item", this.id.toLowerCase());
}
@Override
public UnidentifiedItem getUnidentifiedItem() {
return this.unidentifiedTemplate;
}
@Override
public void load(ConfigurationSection config) {
Validate.notNull(config, String.format("Could not find config for %s", getId()));
name = config.getString("name", name);
item = read(config.getString("display", item == null ? Material.STONE.toString() : item.getType().toString()));
(unidentifiedTemplate = new UnidentifiedItem(this)).update(config.getConfigurationSection("unident-item"));
// Getting overridden?
loreFormat = config.getString("LoreFormat", (parent != null ? parent.loreFormat : loreFormat));
}
private ItemStack read(String data) {
Validate.notNull(data, "Input must not be null");
String[] split = data.split(":");
Material material = Material.valueOf(split[0]);
return split.length > 1 ? MythicLib.plugin.getVersion().getWrapper().textureItem(material, Integer.parseInt(split[1])) : new ItemStack(material);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MMOTypeSet type = (MMOTypeSet) o;
return id.equals(type.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
@Override
public String toString() {
return "Type{" +
"id='" + id + '\'' +
'}';
}
}

View File

@ -1,31 +0,0 @@
package net.Indyuce.mmoitems.api.item.type.set;
import org.jetbrains.annotations.ApiStatus;
/**
* mmoitems
* 21/02/2023
*
* @author Roch Blondiaux (Kiwix).
*/
@ApiStatus.Internal
public abstract class AbstractTypeSet implements MMOTypeSet {
private final String name;
private final boolean hasAttackEffect;
public AbstractTypeSet(String name, boolean hasAttackEffect) {
this.name = name;
this.hasAttackEffect = hasAttackEffect;
}
@Override
public String getName() {
return name;
}
@Override
public boolean hasAttackEffect() {
return hasAttackEffect;
}
}

View File

@ -1,23 +0,0 @@
package net.Indyuce.mmoitems.api.item.type.set;
import io.lumine.mythic.lib.damage.AttackMetadata;
import net.Indyuce.mmoitems.api.interaction.weapon.Weapon;
import net.Indyuce.mmoitems.api.player.PlayerData;
import org.bukkit.entity.LivingEntity;
/**
* mmoitems
* 21/02/2023
*
* @author Roch Blondiaux (Kiwix).
*/
public class DummyTypeSet extends AbstractTypeSet {
public DummyTypeSet(String name) {
super(name, false);
}
@Override
public void apply(AttackMetadata attackData, PlayerData source, LivingEntity target, Weapon weapon) {
}
}

View File

@ -1,27 +0,0 @@
package net.Indyuce.mmoitems.api.item.type.set;
import io.lumine.mythic.lib.damage.AttackMetadata;
import net.Indyuce.mmoitems.api.interaction.weapon.Weapon;
import net.Indyuce.mmoitems.api.player.PlayerData;
import org.bukkit.entity.LivingEntity;
/**
* mmoitems
* 20/02/2023
*
* @author Roch Blondiaux (Kiwix).
*/
public interface MMOTypeSet {
String getName();
void apply(AttackMetadata attackData, PlayerData source, LivingEntity target, Weapon weapon);
boolean hasAttackEffect();
default void applyAttackEffect(AttackMetadata attackMeta, PlayerData damager, LivingEntity target, Weapon weapon) {
if (this.hasAttackEffect())
this.apply(attackMeta, damager, target, weapon);
}
}

View File

@ -1,53 +0,0 @@
package net.Indyuce.mmoitems.api.item.type.set;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.damage.AttackMetadata;
import io.lumine.mythic.lib.script.Script;
import io.lumine.mythic.lib.skill.SkillMetadata;
import net.Indyuce.mmoitems.api.interaction.weapon.Weapon;
import net.Indyuce.mmoitems.api.player.PlayerData;
import org.apache.commons.lang3.Validate;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.LivingEntity;
import org.jetbrains.annotations.NotNull;
/**
* mmoitems
* 21/02/2023
*
* @author Roch Blondiaux (Kiwix).
*/
public class ScriptTypeSet extends AbstractTypeSet {
private final Script script;
public ScriptTypeSet(String name, boolean hasAttackEffect, Script script) {
super(name, hasAttackEffect);
this.script = script;
}
@Override
public void apply(AttackMetadata attackData, PlayerData source, LivingEntity target, Weapon weapon) {
final SkillMetadata skillMetadata = new SkillMetadata(null, source.getMMOPlayerData());
// TODO: check if the scripts are working
script.cast(skillMetadata);
}
public Script getScript() {
return script;
}
public static ScriptTypeSet load(@NotNull ConfigurationSection section) {
Validate.notNull(section, "The section cannot be null");
Validate.isTrue(section.contains("name"), "The section must contain a name");
Validate.isTrue(section.contains("attack-effect"), "The section must contain a has-attack-effect");
Validate.isTrue(section.contains("script"), "The section must contain a script");
final String name = section.getString("name");
final boolean hasAttackEffect = section.getBoolean("has-attack-effect");
final Script script = MythicLib.plugin.getSkills().getScriptOrThrow(section.getString("script"));
return new ScriptTypeSet(name, hasAttackEffect, script);
}
}

View File

@ -6,9 +6,9 @@ import io.lumine.mythic.lib.api.item.NBTItem;
import io.lumine.mythic.lib.util.AdventureUtils; import io.lumine.mythic.lib.util.AdventureUtils;
import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.ItemStats;
import net.Indyuce.mmoitems.api.ItemTier; import net.Indyuce.mmoitems.api.ItemTier;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem; import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
import net.Indyuce.mmoitems.api.item.mmoitem.VolatileMMOItem; import net.Indyuce.mmoitems.api.item.mmoitem.VolatileMMOItem;
import net.Indyuce.mmoitems.api.item.type.MMOItemType;
import net.Indyuce.mmoitems.api.item.util.ConfigItem; import net.Indyuce.mmoitems.api.item.util.ConfigItem;
import net.Indyuce.mmoitems.stat.data.DoubleData; import net.Indyuce.mmoitems.stat.data.DoubleData;
import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemFlag;
@ -22,7 +22,7 @@ import java.io.ByteArrayOutputStream;
import java.util.*; import java.util.*;
public class UnidentifiedItem extends ConfigItem { public class UnidentifiedItem extends ConfigItem {
public UnidentifiedItem(Type type) { public UnidentifiedItem(MMOItemType type) {
super("unidentified", type.getItem().getType()); super("unidentified", type.getItem().getType());
setName("#prefix#Unidentified " + type.getName()); setName("#prefix#Unidentified " + type.getName());

View File

@ -2,111 +2,129 @@ package net.Indyuce.mmoitems.manager;
import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.ConfigFile; import net.Indyuce.mmoitems.api.ConfigFile;
import net.Indyuce.mmoitems.api.Type; import net.Indyuce.mmoitems.api.item.category.MMOTypeCategory;
import net.Indyuce.mmoitems.api.item.type.MMOItemType;
import net.Indyuce.mmoitems.manager.ConfigManager.DefaultFile; import net.Indyuce.mmoitems.manager.ConfigManager.DefaultFile;
import org.apache.commons.lang.Validate; import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field; import java.util.ArrayList;
import java.lang.reflect.Modifier; import java.util.List;
import java.util.*; import java.util.Objects;
import java.util.logging.Level; import java.util.stream.Collectors;
public class TypeManager implements Reloadable { public class TypeManager implements Reloadable {
private final Map<String, Type> map = new LinkedHashMap<>();
/** private final List<MMOItemType> types = new ArrayList<>();
* Reloads the type manager. It entirely empties the currently registered private final List<MMOTypeCategory> categories = new ArrayList<>();
* item types, registers default item types again and reads item-types.yml
*/
public void reload() {
map.clear();
// Load default types /**
for (Field field : Type.class.getFields()) * Reloads the type manager. It entirely empties the currently registered
try { * item types, registers default item types again and reads item-types.yml
if (Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers()) && field.get(null) instanceof Type) */
register((Type) field.get(null)); public void reload() {
} catch (Exception exception) { this.categories.clear();
MMOItems.plugin.getLogger().log(Level.WARNING, "Couldn't register type called '" + field.getName() + "': " + exception.getMessage()); this.types.clear();
}
/* /*
* Register all other types. Important: check if the map already * Register all other types. Important: check if the map already
* contains the id, this way the DEFAULT types are not registered twice, * contains the id, this way the DEFAULT types are not registered twice,
* and only custom types are registered with a parent. * and only custom types are registered with a parent.
*/ */
DefaultFile.ITEM_TYPES.checkFile(); DefaultFile.ITEM_TYPES.checkFile();
ConfigFile config = new ConfigFile("item-types"); // Categories
for (String id : config.getConfig().getKeys(false)) ConfigFile categoriesConfig = new ConfigFile("type-categories.yml");
if (!map.containsKey(id)) ConfigurationSection section = categoriesConfig.getConfig();
try { section.getKeys(false)
register(new Type(this, config.getConfig().getConfigurationSection(id))); .stream()
} catch (IllegalArgumentException exception) { .filter(section::isConfigurationSection)
MMOItems.plugin.getLogger().log(Level.WARNING, "Could not register type '" + id + "': " + exception.getMessage()); .map(section::getConfigurationSection)
} .filter(Objects::nonNull)
.map(MMOTypeCategory::load)
.peek(this.categories::add)
.peek(category -> category.getStats().clear())
.forEach(category -> MMOItems.plugin.getStats()
.getAll()
.forEach(stat -> category.getStats().add(stat)));
for (Iterator<Type> iterator = map.values().iterator(); iterator.hasNext();) { // DEBUG
Type type = iterator.next(); MMOItems.log("Loaded " + this.categories.size() + " item categories.");
try { // Types
type.load(config.getConfig().getConfigurationSection(type.getId())); ConfigFile typesConfig = new ConfigFile("item-types.yml");
} catch (IllegalArgumentException exception) { ConfigurationSection typesSection = typesConfig.getConfig();
MMOItems.plugin.getLogger().log(Level.WARNING, "Could not register type '" + type.getId() + "': " + exception.getMessage()); typesSection.getKeys(false)
iterator.remove(); .stream()
continue; .filter(typesSection::isConfigurationSection)
} .map(typesSection::getConfigurationSection)
.filter(Objects::nonNull)
.map(s -> MMOItemType.load(this, s))
.peek(this.types::add)
.peek(mmoItemType -> mmoItemType.getStats().clear())
.forEach(mmoItemType -> MMOItems.plugin.getStats()
.getAll()
.forEach(stat -> mmoItemType.getStats().add(stat)));
// TODO: Add stats from type category
/* // DEBUG
* caches all the stats which the type can have to reduce future MMOItems.log("Loaded " + this.types.size() + " item types.");
* both item generation (and GUI) calculations. probably the thing }
* which takes the most time when loading item types.
*/
type.getAvailableStats().clear();
MMOItems.plugin.getStats().getAll().stream().filter(stat -> stat.isCompatible(type)).forEach(stat -> type.getAvailableStats().add(stat));
}
}
public void register(Type type) { public void register(MMOItemType type) {
map.put(type.getId(), type); this.types.add(type);
} }
public void registerAll(Type... types) { public void registerAll(MMOItemType... types) {
for (Type type : types) for (MMOItemType type : types)
register(type); register(type);
} }
/** /**
* @param id Internal ID of the type * @param id Internal ID of the type
* * @return The MMOItem Type if it found.
* @return The MMOItem Type if it found. */
*/ @Contract("null -> null")
@Nullable public Type get(@Nullable String id) { @Nullable
if (id == null) { return null; } public MMOItemType get(@Nullable String id) {
return map.get(id); if (id == null) return null;
} return this.types.stream()
.filter(mmoItemType -> mmoItemType.getId().equals(id))
.findFirst()
.orElse(null);
}
@NotNull public Type getOrThrow(@Nullable String id) { @Contract("null -> fail")
Validate.isTrue(map.containsKey(id), "Could not find item type with ID '" + id + "'"); @NotNull
return map.get(id); public MMOItemType getOrThrow(@Nullable String id) {
} if (id == null) throw new IllegalArgumentException(String.format("No type found with id '%s'", id));
return this.types.stream()
.filter(mmoItemType -> mmoItemType.getId().equals(id))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(String.format("No type found with id '%s'", id)));
}
public boolean has(String id) { public boolean has(String id) {
return map.containsKey(id); return this.types.stream()
} .anyMatch(mmoItemType -> mmoItemType.getId().equals(id));
}
public Collection<Type> getAll() { public List<MMOItemType> getAll() {
return map.values(); return this.types;
} }
/** public List<MMOTypeCategory> getCategories() {
* @return The names of all loaded types. return this.categories;
*/ }
public ArrayList<String> getAllTypeNames() {
ArrayList<String> ret = new ArrayList<>(); /**
for (Type t : getAll()) { ret.add(t.getId()); } * @return The names of all loaded types.
return ret; */
} public List<String> getAllTypeNames() {
return this.types.stream()
.map(MMOItemType::getName)
.collect(Collectors.toList());
}
} }

View File

@ -1,4 +1,3 @@
# Default item types. These cannot be removed. They # Default item types. These cannot be removed. They
# may be used as 'parents' to create new item types # may be used as 'parents' to create new item types
# which will behave just like another item type. Parents # which will behave just like another item type. Parents
@ -19,6 +18,11 @@ SWORD:
# Name displayed in the item lore. # Name displayed in the item lore.
name: 'Sword' name: 'Sword'
weapon: true
modifier: "MELEE_WEAPON"
lore-format: ""
category: "SPLASHING"
# Template of an unidentified item. # Template of an unidentified item.
unident-item: unident-item:

View File

@ -0,0 +1,12 @@
SPLASHING:
# The display parameter is used to display the item in both
# the item brower and the recipe list when shifting a
# workbench. You can use durability for custom textures.
# In 1.14, durability is replaced by CustomModelData.
display: IRON_SWORD:0
# Name displayed in the item lore.
name: 'Splashing'
lore-format: ""