Added a player message when trying to cast a locked skill

Fixed players being able to bind locked skills
This commit is contained in:
Indyuce 2020-05-02 14:05:06 +02:00
parent 726d21cc7f
commit b1bead79bb
12 changed files with 105 additions and 77 deletions

View File

@ -572,22 +572,23 @@ public class PlayerData extends OfflinePlayerData {
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(message));
}
@Deprecated
public void setAttribute(PlayerAttribute attribute, int value) {
setAttribute(attribute.getId(), value);
}
@Deprecated
public void setAttribute(String id, int value) {
attributes.setBaseAttribute(id, value);
}
public void clearAttributePoints() {
attributes.getAttributeInstances().forEach(ins -> ins.setBase(0));
@Deprecated
public Map<String, Integer> mapAttributePoints() {
return getAttributes().mapPoints();
}
public Map<String, Integer> mapAttributePoints() {
Map<String, Integer> ap = new HashMap<String, Integer>();
attributes.getAttributeInstances().forEach(ins -> ap.put(ins.getId(), ins.getBase()));
return ap;
public int getSkillLevel(Skill skill) {
return skills.getOrDefault(skill.getId(), 1);
}
public void setSkillLevel(Skill skill, int level) {
@ -598,26 +599,32 @@ public class PlayerData extends OfflinePlayerData {
skills.put(skill, level);
}
public void lockSkill(Skill skill) {
skills.remove(skill.getId());
public void resetSkillLevel(String skill) {
skills.remove(skill);
}
/*
* better use getProfess().findSkill(skill).isPresent()
*/
@Deprecated
public boolean hasSkillUnlocked(Skill skill) {
return skills.containsKey(skill.getId());
return getProfess().hasSkill(skill.getId()) && hasSkillUnlocked(getProfess().getSkill(skill.getId()));
}
public int getSkillLevel(Skill skill) {
return skills.containsKey(skill.getId()) ? skills.get(skill.getId()) : 1;
/*
* (bug fix) any skill, when the player has the right level is instantly
* unlocked, therefore one must NOT check if the player has unlocked the
* skill by checking if the skills map contains the skill id as key. this
* only checks if the player has spent any skill point.
*/
public boolean hasSkillUnlocked(SkillInfo info) {
return getLevel() >= info.getUnlockLevel();
}
public Map<String, Integer> mapSkillLevels() {
return new HashMap<>(skills);
}
public void clearSkillLevels() {
skills.clear();
}
public void giveClassPoints(int value) {
setClassPoints(classPoints + value);
}
@ -713,6 +720,9 @@ public class PlayerData extends OfflinePlayerData {
SkillResult cast = skill.getSkill().whenCast(this, skill);
if (!cast.isSuccessful()) {
if (!skill.getSkill().isPassive()) {
if (cast.getCancelReason() == CancelReason.LOCKED)
MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player);
if (cast.getCancelReason() == CancelReason.MANA)
MMOCore.plugin.configManager.getSimpleMessage("casting.no-mana").send(player);

View File

@ -22,7 +22,7 @@ import net.mmogroup.mmolib.api.stat.modifier.StatModifier;
public class PlayerAttributes {
private final PlayerData data;
private final Map<String, AttributeInstance> extra = new HashMap<>();
private final Map<String, AttributeInstance> instances = new HashMap<>();
public PlayerAttributes(PlayerData data) {
this.data = data;
@ -37,19 +37,19 @@ public class PlayerAttributes {
PlayerAttribute attribute = MMOCore.plugin.attributeManager.get(id);
AttributeInstance ins = new AttributeInstance(attribute);
ins.setBase(config.getInt(key));
extra.put(id, ins);
instances.put(id, ins);
} catch (IllegalArgumentException exception) {
data.log(Level.WARNING, exception.getMessage());
}
}
public void save(ConfigurationSection config) {
extra.values().forEach(ins -> config.set(ins.id, ins.getBase()));
instances.values().forEach(ins -> config.set(ins.id, ins.getBase()));
}
public String toJsonString() {
JsonObject json = new JsonObject();
for (AttributeInstance ins : extra.values())
for (AttributeInstance ins : instances.values())
json.addProperty(ins.getId(), ins.getBase());
return json.toString();
}
@ -65,7 +65,7 @@ public class PlayerAttributes {
PlayerAttribute attribute = MMOCore.plugin.attributeManager.get(id);
AttributeInstance ins = new AttributeInstance(attribute);
ins.setBase(entry.getValue().getAsInt());
extra.put(id, ins);
instances.put(id, ins);
} catch (IllegalArgumentException exception) {
data.log(Level.WARNING, exception.getMessage());
}
@ -80,22 +80,28 @@ public class PlayerAttributes {
return getInstance(attribute).getTotal();
}
public Collection<AttributeInstance> getAttributeInstances() {
return extra.values();
public Collection<AttributeInstance> getInstances() {
return instances.values();
}
public Map<String, Integer> mapPoints() {
Map<String, Integer> map = new HashMap<>();
instances.values().forEach(ins -> map.put(ins.id, ins.spent));
return map;
}
public AttributeInstance getInstance(PlayerAttribute attribute) {
if (extra.containsKey(attribute.getId()))
return extra.get(attribute.getId());
if (instances.containsKey(attribute.getId()))
return instances.get(attribute.getId());
AttributeInstance ins = new AttributeInstance(attribute);
extra.put(attribute.getId(), ins);
instances.put(attribute.getId(), ins);
return ins;
}
public int countSkillPoints() {
int n = 0;
for (AttributeInstance ins : extra.values())
for (AttributeInstance ins : instances.values())
n += ins.getBase();
return n;
}
@ -129,7 +135,7 @@ public class PlayerAttributes {
* and relative attributes which add X% and which must be applied
* afterwards 2) the 'd' parameter lets you choose if the relative
* attributes also apply on the base stat, or if they only apply on the
* extra stat value
* instances stat value
*/
public int getTotal() {
double d = spent;
@ -197,7 +203,7 @@ public class PlayerAttributes {
}
public void setBaseAttribute(String id, int value) {
getAttributeInstances().forEach(ins -> {
getInstances().forEach(ins -> {
if (ins.getId().equals(id))
ins.setBase(value);
});

View File

@ -7,6 +7,7 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
@ -274,8 +275,16 @@ public class PlayerClass extends PostLoadObject {
return getSkill(skill.getId());
}
/*
* reduces map checkups when skills are being checked on events that are
* commonly called like EntityDamageEvent or regen events.
*/
public Optional<SkillInfo> findSkill(Skill skill) {
return skills.containsKey(skill.getId()) ? Optional.of(skills.get(skill.getId())) : Optional.empty();
}
public SkillInfo getSkill(String id) {
return skills.get(id.toUpperCase());
return skills.get(id);
}
public Set<String> getEventTriggers() {

View File

@ -43,21 +43,21 @@ public class SavedClassInformation {
attributes = new HashMap<>();
if (json.has("attribute"))
for(Entry<String, JsonElement> entry : json.getAsJsonObject("attribute").entrySet())
for (Entry<String, JsonElement> entry : json.getAsJsonObject("attribute").entrySet())
attributes.put(entry.getKey(), entry.getValue().getAsInt());
skills = new HashMap<>();
if (json.has("skill"))
for(Entry<String, JsonElement> entry : json.getAsJsonObject("skill").entrySet())
for (Entry<String, JsonElement> entry : json.getAsJsonObject("skill").entrySet())
skills.put(entry.getKey(), entry.getValue().getAsInt());
}
public SavedClassInformation(PlayerData player) {
level = player.getLevel();
skillPoints = player.getSkillPoints();
experience = player.getExperience();
skills = player.mapSkillLevels();
attributes = player.mapAttributePoints();
attributes = player.getAttributes().mapPoints();
attributePoints = player.getAttributePoints();
attributeReallocationPoints = player.getAttributeReallocationPoints();
}
@ -91,7 +91,7 @@ public class SavedClassInformation {
public int getAttributeReallocationPoints() {
return attributeReallocationPoints;
}
public Set<String> getSkillKeys() {
return skills.keySet();
}
@ -112,7 +112,6 @@ public class SavedClassInformation {
skills.put(attribute, level);
}
public Set<String> getAttributeKeys() {
return attributes.keySet();
}
@ -145,11 +144,11 @@ public class SavedClassInformation {
/*
* resets information which much be reset after everything is saved.
*/
player.clearSkillLevels();
player.mapSkillLevels().forEach((skill, level) -> player.resetSkillLevel(skill));
while (player.hasSkillBound(0))
player.unbindSkill(0);
player.clearAttributePoints();
player.getAttributes().getInstances().forEach(ins -> ins.setBase(0));
/*
* reads this class info, applies it to the player. set class after
* changing level so the player stats can be calculated based on new
@ -160,8 +159,8 @@ public class SavedClassInformation {
player.setSkillPoints(skillPoints);
player.setAttributePoints(attributePoints);
player.setAttributeReallocationPoints(attributeReallocationPoints);
skills.keySet().forEach(id -> player.setSkillLevel(id, skills.get(id)));
attributes.keySet().forEach(id -> player.setAttribute(id, attributes.get(id)));
skills.forEach((id, level) -> player.setSkillLevel(id, level));
attributes.forEach((id, pts) -> player.getAttributes().setBaseAttribute(id, pts));
/*
* unload current class information and set the new profess once

View File

@ -194,10 +194,6 @@ public abstract class Skill {
return modifiers.get(modifier).calculate(level);
}
public boolean isUnlocked(PlayerData profess) {
return profess.getLevel() >= level;
}
public List<String> calculateLore(PlayerData data) {
return calculateLore(data, data.getSkillLevel(skill));
}

View File

@ -16,7 +16,7 @@ public class SkillResult {
level = data.getSkillLevel(skill.getSkill());
cooldown = (skill.getSkill().hasModifier("cooldown") ? data.getSkillData().getCooldown(skill) : 0);
mana = (skill.getSkill().hasModifier("mana") ? skill.getModifier("mana", level) : 0);
cancelReason = !data.hasSkillUnlocked(skill.getSkill()) ? CancelReason.LOCKED
cancelReason = !data.hasSkillUnlocked(skill) ? CancelReason.LOCKED
: cooldown > 0 ? CancelReason.COOLDOWN : mana > data.getMana() ? CancelReason.MANA : null;
}

View File

@ -16,14 +16,17 @@ public class TargetSkillResult extends SkillResult {
super(data, skill);
if (isSuccessful()) {
MMORayTraceResult result = MMOLib.plugin.getVersion().getWrapper().rayTrace(data.getPlayer(), range, entity -> MMOCoreUtils.canTarget(data, entity));
MMORayTraceResult result = MMOLib.plugin.getVersion().getWrapper().rayTrace(data.getPlayer(), range,
entity -> MMOCoreUtils.canTarget(data, entity));
if (!result.hasHit())
abort(CancelReason.OTHER);
abort();
else
target = (LivingEntity) result.getHit();
}
}
// check skill result abort reason instead
@Deprecated
public boolean hasTarget() {
return target != null;
}

View File

@ -8,7 +8,6 @@ import org.bukkit.entity.Player;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.experience.Profession;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes.AttributeInstance;
import net.Indyuce.mmocore.command.api.CommandEnd;
import net.Indyuce.mmocore.command.api.CommandMap;
@ -61,10 +60,9 @@ public class ResetCommandMap extends CommandMap {
data.setAttributePoints(0);
data.setAttributeReallocationPoints(0);
for (PlayerAttribute att : MMOCore.plugin.attributeManager.getAll())
data.setAttribute(att, 0);
data.getAttributes().getInstances().forEach(ins -> ins.setBase(0));
MMOCore.plugin.skillManager.getAll().forEach(skill -> data.lockSkill(skill));
data.mapSkillLevels().forEach((skill, level) -> data.resetSkillLevel(skill));
while (data.hasSkillBound(0))
data.unbindSkill(0);
data.getQuestData().resetFinishedQuests();
@ -144,7 +142,7 @@ public class ResetCommandMap extends CommandMap {
}
PlayerData data = PlayerData.get(player);
MMOCore.plugin.skillManager.getAll().forEach(skill -> data.lockSkill(skill));
data.mapSkillLevels().forEach((skill, level) -> data.resetSkillLevel(skill));
while (data.hasSkillBound(0))
data.unbindSkill(0);
sender.sendMessage(ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s skill data was succesfully reset.");
@ -179,7 +177,7 @@ public class ResetCommandMap extends CommandMap {
if (args.length > 4 && args[4].equalsIgnoreCase("-reallocate")) {
int points = 0;
for (AttributeInstance ins : data.getAttributes().getAttributeInstances()) {
for (AttributeInstance ins : data.getAttributes().getInstances()) {
points += ins.getBase();
ins.setBase(0);
}
@ -189,8 +187,7 @@ public class ResetCommandMap extends CommandMap {
return CommandResult.SUCCESS;
}
for (PlayerAttribute att : MMOCore.plugin.attributeManager.getAll())
data.setAttribute(att, 0);
data.getAttributes().getInstances().forEach(ins -> ins.setBase(0));
sender.sendMessage(ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s attributes were succesfully reset.");
return CommandResult.SUCCESS;
}

View File

@ -101,7 +101,7 @@ public class AttributeView extends EditableInventory {
return;
}
playerData.getAttributes().getAttributeInstances().forEach(ins -> ins.setBase(0));
playerData.getAttributes().getInstances().forEach(ins -> ins.setBase(0));
playerData.giveAttributePoints(spent);
playerData.giveAttributeReallocationPoints(-1);
MMOCore.plugin.configManager.getSimpleMessage("attribute-points-reallocated", "points", "" + playerData.getAttributePoints()).send(player);

View File

@ -71,7 +71,8 @@ public class SkillList extends EditableInventory {
if (function.equals("slot"))
return new InventoryPlaceholderItem(config) {
private final String none = ChatColor.translateAlternateColorCodes('&', config.getString("no-skill"));
private final Material emptyMaterial = Material.valueOf(config.getString("empty-item").toUpperCase().replace("-", "_").replace(" ", "_"));
private final Material emptyMaterial = Material
.valueOf(config.getString("empty-item").toUpperCase().replace("-", "_").replace(" ", "_"));
@Override
public Placeholders getPlaceholders(PluginInventory inv, int n) {
@ -172,7 +173,8 @@ public class SkillList extends EditableInventory {
ItemStack item = cloneItem();
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', getName().replace("{skill}", skill.getSkill().getName()).replace("{roman}", MMOCoreUtils.intToRoman(skillLevel)).replace("{level}", "" + skillLevel)));
meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', getName().replace("{skill}", skill.getSkill().getName())
.replace("{roman}", MMOCoreUtils.intToRoman(skillLevel)).replace("{level}", "" + skillLevel)));
meta.addItemFlags(ItemFlag.values());
meta.setLore(lore);
item.setItemMeta(meta);
@ -227,7 +229,8 @@ public class SkillList extends EditableInventory {
for (Iterator<String> iterator = lore.iterator(); iterator.hasNext();) {
String next = iterator.next();
if ((next.startsWith("{unlocked}") && !unlocked) || (next.startsWith("{locked}") && unlocked) || (next.startsWith("{max_level}") && (!skill.hasMaxLevel() || skill.getMaxLevel() > inv.getPlayerData().getSkillLevel(skill.getSkill()))))
if ((next.startsWith("{unlocked}") && !unlocked) || (next.startsWith("{locked}") && unlocked) || (next.startsWith("{max_level}")
&& (!skill.hasMaxLevel() || skill.getMaxLevel() > inv.getPlayerData().getSkillLevel(skill.getSkill()))))
iterator.remove();
}
@ -297,7 +300,8 @@ public class SkillList extends EditableInventory {
@Override
public void whenClicked(InventoryClickEvent event, InventoryItem item) {
if (skillSlots.contains(event.getRawSlot()) && event.getRawSlot() != ((SkillItem) getEditable().getByFunction("skill")).selectedSkillSlot) {
if (skillSlots.contains(event.getRawSlot())
&& event.getRawSlot() != ((SkillItem) getEditable().getByFunction("skill")).selectedSkillSlot) {
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2);
playerData.skillGuiDisplayOffset = (playerData.skillGuiDisplayOffset + (event.getRawSlot() - 13)) % skills.size();
open();
@ -356,20 +360,12 @@ public class SkillList extends EditableInventory {
return;
}
if (!selected.isUnlocked(playerData)) {
if (!playerData.hasSkillUnlocked(selected)) {
MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player);
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
return;
}
// if (playerData.getSkillLevel(selected.getSkill()) <
// 1) {
// player.sendMessage(MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill"));
// player.playSound(player.getLocation(),
// Sound.ENTITY_VILLAGER_NO, 1, 2);
// return;
// }
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2);
playerData.setBoundSkill(index, selected);
open();
@ -381,7 +377,7 @@ public class SkillList extends EditableInventory {
* upgrading a player skill
*/
} else if (item.getFunction().equals("upgrade")) {
if (!selected.isUnlocked(playerData)) {
if (!playerData.hasSkillUnlocked(selected)) {
MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player);
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
return;
@ -401,7 +397,8 @@ public class SkillList extends EditableInventory {
playerData.giveSkillPoints(-1);
playerData.setSkillLevel(selected.getSkill(), playerData.getSkillLevel(selected.getSkill()) + 1);
MMOCore.plugin.configManager.getSimpleMessage("upgrade-skill", "skill", selected.getSkill().getName(), "level", "" + playerData.getSkillLevel(selected.getSkill())).send(player);
MMOCore.plugin.configManager.getSimpleMessage("upgrade-skill", "skill", selected.getSkill().getName(), "level",
"" + playerData.getSkillLevel(selected.getSkill())).send(player);
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2);
open();
}

View File

@ -1,8 +1,11 @@
package net.Indyuce.mmocore.skill;
import java.util.Optional;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import net.Indyuce.mmocore.MMOCore;
@ -25,10 +28,13 @@ public class Fire_Berserker extends Skill implements Listener {
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
}
@EventHandler
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void a(PlayerAttackEvent event) {
PlayerData data = event.getData().getMMOCore();
if (event.getPlayer().getFireTicks() > 0 && data.hasSkillUnlocked(this))
event.getAttack().multiplyDamage(1 + data.getProfess().getSkill(this).getModifier("extra", data.getSkillLevel(this)) / 100);
if (event.getPlayer().getFireTicks() > 0) {
Optional<SkillInfo> skill = data.getProfess().findSkill(this);
if (skill.isPresent())
event.getAttack().multiplyDamage(1 + skill.get().getModifier("extra", data.getSkillLevel(this)) / 100);
}
}
}

View File

@ -1,5 +1,7 @@
package net.Indyuce.mmocore.skill;
import java.util.Optional;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
@ -29,7 +31,10 @@ public class Neptune_Gift extends Skill implements Listener {
@EventHandler
public void a(PlayerRegenResourceEvent event) {
PlayerData data = event.getData();
if (event.getPlayer().getLocation().getBlock().getType() == Material.WATER && data.hasSkillUnlocked(this))
event.setAmount(event.getAmount() * (1 + data.getProfess().getSkill(this).getModifier("extra", data.getSkillLevel(this)) / 100));
if (event.getPlayer().getLocation().getBlock().getType() == Material.WATER) {
Optional<SkillInfo> skill = data.getProfess().findSkill(this);
if (skill.isPresent())
event.setAmount(event.getAmount() * (1 + skill.get().getModifier("extra", data.getSkillLevel(this)) / 100));
}
}
}