!Post-load objects refactor

This commit is contained in:
Indyuce 2020-04-16 14:55:47 +02:00
parent 10456a5345
commit b4ea446430
14 changed files with 192 additions and 164 deletions

View File

@ -0,0 +1,27 @@
package net.Indyuce.mmocore.api.load;
import org.bukkit.configuration.file.FileConfiguration;
public abstract class PostLoadObject {
private FileConfiguration config;
/*
* objects which must load some data afterwards, like quests which must load
* their parent quests after all quests were initialized or classes which
* must load their subclasses
*/
public PostLoadObject(FileConfiguration config) {
this.config = config;
}
public void postLoad() {
whenPostLoaded(config);
/*
* clean config object for garbage collection
*/
config = null;
}
protected abstract void whenPostLoaded(FileConfiguration config);
}

View File

@ -32,8 +32,8 @@ import net.Indyuce.mmocore.api.event.PlayerRegenResourceEvent;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.player.profess.PlayerClass.Subclass;
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
import net.Indyuce.mmocore.api.player.profess.Subclass;
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
import net.Indyuce.mmocore.api.player.social.FriendRequest;
import net.Indyuce.mmocore.api.player.social.Party;

View File

@ -0,0 +1,40 @@
package net.Indyuce.mmocore.api.player.profess;
public enum ClassOption {
/*
* is class by default
*/
DEFAULT,
/*
* displays in the /class GUI
*/
DISPLAY(true),
/*
* only regen resource when out of combat
*/
OFF_COMBAT_HEALTH_REGEN,
OFF_COMBAT_MANA_REGEN,
OFF_COMBAT_STAMINA_REGEN,
OFF_COMBAT_STELLIUM_REGEN;
private final boolean def;
private ClassOption() {
this(false);
}
private ClassOption(boolean def) {
this.def = def;
}
public boolean getDefault() {
return def;
}
public String getPath() {
return name().toLowerCase().replace("_", "-");
}
}

View File

@ -26,6 +26,7 @@ import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.AltChar;
import net.Indyuce.mmocore.api.experience.source.type.ExperienceSource;
import net.Indyuce.mmocore.api.load.MMOLoadException;
import net.Indyuce.mmocore.api.load.PostLoadObject;
import net.Indyuce.mmocore.api.player.ExpCurve;
import net.Indyuce.mmocore.api.player.profess.event.EventTrigger;
import net.Indyuce.mmocore.api.player.profess.resource.ManaDisplayOptions;
@ -37,12 +38,11 @@ import net.Indyuce.mmocore.api.skill.Skill.SkillInfo;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
import net.Indyuce.mmocore.api.util.math.particle.CastingParticle;
import net.Indyuce.mmocore.manager.ClassManager;
import net.mmogroup.mmolib.api.MMOLineConfig;
import net.mmogroup.mmolib.version.VersionMaterial;
public class PlayerClass {
private final String name, id, fileName;
public class PlayerClass extends PostLoadObject {
private final String name, id;
private final List<String> description = new ArrayList<>(), attrDescription = new ArrayList<>();
private final ItemStack icon;
private final Map<ClassOption, Boolean> options = new HashMap<>();
@ -57,21 +57,17 @@ public class PlayerClass {
private final Map<PlayerResource, ResourceHandler> resourceHandlers = new HashMap<>();
private final Map<String, EventTrigger> eventTriggers = new HashMap<>();
private CastingParticle castParticle = new CastingParticle(Particle.SPELL_INSTANT);
/*
* easy load
*/
private FileConfiguration loaded;
private final CastingParticle castParticle;
public PlayerClass(String id, FileConfiguration config) {
this.id = (fileName = id).toUpperCase().replace("-", "_").replace(" ", "_");
this.loaded = config;
super(config);
this.id = id.toUpperCase().replace("-", "_").replace(" ", "_");
name = ChatColor.translateAlternateColorCodes('&', config.getString("display.name"));
icon = MMOCoreUtils.readIcon(config.getString("display.item"));
if (config.contains("display.texture")) {
if (config.contains("display.texture"))
if (icon.getType() == VersionMaterial.PLAYER_HEAD.toMaterial()) {
ItemMeta meta = icon.getItemMeta();
try {
@ -84,10 +80,8 @@ public class PlayerClass {
MMOCore.log(Level.WARNING, "[PlayerClasses:" + id + "] Could not apply playerhead texture: " + exception.getMessage());
}
icon.setItemMeta(meta);
} else {
} else
MMOCore.log(Level.WARNING, "[PlayerClasses:" + id + "] Could not add player head texture. The item is not a playerhead!");
}
}
for (String string : config.getStringList("display.lore"))
description.add(ChatColor.GRAY + ChatColor.translateAlternateColorCodes('&', string));
@ -95,7 +89,7 @@ public class PlayerClass {
attrDescription.add(ChatColor.GRAY + ChatColor.translateAlternateColorCodes('&', string));
manaDisplay = new ManaDisplayOptions(config.getConfigurationSection("mana"));
maxLevel = config.getInt("max-level");
displayOrder = config.getInt("display-order");
displayOrder = config.getInt("display.order");
expCurve = config.contains("exp-curve")
? MMOCore.plugin.experience.getOrThrow(config.get("exp-curve").toString().toLowerCase().replace("_", "-").replace(" ", "-"))
@ -119,12 +113,8 @@ public class PlayerClass {
MMOCore.log(Level.WARNING, "[PlayerClasses:" + id + "] Could not load skill info '" + key + "': " + exception.getMessage());
}
if (config.contains("cast-particle"))
try {
castParticle = new CastingParticle(config.getConfigurationSection("cast-particle"));
} catch (IllegalArgumentException exception) {
MMOCore.log(Level.WARNING, "[PlayerClasses:" + id + "] Could not read casting particle, using default: " + exception.getMessage());
}
castParticle = config.contains("cast-particle") ? new CastingParticle(config.getConfigurationSection("cast-particle"))
: new CastingParticle(Particle.SPELL_INSTANT);
if (config.contains("options"))
for (String key : config.getConfigurationSection("options").getKeys(false))
@ -151,7 +141,6 @@ public class PlayerClass {
eventTriggers.put(format, new EventTrigger(format, config.getStringList("triggers." + key)));
} catch (IllegalArgumentException exception) {
MMOCore.log(Level.WARNING, "[PlayerClasses:" + id + "] " + exception.getMessage());
continue;
}
}
@ -178,13 +167,15 @@ public class PlayerClass {
* used to generate display class
*/
public PlayerClass(String id, String name, Material material) {
super(null);
this.id = id;
this.name = name;
this.fileName = id;
manaDisplay = new ManaDisplayOptions(ChatColor.BLUE, "Mana", AltChar.listSquare.charAt(0));
maxLevel = 0;
displayOrder = 0;
expCurve = ExpCurve.DEFAULT;
castParticle = new CastingParticle(Particle.SPELL_INSTANT);
this.icon = new ItemStack(material);
setOption(ClassOption.DISPLAY, false);
@ -194,11 +185,12 @@ public class PlayerClass {
resourceHandlers.put(resource, new ResourceHandler(resource));
}
public void loadSubclasses(ClassManager manager) {
if (loaded.contains("subclasses"))
for (String key : loaded.getConfigurationSection("subclasses").getKeys(false))
subclasses.add(new Subclass(manager.get(key.toUpperCase().replace("-", "_").replace(" ", "_")), loaded.getInt("subclasses." + key)));
loaded = null;
@Override
protected void whenPostLoaded(FileConfiguration config) {
if (config.contains("subclasses"))
for (String key : config.getConfigurationSection("subclasses").getKeys(false))
subclasses.add(new Subclass(MMOCore.plugin.classManager.get(key.toUpperCase().replace("-", "_").replace(" ", "_")),
config.getInt("subclasses." + key)));
}
public String getId() {
@ -229,10 +221,6 @@ public class PlayerClass {
return expCurve;
}
public String getFileName() {
return fileName;
}
public ItemStack getIcon() {
return icon.clone();
}
@ -305,61 +293,4 @@ public class PlayerClass {
public boolean equals(Object obj) {
return obj != null && obj instanceof PlayerClass && ((PlayerClass) obj).id.equals(id);
}
public class Subclass {
private PlayerClass profess;
private int level;
public Subclass(PlayerClass profess, int level) {
this.profess = profess;
this.level = level;
}
public PlayerClass getProfess() {
return profess;
}
public int getLevel() {
return level;
}
}
public enum ClassOption {
/*
* is class by default
*/
DEFAULT,
/*
* displays in the /class GUI
*/
DISPLAY(true),
/*
* only regen resource when out of combat
*/
OFF_COMBAT_HEALTH_REGEN,
OFF_COMBAT_MANA_REGEN,
OFF_COMBAT_STAMINA_REGEN,
OFF_COMBAT_STELLIUM_REGEN;
private final boolean def;
private ClassOption() {
this(false);
}
private ClassOption(boolean def) {
this.def = def;
}
public boolean getDefault() {
return def;
}
public String getPath() {
return name().toLowerCase().replace("_", "-");
}
}
}

View File

@ -12,7 +12,6 @@ import com.google.gson.JsonObject;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
import net.Indyuce.mmocore.api.player.profess.PlayerClass.ClassOption;
import net.Indyuce.mmocore.api.skill.Skill;
public class SavedClassInformation {

View File

@ -0,0 +1,23 @@
package net.Indyuce.mmocore.api.player.profess;
import org.apache.commons.lang.Validate;
public class Subclass {
private final PlayerClass profess;
private final int level;
public Subclass(PlayerClass profess, int level) {
Validate.notNull(profess, "Subclass cannot be null");
this.profess = profess;
this.level = level;
}
public PlayerClass getProfess() {
return profess;
}
public int getLevel() {
return level;
}
}

View File

@ -6,7 +6,7 @@ import java.util.function.Function;
import org.bukkit.attribute.Attribute;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.PlayerClass.ClassOption;
import net.Indyuce.mmocore.api.player.profess.ClassOption;
import net.Indyuce.mmocore.api.player.stats.StatType;
public enum PlayerResource {

View File

@ -14,70 +14,50 @@ import org.bukkit.configuration.file.FileConfiguration;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.experience.Profession;
import net.Indyuce.mmocore.api.load.MMOLoadException;
import net.Indyuce.mmocore.api.load.PostLoadObject;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.quest.objective.Objective;
import net.Indyuce.mmocore.manager.QuestManager;
import net.mmogroup.mmolib.api.MMOLineConfig;
public class Quest {
public class Quest extends PostLoadObject {
private final String id;
private String name;
private List<Quest> parents = new ArrayList<>();
private List<Objective> objectives = new ArrayList<>();
private List<String> lore;
private final String name;
private final List<Quest> parents = new ArrayList<>();
private final List<Objective> objectives = new ArrayList<>();
private final List<String> lore;
private int mainLevelRestriction;
private Map<Profession, Integer> levelRestrictions = new HashMap<>();
private final int mainLevelRestriction;
private final Map<Profession, Integer> levelRestrictions = new HashMap<>();
// cooldown in millis
private long cooldown;
/*
* cached to load other info to enable parent quests.
*/
private FileConfiguration loaded;
private final long cooldown;
public Quest(String id, FileConfiguration config) {
super(config);
this.id = id.toLowerCase().replace("_", "-").replace(" ", "-");
loaded = config;
}
cooldown = (long) (config.contains("delay") ? config.getDouble("delay") * 60 * 60 * 1000 : -1);
name = config.getString("name");
lore = config.getStringList("lore");
/*
* forced to request a Questmanager instance because the one in the main
* MMOCore class has not been initialized yet, so it can't be accessed using
* MMOCore.plugin.questManager
*/
public void load(QuestManager manager) {
cooldown = (long) (loaded.contains("delay") ? loaded.getDouble("delay") * 60 * 60 * 1000 : -1);
mainLevelRestriction = config.getInt("level-req.main");
if (loaded.contains("parent"))
for (String parent : loaded.getStringList("parent"))
try {
parents.add(manager.get(parent));
} catch (NullPointerException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Couldn't find quest ID '" + parent + "'");
}
name = loaded.getString("name");
lore = loaded.getStringList("lore");
mainLevelRestriction = loaded.getInt("level-req.main");
if (loaded.contains("level-req"))
for (String key : loaded.getConfigurationSection("level-req").getKeys(false))
if (config.contains("level-req"))
for (String key : config.getConfigurationSection("level-req").getKeys(false))
if (!key.equals("main"))
try {
String id = key.toLowerCase().replace("_", "-");
Validate.isTrue(MMOCore.plugin.professionManager.has(id));
levelRestrictions.put(MMOCore.plugin.professionManager.get(id), loaded.getInt("level-req." + key));
String id1 = key.toLowerCase().replace("_", "-");
Validate.isTrue(MMOCore.plugin.professionManager.has(id1), "Could not find profession called '" + id1 + "'");
levelRestrictions.put(MMOCore.plugin.professionManager.get(id1), config.getInt("level-req." + key));
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "[Quests:" + id + "] Couldn't find profession '" + key + "'");
MMOCore.plugin.getLogger().log(Level.WARNING,
"Could not load level requirement '" + key + "' from quest '" + id + "': " + exception.getMessage());
}
for (String key : loaded.getConfigurationSection("objectives").getKeys(false))
for (String key : config.getConfigurationSection("objectives").getKeys(false))
try {
ConfigurationSection section = loaded.getConfigurationSection("objectives." + key);
ConfigurationSection section = config.getConfigurationSection("objectives." + key);
Validate.notNull(section, "Could not find config section");
String format = section.getString("type");
@ -87,8 +67,17 @@ public class Quest {
} catch (MMOLoadException exception) {
exception.printConsole("Quests:" + id, "objective");
}
}
loaded = null;
@Override
protected void whenPostLoaded(FileConfiguration config) {
if (config.contains("parent"))
for (String parent : config.getStringList("parent"))
try {
parents.add(MMOCore.plugin.questManager.get(parent));
} catch (NullPointerException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Couldn't find quest ID '" + parent + "'");
}
}
public String getId() {

View File

@ -55,16 +55,12 @@ public class MMOCoreUtils {
return material == VersionMaterial.PLAYER_HEAD.toMaterial() || material == VersionMaterial.PLAYER_WALL_HEAD.toMaterial();
}
public static ItemStack readIcon(String string) {
try {
Validate.notNull(string, "String cannot be null");
String[] split = string.split("\\:");
Material material = Material.valueOf(split[0].toUpperCase().replace("-", "_").replace(" ", "_"));
return split.length > 1 ? MMOLib.plugin.getVersion().getWrapper().textureItem(material, Integer.parseInt(split[1]))
: new ItemStack(material);
} catch (IllegalArgumentException exception) {
return new ItemStack(Material.BARRIER);
}
public static ItemStack readIcon(String string) throws IllegalArgumentException {
Validate.notNull(string, "String cannot be null");
String[] split = string.split("\\:");
Material material = Material.valueOf(split[0].toUpperCase().replace("-", "_").replace(" ", "_"));
return split.length > 1 ? MMOLib.plugin.getVersion().getWrapper().textureItem(material, Integer.parseInt(split[1])) : new ItemStack(material);
}
public static int getWorth(ItemStack[] items) {

View File

@ -17,8 +17,8 @@ import org.bukkit.inventory.meta.ItemMeta;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.ClassOption;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.player.profess.PlayerClass.ClassOption;
import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
import net.Indyuce.mmocore.gui.api.item.InventoryItem;

View File

@ -15,7 +15,7 @@ import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.player.profess.PlayerClass.Subclass;
import net.Indyuce.mmocore.api.player.profess.Subclass;
import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
@ -61,6 +61,8 @@ public class SubclassSelect extends EditableInventory {
return null;
PlayerClass profess = generated.subclasses.get(n).getProfess();
ItemStack item = profess.getIcon();
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', name).replace("{name}", profess.getName()));
@ -97,7 +99,8 @@ public class SubclassSelect extends EditableInventory {
public SubclassSelectionInventory(PlayerData playerData, EditableInventory editable) {
super(playerData, editable);
subclasses = playerData.getProfess().getSubclasses().stream().filter(sub -> playerData.getLevel() >= sub.getLevel()).collect(Collectors.toList());
subclasses = playerData.getProfess().getSubclasses().stream().filter(sub -> playerData.getLevel() >= sub.getLevel())
.collect(Collectors.toList());
}
@Override

View File

@ -15,8 +15,8 @@ import org.bukkit.event.HandlerList;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.ClassOption;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.player.profess.PlayerClass.ClassOption;
import net.Indyuce.mmocore.api.player.profess.event.EventTriggerHandler;
import net.Indyuce.mmocore.api.player.profess.event.trigger.AttackEventTrigger;
import net.Indyuce.mmocore.api.player.profess.event.trigger.BlockBrokenTrigger;
@ -82,11 +82,18 @@ public class ClassManager extends MMOManager {
String id = file.getName().substring(0, file.getName().length() - 4);
register(new PlayerClass(id, YamlConfiguration.loadConfiguration(file)));
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load class " + file.getName() + ": " + exception.getMessage());
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load class '" + file.getName() + "': " + exception.getMessage());
}
map.values().forEach(profess -> profess.loadSubclasses(this));
defaultClass = map.values().stream().filter(profess -> profess.hasOption(ClassOption.DEFAULT)).findFirst().orElse(new PlayerClass("HUMAN", "Human", Material.LEATHER_BOOTS));
for (PlayerClass profess : map.values())
try {
profess.postLoad();
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not post-load class '" + profess.getId() + "': " + exception.getMessage());
}
defaultClass = map.values().stream().filter(profess -> profess.hasOption(ClassOption.DEFAULT)).findFirst()
.orElse(new PlayerClass("HUMAN", "Human", Material.LEATHER_BOOTS));
/*
* register event triggers

View File

@ -5,6 +5,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.logging.Level;
@ -44,15 +45,16 @@ public class CustomBlockManager extends MMOManager {
private final List<Condition> customMineConditions = new ArrayList<>();
/*
* list of functions which let
* list of functions which let MMOCore recognize what block a player is
* currently breaking
*/
private final List<Function<Block, BlockType>> blockTypes = new ArrayList<>();
private final List<Function<Block, Optional<BlockType>>> blockTypes = new ArrayList<>();
public CustomBlockManager() {
registerBlockType(block -> MMOCoreUtils.isPlayerHead(block.getType()) ? new SkullBlockType(block) : null);
registerBlockType(block -> MMOCoreUtils.isPlayerHead(block.getType()) ? Optional.of(new SkullBlockType(block)) : Optional.empty());
}
public void registerBlockType(Function<Block, BlockType> function) {
public void registerBlockType(Function<Block, Optional<BlockType>> function) {
blockTypes.add(function);
}
@ -65,10 +67,10 @@ public class CustomBlockManager extends MMOManager {
}
public BlockType findBlockType(Block block) {
for (Function<Block, BlockType> blockType : blockTypes) {
BlockType type = blockType.apply(block);
if (type != null)
return type;
for (Function<Block, Optional<BlockType>> blockType : blockTypes) {
Optional<BlockType> type = blockType.apply(block);
if (type.isPresent())
return type.get();
}
return new VanillaBlockType(block);

View File

@ -6,6 +6,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Level;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.file.YamlConfiguration;
import net.Indyuce.mmocore.MMOCore;
@ -34,6 +35,11 @@ public class QuestManager extends MMOManager {
return quests.get(id);
}
public Quest getOrThrow(String id) {
Validate.isTrue(quests.containsKey(id), "Could not find quest with ID '" + id + "'");
return get(id);
}
public Collection<Quest> getAll() {
return quests.values();
}
@ -41,7 +47,12 @@ public class QuestManager extends MMOManager {
@Override
public void reload() {
load(new File(MMOCore.plugin.getDataFolder() + "/quests"));
quests.values().forEach(quest -> quest.load(this));
for (Quest quest : quests.values())
try {
quest.postLoad();
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not post-load quest '" + quest.getId() + "' :" + exception.getMessage());
}
}
@Override