forked from Upstream/mmocore
!skill trees api, item unlocks api, exp tables for classes
This commit is contained in:
parent
604bc2ff48
commit
420d309ac3
@ -9,7 +9,7 @@ import net.Indyuce.mmocore.api.ConfigFile;
|
|||||||
import net.Indyuce.mmocore.api.PlayerActionBar;
|
import net.Indyuce.mmocore.api.PlayerActionBar;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
|
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
|
||||||
import net.Indyuce.mmocore.api.player.social.guilds.Guild;
|
import net.Indyuce.mmocore.guild.provided.Guild;
|
||||||
import net.Indyuce.mmocore.api.player.stats.StatType;
|
import net.Indyuce.mmocore.api.player.stats.StatType;
|
||||||
import net.Indyuce.mmocore.api.util.debug.DebugMode;
|
import net.Indyuce.mmocore.api.util.debug.DebugMode;
|
||||||
import net.Indyuce.mmocore.command.*;
|
import net.Indyuce.mmocore.command.*;
|
||||||
|
@ -11,7 +11,7 @@ import org.bukkit.entity.Player;
|
|||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.player.social.guilds.Guild;
|
import net.Indyuce.mmocore.guild.provided.Guild;
|
||||||
|
|
||||||
public class ConfigFile {
|
public class ConfigFile {
|
||||||
private final File file;
|
private final File file;
|
||||||
|
@ -5,7 +5,7 @@ import org.bukkit.event.HandlerList;
|
|||||||
|
|
||||||
import net.Indyuce.mmocore.api.event.PlayerDataEvent;
|
import net.Indyuce.mmocore.api.event.PlayerDataEvent;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.player.social.guilds.Guild;
|
import net.Indyuce.mmocore.guild.provided.Guild;
|
||||||
|
|
||||||
public class GuildChatEvent extends PlayerDataEvent implements Cancellable {
|
public class GuildChatEvent extends PlayerDataEvent implements Cancellable {
|
||||||
private static final HandlerList handlers = new HandlerList();
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
@ -1,45 +1,49 @@
|
|||||||
package net.Indyuce.mmocore.api.player;
|
package net.Indyuce.mmocore.api.player;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.event.PlayerCombatEvent;
|
import net.Indyuce.mmocore.api.event.PlayerCombatEvent;
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
public class CombatRunnable extends BukkitRunnable {
|
public class CombatRunnable extends BukkitRunnable {
|
||||||
private final PlayerData player;
|
private final PlayerData player;
|
||||||
|
|
||||||
private long lastHit = System.currentTimeMillis();
|
private long lastHit = System.currentTimeMillis();
|
||||||
|
|
||||||
public CombatRunnable(PlayerData player) {
|
private boolean open = true;
|
||||||
this.player = player;
|
|
||||||
|
|
||||||
if (player.isOnline()) {
|
public CombatRunnable(PlayerData player) {
|
||||||
MMOCore.plugin.configManager.getSimpleMessage("now-in-combat").send(player.getPlayer());
|
this.player = player;
|
||||||
Bukkit.getPluginManager().callEvent(new PlayerCombatEvent(player, true));
|
|
||||||
runTaskTimer(MMOCore.plugin, 20, 20);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update() {
|
if (player.isOnline()) {
|
||||||
lastHit = System.currentTimeMillis();
|
MMOCore.plugin.configManager.getSimpleMessage("now-in-combat").send(player.getPlayer());
|
||||||
}
|
Bukkit.getPluginManager().callEvent(new PlayerCombatEvent(player, true));
|
||||||
|
runTaskTimer(MMOCore.plugin, 20, 20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
public void update() {
|
||||||
public void run() {
|
lastHit = System.currentTimeMillis();
|
||||||
if (!player.isOnline()) {
|
}
|
||||||
close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (lastHit + MMOCore.plugin.configManager.combatLogTimer < System.currentTimeMillis()) {
|
|
||||||
Bukkit.getPluginManager().callEvent(new PlayerCombatEvent(player, false));
|
|
||||||
MMOCore.plugin.configManager.getSimpleMessage("leave-combat").send(player.getPlayer());
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void close() {
|
@Override
|
||||||
player.combat = null;
|
public void run() {
|
||||||
cancel();
|
if (!player.isOnline()) {
|
||||||
}
|
close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (lastHit + MMOCore.plugin.configManager.combatLogTimer < System.currentTimeMillis()) {
|
||||||
|
Bukkit.getPluginManager().callEvent(new PlayerCombatEvent(player, false));
|
||||||
|
MMOCore.plugin.configManager.getSimpleMessage("leave-combat").send(player.getPlayer());
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void close() {
|
||||||
|
Validate.isTrue(open, "Combat runnable has already been closed");
|
||||||
|
player.combat = null;
|
||||||
|
cancel();
|
||||||
|
open = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@ import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
|
|||||||
import net.Indyuce.mmocore.api.player.profess.Subclass;
|
import net.Indyuce.mmocore.api.player.profess.Subclass;
|
||||||
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
|
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
|
||||||
import net.Indyuce.mmocore.api.player.social.FriendRequest;
|
import net.Indyuce.mmocore.api.player.social.FriendRequest;
|
||||||
import net.Indyuce.mmocore.api.player.social.guilds.Guild;
|
|
||||||
import net.Indyuce.mmocore.api.player.stats.PlayerStats;
|
import net.Indyuce.mmocore.api.player.stats.PlayerStats;
|
||||||
import net.Indyuce.mmocore.api.player.stats.StatType;
|
import net.Indyuce.mmocore.api.player.stats.StatType;
|
||||||
import net.Indyuce.mmocore.api.quest.PlayerQuests;
|
import net.Indyuce.mmocore.api.quest.PlayerQuests;
|
||||||
@ -25,7 +24,12 @@ import net.Indyuce.mmocore.api.util.Closable;
|
|||||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||||
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
||||||
import net.Indyuce.mmocore.experience.EXPSource;
|
import net.Indyuce.mmocore.experience.EXPSource;
|
||||||
|
import net.Indyuce.mmocore.experience.ExperienceObject;
|
||||||
|
import net.Indyuce.mmocore.experience.ExperienceTableClaimer;
|
||||||
import net.Indyuce.mmocore.experience.PlayerProfessions;
|
import net.Indyuce.mmocore.experience.PlayerProfessions;
|
||||||
|
import net.Indyuce.mmocore.experience.droptable.ExperienceItem;
|
||||||
|
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
|
||||||
|
import net.Indyuce.mmocore.guild.provided.Guild;
|
||||||
import net.Indyuce.mmocore.party.AbstractParty;
|
import net.Indyuce.mmocore.party.AbstractParty;
|
||||||
import net.Indyuce.mmocore.party.provided.Party;
|
import net.Indyuce.mmocore.party.provided.Party;
|
||||||
import net.Indyuce.mmocore.skill.ClassSkill;
|
import net.Indyuce.mmocore.skill.ClassSkill;
|
||||||
@ -47,7 +51,7 @@ import java.util.*;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
|
||||||
public class PlayerData extends OfflinePlayerData implements Closable {
|
public class PlayerData extends OfflinePlayerData implements Closable, ExperienceTableClaimer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Corresponds to the MythicLib player data. It is used to keep
|
* Corresponds to the MythicLib player data. It is used to keep
|
||||||
@ -78,6 +82,21 @@ public class PlayerData extends OfflinePlayerData implements Closable {
|
|||||||
private final Map<String, SavedClassInformation> classSlots = new HashMap<>();
|
private final Map<String, SavedClassInformation> classSlots = new HashMap<>();
|
||||||
private final Map<PlayerActivity, Long> lastActivity = new HashMap<>();
|
private final Map<PlayerActivity, Long> lastActivity = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves all the items that have been unlocked so far by
|
||||||
|
* the player. This can be used by other plugins by
|
||||||
|
* implementing the {@link Unlockable} interface
|
||||||
|
*
|
||||||
|
* @see {@link Unlockable}
|
||||||
|
*/
|
||||||
|
private final Set<String> unlockedItems = new HashSet<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the amount of times the player has claimed some
|
||||||
|
* exp item in exp tables, for both exp tables used
|
||||||
|
*/
|
||||||
|
private final Map<String, Integer> tableItemClaims = new HashMap<>();
|
||||||
|
|
||||||
// NON-FINAL player data stuff made public to facilitate field change
|
// NON-FINAL player data stuff made public to facilitate field change
|
||||||
public int skillGuiDisplayOffset;
|
public int skillGuiDisplayOffset;
|
||||||
public boolean noCooldown;
|
public boolean noCooldown;
|
||||||
@ -225,6 +244,24 @@ public class PlayerData extends OfflinePlayerData implements Closable {
|
|||||||
return skillPoints;
|
return skillPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getClaims(ExperienceObject object, ExperienceTable table, ExperienceItem item) {
|
||||||
|
String key = object.geyKey() + "." + table.getId() + "." + item.getId();
|
||||||
|
return tableItemClaims.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setClaims(ExperienceObject object, ExperienceTable table, ExperienceItem item, int times) {
|
||||||
|
String key = object.geyKey() + "." + table.getId() + "." + item.getId();
|
||||||
|
tableItemClaims.put(key, times);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated(since = "1.9")
|
||||||
|
public void setProfessionExpItemClaims(String professionTableItemKey, int times) {
|
||||||
|
Validate.isTrue(!professionTableItemKey.startsWith("class.") && !professionTableItemKey.startsWith("profession."), "Invalid exp item key");
|
||||||
|
tableItemClaims.put("profession." + professionTableItemKey, times);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Experience needed in order to reach next level
|
* @return Experience needed in order to reach next level
|
||||||
*/
|
*/
|
||||||
@ -252,6 +289,19 @@ public class PlayerData extends OfflinePlayerData implements Closable {
|
|||||||
return guild != null;
|
return guild != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasUnlocked(Unlockable unlockable) {
|
||||||
|
throw new RuntimeException("Not implemented yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlocks an item for the player
|
||||||
|
*
|
||||||
|
* @return If the item was already unlocked when calling this method
|
||||||
|
*/
|
||||||
|
public boolean unlock(Unlockable unlockable) {
|
||||||
|
throw new RuntimeException("Not implemented yet");
|
||||||
|
}
|
||||||
|
|
||||||
public void setLevel(int level) {
|
public void setLevel(int level) {
|
||||||
this.level = Math.max(1, level);
|
this.level = Math.max(1, level);
|
||||||
|
|
||||||
@ -820,7 +870,7 @@ public class PlayerData extends OfflinePlayerData implements Closable {
|
|||||||
* checks if they could potentially upgrade to one of these
|
* checks if they could potentially upgrade to one of these
|
||||||
*
|
*
|
||||||
* @return If the player can change its current class to
|
* @return If the player can change its current class to
|
||||||
* a subclass
|
* a subclass
|
||||||
*/
|
*/
|
||||||
public boolean canChooseSubclass() {
|
public boolean canChooseSubclass() {
|
||||||
for (Subclass subclass : getProfess().getSubclasses())
|
for (Subclass subclass : getProfess().getSubclasses())
|
||||||
|
15
src/main/java/net/Indyuce/mmocore/api/player/Unlockable.java
Normal file
15
src/main/java/net/Indyuce/mmocore/api/player/Unlockable.java
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package net.Indyuce.mmocore.api.player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some item that can be unlocked
|
||||||
|
*
|
||||||
|
* @see {@link PlayerData#unlock(Unlockable)} and {@link PlayerData#hasUnlocked(Unlockable)}
|
||||||
|
*/
|
||||||
|
public interface Unlockable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format being used is the minecraft's default
|
||||||
|
* namespaced key format, e.g skill_tree:strength_1_5
|
||||||
|
*/
|
||||||
|
String getUnlockNamespacedKey();
|
||||||
|
}
|
@ -15,6 +15,8 @@ import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
|||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
import net.Indyuce.mmocore.api.util.math.particle.CastingParticle;
|
import net.Indyuce.mmocore.api.util.math.particle.CastingParticle;
|
||||||
import net.Indyuce.mmocore.experience.ExpCurve;
|
import net.Indyuce.mmocore.experience.ExpCurve;
|
||||||
|
import net.Indyuce.mmocore.experience.ExperienceObject;
|
||||||
|
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
|
||||||
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
|
||||||
import net.Indyuce.mmocore.experience.provider.MainExperienceDispenser;
|
import net.Indyuce.mmocore.experience.provider.MainExperienceDispenser;
|
||||||
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
|
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
|
||||||
@ -28,12 +30,14 @@ import org.bukkit.configuration.ConfigurationSection;
|
|||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class PlayerClass extends PostLoadObject {
|
public class PlayerClass extends PostLoadObject implements ExperienceObject {
|
||||||
private final String name, id, actionBarFormat;
|
private final String name, id, actionBarFormat;
|
||||||
private final List<String> description = new ArrayList<>(), attrDescription = new ArrayList<>();
|
private final List<String> description = new ArrayList<>(), attrDescription = new ArrayList<>();
|
||||||
private final ItemStack icon;
|
private final ItemStack icon;
|
||||||
@ -41,6 +45,7 @@ public class PlayerClass extends PostLoadObject {
|
|||||||
private final ManaDisplayOptions manaDisplay;
|
private final ManaDisplayOptions manaDisplay;
|
||||||
private final int maxLevel, displayOrder;
|
private final int maxLevel, displayOrder;
|
||||||
private final ExpCurve expCurve;
|
private final ExpCurve expCurve;
|
||||||
|
private final ExperienceTable expTable;
|
||||||
|
|
||||||
private final Map<StatType, LinearValue> stats = new HashMap<>();
|
private final Map<StatType, LinearValue> stats = new HashMap<>();
|
||||||
private final Map<String, ClassSkill> skills = new LinkedHashMap<>();
|
private final Map<String, ClassSkill> skills = new LinkedHashMap<>();
|
||||||
@ -87,6 +92,15 @@ public class PlayerClass extends PostLoadObject {
|
|||||||
config.get("exp-curve").toString().toLowerCase().replace("_", "-").replace(" ", "-"))
|
config.get("exp-curve").toString().toLowerCase().replace("_", "-").replace(" ", "-"))
|
||||||
: ExpCurve.DEFAULT;
|
: ExpCurve.DEFAULT;
|
||||||
|
|
||||||
|
ExperienceTable expTable = null;
|
||||||
|
if (config.contains("exp-table"))
|
||||||
|
try {
|
||||||
|
expTable = MMOCore.plugin.experience.loadExperienceTable(config.get("exp-table"));
|
||||||
|
} catch (RuntimeException exception) {
|
||||||
|
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp table from class '" + id + "': " + exception.getMessage());
|
||||||
|
}
|
||||||
|
this.expTable = expTable;
|
||||||
|
|
||||||
if (config.contains("attributes"))
|
if (config.contains("attributes"))
|
||||||
for (String key : config.getConfigurationSection("attributes").getKeys(false))
|
for (String key : config.getConfigurationSection("attributes").getKeys(false))
|
||||||
try {
|
try {
|
||||||
@ -168,6 +182,7 @@ public class PlayerClass extends PostLoadObject {
|
|||||||
maxLevel = 0;
|
maxLevel = 0;
|
||||||
displayOrder = 0;
|
displayOrder = 0;
|
||||||
expCurve = ExpCurve.DEFAULT;
|
expCurve = ExpCurve.DEFAULT;
|
||||||
|
expTable = null;
|
||||||
castParticle = new CastingParticle(Particle.SPELL_INSTANT);
|
castParticle = new CastingParticle(Particle.SPELL_INSTANT);
|
||||||
actionBarFormat = "";
|
actionBarFormat = "";
|
||||||
|
|
||||||
@ -202,10 +217,17 @@ public class PlayerClass extends PostLoadObject {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String geyKey() {
|
||||||
|
return "class." + getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public ManaDisplayOptions getManaDisplay() {
|
public ManaDisplayOptions getManaDisplay() {
|
||||||
return manaDisplay;
|
return manaDisplay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public ResourceRegeneration getHandler(PlayerResource resource) {
|
public ResourceRegeneration getHandler(PlayerResource resource) {
|
||||||
return resourceHandlers.get(resource);
|
return resourceHandlers.get(resource);
|
||||||
}
|
}
|
||||||
@ -218,10 +240,16 @@ public class PlayerClass extends PostLoadObject {
|
|||||||
return displayOrder;
|
return displayOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ExpCurve getExpCurve() {
|
public ExpCurve getExpCurve() {
|
||||||
return expCurve;
|
return expCurve;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExperienceTable getExperienceTable() {
|
||||||
|
return expTable;
|
||||||
|
}
|
||||||
|
|
||||||
public ItemStack getIcon() {
|
public ItemStack getIcon() {
|
||||||
return icon.clone();
|
return icon.clone();
|
||||||
}
|
}
|
||||||
@ -246,8 +274,13 @@ public class PlayerClass extends PostLoadObject {
|
|||||||
return options.containsKey(option) ? options.get(option) : option.getDefault();
|
return options.containsKey(option) ? options.get(option) : option.getDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public void setStat(StatType type, double base, double perLevel) {
|
public void setStat(StatType type, double base, double perLevel) {
|
||||||
stats.put(type, new LinearValue(base, perLevel));
|
setStat(type, new LinearValue(base, perLevel));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStat(StatType type, LinearValue value) {
|
||||||
|
stats.put(type, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double calculateStat(StatType stat, int level) {
|
public double calculateStat(StatType stat, int level) {
|
||||||
|
@ -14,7 +14,7 @@ import net.Indyuce.mmocore.MMOCore;
|
|||||||
import net.Indyuce.mmocore.api.event.MMOCommandEvent;
|
import net.Indyuce.mmocore.api.event.MMOCommandEvent;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.player.social.Request;
|
import net.Indyuce.mmocore.api.player.social.Request;
|
||||||
import net.Indyuce.mmocore.api.player.social.guilds.GuildInvite;
|
import net.Indyuce.mmocore.guild.provided.GuildInvite;
|
||||||
import net.Indyuce.mmocore.manager.InventoryManager;
|
import net.Indyuce.mmocore.manager.InventoryManager;
|
||||||
|
|
||||||
public class GuildCommand extends BukkitCommand {
|
public class GuildCommand extends BukkitCommand {
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package net.Indyuce.mmocore.experience;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Either a profession or a class
|
||||||
|
*
|
||||||
|
* @author jules
|
||||||
|
*/
|
||||||
|
public interface ExperienceObject {
|
||||||
|
|
||||||
|
String geyKey();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the amount of exp required to level up
|
||||||
|
*
|
||||||
|
* @return Exp curve of that object
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
ExpCurve getExpCurve();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Table read when leveling up
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
ExperienceTable getExperienceTable();
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package net.Indyuce.mmocore.experience;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.experience.droptable.ExperienceItem;
|
||||||
|
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Professions and classes share the same properties because
|
||||||
|
* they have both exp curves and tables.
|
||||||
|
* <p>
|
||||||
|
* A 'claimer' is an object that can claim exp tables and therefore
|
||||||
|
* needs to save how many times it has already claimed some item
|
||||||
|
* before.
|
||||||
|
* <p>
|
||||||
|
* Since MMOCore 1.9 it's all centralized in the player class data
|
||||||
|
*/
|
||||||
|
public interface ExperienceTableClaimer {
|
||||||
|
|
||||||
|
int getClaims(ExperienceObject object, ExperienceTable table, ExperienceItem item);
|
||||||
|
|
||||||
|
void setClaims(ExperienceObject object, ExperienceTable table, ExperienceItem item, int claims);
|
||||||
|
}
|
@ -12,9 +12,6 @@ import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent;
|
|||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||||
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
||||||
import net.Indyuce.mmocore.experience.droptable.ExperienceItem;
|
|
||||||
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
|
|
||||||
import net.Indyuce.mmocore.manager.SoundManager;
|
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
@ -28,204 +25,194 @@ import java.util.Map;
|
|||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
public class PlayerProfessions {
|
public class PlayerProfessions {
|
||||||
private final Map<String, Integer> exp = new HashMap<>();
|
private final Map<String, Integer> exp = new HashMap<>();
|
||||||
private final Map<String, Integer> level = new HashMap<>();
|
private final Map<String, Integer> level = new HashMap<>();
|
||||||
private final Map<String, Integer> timesClaimed = new HashMap<>();
|
|
||||||
private final PlayerData playerData;
|
|
||||||
|
|
||||||
public PlayerProfessions(PlayerData playerData) {
|
private final PlayerData playerData;
|
||||||
this.playerData = playerData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlayerProfessions load(ConfigurationSection config) {
|
public PlayerProfessions(PlayerData playerData) {
|
||||||
for (String key : config.getKeys(false))
|
this.playerData = playerData;
|
||||||
if (MMOCore.plugin.professionManager.has(key)) {
|
}
|
||||||
exp.put(key, config.getInt(key + ".exp"));
|
|
||||||
level.put(key, config.getInt(key + ".level"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.contains("times-claimed"))
|
/**
|
||||||
// Watch out for the deep section lookup
|
* When loading data through YAML
|
||||||
for (String key : config.getConfigurationSection("times-claimed").getKeys(true))
|
*/
|
||||||
this.timesClaimed.put(key, config.getInt("times-claimed." + key));
|
public PlayerProfessions load(ConfigurationSection config) {
|
||||||
|
for (String key : config.getKeys(false))
|
||||||
|
if (MMOCore.plugin.professionManager.has(key)) {
|
||||||
|
exp.put(key, config.getInt(key + ".exp"));
|
||||||
|
level.put(key, config.getInt(key + ".level"));
|
||||||
|
}
|
||||||
|
|
||||||
return this;
|
if (config.contains("times-claimed"))
|
||||||
}
|
// Watch out for the deep section lookup
|
||||||
|
for (String key : config.getConfigurationSection("times-claimed").getKeys(true))
|
||||||
|
playerData.setProfessionExpItemClaims(key, config.getInt("times-claimed." + key));
|
||||||
|
|
||||||
public void save(ConfigurationSection config) {
|
return this;
|
||||||
for (String id : exp.keySet())
|
}
|
||||||
config.set(id + ".exp", exp.get(id));
|
|
||||||
for (String id : level.keySet())
|
|
||||||
config.set(id + ".level", level.get(id));
|
|
||||||
|
|
||||||
timesClaimed.forEach((key, value) -> config.set("times-claimed." + key, value));
|
/**
|
||||||
}
|
* When saving data through YAML
|
||||||
|
*/
|
||||||
|
public void save(ConfigurationSection config) {
|
||||||
|
for (String id : exp.keySet())
|
||||||
|
config.set(id + ".exp", exp.get(id));
|
||||||
|
for (String id : level.keySet())
|
||||||
|
config.set(id + ".level", level.get(id));
|
||||||
|
}
|
||||||
|
|
||||||
public String toJsonString() {
|
/**
|
||||||
JsonObject json = new JsonObject();
|
* When saving data through SQL
|
||||||
for (Profession profession : MMOCore.plugin.professionManager.getAll()) {
|
*/
|
||||||
JsonObject object = new JsonObject();
|
public String toJsonString() {
|
||||||
object.addProperty("exp", getExperience(profession));
|
JsonObject json = new JsonObject();
|
||||||
object.addProperty("level", getLevel(profession));
|
for (Profession profession : MMOCore.plugin.professionManager.getAll()) {
|
||||||
|
JsonObject object = new JsonObject();
|
||||||
|
object.addProperty("exp", getExperience(profession));
|
||||||
|
object.addProperty("level", getLevel(profession));
|
||||||
|
|
||||||
json.add(profession.getId(), object);
|
json.add(profession.getId(), object);
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObject timesClaimed = new JsonObject();
|
return json.toString();
|
||||||
this.timesClaimed.forEach((key, value) -> timesClaimed.addProperty(key, value));
|
}
|
||||||
json.add("timesClaimed", timesClaimed);
|
|
||||||
|
|
||||||
return json.toString();
|
/**
|
||||||
}
|
* When loading data through SQL
|
||||||
|
*/
|
||||||
|
public void load(String json) {
|
||||||
|
JsonObject obj = new Gson().fromJson(json, JsonObject.class);
|
||||||
|
|
||||||
public void load(String json) {
|
// Load profession exp and levels
|
||||||
JsonObject obj = new Gson().fromJson(json, JsonObject.class);
|
for (Entry<String, JsonElement> entry : obj.entrySet())
|
||||||
|
if (MMOCore.plugin.professionManager.has(entry.getKey())) {
|
||||||
|
JsonObject value = entry.getValue().getAsJsonObject();
|
||||||
|
exp.put(entry.getKey(), value.get("exp").getAsInt());
|
||||||
|
level.put(entry.getKey(), value.get("level").getAsInt());
|
||||||
|
}
|
||||||
|
|
||||||
// Load profession exp and levels
|
// Load times claimed
|
||||||
for (Entry<String, JsonElement> entry : obj.entrySet())
|
if (obj.has("timesClaimed"))
|
||||||
if (MMOCore.plugin.professionManager.has(entry.getKey())) {
|
for (Entry<String, JsonElement> entry : obj.getAsJsonObject("timesClaimed").entrySet())
|
||||||
JsonObject value = entry.getValue().getAsJsonObject();
|
playerData.setProfessionExpItemClaims(entry.getKey(), entry.getValue().getAsInt());
|
||||||
exp.put(entry.getKey(), value.get("exp").getAsInt());
|
}
|
||||||
level.put(entry.getKey(), value.get("level").getAsInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load times claimed
|
public PlayerData getPlayerData() {
|
||||||
if (obj.has("timesClaimed"))
|
return playerData;
|
||||||
for (Entry<String, JsonElement> entry : obj.getAsJsonObject("timesClaimed").entrySet())
|
}
|
||||||
timesClaimed.put(entry.getKey(), entry.getValue().getAsInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlayerData getPlayerData() {
|
public int getLevel(String profession) {
|
||||||
return playerData;
|
return Math.max(1, level.getOrDefault(profession, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLevel(String profession) {
|
public int getLevel(Profession profession) {
|
||||||
return Math.max(1, level.getOrDefault(profession, 1));
|
return getLevel(profession.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLevel(Profession profession) {
|
public int getExperience(String id) {
|
||||||
return getLevel(profession.getId());
|
return exp.getOrDefault(id, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getExperience(String id) {
|
public int getExperience(Profession profession) {
|
||||||
return exp.getOrDefault(id, 0);
|
return getExperience(profession.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getExperience(Profession profession) {
|
public int getLevelUpExperience(Profession profession) {
|
||||||
return getExperience(profession.getId());
|
return profession.getExpCurve().getExperience(getLevel(profession) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLevelUpExperience(Profession profession) {
|
public int getLevelUpExperience(String id) {
|
||||||
return profession.getExpCurve().getExperience(getLevel(profession) + 1);
|
return MMOCore.plugin.professionManager.has(id) ? MMOCore.plugin.professionManager.get(id).getExpCurve().getExperience(getLevel(id) + 1) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLevelUpExperience(String id) {
|
public void setLevel(Profession profession, int value) {
|
||||||
return MMOCore.plugin.professionManager.has(id) ? MMOCore.plugin.professionManager.get(id).getExpCurve().getExperience(getLevel(id) + 1) : 0;
|
level.put(profession.getId(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLevel(Profession profession, int value) {
|
public void takeLevels(Profession profession, int value) {
|
||||||
level.put(profession.getId(), value);
|
int current = level.getOrDefault(profession.getId(), 1);
|
||||||
}
|
level.put(profession.getId(), Math.max(1, current - value));
|
||||||
|
}
|
||||||
|
|
||||||
public void takeLevels(Profession profession, int value) {
|
public void setExperience(Profession profession, int value) {
|
||||||
int current = level.getOrDefault(profession.getId(), 1);
|
exp.put(profession.getId(), value);
|
||||||
level.put(profession.getId(), Math.max(1, current - value));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void setExperience(Profession profession, int value) {
|
public void giveLevels(Profession profession, int value, EXPSource source) {
|
||||||
exp.put(profession.getId(), value);
|
int total = 0, level = getLevel(profession);
|
||||||
}
|
while (value-- > 0)
|
||||||
|
total += profession.getExpCurve().getExperience(level + value + 1);
|
||||||
|
giveExperience(profession, total, source);
|
||||||
|
}
|
||||||
|
|
||||||
public void giveLevels(Profession profession, int value, EXPSource source) {
|
public void giveExperience(Profession profession, int value, EXPSource source) {
|
||||||
int total = 0, level = getLevel(profession);
|
giveExperience(profession, value, source, null);
|
||||||
while (value-- > 0)
|
}
|
||||||
total += profession.getExpCurve().getExperience(level + value + 1);
|
|
||||||
giveExperience(profession, total, source);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void giveExperience(Profession profession, int value, EXPSource source) {
|
public boolean hasReachedMaxLevel(Profession profession) {
|
||||||
giveExperience(profession, value, source, null);
|
return profession.hasMaxLevel() && getLevel(profession) >= profession.getMaxLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasReachedMaxLevel(Profession profession) {
|
public void giveExperience(Profession profession, double value, EXPSource source, @Nullable Location hologramLocation) {
|
||||||
return profession.hasMaxLevel() && getLevel(profession) >= profession.getMaxLevel();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void giveExperience(Profession profession, double value, EXPSource source, @Nullable Location hologramLocation) {
|
|
||||||
Validate.isTrue(playerData.isOnline(), "Cannot give experience to offline player");
|
Validate.isTrue(playerData.isOnline(), "Cannot give experience to offline player");
|
||||||
|
|
||||||
if (hasReachedMaxLevel(profession)) {
|
if (hasReachedMaxLevel(profession)) {
|
||||||
setExperience(profession, 0);
|
setExperience(profession, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = MMOCore.plugin.boosterManager.calculateExp(profession, value);
|
value = MMOCore.plugin.boosterManager.calculateExp(profession, value);
|
||||||
|
|
||||||
// display hologram
|
// Display hologram
|
||||||
if (hologramLocation != null )
|
if (hologramLocation != null)
|
||||||
MMOCoreUtils.displayIndicator(hologramLocation.add(.5, 1.5, .5), MMOCore.plugin.configManager.getSimpleMessage("exp-hologram", "exp", "" + value).message());
|
MMOCoreUtils.displayIndicator(hologramLocation.add(.5, 1.5, .5), MMOCore.plugin.configManager.getSimpleMessage("exp-hologram", "exp", "" + value).message());
|
||||||
|
|
||||||
PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(playerData, profession, (int) value, source);
|
PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(playerData, profession, (int) value, source);
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
if (event.isCancelled())
|
if (event.isCancelled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
exp.put(profession.getId(), exp.containsKey(profession.getId()) ? exp.get(profession.getId()) + event.getExperience() : event.getExperience());
|
exp.put(profession.getId(), exp.containsKey(profession.getId()) ? exp.get(profession.getId()) + event.getExperience() : event.getExperience());
|
||||||
int needed, exp, level, oldLevel = getLevel(profession);
|
int needed, exp, level, oldLevel = getLevel(profession);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* loop for exp overload when leveling up, will continue looping until
|
* Loop for exp overload when leveling up, will continue
|
||||||
* exp is 0 or max level has been reached
|
* looping until exp is 0 or max level has been reached
|
||||||
*/
|
*/
|
||||||
boolean check = false;
|
boolean check = false;
|
||||||
while ((exp = this.exp.get(profession.getId())) >= (needed = profession.getExpCurve().getExperience((level = getLevel(profession)) + 1))) {
|
while ((exp = this.exp.get(profession.getId())) >= (needed = profession.getExpCurve().getExperience((level = getLevel(profession)) + 1))) {
|
||||||
if (hasReachedMaxLevel(profession)) {
|
if (hasReachedMaxLevel(profession)) {
|
||||||
setExperience(profession, 0);
|
setExperience(profession, 0);
|
||||||
check = true;
|
check = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.exp.put(profession.getId(), exp - needed);
|
this.exp.put(profession.getId(), exp - needed);
|
||||||
this.level.put(profession.getId(), level + 1);
|
this.level.put(profession.getId(), level + 1);
|
||||||
check = true;
|
check = true;
|
||||||
playerData.giveExperience((int) profession.getExperience().calculate(level), null);
|
playerData.giveExperience((int) profession.getExperience().calculate(level), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check) {
|
if (check) {
|
||||||
Bukkit.getPluginManager().callEvent(new PlayerLevelUpEvent(playerData, profession, oldLevel, level));
|
Bukkit.getPluginManager().callEvent(new PlayerLevelUpEvent(playerData, profession, oldLevel, level));
|
||||||
new SmallParticleEffect(playerData.getPlayer(), Particle.SPELL_INSTANT);
|
new SmallParticleEffect(playerData.getPlayer(), Particle.SPELL_INSTANT);
|
||||||
new ConfigMessage("profession-level-up").addPlaceholders("level", "" + level, "profession", profession.getName())
|
new ConfigMessage("profession-level-up").addPlaceholders("level", "" + level, "profession", profession.getName())
|
||||||
.send(playerData.getPlayer());
|
.send(playerData.getPlayer());
|
||||||
MMOCore.plugin.soundManager.getSound(SoundEvent.LEVEL_UP).playTo(playerData.getPlayer());
|
MMOCore.plugin.soundManager.getSound(SoundEvent.LEVEL_UP).playTo(playerData.getPlayer());
|
||||||
playerData.getStats().updateStats();
|
playerData.getStats().updateStats();
|
||||||
|
|
||||||
// Apply profession experience table
|
// Apply profession experience table
|
||||||
if (profession.hasExperienceTable())
|
if (profession.hasExperienceTable())
|
||||||
profession.getExperienceTable().claim(playerData, level, this);
|
profession.getExperienceTable().claim(playerData, level, profession);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder bar = new StringBuilder("" + ChatColor.BOLD);
|
StringBuilder bar = new StringBuilder("" + ChatColor.BOLD);
|
||||||
int chars = (int) ((double) exp / needed * 20);
|
int chars = (int) ((double) exp / needed * 20);
|
||||||
for (int j = 0; j < 20; j++)
|
for (int j = 0; j < 20; j++)
|
||||||
bar.append(j == chars ? "" + ChatColor.WHITE + ChatColor.BOLD : "").append("|");
|
bar.append(j == chars ? "" + ChatColor.WHITE + ChatColor.BOLD : "").append("|");
|
||||||
if (playerData.isOnline())
|
if (playerData.isOnline())
|
||||||
MMOCore.plugin.configManager.getSimpleMessage("exp-notification", "profession", profession.getName(), "progress", bar.toString(), "ratio",
|
MMOCore.plugin.configManager.getSimpleMessage("exp-notification", "profession", profession.getName(), "progress", bar.toString(), "ratio",
|
||||||
MythicLib.plugin.getMMOConfig().decimal.format((double) exp / needed * 100)).send(playerData.getPlayer());
|
MythicLib.plugin.getMMOConfig().decimal.format((double) exp / needed * 100)).send(playerData.getPlayer());
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The amount of times that specific experience item was claimed by the player
|
|
||||||
*/
|
|
||||||
public int getTimesClaimed(ExperienceTable table, ExperienceItem item) {
|
|
||||||
String path = table.getId() + "." + item.getId();
|
|
||||||
return timesClaimed.getOrDefault(path, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* See {@link #getTimesClaimed(ExperienceTable, ExperienceItem)}
|
|
||||||
*/
|
|
||||||
public void setTimesClaimed(ExperienceTable table, ExperienceItem item, int timesClaimed) {
|
|
||||||
String path = table.getId() + "." + item.getId();
|
|
||||||
this.timesClaimed.put(path, timesClaimed);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,15 +16,16 @@ import java.util.Map;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class Profession {
|
public class Profession implements ExperienceObject {
|
||||||
private final String id, name;
|
private final String id, name;
|
||||||
private final ExpCurve expCurve;
|
|
||||||
private final int maxLevel;
|
private final int maxLevel;
|
||||||
private final Map<ProfessionOption, Boolean> options = new HashMap<>();
|
private final Map<ProfessionOption, Boolean> options = new HashMap<>();
|
||||||
|
private final ExpCurve expCurve;
|
||||||
private final ExperienceTable expTable;
|
private final ExperienceTable expTable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Experience given to the main player level whenever he levels up this profession
|
* Experience given to the main player level
|
||||||
|
* whenever he levels up this profession
|
||||||
*/
|
*/
|
||||||
private final LinearValue experience;
|
private final LinearValue experience;
|
||||||
|
|
||||||
@ -41,7 +42,7 @@ public class Profession {
|
|||||||
ExperienceTable expTable = null;
|
ExperienceTable expTable = null;
|
||||||
if (config.contains("exp-table"))
|
if (config.contains("exp-table"))
|
||||||
try {
|
try {
|
||||||
expTable = loadExperienceTable(config.get("exp-table"));
|
expTable = MMOCore.plugin.experience.loadExperienceTable(config.get("exp-table"));
|
||||||
} catch (RuntimeException exception) {
|
} catch (RuntimeException exception) {
|
||||||
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp table from profession '" + id + "': " + exception.getMessage());
|
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp table from profession '" + id + "': " + exception.getMessage());
|
||||||
}
|
}
|
||||||
@ -73,16 +74,7 @@ public class Profession {
|
|||||||
MMOCore.plugin.professionManager.loadProfessionConfigurations(this, config);
|
MMOCore.plugin.professionManager.loadProfessionConfigurations(this, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExperienceTable loadExperienceTable(Object obj) {
|
|
||||||
|
|
||||||
if (obj instanceof ConfigurationSection)
|
|
||||||
return new ExperienceTable((ConfigurationSection) obj);
|
|
||||||
|
|
||||||
if (obj instanceof String)
|
|
||||||
return MMOCore.plugin.experience.getTableOrThrow(obj.toString());
|
|
||||||
|
|
||||||
throw new IllegalArgumentException("Please provide either a string (exp table name) or a config section (locally define an exp table)");
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getOption(ProfessionOption option) {
|
public boolean getOption(ProfessionOption option) {
|
||||||
return options.getOrDefault(option, option.getDefault());
|
return options.getOrDefault(option, option.getDefault());
|
||||||
@ -96,6 +88,12 @@ public class Profession {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String geyKey() {
|
||||||
|
return "profession." + getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ExpCurve getExpCurve() {
|
public ExpCurve getExpCurve() {
|
||||||
return expCurve;
|
return expCurve;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package net.Indyuce.mmocore.experience.droptable;
|
|||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.experience.PlayerProfessions;
|
import net.Indyuce.mmocore.experience.ExperienceObject;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
|
||||||
@ -40,15 +40,15 @@ public class ExperienceTable {
|
|||||||
*
|
*
|
||||||
* @param levelingUp Player leveling up
|
* @param levelingUp Player leveling up
|
||||||
* @param professionLevel New profession level
|
* @param professionLevel New profession level
|
||||||
* @param professionData Player profession data
|
* @param object Either profession or class leveling up
|
||||||
*/
|
*/
|
||||||
public void claim(PlayerData levelingUp, int professionLevel, PlayerProfessions professionData) {
|
public void claim(PlayerData levelingUp, int professionLevel, ExperienceObject object) {
|
||||||
for (ExperienceItem item : items) {
|
for (ExperienceItem item : items) {
|
||||||
int timesClaimed = professionData.getTimesClaimed(this, item);
|
int timesClaimed = levelingUp.getClaims(object, this, item);
|
||||||
if (!item.roll(professionLevel, timesClaimed))
|
if (!item.roll(professionLevel, timesClaimed))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
professionData.setTimesClaimed(this, item, timesClaimed + 1);
|
levelingUp.setClaims(object, this, item, timesClaimed + 1);
|
||||||
item.applyTriggers(levelingUp);
|
item.applyTriggers(levelingUp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
package net.Indyuce.mmocore.guild;
|
package net.Indyuce.mmocore.guild;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
|
||||||
public interface GuildModule {
|
public interface GuildModule {
|
||||||
|
|
||||||
|
public AbstractGuild getGuild(PlayerData playerData);
|
||||||
}
|
}
|
||||||
|
@ -1,165 +1,164 @@
|
|||||||
package net.Indyuce.mmocore.api.player.social.guilds;
|
package net.Indyuce.mmocore.guild.provided;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import net.Indyuce.mmocore.guild.AbstractGuild;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.ConfigMessage;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.ConfigMessage;
|
||||||
import net.Indyuce.mmocore.api.player.social.Request;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.gui.api.PluginInventory;
|
import net.Indyuce.mmocore.api.player.social.Request;
|
||||||
import net.Indyuce.mmocore.gui.social.guild.EditableGuildView.GuildViewInventory;
|
import net.Indyuce.mmocore.gui.api.PluginInventory;
|
||||||
import net.Indyuce.mmocore.manager.InventoryManager;
|
import net.Indyuce.mmocore.gui.social.guild.EditableGuildView.GuildViewInventory;
|
||||||
|
import net.Indyuce.mmocore.manager.InventoryManager;
|
||||||
public class Guild {
|
|
||||||
private final GuildMembers members = new GuildMembers();
|
public class Guild implements AbstractGuild {
|
||||||
private final Map<UUID, Long> invites = new HashMap<>();
|
private final GuildMembers members = new GuildMembers();
|
||||||
private final String guildId;
|
private final Map<UUID, Long> invites = new HashMap<>();
|
||||||
private final String guildName;
|
private final String guildId, guildName, guildTag;
|
||||||
private final String guildTag;
|
|
||||||
|
/**
|
||||||
/*
|
* Owner changes when the old owner leaves guild
|
||||||
* owner changes when the old owner leaves guild
|
*/
|
||||||
*/
|
private UUID owner;
|
||||||
private UUID owner;
|
|
||||||
|
public Guild(UUID owner, String name, String tag) {
|
||||||
public Guild(UUID owner, String name, String tag) {
|
this.owner = owner;
|
||||||
this.owner = owner;
|
this.guildId = tag.toLowerCase();
|
||||||
this.guildId = tag.toLowerCase();
|
this.guildName = name;
|
||||||
this.guildName = name;
|
this.guildTag = tag;
|
||||||
this.guildTag = tag;
|
}
|
||||||
}
|
|
||||||
|
public UUID getOwner() {
|
||||||
public UUID getOwner() {
|
return owner;
|
||||||
return owner;
|
}
|
||||||
}
|
|
||||||
|
public String getName() {
|
||||||
public String getName() {
|
return guildName;
|
||||||
return guildName;
|
}
|
||||||
}
|
|
||||||
|
public String getId() {
|
||||||
public String getId() {
|
return guildId;
|
||||||
return guildId;
|
}
|
||||||
}
|
|
||||||
|
public String getTag() {
|
||||||
public String getTag() {
|
return guildTag;
|
||||||
return guildTag;
|
}
|
||||||
}
|
|
||||||
|
public GuildMembers getMembers() {
|
||||||
public GuildMembers getMembers() {
|
return members;
|
||||||
return members;
|
}
|
||||||
}
|
|
||||||
|
public long getLastInvite(Player player) {
|
||||||
public long getLastInvite(Player player) {
|
return invites.containsKey(player.getUniqueId()) ? invites.get(player.getUniqueId()) : 0;
|
||||||
return invites.containsKey(player.getUniqueId()) ? invites.get(player.getUniqueId()) : 0;
|
}
|
||||||
}
|
|
||||||
|
public void removeLastInvite(Player player) {
|
||||||
public void removeLastInvite(Player player) {
|
invites.remove(player.getUniqueId());
|
||||||
invites.remove(player.getUniqueId());
|
}
|
||||||
}
|
|
||||||
|
public void removeMember(UUID uuid)
|
||||||
public void removeMember(UUID uuid)
|
{ removeMember(uuid, false); }
|
||||||
{ removeMember(uuid, false); }
|
|
||||||
|
// Disband boolean is to prevent co-modification exception when disbanding a guild
|
||||||
// Disband boolean is to prevent co-modification exception when disbanding a guild
|
public void removeMember(UUID uuid, boolean disband) {
|
||||||
public void removeMember(UUID uuid, boolean disband) {
|
PlayerData data = PlayerData.get(uuid);
|
||||||
PlayerData data = PlayerData.get(uuid);
|
if (data != null && data.isOnline() && data.getPlayer().getOpenInventory() != null && data.getPlayer().getOpenInventory().getTopInventory().getHolder() instanceof GuildViewInventory)
|
||||||
if (data != null && data.isOnline() && data.getPlayer().getOpenInventory() != null && data.getPlayer().getOpenInventory().getTopInventory().getHolder() instanceof GuildViewInventory)
|
InventoryManager.GUILD_CREATION.newInventory(data).open();
|
||||||
InventoryManager.GUILD_CREATION.newInventory(data).open();
|
|
||||||
|
if(!disband) members.remove(uuid);
|
||||||
if(!disband) members.remove(uuid);
|
if(data != null) data.setGuild(null);
|
||||||
if(data != null) data.setGuild(null);
|
reopenInventories();
|
||||||
reopenInventories();
|
|
||||||
|
//if(!disband) {
|
||||||
//if(!disband) {
|
|
||||||
|
// disband the guild if no member left
|
||||||
// disband the guild if no member left
|
if (members.count() < 1) {
|
||||||
if (members.count() < 1) {
|
MMOCore.plugin.dataProvider.getGuildManager().unregisterGuild(this);
|
||||||
MMOCore.plugin.dataProvider.getGuildManager().unregisterGuild(this);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
// transfer ownership
|
||||||
// transfer ownership
|
if (owner.equals(uuid)) {
|
||||||
if (owner.equals(uuid)) {
|
owner = members.get(0);
|
||||||
owner = members.get(0);
|
MMOCore.plugin.configManager.getSimpleMessage("transfer-guild-ownership").send(Bukkit.getPlayer(owner));
|
||||||
MMOCore.plugin.configManager.getSimpleMessage("transfer-guild-ownership").send(Bukkit.getPlayer(owner));
|
}
|
||||||
}
|
//}
|
||||||
//}
|
}
|
||||||
}
|
|
||||||
|
public void addMember(UUID uuid) {
|
||||||
public void addMember(UUID uuid) {
|
PlayerData data = PlayerData.get(uuid);
|
||||||
PlayerData data = PlayerData.get(uuid);
|
if (data.inGuild())
|
||||||
if (data.inGuild())
|
data.getGuild().removeMember(uuid);
|
||||||
data.getGuild().removeMember(uuid);
|
|
||||||
|
data.setGuild(this);
|
||||||
data.setGuild(this);
|
members.add(uuid);
|
||||||
members.add(uuid);
|
|
||||||
|
reopenInventories();
|
||||||
reopenInventories();
|
}
|
||||||
}
|
|
||||||
|
public void registerMember(UUID uuid) {
|
||||||
public void registerMember(UUID uuid) {
|
members.add(uuid);
|
||||||
members.add(uuid);
|
}
|
||||||
}
|
|
||||||
|
public void reopenInventories() {
|
||||||
public void reopenInventories() {
|
for (UUID uuid : members.members) {
|
||||||
for (UUID uuid : members.members) {
|
PlayerData member = PlayerData.get(uuid);
|
||||||
PlayerData member = PlayerData.get(uuid);
|
if (member != null && member.isOnline() && member.getPlayer().getOpenInventory() != null && member.getPlayer().getOpenInventory().getTopInventory().getHolder() instanceof GuildViewInventory)
|
||||||
if (member != null && member.isOnline() && member.getPlayer().getOpenInventory() != null && member.getPlayer().getOpenInventory().getTopInventory().getHolder() instanceof GuildViewInventory)
|
((PluginInventory) member.getPlayer().getOpenInventory().getTopInventory().getHolder()).open();
|
||||||
((PluginInventory) member.getPlayer().getOpenInventory().getTopInventory().getHolder()).open();
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public void sendGuildInvite(PlayerData inviter, PlayerData target) {
|
||||||
public void sendGuildInvite(PlayerData inviter, PlayerData target) {
|
invites.put(target.getUniqueId(), System.currentTimeMillis());
|
||||||
invites.put(target.getUniqueId(), System.currentTimeMillis());
|
Request request = new GuildInvite(this, inviter, target);
|
||||||
Request request = new GuildInvite(this, inviter, target);
|
new ConfigMessage("guild-invite").addPlaceholders("player", inviter.getPlayer().getName(), "uuid", request.getUniqueId().toString()).sendAsJSon(target.getPlayer());
|
||||||
new ConfigMessage("guild-invite").addPlaceholders("player", inviter.getPlayer().getName(), "uuid", request.getUniqueId().toString()).sendAsJSon(target.getPlayer());
|
MMOCore.plugin.requestManager.registerRequest(request);
|
||||||
MMOCore.plugin.requestManager.registerRequest(request);
|
}
|
||||||
}
|
|
||||||
|
public static class GuildMembers {
|
||||||
public static class GuildMembers {
|
private final List<UUID> members = new ArrayList<>();
|
||||||
private final List<UUID> members = new ArrayList<>();
|
|
||||||
|
public UUID get(int count) {
|
||||||
public UUID get(int count) {
|
return members.get(count);
|
||||||
return members.get(count);
|
}
|
||||||
}
|
|
||||||
|
public boolean has(UUID player) {
|
||||||
public boolean has(UUID player) {
|
return members.contains(player);
|
||||||
return members.contains(player);
|
}
|
||||||
}
|
|
||||||
|
public void add(UUID player) {
|
||||||
public void add(UUID player) {
|
members.add(player);
|
||||||
members.add(player);
|
}
|
||||||
}
|
|
||||||
|
public void remove(UUID player) {
|
||||||
public void remove(UUID player) {
|
members.remove(player);
|
||||||
members.remove(player);
|
}
|
||||||
}
|
|
||||||
|
public void forEach(Consumer<? super UUID> action) {
|
||||||
public void forEach(Consumer<? super UUID> action) {
|
members.forEach(action);
|
||||||
members.forEach(action);
|
}
|
||||||
}
|
|
||||||
|
public int countOnline() {
|
||||||
public int countOnline() {
|
int online = 0;
|
||||||
int online = 0;
|
|
||||||
|
for(UUID member : members)
|
||||||
for(UUID member : members)
|
if(Bukkit.getOfflinePlayer(member).isOnline())
|
||||||
if(Bukkit.getOfflinePlayer(member).isOnline())
|
online += 1;
|
||||||
online += 1;
|
|
||||||
|
return online;
|
||||||
return online;
|
}
|
||||||
}
|
|
||||||
|
public int count()
|
||||||
public int count()
|
{ return members.size(); }
|
||||||
{ return members.size(); }
|
public void clear()
|
||||||
public void clear()
|
{ members.clear(); }
|
||||||
{ members.clear(); }
|
}
|
||||||
}
|
}
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package net.Indyuce.mmocore.api.player.social.guilds;
|
package net.Indyuce.mmocore.guild.provided;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
|
@ -0,0 +1,13 @@
|
|||||||
|
package net.Indyuce.mmocore.guild.provided;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.guild.AbstractGuild;
|
||||||
|
import net.Indyuce.mmocore.guild.GuildModule;
|
||||||
|
|
||||||
|
public class MMOCoreGuildModule implements GuildModule {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AbstractGuild getGuild(PlayerData playerData) {
|
||||||
|
return playerData.getGuild();
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,7 @@ import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
|
|||||||
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
|
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
|
||||||
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
|
|
||||||
@ -58,6 +59,18 @@ public class ExperienceManager implements MMOCoreManager {
|
|||||||
return Objects.requireNonNull(expTables.get(id), "Could not find exp table with ID '" + id + "'");
|
return Objects.requireNonNull(expTables.get(id), "Could not find exp table with ID '" + id + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public ExperienceTable loadExperienceTable(Object obj) {
|
||||||
|
|
||||||
|
if (obj instanceof ConfigurationSection)
|
||||||
|
return new ExperienceTable((ConfigurationSection) obj);
|
||||||
|
|
||||||
|
if (obj instanceof String)
|
||||||
|
return MMOCore.plugin.experience.getTableOrThrow(obj.toString());
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Please provide either a string (exp table name) or a config section (locally define an exp table)");
|
||||||
|
}
|
||||||
|
|
||||||
public Collection<ExpCurve> getCurves() {
|
public Collection<ExpCurve> getCurves() {
|
||||||
return expCurves.values();
|
return expCurves.values();
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
package net.Indyuce.mmocore.manager.data;
|
package net.Indyuce.mmocore.manager.data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to separate MySQL data storage from YAML data storage.
|
||||||
|
* <p>
|
||||||
|
* There is one data provider per storage mecanism (one for YAML, one for MySQL).
|
||||||
|
* A data provider provides corresponding MMOManagers to correctly save and load
|
||||||
|
* data
|
||||||
|
*/
|
||||||
public interface DataProvider {
|
public interface DataProvider {
|
||||||
|
|
||||||
/*
|
PlayerDataManager getDataManager();
|
||||||
* used to separate MySQL data storage from YAML data storage. there is one
|
|
||||||
* dataProvider per storage mecanism (one for YAML, one for MySQL). a
|
|
||||||
* dataProvider provides corresponding mmoManagers to correctly save and load
|
|
||||||
* data
|
|
||||||
*/
|
|
||||||
|
|
||||||
PlayerDataManager getDataManager();
|
GuildDataManager getGuildManager();
|
||||||
GuildDataManager getGuildManager();
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import org.bukkit.configuration.ConfigurationSection;
|
|||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.ConfigFile;
|
import net.Indyuce.mmocore.api.ConfigFile;
|
||||||
import net.Indyuce.mmocore.api.player.social.guilds.Guild;
|
import net.Indyuce.mmocore.guild.provided.Guild;
|
||||||
|
|
||||||
public abstract class GuildDataManager {
|
public abstract class GuildDataManager {
|
||||||
protected final Map<String, Guild> guilds = new HashMap<>();
|
protected final Map<String, Guild> guilds = new HashMap<>();
|
||||||
@ -39,14 +39,6 @@ public abstract class GuildDataManager {
|
|||||||
delete(guild);
|
delete(guild);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO has nothing to do here
|
|
||||||
public Guild stillInGuild(UUID uuid, String id) {
|
|
||||||
Guild guild = getGuild(id);
|
|
||||||
if (guild != null && guild.getMembers().has(uuid))
|
|
||||||
return guild;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Guild getGuild(String guild) {
|
public Guild getGuild(String guild) {
|
||||||
return guilds.get(guild);
|
return guilds.get(guild);
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ public abstract class PlayerDataManager {
|
|||||||
*/
|
*/
|
||||||
public abstract void saveData(PlayerData data);
|
public abstract void saveData(PlayerData data);
|
||||||
|
|
||||||
public static class DefaultPlayerData {
|
public class DefaultPlayerData {
|
||||||
private final int level, classPoints, skillPoints, attributePoints, attrReallocPoints;
|
private final int level, classPoints, skillPoints, attributePoints, attrReallocPoints;
|
||||||
|
|
||||||
public DefaultPlayerData(ConfigurationSection config) {
|
public DefaultPlayerData(ConfigurationSection config) {
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.manager.data.mysql;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.ConfigFile;
|
|
||||||
import net.Indyuce.mmocore.api.player.social.guilds.Guild;
|
|
||||||
import net.Indyuce.mmocore.manager.data.GuildDataManager;
|
|
||||||
|
|
||||||
public class MySQLGuildDataManager extends GuildDataManager {
|
|
||||||
@Override
|
|
||||||
public void save(Guild guild) {
|
|
||||||
ConfigFile config = new ConfigFile(guild);
|
|
||||||
config.getConfig().set("name", guild.getName());
|
|
||||||
config.getConfig().set("tag", guild.getTag());
|
|
||||||
config.getConfig().set("owner", guild.getOwner().toString());
|
|
||||||
|
|
||||||
List<String> memberList = new ArrayList<>();
|
|
||||||
guild.getMembers().forEach(uuid -> memberList.add(uuid.toString()));
|
|
||||||
config.getConfig().set("members", memberList);
|
|
||||||
|
|
||||||
config.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load() {
|
|
||||||
File guildsFolder = new File(MMOCore.plugin.getDataFolder(), "guilds");
|
|
||||||
if(!guildsFolder.exists()) guildsFolder.mkdirs();
|
|
||||||
for (File file : guildsFolder.listFiles()) {
|
|
||||||
if (!file.isDirectory() && file.getName().substring(file.getName().lastIndexOf('.')).equalsIgnoreCase(".yml")) {
|
|
||||||
FileConfiguration c = YamlConfiguration.loadConfiguration(file);
|
|
||||||
Guild guild = newRegisteredGuild(UUID.fromString(c.getString("owner")), c.getString("name"), c.getString("tag"));
|
|
||||||
for(String m : c.getStringList("members"))
|
|
||||||
guild.registerMember(UUID.fromString(m));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete(Guild guild) {
|
|
||||||
new ConfigFile(guild).delete();
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,26 +2,22 @@ package net.Indyuce.mmocore.manager.data.mysql;
|
|||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import io.lumine.mythic.lib.MythicLib;
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.player.OfflinePlayerData;
|
import net.Indyuce.mmocore.api.player.OfflinePlayerData;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||||
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
|
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
|
||||||
import net.Indyuce.mmocore.api.player.stats.StatType;
|
import net.Indyuce.mmocore.api.player.stats.StatType;
|
||||||
|
import net.Indyuce.mmocore.guild.provided.Guild;
|
||||||
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
|
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
|
||||||
import net.Indyuce.mmocore.manager.data.mysql.MySQLTableEditor.Table;
|
import net.Indyuce.mmocore.manager.data.mysql.MySQLTableEditor.Table;
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -73,8 +69,10 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
|
|||||||
data.setStellium(data.getStats().getStat(StatType.MAX_STELLIUM));
|
data.setStellium(data.getStats().getStat(StatType.MAX_STELLIUM));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isEmpty(result.getString("guild")))
|
if (!isEmpty(result.getString("guild"))) {
|
||||||
data.setGuild(MMOCore.plugin.dataProvider.getGuildManager().stillInGuild(data.getUniqueId(), result.getString("guild")));
|
Guild guild = provider.getGuildManager().getGuild(result.getString("guild"));
|
||||||
|
data.setGuild(guild.getMembers().has(data.getUniqueId()) ? guild : null);
|
||||||
|
}
|
||||||
if (!isEmpty(result.getString("attributes"))) data.getAttributes().load(result.getString("attributes"));
|
if (!isEmpty(result.getString("attributes"))) data.getAttributes().load(result.getString("attributes"));
|
||||||
if (!isEmpty(result.getString("professions")))
|
if (!isEmpty(result.getString("professions")))
|
||||||
data.getCollectionSkills().load(result.getString("professions"));
|
data.getCollectionSkills().load(result.getString("professions"));
|
||||||
|
@ -5,7 +5,7 @@ import net.Indyuce.mmocore.manager.data.GuildDataManager;
|
|||||||
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
|
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
|
||||||
|
|
||||||
public class YAMLDataProvider implements DataProvider {
|
public class YAMLDataProvider implements DataProvider {
|
||||||
private final YAMLPlayerDataManager playerManager = new YAMLPlayerDataManager();
|
private final YAMLPlayerDataManager playerManager = new YAMLPlayerDataManager(this);
|
||||||
private final YAMLGuildDataManager guildManager = new YAMLGuildDataManager();
|
private final YAMLGuildDataManager guildManager = new YAMLGuildDataManager();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -10,7 +10,7 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
|||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.ConfigFile;
|
import net.Indyuce.mmocore.api.ConfigFile;
|
||||||
import net.Indyuce.mmocore.api.player.social.guilds.Guild;
|
import net.Indyuce.mmocore.guild.provided.Guild;
|
||||||
import net.Indyuce.mmocore.manager.data.GuildDataManager;
|
import net.Indyuce.mmocore.manager.data.GuildDataManager;
|
||||||
|
|
||||||
public class YAMLGuildDataManager extends GuildDataManager {
|
public class YAMLGuildDataManager extends GuildDataManager {
|
||||||
|
@ -11,8 +11,8 @@ import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
|||||||
public class YAMLOfflinePlayerData extends OfflinePlayerData {
|
public class YAMLOfflinePlayerData extends OfflinePlayerData {
|
||||||
private final ConfigFile config;
|
private final ConfigFile config;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* supports offline player data operations like friend removals which can't
|
* Supports offline player data operations like friend removals which can't
|
||||||
* be handled when their player data is not loaded in the data map.
|
* be handled when their player data is not loaded in the data map.
|
||||||
*/
|
*/
|
||||||
public YAMLOfflinePlayerData(UUID uuid) {
|
public YAMLOfflinePlayerData(UUID uuid) {
|
||||||
|
@ -1,14 +1,5 @@
|
|||||||
package net.Indyuce.mmocore.manager.data.yaml;
|
package net.Indyuce.mmocore.manager.data.yaml;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.Validate;
|
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.ConfigFile;
|
import net.Indyuce.mmocore.api.ConfigFile;
|
||||||
import net.Indyuce.mmocore.api.player.OfflinePlayerData;
|
import net.Indyuce.mmocore.api.player.OfflinePlayerData;
|
||||||
@ -16,10 +7,25 @@ import net.Indyuce.mmocore.api.player.PlayerData;
|
|||||||
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||||
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
|
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
|
||||||
import net.Indyuce.mmocore.api.player.stats.StatType;
|
import net.Indyuce.mmocore.api.player.stats.StatType;
|
||||||
|
import net.Indyuce.mmocore.guild.provided.Guild;
|
||||||
|
import net.Indyuce.mmocore.manager.data.DataProvider;
|
||||||
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
|
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class YAMLPlayerDataManager extends PlayerDataManager {
|
public class YAMLPlayerDataManager extends PlayerDataManager {
|
||||||
|
private final DataProvider provider;
|
||||||
|
|
||||||
|
public YAMLPlayerDataManager(DataProvider provider) {
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadData(PlayerData data) {
|
public void loadData(PlayerData data) {
|
||||||
@ -40,8 +46,10 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
|
|||||||
data.setStellium(data.getStats().getStat(StatType.MAX_STELLIUM));
|
data.setStellium(data.getStats().getStat(StatType.MAX_STELLIUM));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.contains("guild"))
|
if (config.contains("guild")) {
|
||||||
data.setGuild(MMOCore.plugin.dataProvider.getGuildManager().stillInGuild(data.getUniqueId(), config.getString("guild")));
|
Guild guild = provider.getGuildManager().getGuild(config.getString("guild"));
|
||||||
|
data.setGuild(guild.getMembers().has(data.getUniqueId()) ? guild : null);
|
||||||
|
}
|
||||||
if (config.contains("attribute"))
|
if (config.contains("attribute"))
|
||||||
data.getAttributes().load(config.getConfigurationSection("attribute"));
|
data.getAttributes().load(config.getConfigurationSection("attribute"));
|
||||||
if (config.contains("profession"))
|
if (config.contains("profession"))
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
package net.Indyuce.mmocore.tree;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class IntegerCoordinates {
|
||||||
|
private final int x, y;
|
||||||
|
|
||||||
|
public IntegerCoordinates(int x, int y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public IntegerCoordinates(String str) {
|
||||||
|
String[] split = str.split("\\.");
|
||||||
|
Validate.isTrue(split.length == 2, "Invalid format");
|
||||||
|
x = Integer.parseInt(split[0]);
|
||||||
|
y = Integer.parseInt(split[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
IntegerCoordinates that = (IntegerCoordinates) o;
|
||||||
|
return x == that.x && y == that.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return x + "." + y;
|
||||||
|
}
|
||||||
|
}
|
71
src/main/java/net/Indyuce/mmocore/tree/SkillTree.java
Normal file
71
src/main/java/net/Indyuce/mmocore/tree/SkillTree.java
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package net.Indyuce.mmocore.tree;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A passive skill tree that features nodes, or passive skills.
|
||||||
|
* <p>
|
||||||
|
* The player can explore the passive skill tree using the right GUI
|
||||||
|
* and unlock nodes by spending passive skill points. Unlocking nodes
|
||||||
|
* grant permanent player modifiers, including
|
||||||
|
* - stats
|
||||||
|
* - active or passive MythicLib skills
|
||||||
|
* - active or passive MMOCore skills
|
||||||
|
* - extra attribute pts
|
||||||
|
* - particle or potion effects
|
||||||
|
*
|
||||||
|
* @author jules
|
||||||
|
* @see {@link SkillTreeNode}
|
||||||
|
*/
|
||||||
|
public class SkillTree {
|
||||||
|
private final String id, name;
|
||||||
|
private final Map<IntegerCoordinates, SkillTreeNode> nodes = new HashMap<>();
|
||||||
|
|
||||||
|
public SkillTree(ConfigurationSection config) {
|
||||||
|
this.id = config.getName();
|
||||||
|
this.name = Objects.requireNonNull(config.getString("name"), "Could not find skill tree name");
|
||||||
|
Validate.isTrue(config.isConfigurationSection("nodes"), "Could not find tree passive skills");
|
||||||
|
for (String xKey : config.getConfigurationSection("nodes").getKeys(false))
|
||||||
|
for (String yKey : config.getConfigurationSection("nodes." + xKey).getKeys(false))
|
||||||
|
try {
|
||||||
|
int x = Integer.parseInt(xKey), y = Integer.parseInt(yKey);
|
||||||
|
SkillTreeNode node = new SkillTreeNode(this, x, y, config.getConfigurationSection("nodes." + xKey + "." + yKey));
|
||||||
|
nodes.put(node.getCoordinates(), node);
|
||||||
|
} catch (RuntimeException exception) {
|
||||||
|
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load tree node '" + xKey + "." + yKey + "' for skill tree '" + id + "': " + exception.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<SkillTreeNode> getNodes() {
|
||||||
|
return nodes.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
SkillTree skillTree = (SkillTree) o;
|
||||||
|
return id.equals(skillTree.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id);
|
||||||
|
}
|
||||||
|
}
|
70
src/main/java/net/Indyuce/mmocore/tree/SkillTreeNode.java
Normal file
70
src/main/java/net/Indyuce/mmocore/tree/SkillTreeNode.java
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package net.Indyuce.mmocore.tree;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.MythicLib;
|
||||||
|
import io.lumine.mythic.lib.player.modifier.PlayerModifier;
|
||||||
|
import io.lumine.mythic.lib.util.configobject.ConfigSectionObject;
|
||||||
|
import net.Indyuce.mmocore.api.player.Unlockable;
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class SkillTreeNode implements Unlockable {
|
||||||
|
private final SkillTree tree;
|
||||||
|
private final String name;
|
||||||
|
private final IntegerCoordinates coordinates;
|
||||||
|
private final List<String> lore;
|
||||||
|
private final Set<PlayerModifier> modifiers = new HashSet<>();
|
||||||
|
|
||||||
|
public SkillTreeNode(SkillTree tree, int x, int y, ConfigurationSection config) {
|
||||||
|
Validate.notNull(config, "Config cannot be null");
|
||||||
|
this.tree = tree;
|
||||||
|
name = Objects.requireNonNull(config.getString("name"), "Could not find node name");
|
||||||
|
coordinates = new IntegerCoordinates(x, y);
|
||||||
|
lore = config.getStringList("lore");
|
||||||
|
for (String key : config.getConfigurationSection("modifiers").getKeys(false)) {
|
||||||
|
PlayerModifier mod = MythicLib.plugin.getModifiers().loadPlayerModifier(new ConfigSectionObject(config.getConfigurationSection(key)));
|
||||||
|
modifiers.add(mod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntegerCoordinates getCoordinates() {
|
||||||
|
return coordinates;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<PlayerModifier> getModifiers() {
|
||||||
|
return modifiers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Uncolored lore with no placeholders
|
||||||
|
*/
|
||||||
|
public List<String> getLore() {
|
||||||
|
return lore;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
SkillTreeNode that = (SkillTreeNode) o;
|
||||||
|
return tree.equals(that.tree) && coordinates.equals(that.coordinates);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(tree, coordinates);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUnlockNamespacedKey() {
|
||||||
|
return "skill_tree:" + tree.getId() + "_" + coordinates.getX() + "_" + coordinates.getY();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user