Passive Skill Slots

This commit is contained in:
Ka0rX 2022-10-03 07:51:18 +02:00
parent f4d6f21b0f
commit bbecebc348
7 changed files with 226 additions and 59 deletions

View File

@ -86,6 +86,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
private final Set<String> waypoints = new HashSet<>();
private final Map<String, Integer> skills = new HashMap<>();
private final List<ClassSkill> boundSkills = new ArrayList<>();
private final List<ClassSkill> boundPassiveSkills = new ArrayList<>();
private final PlayerProfessions collectSkills = new PlayerProfessions(this);
private final PlayerAttributes attributes = new PlayerAttributes(this);
private final Map<String, SavedClassInformation> classSlots = new HashMap<>();
@ -180,8 +181,8 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
//Stat triggers setup
for (SkillTree skillTree : MMOCore.plugin.skillTreeManager.getAll()) {
for(SkillTreeNode node: skillTree.getNodes()) {
node.getExperienceTable().claimStatTriggers(this,node);
for (SkillTreeNode node : skillTree.getNodes()) {
node.getExperienceTable().claimStatTriggers(this, node);
}
}
@ -1049,6 +1050,29 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
return slot >= boundSkills.size() ? null : boundSkills.get(slot);
}
public void setBoundPassiveSkill(int slot, ClassSkill skill) {
Validate.notNull(skill, "Skill cannot be null");
if (boundPassiveSkills.size() < getProfess().getMaxBoundSkills())
boundPassiveSkills.add(skill);
else
boundPassiveSkills.set(slot, skill);
boundPassiveSkills.get(slot).toPassive(this).register(getMMOPlayerData());
}
public boolean hasPassiveSkillBound(int slot) {
return slot < boundPassiveSkills.size();
}
public ClassSkill getBoundPassiveSkill(int slot) {
return slot >= boundPassiveSkills.size() ? null : boundPassiveSkills.get(slot);
}
public void addPassiveBoundSkill(ClassSkill skill) {
boundPassiveSkills.add(skill);
skill.toPassive(this).register(getMMOPlayerData());
}
public void setBoundSkill(int slot, ClassSkill skill) {
Validate.notNull(skill, "Skill cannot be null");
if (boundSkills.size() < getProfess().getMaxBoundSkills())
@ -1061,10 +1085,20 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
boundSkills.remove(slot);
}
public void unbindPassiveSkill(int slot) {
boundPassiveSkills.get(slot).toPassive(this).unregister(getMMOPlayerData());
boundPassiveSkills.remove(slot);
}
public List<ClassSkill> getBoundSkills() {
return boundSkills;
}
public List<ClassSkill> getBoundPassiveSkills() {
return boundPassiveSkills;
}
public boolean isInCombat() {
return combat != null;
}

View File

@ -68,7 +68,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
@NotNull
private final CastingParticle castParticle;
private final int maxBoundSkills;
private final int maxBoundSkills, maxBoundPassiveSkills;
private final List<PassiveSkill> classScripts = new LinkedList();
private final Map<String, LinearValue> stats = new HashMap<>();
private final Map<String, ClassSkill> skills = new LinkedHashMap<>();
@ -124,6 +124,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
config.get("exp-curve").toString().toLowerCase().replace("_", "-").replace(" ", "-"))
: ExpCurve.DEFAULT;
maxBoundSkills = config.getInt("max-bound-skills", 6);
maxBoundPassiveSkills = config.getInt("max-bound-passive-skills", 3);
ExperienceTable expTable = null;
if (config.contains("exp-table"))
try {
@ -259,6 +260,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
setOption(ClassOption.DISPLAY, false);
setOption(ClassOption.DEFAULT, false);
maxBoundSkills = 6;
maxBoundPassiveSkills=3;
for (PlayerResource resource : PlayerResource.values())
resourceHandlers.put(resource, new ResourceRegeneration(resource));
}
@ -317,6 +319,9 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
public int getMaxBoundSkills() {
return maxBoundSkills;
}
public int getMaxBoundPassiveSkills() {
return maxBoundPassiveSkills;
}
@NotNull
public ExperienceTable getExperienceTable() {

View File

@ -60,28 +60,8 @@ public class SkillList extends EditableInventory {
};
}
if (function.equals("slot"))
return new InventoryItem<SkillViewerInventory>(config) {
private final String none = MythicLib.plugin.parseColors(config.getString("no-skill"));
private final Material emptyMaterial = Material
.valueOf(config.getString("empty-item").toUpperCase().replace("-", "_").replace(" ", "_"));
private final int emptyCMD = config.getInt("empty-custom-model-data", getModelData());
@Override
public Placeholders getPlaceholders(SkillViewerInventory inv, int n) {
RegisteredSkill selected = inv.selected == null ? null : inv.selected.getSkill();
RegisteredSkill skill = inv.getPlayerData().hasSkillBound(n) ? inv.getPlayerData().getBoundSkill(n).getSkill() : null;
Placeholders holders = new Placeholders();
holders.register("skill", skill == null ? none : skill.getName());
holders.register("index", "" + (n + 1));
holders.register("slot", MMOCoreUtils.intToRoman(n + 1));
holders.register("selected", selected == null ? none : selected.getName());
return holders;
}
if (function.equals("active-slot"))
return new SlotItem(config) {
@Override
public ItemStack display(SkillViewerInventory inv, int n) {
if (n >= inv.getPlayerData().getProfess().getMaxBoundSkills()) {
@ -89,11 +69,11 @@ public class SkillList extends EditableInventory {
}
ItemStack item = super.display(inv, n);
if (!inv.getPlayerData().hasSkillBound(n)) {
item.setType(emptyMaterial);
item.setType(super.emptyMaterial);
if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 13)) {
ItemMeta meta = item.getItemMeta();
meta.setCustomModelData(emptyCMD);
meta.setCustomModelData(super.emptyCMD);
item.setItemMeta(meta);
}
}
@ -101,10 +81,46 @@ public class SkillList extends EditableInventory {
}
@Override
public boolean hasDifferentDisplay() {
return true;
public Placeholders getPlaceholders(SkillViewerInventory inv, int n) {
Placeholders holders= super.getPlaceholders(inv, n);
String none = MythicLib.plugin.parseColors(config.getString("no-skill"));
RegisteredSkill skill = inv.getPlayerData().hasSkillBound(n) ? inv.getPlayerData().getBoundSkill(n).getSkill() : null;
holders.register("skill", skill == null ? none : skill.getName());
return holders;
}
};
if (function.equals("passive-slot"))
return new SlotItem(config) {
@Override
public ItemStack display(SkillViewerInventory inv, int n) {
if (n >= inv.getPlayerData().getProfess().getMaxBoundPassiveSkills()) {
return new ItemStack(Material.AIR);
}
ItemStack item = super.display(inv, n);
if (!inv.getPlayerData().hasPassiveSkillBound(n)) {
item.setType(super.emptyMaterial);
if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 13)) {
ItemMeta meta = item.getItemMeta();
meta.setCustomModelData(super.emptyCMD);
item.setItemMeta(meta);
}
}
return item;
}
@Override
public Placeholders getPlaceholders(SkillViewerInventory inv, int n) {
Placeholders holders= super.getPlaceholders(inv, n);
String none = MythicLib.plugin.parseColors(config.getString("no-skill"));
RegisteredSkill skill = inv.getPlayerData().hasPassiveSkillBound(n) ? inv.getPlayerData().getBoundPassiveSkill(n).getSkill() : null;
holders.register("skill", skill == null ? none : skill.getName());
return holders;
}
};
if (function.equals("previous"))
return new SimplePlaceholderItem<SkillViewerInventory>(config) {
@ -182,6 +198,40 @@ public class SkillList extends EditableInventory {
}
}
public class SlotItem extends InventoryItem<SkillViewerInventory> {
private final String none;
private final Material emptyMaterial;
private final int emptyCMD;
public SlotItem(ConfigurationSection config) {
super(config);
none = MythicLib.plugin.parseColors(config.getString("no-skill"));
emptyMaterial = Material
.valueOf(config.getString("empty-item").toUpperCase().replace("-", "_").replace(" ", "_"));
emptyCMD = config.getInt("empty-custom-model-data", getModelData());
}
@Override
public Placeholders getPlaceholders(SkillViewerInventory inv, int n) {
RegisteredSkill selected = inv.selected == null ? null : inv.selected.getSkill();
Placeholders holders = new Placeholders();
holders.register("index", "" + (n + 1));
holders.register("slot", MMOCoreUtils.intToRoman(n + 1));
holders.register("selected", selected == null ? none : selected.getName());
return holders;
}
@Override
public boolean hasDifferentDisplay() {
return true;
}
}
;
public class SkillItem extends InventoryItem<SkillViewerInventory> {
public SkillItem(ConfigurationSection config) {
super(Material.BARRIER, config);
@ -276,7 +326,8 @@ public class SkillList extends EditableInventory {
// Cached information
private final List<ClassSkill> skills;
private final List<Integer> skillSlots;
private final List<Integer> slotSlots;
private final List<Integer> activeSlotSlots;
private final List<Integer> passiveSlotSlots;
//The skill the player Selected
private ClassSkill selected;
@ -287,7 +338,8 @@ public class SkillList extends EditableInventory {
skills = new ArrayList<>(playerData.getProfess().getSkills());
skillSlots = getEditable().getByFunction("skill").getSlots();
slotSlots = getEditable().getByFunction("slot").getSlots();
activeSlotSlots = getEditable().getByFunction("active-slot").getSlots();
passiveSlotSlots = getEditable().getByFunction("passive-slot").getSlots();
selected = skills.get(page * skillSlots.size());
}
@ -322,11 +374,10 @@ public class SkillList extends EditableInventory {
return;
}
if(item.getFunction().equals("reallocation")) {
if (item.getFunction().equals("reallocation")) {
int spent= getPlayerData().countSkillPointsWhenReallocate();
int spent = getPlayerData().countSkillPointsWhenReallocate();
if (spent < 1) {
MMOCore.plugin.configManager.getSimpleMessage("no-skill-points-spent").send(player);
@ -341,11 +392,11 @@ public class SkillList extends EditableInventory {
}
for(ClassSkill skill:playerData.getProfess().getSkills()) {
for (ClassSkill skill : playerData.getProfess().getSkills()) {
playerData.setSkillLevel(skill.getSkill(), 1);
}
playerData.giveSkillPoints(spent);
playerData.setSkillReallocationPoints(playerData.getSkillReallocationPoints()-1);
playerData.setSkillReallocationPoints(playerData.getSkillReallocationPoints() - 1);
MMOCore.plugin.configManager.getSimpleMessage("skill-points-reallocated", "points", "" + playerData.getSkillPoints()).send(player);
MMOCore.plugin.soundManager.getSound(SoundEvent.RESET_SKILLS).playTo(getPlayer());
open();
@ -365,11 +416,54 @@ public class SkillList extends EditableInventory {
return;
}
/*
* binding or unbinding passive skills.
*/
if (item.getFunction().equals("passive-slot")) {
int index = passiveSlotSlots.indexOf(context.getSlot());
// unbind if there is a current spell.
if (context.getClickType() == ClickType.RIGHT) {
if (!playerData.hasPassiveSkillBound(index)) {
MMOCore.plugin.configManager.getSimpleMessage("no-skill-bound").send(player);
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
return;
}
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2);
playerData.unbindPassiveSkill(index);
open();
return;
}
if (selected == null)
return;
if (!selected.getSkill().getTrigger().isPassive()) {
MMOCore.plugin.configManager.getSimpleMessage("not-passive-skill").send(player);
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
return;
}
if (!playerData.hasSkillUnlocked(selected)) {
MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player);
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
return;
}
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2);
playerData.setBoundPassiveSkill(index, selected);
open();
return;
}
/*
* binding or unbinding skills.
*/
if (item.getFunction().equals("slot")) {
int index = slotSlots.indexOf(context.getSlot());
if (item.getFunction().equals("active-slot")) {
int index = activeSlotSlots.indexOf(context.getSlot());
// unbind if there is a current spell.
if (context.getClickType() == ClickType.RIGHT) {

View File

@ -12,6 +12,7 @@ import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
import net.Indyuce.mmocore.guild.provided.Guild;
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.tree.SkillTreeNode;
import net.Indyuce.mmocore.tree.skilltree.SkillTree;
import org.apache.commons.lang.Validate;
@ -76,18 +77,18 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
JsonObject json = new JsonParser().parse(result.getString("times_claimed")).getAsJsonObject();
json.entrySet().forEach(entry -> data.getItemClaims().put(entry.getKey(), entry.getValue().getAsInt()));
}
if(!isEmpty(result.getString("skill_tree_points"))) {
if (!isEmpty(result.getString("skill_tree_points"))) {
JsonObject json = new JsonParser().parse(result.getString("skill_tree_points")).getAsJsonObject();
for(SkillTree skillTree: MMOCore.plugin.skillTreeManager.getAll()) {
data.setSkillTreePoints(skillTree.getId(),json.has(skillTree.getId())?json.get(skillTree.getId()).getAsInt():0);
for (SkillTree skillTree : MMOCore.plugin.skillTreeManager.getAll()) {
data.setSkillTreePoints(skillTree.getId(), json.has(skillTree.getId()) ? json.get(skillTree.getId()).getAsInt() : 0);
}
data.setSkillTreePoints("global",json.has("global")?json.get("global").getAsInt():0);
data.setSkillTreePoints("global", json.has("global") ? json.get("global").getAsInt() : 0);
}
if(!isEmpty(result.getString("skill_tree_levels"))) {
if (!isEmpty(result.getString("skill_tree_levels"))) {
JsonObject json = new JsonParser().parse(result.getString("skill_tree_levels")).getAsJsonObject();
for(SkillTreeNode skillTreeNode: MMOCore.plugin.skillTreeManager.getAllNodes()) {
data.setNodeLevel(skillTreeNode,json.has(skillTreeNode.getFullId())?json.get(skillTreeNode.getFullId()).getAsInt():0);
for (SkillTreeNode skillTreeNode : MMOCore.plugin.skillTreeManager.getAllNodes()) {
data.setNodeLevel(skillTreeNode, json.has(skillTreeNode.getFullId()) ? json.get(skillTreeNode.getFullId()).getAsInt() : 0);
}
}
data.setupSkillTree();
@ -114,9 +115,14 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
data.setSkillLevel(entry.getKey(), entry.getValue().getAsInt());
}
if (!isEmpty(result.getString("bound_skills")))
for (String skill : MMOCoreUtils.jsonArrayToList(result.getString("bound_skills")))
if (data.getProfess().hasSkill(skill))
data.getBoundSkills().add(data.getProfess().getSkill(skill));
for (String id : MMOCoreUtils.jsonArrayToList(result.getString("bound_skills")))
if (data.getProfess().hasSkill(id)) {
ClassSkill skill = data.getProfess().getSkill(id);
if (skill.getSkill().getTrigger().isPassive())
data.addPassiveBoundSkill(skill);
else
data.getBoundSkills().add(skill);
}
if (!isEmpty(result.getString("class_info"))) {
JsonObject object = MythicLib.plugin.getJson().parse(result.getString("class_info"), JsonObject.class);
for (Entry<String, JsonElement> entry : object.entrySet()) {
@ -177,13 +183,13 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
sql.updateData("class_points", data.getClassPoints());
sql.updateData("skill_points", data.getSkillPoints());
sql.updateData("skill_reallocation_points",data.getSkillReallocationPoints());
sql.updateData("skill_reallocation_points", data.getSkillReallocationPoints());
sql.updateData("attribute_points", data.getAttributePoints());
sql.updateData("attribute_realloc_points", data.getAttributeReallocationPoints());
sql.updateData("skill_tree_reallocation_points",data.getSkillTreeReallocationPoints());
sql.updateData("mana",data.getMana());
sql.updateData("stellium",data.getStellium());
sql.updateData("stamina",data.getStamina());
sql.updateData("skill_tree_reallocation_points", data.getSkillTreeReallocationPoints());
sql.updateData("mana", data.getMana());
sql.updateData("stellium", data.getStellium());
sql.updateData("stamina", data.getStamina());
sql.updateData("level", data.getLevel());
sql.updateData("experience", data.getExperience());
sql.updateData("class", data.getProfess().getId());
@ -192,12 +198,15 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
sql.updateJSONArray("waypoints", data.getWaypoints());
sql.updateJSONArray("friends", data.getFriends().stream().map(UUID::toString).collect(Collectors.toList()));
sql.updateJSONArray("bound_skills", data.getBoundSkills().stream().map(skill -> skill.getSkill().getHandler().getId()).collect(Collectors.toList()));
List<String> boundSkills = new ArrayList<>();
data.getBoundSkills().forEach(skill -> boundSkills.add(skill.getSkill().getHandler().getId()));
data.getBoundPassiveSkills().forEach(skill -> boundSkills.add(skill.getSkill().getHandler().getId()));
sql.updateJSONArray("bound_skills", boundSkills);
sql.updateJSONObject("skills", data.mapSkillLevels().entrySet());
sql.updateJSONObject("times_claimed", data.getItemClaims().entrySet());
sql.updateJSONObject("skill_tree_points",data.getSkillTreePoints().entrySet());
sql.updateJSONObject("skill_tree_levels",data.getNodeLevelsEntrySet());
sql.updateJSONObject("skill_tree_points", data.getSkillTreePoints().entrySet());
sql.updateJSONObject("skill_tree_levels", data.getNodeLevelsEntrySet());
sql.updateData("attributes", data.getAttributes().toJsonString());

View File

@ -10,6 +10,7 @@ import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
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.skill.ClassSkill;
import net.Indyuce.mmocore.tree.SkillTreeNode;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
@ -67,8 +68,14 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
config.getConfigurationSection("skill").getKeys(false).forEach(id -> data.setSkillLevel(id, config.getInt("skill." + id)));
if (config.contains("bound-skills"))
for (String id : config.getStringList("bound-skills"))
if (data.getProfess().hasSkill(id))
data.getBoundSkills().add(data.getProfess().getSkill(id));
if (data.getProfess().hasSkill(id)) {
ClassSkill skill = data.getProfess().getSkill(id);
if (skill.getSkill().getTrigger().isPassive())
data.addPassiveBoundSkill(skill);
else
data.getBoundSkills().add(skill);
}
for (String key : MMOCore.plugin.skillTreeManager.getAll().stream().map(skillTree -> skillTree.getId()).toList()) {
data.setSkillTreePoints(key, config.getInt("skill-tree-points." + key, 0));
@ -145,6 +152,7 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
List<String> boundSkills = new ArrayList<>();
data.getBoundSkills().forEach(skill -> boundSkills.add(skill.getSkill().getHandler().getId()));
data.getBoundPassiveSkills().forEach(skill -> boundSkills.add(skill.getSkill().getHandler().getId()));
config.set("bound-skills", boundSkills);
config.set("attribute", null);

View File

@ -59,9 +59,25 @@ items:
# item: PINK_STAINED_GLASS
# name: '&aSwitch to Upgrading'
# lore: {}
passive-skill-slot:
slots: [ 7,16,25,34,43,52 ]
function: passive-slot
item: BOOK
# Material used when the slot is empty
empty-item: BLUE_DYE
name: '&aPassive Skill Slot {slot}'
no-skill: '&cNone'
lore:
- '&7Current Passive Skill: &6{skill}'
- ''
- '&e► Left click to bind {selected}.'
- '&e► Right click to unbind.'
skill-slot:
slots: [ 8,17,26,35,44,53 ]
function: slot
function: active-slot
item: BOOK
# Material used when the slot is empty

View File

@ -171,6 +171,7 @@ upgrade-skill: '&eYour &6{skill} &eis now Level &6{level}&e!'
not-unlocked-skill: '&cYou have not unlocked that skill yet.'
no-skill-bound: '&cYou don''t have any skill bound to this slot.'
not-active-skill: '&cThis is not an active skill.'
not-passive-skill: '&cThis is not a passive skill.'
skill-max-level-hit: '&cYou already hit the max level for that skill.'
no-skill-placeholder: 'No Skill Bound'
not-skill-reallocation-point: '&cYou do not have 1 skill reallocation point.'