!AureliumSkills profession requirements

This commit is contained in:
Jules 2021-07-24 20:12:31 +02:00
parent d4cbc3d051
commit a7749365cf
10 changed files with 280 additions and 80 deletions

View File

@ -13,24 +13,25 @@ import org.bukkit.ChatColor;
import org.bukkit.Sound;
public class Required_Attribute extends DoubleStat implements ItemRestriction, GemStoneStat {
private final PlayerAttribute attribute;
private final PlayerAttribute attribute;
public Required_Attribute(PlayerAttribute attribute) {
super("REQUIRED_" + attribute.getId().toUpperCase().replace("-", "_"), VersionMaterial.GRAY_DYE.toMaterial(), attribute.getName() + " Requirement (MMOCore)", new String[] { "Amount of " + attribute.getName() + " points the", "player needs to use the item." }, new String[] { "!block", "all" });
// TODO merge with RequiredLevelStat
public Required_Attribute(PlayerAttribute attribute) {
super("REQUIRED_" + attribute.getId().toUpperCase().replace("-", "_"), VersionMaterial.GRAY_DYE.toMaterial(), attribute.getName() + " Requirement (MMOCore)", new String[]{"Amount of " + attribute.getName() + " points the", "player needs to use the item."}, new String[]{"!block", "all"});
this.attribute = attribute;
}
this.attribute = attribute;
}
@Override
public boolean canUse(RPGPlayer player, NBTItem item, boolean message) {
MMOCoreRPGPlayer mmocore = (MMOCoreRPGPlayer) player;
if (mmocore.getData().getAttributes().getAttribute(attribute) < item.getStat(getId())) {
if (message) {
Message.NOT_ENOUGH_ATTRIBUTE.format(ChatColor.RED, "#attribute#", attribute.getName()).send(player.getPlayer());
player.getPlayer().playSound(player.getPlayer().getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1.5f);
}
return false;
}
return true;
}
@Override
public boolean canUse(RPGPlayer player, NBTItem item, boolean message) {
MMOCoreRPGPlayer mmocore = (MMOCoreRPGPlayer) player;
if (mmocore.getData().getAttributes().getAttribute(attribute) < item.getStat(getId())) {
if (message) {
Message.NOT_ENOUGH_ATTRIBUTE.format(ChatColor.RED, "#attribute#", attribute.getName()).send(player.getPlayer());
player.getPlayer().playSound(player.getPlayer().getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1.5f);
}
return false;
}
return true;
}
}

View File

@ -15,8 +15,11 @@ import org.bukkit.Sound;
public class Required_Profession extends DoubleStat implements ItemRestriction, GemStoneStat {
private final Profession profession;
// TODO merge with RequiredLevelStat
public Required_Profession(Profession profession) {
super("PROFESSION_" + profession.getId().toUpperCase().replace("-", "_"), Material.PINK_DYE, profession.getName() + " Requirement (MMOCore)", new String[] { "Amount of " + profession.getName() + " levels the", "player needs to use the item." }, new String[] { "!block", "all" });
super("PROFESSION_" + profession.getId().toUpperCase().replace("-", "_"), Material.PINK_DYE, profession.getName() + " Requirement (MMOCore)",
new String[]{"Amount of " + profession.getName() + " levels the", "player needs to use the item."}, new String[]{"!block", "all"});
this.profession = profession;
}

View File

@ -1,16 +1,47 @@
package net.Indyuce.mmoitems.comp.rpg;
import com.archyx.aureliumskills.AureliumSkills;
import com.archyx.aureliumskills.api.AureliumAPI;
import com.archyx.aureliumskills.api.event.SkillLevelUpEvent;
import com.archyx.aureliumskills.data.PlayerDataLoadEvent;
import com.archyx.aureliumskills.skills.Skill;
import com.archyx.aureliumskills.stats.Stats;
import io.lumine.mythic.lib.api.item.NBTItem;
import io.lumine.mythic.lib.version.VersionMaterial;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.player.EmptyRPGPlayer;
import net.Indyuce.mmoitems.api.player.PlayerData;
import net.Indyuce.mmoitems.api.player.RPGPlayer;
import org.bukkit.OfflinePlayer;
import net.Indyuce.mmoitems.api.util.message.Message;
import net.Indyuce.mmoitems.stat.type.DoubleStat;
import net.Indyuce.mmoitems.stat.type.ItemStat;
import net.Indyuce.mmoitems.stat.type.RequiredLevelStat;
import org.bukkit.*;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import us.eunoians.mcrpg.types.Skills;
import java.util.Locale;
public class AureliumSkillsHook implements RPGHandler, Listener {
private final AureliumSkills aSkills;
private static final ItemStat WISDOM = new DoubleStat("WISDOM", Material.BOOK,
"Additional Wisdom",
new String[]{"Additional wisdom (AureliumSkills)"},
new String[]{"!miscellaneous", "!block", "all"});
public AureliumSkillsHook() {
aSkills = (AureliumSkills) Bukkit.getPluginManager().getPlugin("AureliumSkills");
// Register wisdom for the max mana stat
MMOItems.plugin.getStats().register(WISDOM);
// Register stat for required professions
for (Skills skill : Skills.values())
MMOItems.plugin.getStats().register(new RequiredProfessionStat(skill));
}
@EventHandler
public void a(SkillLevelUpEvent event) {
@ -21,6 +52,7 @@ public class AureliumSkillsHook implements RPGHandler, Listener {
@Override
public void refreshStats(PlayerData data) {
AureliumAPI.addStatModifier(data.getPlayer(), "mmoitems", Stats.WISDOM, data.getStats().getStat(WISDOM));
}
@Override
@ -42,7 +74,7 @@ public class AureliumSkillsHook implements RPGHandler, Listener {
playerData.setRPGPlayer(new AureliumSkillsPlayer(playerData, event.getPlayerData()));
}
public static class AureliumSkillsPlayer extends RPGPlayer {
public class AureliumSkillsPlayer extends RPGPlayer {
private final com.archyx.aureliumskills.data.PlayerData info;
public AureliumSkillsPlayer(PlayerData playerData, com.archyx.aureliumskills.data.PlayerData rpgPlayerData) {
@ -51,6 +83,10 @@ public class AureliumSkillsHook implements RPGHandler, Listener {
info = rpgPlayerData;
}
public com.archyx.aureliumskills.data.PlayerData getAureliumSkillsPlayerData() {
return info;
}
@Override
public int getLevel() {
return info.getPowerLevel();
@ -81,4 +117,31 @@ public class AureliumSkillsHook implements RPGHandler, Listener {
getPlayer().setFoodLevel((int) value);
}
}
public class RequiredProfessionStat extends RequiredLevelStat {
private final Skill skill;
public RequiredProfessionStat(Skills skill) {
super(skill.name(), VersionMaterial.EXPERIENCE_BOTTLE.toMaterial(), skill.getName(),
new String[]{"Amount of " + skill.getName() + " levels the", "player needs to use the item."});
this.skill = aSkills.getSkillRegistry().getSkill(skill.name());
}
@Override
public boolean canUse(RPGPlayer player, NBTItem item, boolean message) {
int skillLevel = ((AureliumSkillsPlayer) player).info.getSkillLevel(skill);
int required = item.getInteger("MMOITEMS_REQUIRED_" + skill.name());
if (skillLevel < required && !player.getPlayer().hasPermission("mmoitems.bypass.level")) {
if (message) {
Message.NOT_ENOUGH_PROFESSION.format(ChatColor.RED, "profession", skill.getDisplayName(Locale.getDefault())).send(player.getPlayer());
player.getPlayer().playSound(player.getPlayer().getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1.5f);
}
return false;
}
return false;
}
}
}

View File

@ -5,38 +5,47 @@ import net.Indyuce.mmoitems.stat.data.type.StatData;
import org.apache.commons.lang.Validate;
import org.jetbrains.annotations.NotNull;
/**
* When a gem stone is applied onto an item with a lower level
* requirement, the new item must save the HIGHEST level requirement
* of the two so that newbies cannot use over powered items.
* <p>
* Hence the need to create a RequiredLevelData for that custom merge function.
* <p>
* Used by the 'required level' item stat as well as the 'required profession'
* stats for both MMOCore and AureliumSkills
*/
public class RequiredLevelData extends DoubleData {
public RequiredLevelData(double value) {
super(value);
}
public RequiredLevelData(double value) {
super(value);
}
/*
* when a gem stone is applied on an item with a lower level requirement,
* the item must save the HIGHEST level requirement so that newbies cannot
* use over powered items
*/
@Override
public void merge(StatData data) {
Validate.isTrue(data instanceof RequiredLevelData, "Cannot merge two different stat data types");
boolean additiveMerge = MMOItems.plugin.getConfig().getBoolean("stat-merging.additive-levels", false);
@Override
public void merge(StatData data) {
Validate.isTrue(data instanceof RequiredLevelData, "Cannot merge two different stat data types");
boolean additiveMerge = MMOItems.plugin.getConfig().getBoolean("stat-merging.additive-levels", false);
// Adding up
if (additiveMerge) {
// Adding up
if (additiveMerge) {
// Additive
setValue(((RequiredLevelData) data).getValue() + getValue());
// Additive
setValue(((RequiredLevelData) data).getValue() + getValue());
} else {
} else {
// Max Level
setValue(Math.max(((RequiredLevelData) data).getValue(), getValue()));
}
}
// Max Level
setValue(Math.max(((RequiredLevelData) data).getValue(), getValue()));
}
}
@Override
public @NotNull
StatData cloneData() { return new RequiredLevelData(getValue()); }
@Override
public @NotNull
StatData cloneData() {
return new RequiredLevelData(getValue());
}
@Override
public String toString() { return String.valueOf(getValue()); }
@Override
public String toString() {
return String.valueOf(getValue());
}
}

View File

@ -5,17 +5,21 @@ import net.Indyuce.mmoitems.api.util.NumericStatFormula;
import net.Indyuce.mmoitems.stat.data.RequiredLevelData;
import net.Indyuce.mmoitems.stat.data.type.StatData;
/**
* Used by the item level restriction as well as attribute
* and profession item requirements for MMOCore and AureliumSkills
*/
public class RandomRequiredLevelData extends NumericStatFormula {
public RandomRequiredLevelData(Object object) {
super(object);
}
public RandomRequiredLevelData(Object object) {
super(object);
}
public RandomRequiredLevelData(double base, double scale, double spread, double maxSpread) {
super(base, scale, spread, maxSpread);
}
public RandomRequiredLevelData(double base, double scale, double spread, double maxSpread) {
super(base, scale, spread, maxSpread);
}
@Override
public StatData randomize(MMOItemBuilder builder) {
return new RequiredLevelData(calculate(builder.getLevel()));
}
@Override
public StatData randomize(MMOItemBuilder builder) {
return new RequiredLevelData(calculate(builder.getLevel()));
}
}

View File

@ -4,12 +4,7 @@ package net.Indyuce.mmoitems.stat.type;
* Statistics which must NOT be applied onto an item when socketing the gem
* stone. For instance, 'Success Rate' is a gem stone stat but it must not be
* transferred onto the item.
*
*
* @author indyuce
*/
public interface GemStoneStat {
/*
* No method is required.
*/
}
public interface GemStoneStat { }

View File

@ -1,15 +1,5 @@
package net.Indyuce.mmoitems.stat.type;
import java.util.List;
import java.util.Optional;
import org.bukkit.Material;
import org.bukkit.event.inventory.InventoryClickEvent;
import net.Indyuce.mmoitems.gui.edition.EditionInventory;
import net.Indyuce.mmoitems.stat.data.random.RandomStatData;
import org.jetbrains.annotations.NotNull;
/**
* Internal stats can be used to store specific item data and cannot be
* edited in the item edition GUI since they only exist once the item is

View File

@ -24,7 +24,7 @@ public interface ItemRestriction {
* internally needs some similar check)
* @return False if the item cannot be used
*/
boolean canUse(RPGPlayer/**/ player, NBTItem item, boolean message);
boolean canUse(RPGPlayer player, NBTItem item, boolean message);
/**
* Usually, item restrictions are checked <i>when equipping</i>

View File

@ -0,0 +1,136 @@
package net.Indyuce.mmoitems.stat.type;
import io.lumine.mythic.lib.api.item.ItemTag;
import io.lumine.mythic.lib.api.item.SupportedNBTTagValues;
import io.lumine.mythic.lib.api.util.ui.SilentNumbers;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder;
import net.Indyuce.mmoitems.api.item.mmoitem.ReadMMOItem;
import net.Indyuce.mmoitems.api.util.NumericStatFormula;
import net.Indyuce.mmoitems.stat.data.DoubleData;
import net.Indyuce.mmoitems.stat.data.RequiredLevelData;
import net.Indyuce.mmoitems.stat.data.random.RandomRequiredLevelData;
import net.Indyuce.mmoitems.stat.data.random.RandomStatData;
import net.Indyuce.mmoitems.stat.data.type.StatData;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
/**
* Used by {@link net.Indyuce.mmoitems.comp.rpg.AureliumSkillsHook} to handle
* required skill levels.
*/
public abstract class RequiredLevelStat extends DoubleStat implements ItemRestriction, GemStoneStat {
private final String idKey;
public RequiredLevelStat(String idKey, Material mat, String nameKey, String[] lore) {
super("REQUIRED_" + idKey,
mat,
"Required " + nameKey,
lore,
new String[]{"!block", "all"});
this.idKey = idKey;
}
@Override
public void whenApplied(@NotNull ItemStackBuilder item, @NotNull StatData data) {
// Lore Management
int lvl = (int) ((DoubleData) data).getValue();
String format = MMOItems.plugin.getLanguage().getStatFormat(getPath()).replace("#", "" + lvl);
item.getLore().insert(getPath(), format);
// Insert NBT
item.addItemTag(new ItemTag(getNBTPath(), lvl));
}
@Override
public void whenPreviewed(@NotNull ItemStackBuilder item, @NotNull StatData currentData, @NotNull RandomStatData templateData) throws IllegalArgumentException {
Validate.isTrue(currentData instanceof DoubleData, "Current Data is not Double Data");
Validate.isTrue(templateData instanceof NumericStatFormula, "Template Data is not Numeric Stat Formula");
// Get Value
double techMinimum = ((NumericStatFormula) templateData).calculate(0, -2.5);
double techMaximum = ((NumericStatFormula) templateData).calculate(0, 2.5);
// Cancel if it its NEGATIVE and this doesn't support negative stats.
if (techMaximum < 0 && !handleNegativeStats()) {
return;
}
if (techMinimum < 0 && !handleNegativeStats()) {
techMinimum = 0;
}
if (techMinimum < ((NumericStatFormula) templateData).getBase() - ((NumericStatFormula) templateData).getMaxSpread()) {
techMinimum = ((NumericStatFormula) templateData).getBase() - ((NumericStatFormula) templateData).getMaxSpread();
}
if (techMaximum > ((NumericStatFormula) templateData).getBase() + ((NumericStatFormula) templateData).getMaxSpread()) {
techMaximum = ((NumericStatFormula) templateData).getBase() + ((NumericStatFormula) templateData).getMaxSpread();
}
// Add NBT Path
item.addItemTag(getAppliedNBT(currentData));
// Display if not ZERO
if (techMinimum != 0 || techMaximum != 0) {
String builtRange;
if (SilentNumbers.round(techMinimum, 2) == SilentNumbers.round(techMaximum, 2)) {
builtRange = SilentNumbers.readableRounding(techMinimum, 0);
} else {
builtRange = SilentNumbers.removeDecimalZeros(String.valueOf(techMinimum)) + "-" + SilentNumbers.removeDecimalZeros(String.valueOf(techMaximum));
}
// Just display normally
item.getLore().insert(getPath(), formatNumericStat(techMinimum, "#", builtRange));
}
}
@NotNull
@Override
public ArrayList<ItemTag> getAppliedNBT(@NotNull StatData data) {
ArrayList<ItemTag> ret = new ArrayList<>();
ret.add(new ItemTag(getNBTPath(), ((DoubleData) data).getValue()));
return ret;
}
@Override
public RandomStatData whenInitialized(Object object) {
return new RandomRequiredLevelData(object);
}
@Override
public void whenLoaded(@NotNull ReadMMOItem mmoitem) {
// Find relevat tgs
ArrayList<ItemTag> tags = new ArrayList<>();
if (mmoitem.getNBT().hasTag(getNBTPath()))
tags.add(ItemTag.getTagAtPath(getNBTPath(), mmoitem.getNBT(), SupportedNBTTagValues.DOUBLE));
// Build
StatData data = getLoadedNBT(tags);
// Valid?
if (data != null)
mmoitem.setData(this, data);
}
@Nullable
@Override
public StatData getLoadedNBT(@NotNull ArrayList<ItemTag> storedTags) {
ItemTag rTag = ItemTag.getTagAtPath(getNBTPath(), storedTags);
if (rTag != null)
return new RequiredLevelData((Double) rTag.getValue());
return null;
}
@Override
public @NotNull
StatData getClearStatData() {
return new RequiredLevelData(0D);
}
}

View File

@ -11,15 +11,14 @@ import org.jetbrains.annotations.Nullable;
* The methods required for this ItemStat to be Upgradeable. <p></p>
* <b>It makes sense then that the <code>StatData</code> this uses
* implements {@link Mergeable}</b> and it is even assumed so.
*
* An upgradable stat can be used in an upgrade template to be upgraded
*
* TODO add abilities so that ability damage, effect duration etc. can
* increase as well when upgrading an item.
*/
public interface Upgradable {
/*
* an upgradable stat can be used in an upgrade template to be upgraded!
* TODO add abilities so that ability damage, effect duration etc. can
* increase when upgrading the item!
*/
/**
* When an {@link net.Indyuce.mmoitems.api.UpgradeTemplate} is read from a YML file,
* it loads each stat's {@link UpgradeInfo} through this method, passing on the