forked from Upstream/mmocore
Skill Slots Update
This commit is contained in:
parent
1718e04ba5
commit
2ec66e92ef
@ -5,6 +5,7 @@ import io.lumine.mythic.lib.api.player.MMOPlayerData;
|
||||
import io.lumine.mythic.lib.api.stat.StatInstance;
|
||||
import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
|
||||
import io.lumine.mythic.lib.player.cooldown.CooldownMap;
|
||||
import io.lumine.mythic.lib.player.skill.PassiveSkill;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.ConfigMessage;
|
||||
import net.Indyuce.mmocore.api.SoundEvent;
|
||||
@ -17,6 +18,7 @@ import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
|
||||
import net.Indyuce.mmocore.api.player.profess.Subclass;
|
||||
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
|
||||
import net.Indyuce.mmocore.api.player.profess.skillbinding.BoundSkillInfo;
|
||||
import net.Indyuce.mmocore.api.player.social.FriendRequest;
|
||||
import net.Indyuce.mmocore.api.player.stats.PlayerStats;
|
||||
import net.Indyuce.mmocore.api.quest.PlayerQuests;
|
||||
@ -91,7 +93,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
private final List<UUID> friends = new ArrayList<>();
|
||||
private final Set<String> waypoints = new HashSet<>();
|
||||
private final Map<String, Integer> skills = new HashMap<>();
|
||||
private final List<ClassSkill> boundSkills = new ArrayList<>();
|
||||
private final Map<Integer,BoundSkillInfo> boundSkills = new HashMap<>();
|
||||
private final PlayerProfessions collectSkills = new PlayerProfessions(this);
|
||||
private final PlayerAttributes attributes = new PlayerAttributes(this);
|
||||
private final Map<String, SavedClassInformation> classSlots = new HashMap<>();
|
||||
@ -164,13 +166,13 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
MMOCore.log(Level.SEVERE, "[Userdata] Could not find class " + getProfess().getId() + " while refreshing player data.");
|
||||
}
|
||||
|
||||
int j = 0;
|
||||
while (j < boundSkills.size())
|
||||
Iterator<Integer> ite=boundSkills.keySet().iterator();
|
||||
while (ite.hasNext())
|
||||
try {
|
||||
boundSkills.set(j, Objects.requireNonNull(getProfess().getSkill(boundSkills.get(j).getSkill())));
|
||||
int slot=ite.next();
|
||||
BoundSkillInfo boundSkillInfo=new BoundSkillInfo(boundSkills.get(slot));
|
||||
boundSkills.put(slot, boundSkillInfo);
|
||||
} catch (Exception ignored) {
|
||||
} finally {
|
||||
j++;
|
||||
}
|
||||
|
||||
for (SkillTree skillTree : getProfess().getSkillTrees())
|
||||
@ -1047,10 +1049,23 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
|
||||
public void setSkillLevel(String skill, int level) {
|
||||
skills.put(skill, level);
|
||||
refreshBoundedSkill(skill);
|
||||
}
|
||||
|
||||
public void resetSkillLevel(String skill) {
|
||||
skills.remove(skill);
|
||||
refreshBoundedSkill(skill);
|
||||
}
|
||||
|
||||
public void refreshBoundedSkill(String skill) {
|
||||
boundSkills.values()
|
||||
.stream()
|
||||
.filter(skillInfo->skillInfo.getClassSkill().getSkill().getHandler().getId().equals(skill))
|
||||
.forEach(BoundSkillInfo::refresh);
|
||||
//TODO Remove test:
|
||||
Bukkit.broadcastMessage("match"+boundSkills.values()
|
||||
.stream()
|
||||
.filter(skillInfo->skillInfo.getClassSkill().getSkill().getHandler().getId().equals(skill)).toList().size());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ -1108,8 +1123,8 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
this.profess = profess;
|
||||
|
||||
// Clear old skills
|
||||
for (Iterator<ClassSkill> iterator = boundSkills.iterator(); iterator.hasNext(); )
|
||||
if (!getProfess().hasSkill(iterator.next().getSkill()))
|
||||
for (Iterator<BoundSkillInfo> iterator = boundSkills.values().iterator(); iterator.hasNext(); )
|
||||
if (!getProfess().hasSkill(iterator.next().getClassSkill().getSkill()))
|
||||
iterator.remove();
|
||||
|
||||
// Update stats
|
||||
@ -1122,7 +1137,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
}
|
||||
|
||||
public ClassSkill getBoundSkill(int slot) {
|
||||
return slot >= boundSkills.size() ? null : boundSkills.get(slot);
|
||||
return slot >= boundSkills.size() ? null : boundSkills.get(slot).getClassSkill();
|
||||
}
|
||||
|
||||
|
||||
@ -1140,8 +1155,18 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
*/
|
||||
public void bindSkill(int slot, ClassSkill skill) {
|
||||
Validate.notNull(skill, "Skill cannot be null");
|
||||
if (slot >= 0)
|
||||
boundSkills.set(slot, skill);
|
||||
//Unbinds the previous skill (Important for passive skills.
|
||||
if (boundSkills.containsKey(slot))
|
||||
boundSkills.get(slot).unbind();
|
||||
if (slot >= 0) {
|
||||
if (skill.getSkill().getTrigger().isPassive()) {
|
||||
PassiveSkill passiveSkill = skill.toPassive(this);
|
||||
passiveSkill.register(mmoData);
|
||||
boundSkills.put(slot, new BoundSkillInfo(skill, this, passiveSkill.getUniqueId()));
|
||||
} else {
|
||||
boundSkills.put(slot, new BoundSkillInfo(skill, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void unbindSkill(int slot) {
|
||||
@ -1150,7 +1175,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
|
||||
|
||||
public List<ClassSkill> getBoundSkills() {
|
||||
return boundSkills;
|
||||
return boundSkills.values().stream().map(BoundSkillInfo::getClassSkill).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
@ -21,7 +21,7 @@ import net.Indyuce.mmocore.api.player.profess.event.EventTrigger;
|
||||
import net.Indyuce.mmocore.api.player.profess.resource.ManaDisplayOptions;
|
||||
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
|
||||
import net.Indyuce.mmocore.api.player.profess.resource.ResourceRegeneration;
|
||||
import net.Indyuce.mmocore.api.player.profess.skillslot.SkillSlot;
|
||||
import net.Indyuce.mmocore.api.player.profess.skillbinding.SkillSlot;
|
||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||
import net.Indyuce.mmocore.experience.EXPSource;
|
||||
|
@ -0,0 +1,67 @@
|
||||
package net.Indyuce.mmocore.api.player.profess.skillbinding;
|
||||
|
||||
import io.lumine.mythic.lib.player.skill.PassiveSkill;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.skill.ClassSkill;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BoundSkillInfo {
|
||||
private final PlayerData playerData;
|
||||
private final ClassSkill classSkill;
|
||||
private UUID passiveSkillUUID;
|
||||
|
||||
public BoundSkillInfo(ClassSkill classSkill, PlayerData playerData) {
|
||||
this.classSkill = classSkill;
|
||||
this.playerData = playerData;
|
||||
}
|
||||
|
||||
public BoundSkillInfo(ClassSkill classSkill, PlayerData playerData, UUID passiveSkillUUID) {
|
||||
this.classSkill = classSkill;
|
||||
this.playerData = playerData;
|
||||
this.passiveSkillUUID = passiveSkillUUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used on update to refresh the classSkill & all references to old data.
|
||||
*/
|
||||
public BoundSkillInfo(BoundSkillInfo info) {
|
||||
this.playerData=info.getPlayerData();
|
||||
this.classSkill= Objects.requireNonNull(playerData.getProfess().getSkill(info.getClassSkill().getSkill()));
|
||||
info.unbind();
|
||||
PassiveSkill passiveSkill = classSkill.toPassive(playerData);
|
||||
passiveSkill.register(playerData.getMMOPlayerData());
|
||||
this.passiveSkillUUID=passiveSkill.getUniqueId();
|
||||
}
|
||||
|
||||
public ClassSkill getClassSkill() {
|
||||
return classSkill;
|
||||
}
|
||||
|
||||
public PlayerData getPlayerData() {
|
||||
return playerData;
|
||||
}
|
||||
|
||||
public UUID getPassiveSkillUUID() {
|
||||
return passiveSkillUUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to refresh the PassiveSkill playerModifier so it is always associated to the
|
||||
*/
|
||||
public void refresh() {
|
||||
if (classSkill.getSkill().getTrigger().isPassive()) {
|
||||
playerData.getMMOPlayerData().getPassiveSkillMap().removeModifier(passiveSkillUUID);
|
||||
PassiveSkill passiveSkill = classSkill.toPassive(playerData);
|
||||
passiveSkill.register(playerData.getMMOPlayerData());
|
||||
this.passiveSkillUUID=passiveSkill.getUniqueId();
|
||||
}
|
||||
}
|
||||
|
||||
public void unbind() {
|
||||
if (classSkill.getSkill().getTrigger().isPassive()) {
|
||||
playerData.getMMOPlayerData().getPassiveSkillMap().removeModifier(passiveSkillUUID);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +1,12 @@
|
||||
package net.Indyuce.mmocore.api.player.profess.skillslot;
|
||||
package net.Indyuce.mmocore.api.player.profess.skillbinding;
|
||||
|
||||
import io.lumine.mythic.lib.api.math.BooleanExpressionParser;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import net.Indyuce.mmocore.comp.mythicmobs.MythicHook;
|
||||
import net.Indyuce.mmocore.skill.ClassSkill;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import javax.script.ScriptException;
|
||||
import java.util.List;
|
||||
|
||||
public class SkillSlot {
|
||||
@ -49,8 +50,9 @@ public class SkillSlot {
|
||||
public Material getItem() {
|
||||
return item;
|
||||
}
|
||||
public boolean hasItem(){
|
||||
return item!=null;
|
||||
|
||||
public boolean hasItem() {
|
||||
return item != null;
|
||||
}
|
||||
|
||||
public int getModelData() {
|
||||
@ -58,6 +60,16 @@ public class SkillSlot {
|
||||
}
|
||||
|
||||
public boolean canPlaceSkill(ClassSkill classSkill) {
|
||||
return new BooleanExpressionParser(expression).parse(classSkill.getSkill().getCategories());
|
||||
|
||||
String parsedExpression = expression;
|
||||
for (String category : classSkill.getSkill().getCategories())
|
||||
parsedExpression = parsedExpression.replace("<" + category + ">", "true");
|
||||
parsedExpression = parsedExpression.replaceAll("<.*>", "false");
|
||||
try {
|
||||
boolean res = (boolean) MythicLib.plugin.getScriptEngine().eval(parsedExpression);
|
||||
return res;
|
||||
} catch (ScriptException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import io.lumine.mythic.lib.api.item.ItemTag;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.player.profess.skillbinding.SkillSlot;
|
||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||
import net.Indyuce.mmocore.gui.api.EditableInventory;
|
||||
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
|
||||
@ -28,8 +29,9 @@ import org.bukkit.inventory.meta.ItemMeta;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SkillList extends EditableInventory {
|
||||
public class SkillList extends EditableInventory {
|
||||
public SkillList() {
|
||||
super("skill-list");
|
||||
}
|
||||
@ -65,25 +67,39 @@ public class SkillList extends EditableInventory {
|
||||
return new SlotItem(config) {
|
||||
@Override
|
||||
public ItemStack display(SkillViewerInventory inv, int n) {
|
||||
if (n >= inv.getPlayerData().getSkillSlotLimit()) {
|
||||
if (!inv.getPlayerData().getProfess().hasSlot(n)) {
|
||||
return new ItemStack(Material.AIR);
|
||||
}
|
||||
SkillSlot skillSlot = inv.getPlayerData().getProfess().getSkillSlot(n);
|
||||
ItemStack item = super.display(inv, n);
|
||||
if (!inv.getPlayerData().hasSkillBound(n)) {
|
||||
item.setType(super.emptyMaterial);
|
||||
|
||||
//If there is an item filled in the slot config it shows it, else shows the default item.
|
||||
Material material = skillSlot.hasItem() ? skillSlot.getItem() : super.emptyMaterial;
|
||||
int customModelData = skillSlot.hasItem() ? skillSlot.getModelData() : super.emptyCMD;
|
||||
item.setType(material);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
meta.setDisplayName(MMOCore.plugin.placeholderParser.parse(inv.getPlayerData().getPlayer(),skillSlot.getName()));
|
||||
List<String> lore=skillSlot.getLore()
|
||||
.stream()
|
||||
.map(str->MMOCore.plugin.placeholderParser.parse(inv.getPlayerData().getPlayer(),str))
|
||||
.collect(Collectors.toList());
|
||||
meta.setLore(lore);
|
||||
if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 13)) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
meta.setCustomModelData(super.emptyCMD);
|
||||
item.setItemMeta(meta);
|
||||
meta.setCustomModelData(customModelData);
|
||||
}
|
||||
item.setItemMeta(meta);
|
||||
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* This should only be called when there is a skill bound.
|
||||
*/
|
||||
@Override
|
||||
public Placeholders getPlaceholders(SkillViewerInventory inv, int n) {
|
||||
Placeholders holders= super.getPlaceholders(inv, 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());
|
||||
@ -297,8 +313,7 @@ public class SkillList extends EditableInventory {
|
||||
// Cached information
|
||||
private final List<ClassSkill> skills;
|
||||
private final List<Integer> skillSlots;
|
||||
private final List<Integer> activeSlotSlots;
|
||||
private final List<Integer> passiveSlotSlots;
|
||||
private final List<Integer> slotSlots;
|
||||
|
||||
//The skill the player Selected
|
||||
private ClassSkill selected;
|
||||
@ -309,9 +324,8 @@ public class SkillList extends EditableInventory {
|
||||
|
||||
skills = new ArrayList<>(playerData.getProfess().getSkills());
|
||||
skillSlots = getEditable().getByFunction("skill").getSlots();
|
||||
Validate.notNull(getEditable().getByFunction("active-slot"), "Your skill GUI config file is out-of-date, please regenerate it.");
|
||||
activeSlotSlots = getEditable().getByFunction("active-slot").getSlots();
|
||||
passiveSlotSlots = getEditable().getByFunction("passive-slot").getSlots();
|
||||
Validate.notNull(getEditable().getByFunction("slot"), "Your skill GUI config file is out-of-date, please regenerate it.");
|
||||
slotSlots = getEditable().getByFunction("slot").getSlots();
|
||||
selected = skills.get(page * skillSlots.size());
|
||||
}
|
||||
|
||||
@ -379,9 +393,9 @@ public class SkillList extends EditableInventory {
|
||||
/*
|
||||
* binding or unbinding skills.
|
||||
*/
|
||||
if (item.getFunction().equals("active-slot")) {
|
||||
int index = activeSlotSlots.indexOf(context.getSlot());
|
||||
|
||||
if (item.getFunction().equals("slot")) {
|
||||
int index = slotSlots.indexOf(context.getSlot());
|
||||
SkillSlot skillSlot=playerData.getProfess().getSkillSlot(index);
|
||||
// unbind if there is a current spell.
|
||||
if (context.getClickType() == ClickType.RIGHT) {
|
||||
if (!playerData.hasSkillBound(index)) {
|
||||
@ -404,6 +418,13 @@ public class SkillList extends EditableInventory {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!skillSlot.canPlaceSkill(selected)){
|
||||
MMOCore.plugin.configManager.getSimpleMessage("not-compatible-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.bindSkill(index, selected);
|
||||
open();
|
||||
|
@ -199,6 +199,7 @@ not-enough-skill-points-shift: '&cYou need {shift_points} skill points.'
|
||||
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-compatible-skill: '&cThe selected skill is not compatible with this slot.'
|
||||
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.'
|
||||
|
Loading…
Reference in New Issue
Block a user