io.papermc
@@ -149,7 +143,7 @@
io.lumine
MythicLib-dist
- 1.3.1
+ 1.3.4
provided
diff --git a/src/main/java/net/Indyuce/mmocore/MMOCore.java b/src/main/java/net/Indyuce/mmocore/MMOCore.java
index 99a62ed3..57d664ce 100644
--- a/src/main/java/net/Indyuce/mmocore/MMOCore.java
+++ b/src/main/java/net/Indyuce/mmocore/MMOCore.java
@@ -2,9 +2,8 @@ package net.Indyuce.mmocore;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.UtilityMethods;
-import io.lumine.mythic.lib.comp.Metrics;
+import io.lumine.mythic.lib.metrics.bukkit.Metrics;
import io.lumine.mythic.lib.version.SpigotPlugin;
-import io.lumine.mythic.utils.plugin.LuminePlugin;
import net.Indyuce.mmocore.comp.citizens.CitizenInteractEventListener;
import net.Indyuce.mmocore.comp.citizens.CitizensMMOLoader;
import net.Indyuce.mmocore.comp.mythicmobs.MythicHook;
@@ -48,11 +47,16 @@ import net.Indyuce.mmocore.party.PartyModule;
import net.Indyuce.mmocore.party.PartyModuleType;
import net.Indyuce.mmocore.party.provided.MMOCorePartyModule;
import net.Indyuce.mmocore.skill.cast.SkillCastingMode;
+import net.Indyuce.mmocore.skill.custom.mechanic.ExperienceMechanic;
+import net.Indyuce.mmocore.skill.custom.mechanic.ManaMechanic;
+import net.Indyuce.mmocore.skill.custom.mechanic.StaminaMechanic;
+import net.Indyuce.mmocore.skill.custom.mechanic.StelliumMechanic;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandMap;
import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull;
import org.spigotmc.SpigotConfig;
@@ -61,7 +65,7 @@ import java.io.File;
import java.lang.reflect.Field;
import java.util.logging.Level;
-public class MMOCore extends LuminePlugin {
+public class MMOCore extends JavaPlugin {
public static MMOCore plugin;
public final WaypointManager waypointManager = new WaypointManager();
@@ -107,25 +111,22 @@ public class MMOCore extends LuminePlugin {
public boolean shouldDebugSQL, hasBungee;
- private static final int MYTHICLIB_COMPATIBILITY_INDEX = 7;
-
public MMOCore() {
plugin = this;
}
- public void load() {
-
- // Check if the ML build matches
- if (MYTHICLIB_COMPATIBILITY_INDEX != MythicLib.MMOCORE_COMPATIBILITY_INDEX) {
- getLogger().log(Level.WARNING, "Your versions of MythicLib and MMOCore do not match. Make sure you are using the latest builds of both plugins");
- disable();
- return;
- }
+ @Override
+ public void onLoad() {
// Register MMOCore-specific objects
MythicLib.plugin.getEntities().registerRestriction(new MMOCoreTargetRestriction());
MythicLib.plugin.getModifiers().registerModifierType("attribute", configObject -> new AttributeModifier(configObject));
+ // Skill creation
+ MythicLib.plugin.getSkills().registerMechanic("mana", config -> new ManaMechanic(config));
+ MythicLib.plugin.getSkills().registerMechanic("stamina", config -> new StaminaMechanic(config));
+ MythicLib.plugin.getSkills().registerMechanic("stellium", config -> new StelliumMechanic(config));
+ MythicLib.plugin.getSkills().registerMechanic("experience", config -> new ExperienceMechanic(config));
// Register extra objective, drop items...
if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null)
@@ -140,7 +141,8 @@ public class MMOCore extends LuminePlugin {
loadManager.registerLoader(new MythicMobsMMOLoader());
}
- public void enable() {
+ @Override
+ public void onEnable() {
new SpigotPlugin(70575, this).checkForUpdate();
new Metrics(this);
saveDefaultConfig();
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java
index 5b770865..20db1fb1 100644
--- a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java
+++ b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java
@@ -24,9 +24,12 @@ import net.Indyuce.mmocore.api.util.Closable;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
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.droptable.ExperienceItem;
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
import net.Indyuce.mmocore.guild.provided.Guild;
+import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect;
import net.Indyuce.mmocore.manager.data.mysql.MySQLTableEditor;
import net.Indyuce.mmocore.party.AbstractParty;
import net.Indyuce.mmocore.party.provided.Party;
@@ -36,9 +39,6 @@ import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.Indyuce.mmocore.skill.cast.SkillCastingHandler;
import net.Indyuce.mmocore.waypoint.Waypoint;
import net.Indyuce.mmocore.waypoint.WaypointOption;
-import net.Indyuce.mmocore.experience.ExperienceTableClaimer;
-import net.Indyuce.mmocore.experience.PlayerProfessions;
-import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent;
import org.apache.commons.lang.Validate;
@@ -589,8 +589,8 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
*
* @param value Experience to give the player
* @param source How the player earned experience
- * @param hologramLocation Location used to display the hologram. If it's null, no
- * hologram will be displayed
+ * @param hologramLocation Location used to display the hologram.
+ * If it's null, no hologram will be displayed
* @param splitExp Should the exp be split among party members
*/
public void giveExperience(double value, EXPSource source, @Nullable Location hologramLocation, boolean splitExp) {
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttributes.java b/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttributes.java
index 769e34ea..82eae2ce 100644
--- a/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttributes.java
+++ b/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttributes.java
@@ -129,17 +129,8 @@ public class PlayerAttributes {
update();
}
- /**
- * Adds X points to the base of the player attribute AND applies
- * the attribute experience table.
- *
- * @param value Amount of attribute points spent in the attribute
- */
public void addBase(int value) {
- PlayerAttribute attribute = MMOCore.plugin.attributeManager.get(id);
setBase(spent + value);
- if (attribute.hasExperienceTable())
- attribute.getExperienceTable().claim(data, spent, attribute);
}
/*
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java b/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java
index 48246532..765b54e5 100644
--- a/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java
+++ b/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java
@@ -8,9 +8,6 @@ import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.api.util.PostLoadObject;
import io.lumine.mythic.lib.version.VersionMaterial;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.experience.EXPSource;
-import net.Indyuce.mmocore.skill.list.Ambers;
-import net.Indyuce.mmocore.skill.list.Neptune_Gift;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.event.EventTrigger;
import net.Indyuce.mmocore.api.player.profess.resource.ManaDisplayOptions;
@@ -18,6 +15,7 @@ import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
import net.Indyuce.mmocore.api.player.profess.resource.ResourceRegeneration;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
+import net.Indyuce.mmocore.experience.EXPSource;
import net.Indyuce.mmocore.experience.ExpCurve;
import net.Indyuce.mmocore.experience.ExperienceObject;
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
@@ -188,11 +186,12 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
}
/**
- * Used to generate the default Human class if no one is
- * specified after loading all the player classes. This is
- * a very basic class that will make sure MMOCore can still
- * continue to run without having to stop the server because
- * some option was not provided
+ * Used to generate the default Human class if no one is specified
+ * after loading all the player classes.
+ *
+ * This is a very basic class that will make sure MMOCore can still
+ * continue to run without having to stop the server because some
+ * option was not provided.
*/
public PlayerClass(String id, String name, Material material) {
super(null);
@@ -371,19 +370,6 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
return getSkill(skill.getHandler().getId());
}
- /**
- * Reduces map checkups when skills are being checked on events that are
- * commonly called like EntityDamageEvent or regen events.
- *
- * Examples:
- * - {@link Neptune_Gift}
- * - {@link Ambers}
- */
- public Optional findSkill(RegisteredSkill skill) {
- ClassSkill found = skills.get(skill.getHandler().getId());
- return found == null ? Optional.empty() : Optional.of(found);
- }
-
@Nullable
public ClassSkill getSkill(String id) {
return skills.get(id);
@@ -404,6 +390,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
return obj instanceof PlayerClass && ((PlayerClass) obj).id.equals(id);
}
+ @Nullable
public String getActionBar() {
return actionBarFormat;
}
diff --git a/src/main/java/net/Indyuce/mmocore/api/util/MMOCoreUtils.java b/src/main/java/net/Indyuce/mmocore/api/util/MMOCoreUtils.java
index bd3b4050..2c57d437 100644
--- a/src/main/java/net/Indyuce/mmocore/api/util/MMOCoreUtils.java
+++ b/src/main/java/net/Indyuce/mmocore/api/util/MMOCoreUtils.java
@@ -3,9 +3,8 @@ package net.Indyuce.mmocore.api.util;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import io.lumine.mythic.lib.MythicLib;
+import io.lumine.mythic.lib.hologram.Hologram;
import io.lumine.mythic.lib.version.VersionMaterial;
-import io.lumine.mythic.utils.holograms.Hologram;
-import io.lumine.mythic.utils.serialize.Position;
import net.Indyuce.mmocore.MMOCore;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@@ -64,8 +63,7 @@ public class MMOCoreUtils {
* @param message Message to display
*/
public static void displayIndicator(Location loc, String message) {
- Hologram holo = Hologram.create(Position.of(loc), Arrays.asList(message));
- holo.spawn();
+ Hologram holo = Hologram.create(loc, Arrays.asList(message));
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> holo.despawn(), 20);
}
diff --git a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/CurrencyItemDrop.java b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/CurrencyItemDrop.java
index ccba02f2..4285eca5 100644
--- a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/CurrencyItemDrop.java
+++ b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/CurrencyItemDrop.java
@@ -1,17 +1,16 @@
package net.Indyuce.mmocore.comp.mythicmobs.load;
+import io.lumine.mythic.api.adapters.AbstractItemStack;
import io.lumine.mythic.api.config.MythicLineConfig;
import io.lumine.mythic.api.drops.DropMetadata;
-import io.lumine.mythic.api.drops.IMultiDrop;
+import io.lumine.mythic.api.drops.IItemDrop;
import io.lumine.mythic.bukkit.adapters.BukkitItemStack;
import io.lumine.mythic.core.drops.Drop;
-import io.lumine.mythic.core.drops.LootBag;
-import io.lumine.mythic.core.drops.droppables.ItemDrop;
import net.Indyuce.mmocore.util.item.CurrencyItemBuilder;
import java.util.Random;
-public class CurrencyItemDrop extends Drop implements IMultiDrop {
+public class CurrencyItemDrop extends Drop implements IItemDrop {
private final String key;
private final int minw;
private final int maxw;
@@ -26,12 +25,9 @@ public class CurrencyItemDrop extends Drop implements IMultiDrop {
maxw = config.getInteger("maxw", 1);
}
- @SuppressWarnings("deprecation")
@Override
- public LootBag get(DropMetadata metadata) {
- LootBag loot = new LootBag(metadata);
- loot.add(new ItemDrop(this.getLine(), this.getConfig(), new BukkitItemStack(new CurrencyItemBuilder(key, random(minw, maxw)).build())));
- return loot;
+ public AbstractItemStack getDrop(DropMetadata dropMetadata, double v) {
+ return new BukkitItemStack(new CurrencyItemBuilder(key, random(minw, maxw)).build());
}
private int random(int a, int b) {
diff --git a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/GoldPouchDrop.java b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/GoldPouchDrop.java
index 65c4123a..7d952e26 100644
--- a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/GoldPouchDrop.java
+++ b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/GoldPouchDrop.java
@@ -1,12 +1,11 @@
package net.Indyuce.mmocore.comp.mythicmobs.load;
+import io.lumine.mythic.api.adapters.AbstractItemStack;
import io.lumine.mythic.api.config.MythicLineConfig;
import io.lumine.mythic.api.drops.DropMetadata;
-import io.lumine.mythic.api.drops.IMultiDrop;
+import io.lumine.mythic.api.drops.IItemDrop;
import io.lumine.mythic.bukkit.adapters.BukkitItemStack;
import io.lumine.mythic.core.drops.Drop;
-import io.lumine.mythic.core.drops.LootBag;
-import io.lumine.mythic.core.drops.droppables.ItemDrop;
import io.lumine.mythic.lib.api.item.ItemTag;
import io.lumine.mythic.lib.api.item.NBTItem;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
@@ -17,7 +16,7 @@ import org.bukkit.inventory.ItemStack;
import java.util.Random;
-public class GoldPouchDrop extends Drop implements IMultiDrop {
+public class GoldPouchDrop extends Drop implements IItemDrop {
private final int min;
private final int max;
@@ -30,10 +29,8 @@ public class GoldPouchDrop extends Drop implements IMultiDrop {
max = config.getInteger("max", 10);
}
- @SuppressWarnings("deprecation")
@Override
- public LootBag get(DropMetadata metadata) {
- LootBag loot = new LootBag(metadata);
+ public AbstractItemStack getDrop(DropMetadata dropMetadata, double v) {
NBTItem nbt = NBTItem.get(new SimpleItemBuilder("MOB_GOLD_POUCH").build());
ItemStack[] content = new ItemStack[18];
@@ -52,8 +49,7 @@ public class GoldPouchDrop extends Drop implements IMultiDrop {
}
nbt.addTag(new ItemTag("RpgPouchSize", 18), new ItemTag("RpgPouchMob", true), new ItemTag("RpgPouchInventory", MMOCoreUtils.toBase64(content)));
- loot.add(new ItemDrop(this.getLine(), this.getConfig(), new BukkitItemStack(nbt.toItem())));
- return loot;
+ return new BukkitItemStack(nbt.toItem());
}
private ItemStack setAmount(ItemStack item, int amount) {
diff --git a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/KillMythicMobExperienceSource.java b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/KillMythicMobExperienceSource.java
index bf161320..f81621fc 100644
--- a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/KillMythicMobExperienceSource.java
+++ b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/KillMythicMobExperienceSource.java
@@ -4,6 +4,7 @@ import io.lumine.mythic.bukkit.events.MythicMobDeathEvent;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
@@ -33,7 +34,7 @@ public class KillMythicMobExperienceSource extends SpecificExperienceSource onlineMembers = party.getOnlineMembers();
value /= onlineMembers.size();
for (PlayerData member : onlineMembers)
diff --git a/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java b/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java
index 768dd678..e9a6035a 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java
@@ -2,10 +2,9 @@ package net.Indyuce.mmocore.experience.droptable;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.quest.trigger.Trigger;
import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.api.quest.trigger.Trigger;
import org.apache.commons.lang.Validate;
-import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import java.util.ArrayList;
@@ -15,19 +14,23 @@ import java.util.Random;
public class ExperienceItem {
private final String id;
- //A period of 0 means the item will only trigger one time.
- private final int period;
- private final int firstTrigger;
+ private final int period, firstTrigger, lastTrigger;
private final double claimChance, failReduction;
private final List triggers;
private static final Random random = new Random();
+ @Deprecated
+ public ExperienceItem(String id, int period, int firstTrigger, double claimChance, double failReduction, List triggers) {
+ this(id, period, firstTrigger, Integer.MAX_VALUE, claimChance, failReduction, triggers);
+ }
+
/**
* One item for an experience table
*
* @param period The experience item is claimed every X level ups
* @param firstTrigger The experience item if claimed for the first time at X level ups.
+ * @param lastTrigger The last level at which the item can be claimed.
* @param claimChance Chance for that item to be claimed every X level ups
* @param failReduction Between 0 and 1, by how much the fail chance is reduced
* every time the item is not claimed when leveling up.
@@ -37,13 +40,14 @@ public class ExperienceItem {
* where n is the amount of successive claiming fails
* @param triggers Actions cast when the exp item is claimed
*/
- public ExperienceItem(String id, int period, int firstTrigger, double claimChance, double failReduction, List triggers) {
+ public ExperienceItem(String id, int period, int firstTrigger, int lastTrigger, double claimChance, double failReduction, List triggers) {
this.id = id;
this.period = period;
this.claimChance = claimChance;
this.failReduction = failReduction;
this.triggers = triggers;
this.firstTrigger = firstTrigger;
+ this.lastTrigger = lastTrigger;
}
public ExperienceItem(ConfigurationSection config) {
@@ -51,8 +55,11 @@ public class ExperienceItem {
Validate.isTrue(config.contains("triggers"));
id = config.getName();
- period = config.getInt("period", 1);
+ final int periodOption = config.getInt("period", 1);
+ // A period of 0 means the item will only trigger once
+ period = periodOption == 0 ? Integer.MAX_VALUE : periodOption;
firstTrigger = config.getInt("first-trigger", period);
+ lastTrigger = config.getInt("last-trigger", Integer.MAX_VALUE);
claimChance = config.getDouble("chance", 100) / 100;
failReduction = config.getDouble("fail-reduction", 80) / 100;
triggers = new ArrayList<>();
@@ -72,7 +79,10 @@ public class ExperienceItem {
* account the randomness factor from the 'chance' parameter
*/
public boolean roll(int professionLevel, int timesCollected) {
- int claimsRequired = (professionLevel + 1 - (firstTrigger + (timesCollected) * period));
+ if (professionLevel > lastTrigger)
+ return false;
+
+ int claimsRequired = (professionLevel + 1 - (firstTrigger + timesCollected * period));
if (claimsRequired < 1)
return false;
diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/EatExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/EatExperienceSource.java
index b312b5ac..505396aa 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/source/EatExperienceSource.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/source/EatExperienceSource.java
@@ -5,7 +5,7 @@ import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
import net.Indyuce.mmocore.api.player.PlayerData;
-import org.apache.commons.lang3.Validate;
+import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
diff --git a/src/main/java/net/Indyuce/mmocore/gui/AttributeView.java b/src/main/java/net/Indyuce/mmocore/gui/AttributeView.java
index b63c7f22..ebd108e7 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/AttributeView.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/AttributeView.java
@@ -1,16 +1,16 @@
package net.Indyuce.mmocore.gui;
import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.SoundEvent;
import net.Indyuce.mmocore.api.event.PlayerAttributeUseEvent;
+import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes;
+import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
-import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
-import net.Indyuce.mmocore.api.SoundEvent;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.api.item.Placeholders;
+import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
import net.Indyuce.mmocore.player.stats.StatInfo;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
@@ -79,7 +79,6 @@ public class AttributeView extends EditableInventory {
StatInfo info = StatInfo.valueOf(buff.getStat());
holders.register("buff_" + buff.getStat().toLowerCase(), info.format(buff.getValue()));
holders.register("total_" + buff.getStat().toLowerCase(), info.format(buff.multiply(total).getValue()));
-
});
return holders;
@@ -139,22 +138,29 @@ public class AttributeView extends EditableInventory {
MMOCore.plugin.soundManager.getSound(SoundEvent.NOT_ENOUGH_POINTS).playTo(getPlayer());
return;
}
-
+
+ // Amount of points spent
+ int pointsSpent = 1;
+
if (event.isShiftClick()) {
if (playerData.getAttributePoints() < shiftCost) {
MMOCore.plugin.configManager.getSimpleMessage("not-attribute-point-shift", "shift_points", "" + shiftCost).send(player);
MMOCore.plugin.soundManager.getSound(SoundEvent.NOT_ENOUGH_POINTS).playTo(getPlayer());
return;
}
-
- ins.addBase(shiftCost);
- playerData.giveAttributePoints(-shiftCost);
- } else {
- ins.addBase(1);
- playerData.giveAttributePoints(-1);
+
+ pointsSpent = shiftCost;
}
-
- MMOCore.plugin.configManager.getSimpleMessage("attribute-level-up", "attribute", attribute.getName(), "level", "" + ins.getBase()).send(player);
+
+ ins.addBase(pointsSpent);
+ playerData.giveAttributePoints(-pointsSpent);
+
+ // Apply exp table as many times as required
+ if (attribute.hasExperienceTable())
+ while (pointsSpent-- > 0)
+ attribute.getExperienceTable().claim(playerData, ins.getBase(), attribute);
+
+ MMOCore.plugin.configManager.getSimpleMessage("attribute-level-up", "attribute", attribute.getName(), "level", String.valueOf(ins.getBase())).send(player);
MMOCore.plugin.soundManager.getSound(SoundEvent.LEVEL_ATTRIBUTE).playTo(getPlayer());
PlayerAttributeUseEvent playerAttributeUseEvent = new PlayerAttributeUseEvent(playerData, attribute);
diff --git a/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java b/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java
index 54518f13..16bbd451 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java
@@ -5,20 +5,19 @@ import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
import io.lumine.mythic.lib.version.VersionMaterial;
import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
+import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
+import net.Indyuce.mmocore.experience.Booster;
+import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.Placeholders;
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.player.stats.StatInfo;
-import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
-import net.Indyuce.mmocore.experience.Booster;
-import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.party.AbstractParty;
+import net.Indyuce.mmocore.player.stats.StatInfo;
import org.apache.commons.lang.Validate;
-import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
@@ -29,311 +28,323 @@ import org.bukkit.inventory.meta.SkullMeta;
import java.util.Objects;
public class PlayerStats extends EditableInventory {
- public PlayerStats() {
- super("player-stats");
- }
+ public PlayerStats() {
+ super("player-stats");
+ }
- @Override
- public InventoryItem load(String function, ConfigurationSection config) {
+ @Override
+ public InventoryItem load(String function, ConfigurationSection config) {
- if (function.equals("boost"))
- return new BoostItem(config);
+ if (function.equals("boost"))
+ return new BoostItem(config);
- if (function.equals("boost-next"))
- return new SimplePlaceholderItem(config) {
+ if (function.equals("boost-next"))
+ return new SimplePlaceholderItem(config) {
- @Override
- public boolean hasDifferentDisplay() {
- return true;
- }
+ @Override
+ public boolean hasDifferentDisplay() {
+ return true;
+ }
- @Override
- public boolean canDisplay(PlayerStatsInventory inv) {
- InventoryItem boost = inv.getByFunction("boost");
- return boost != null && inv.boostOffset + boost.getSlots().size() < MMOCore.plugin.boosterManager.getActive().size();
- }
- };
+ @Override
+ public boolean canDisplay(PlayerStatsInventory inv) {
+ InventoryItem boost = inv.getByFunction("boost");
+ return boost != null && inv.boostOffset + boost.getSlots().size() < MMOCore.plugin.boosterManager.getActive().size();
+ }
+ };
- if (function.equals("boost-previous"))
- return new SimplePlaceholderItem(config) {
+ if (function.equals("boost-previous"))
+ return new SimplePlaceholderItem(config) {
- @Override
- public boolean canDisplay(PlayerStatsInventory inv) {
- return inv.boostOffset > 0;
- }
- };
+ @Override
+ public boolean canDisplay(PlayerStatsInventory inv) {
+ return inv.boostOffset > 0;
+ }
+ };
- if (function.equals("party"))
- return new PartyMoraleItem(config);
+ if (function.equals("party"))
+ return new PartyMoraleItem(config);
- if (function.startsWith("profession_")) {
- String id = function.substring("profession_".length()).toLowerCase();
- Validate.isTrue(MMOCore.plugin.professionManager.has(id));
- Profession profession = MMOCore.plugin.professionManager.get(id);
+ if (function.startsWith("profession_")) {
+ String id = function.substring("profession_".length()).toLowerCase();
+ Validate.isTrue(MMOCore.plugin.professionManager.has(id));
+ Profession profession = MMOCore.plugin.professionManager.get(id);
- return new InventoryItem(config) {
+ return new InventoryItem(config) {
- @Override
- public boolean hasDifferentDisplay() {
- return true;
- }
+ @Override
+ public boolean hasDifferentDisplay() {
+ return true;
+ }
- @Override
- public Placeholders getPlaceholders(GeneratedInventory inv, int n) {
+ @Override
+ public Placeholders getPlaceholders(PlayerStatsInventory inv, int n) {
- Placeholders holders = new Placeholders();
- net.Indyuce.mmocore.api.player.stats.PlayerStats stats = inv.getPlayerData().getStats();
+ Placeholders holders = new Placeholders();
+ net.Indyuce.mmocore.api.player.stats.PlayerStats stats = inv.target.getStats();
- double ratio = inv.getPlayerData().getCollectionSkills().getExperience(profession)
- / (double) inv.getPlayerData().getCollectionSkills().getLevelUpExperience(profession);
+ double ratio = inv.target.getCollectionSkills().getExperience(profession)
+ / (double) inv.target.getCollectionSkills().getLevelUpExperience(profession);
- String bar = "" + ChatColor.BOLD;
- int chars = (int) (ratio * 20);
- for (int j = 0; j < 20; j++)
- bar += (j == chars ? "" + ChatColor.WHITE + ChatColor.BOLD : "") + "|";
+ String bar = "" + ChatColor.BOLD;
+ int chars = (int) (ratio * 20);
+ for (int j = 0; j < 20; j++)
+ bar += (j == chars ? "" + ChatColor.WHITE + ChatColor.BOLD : "") + "|";
- // holders.register("profession", type.getName());
- holders.register("progress", bar);
- holders.register("level", "" + inv.getPlayerData().getCollectionSkills().getLevel(profession));
- holders.register("xp", inv.getPlayerData().getCollectionSkills().getExperience(profession));
- holders.register("percent", decimal.format(ratio * 100));
- for (StatInfo stat : MMOCore.plugin.statManager.getLoaded())
- if (Objects.equals(stat.profession, profession))
- holders.register(stat.name.toLowerCase(), stat.format(stats.getStat(stat.name)));
+ // holders.register("profession", type.getName());
+ holders.register("progress", bar);
+ holders.register("level", "" + inv.target.getCollectionSkills().getLevel(profession));
+ holders.register("xp", inv.target.getCollectionSkills().getExperience(profession));
+ holders.register("percent", decimal.format(ratio * 100));
+ for (StatInfo stat : MMOCore.plugin.statManager.getLoaded())
+ if (Objects.equals(stat.profession, profession))
+ holders.register(stat.name.toLowerCase(), stat.format(stats.getStat(stat.name)));
- return holders;
- }
- };
- }
+ return holders;
+ }
+ };
+ }
- if (function.equals("profile"))
- return new PlayerProfileItem(config);
+ if (function.equals("profile"))
+ return new PlayerProfileItem(config);
- if (function.equals("stats"))
- return new InventoryItem(config) {
+ if (function.equals("stats"))
+ return new InventoryItem(config) {
- @Override
- public boolean hasDifferentDisplay() {
- return true;
- }
+ @Override
+ public boolean hasDifferentDisplay() {
+ return true;
+ }
- @Override
- public Placeholders getPlaceholders(GeneratedInventory inv, int n) {
- return new Placeholders() {
- final net.Indyuce.mmocore.api.player.stats.PlayerStats stats = inv.getPlayerData().getStats();
+ @Override
+ public Placeholders getPlaceholders(PlayerStatsInventory inv, int n) {
+ return new Placeholders() {
+ final net.Indyuce.mmocore.api.player.stats.PlayerStats stats = inv.target.getStats();
- public String apply(Player player, String str) {
- while (str.contains("{") && str.substring(str.indexOf("{")).contains("}")) {
- String holder = str.substring(str.indexOf("{") + 1, str.indexOf("}"));
- String replaced;
+ public String apply(Player player, String str) {
+ while (str.contains("{") && str.substring(str.indexOf("{")).contains("}")) {
+ String holder = str.substring(str.indexOf("{") + 1, str.indexOf("}"));
+ String replaced;
- if (holder.endsWith("_base")) {
- StatInfo info = StatInfo.valueOf(UtilityMethods.enumName(holder.substring(0, holder.length() - 5)));
- replaced = info.format(stats.getBase(info.name));
- } else if (holder.endsWith("_extra")) {
- StatInfo info = StatInfo.valueOf(UtilityMethods.enumName(holder.substring(0, holder.length() - 5)));
- replaced = info.format(stats.getStat(info.name) - stats.getBase(info.name));
- } else if (holder.startsWith("attribute_")) {
- PlayerAttribute attr = MMOCore.plugin.attributeManager.get(holder.substring(10).replace("_", "-").toLowerCase());
- replaced = String.valueOf(inv.getPlayerData().getAttributes().getAttribute(attr));
- } else {
- StatInfo info = StatInfo.valueOf(UtilityMethods.enumName(holder));
- replaced = info.format(stats.getStat(info.name));
- }
+ if (holder.endsWith("_base")) {
+ StatInfo info = StatInfo.valueOf(UtilityMethods.enumName(holder.substring(0, holder.length() - 5)));
+ replaced = info.format(stats.getBase(info.name));
+ } else if (holder.endsWith("_extra")) {
+ StatInfo info = StatInfo.valueOf(UtilityMethods.enumName(holder.substring(0, holder.length() - 5)));
+ replaced = info.format(stats.getStat(info.name) - stats.getBase(info.name));
+ } else if (holder.startsWith("attribute_")) {
+ PlayerAttribute attr = MMOCore.plugin.attributeManager.get(holder.substring(10).replace("_", "-").toLowerCase());
+ replaced = String.valueOf(inv.target.getAttributes().getAttribute(attr));
+ } else {
+ StatInfo info = StatInfo.valueOf(UtilityMethods.enumName(holder));
+ replaced = info.format(stats.getStat(info.name));
+ }
- str = str.replace("{" + holder + "}", replaced);
- }
+ str = str.replace("{" + holder + "}", replaced);
+ }
- // External placeholders
- return MMOCore.plugin.placeholderParser.parse(player, str);
- }
- };
- }
- };
+ // External placeholders
+ return MMOCore.plugin.placeholderParser.parse(player, str);
+ }
+ };
+ }
+ };
- return new SimplePlaceholderItem(config);
- }
+ return new SimplePlaceholderItem(config);
+ }
- public PlayerStatsInventory newInventory(PlayerData data) {
- return new PlayerStatsInventory(data, this);
- }
+ public PlayerStatsInventory newInventory(PlayerData invTarget, PlayerData opening) {
+ return new PlayerStatsInventory(invTarget, opening, this);
+ }
- public class PlayerStatsInventory extends GeneratedInventory {
- private int boostOffset;
+ public PlayerStatsInventory newInventory(PlayerData player) {
+ return new PlayerStatsInventory(player, player, this);
+ }
- public PlayerStatsInventory(PlayerData playerData, EditableInventory editable) {
- super(playerData, editable);
- }
+ public class PlayerStatsInventory extends GeneratedInventory {
+ private final PlayerData target;
- @Override
- public String calculateName() {
- return getName();
- }
+ private int boostOffset;
- @Override
- public void whenClicked(InventoryClickEvent event, InventoryItem item) {
- if (item.hasFunction())
- if (item.getFunction().equals("boost-next")) {
- boostOffset++;
- open();
+ /**
+ * @param invTarget Target player
+ * @param opening Player opening the inventory
+ * @param inv Corresponding editable inventory
+ */
+ public PlayerStatsInventory(PlayerData invTarget, PlayerData opening, EditableInventory inv) {
+ super(opening, inv);
- } else if (item.getFunction().equals("boost-previous")) {
- boostOffset--;
- open();
- }
- }
- }
+ this.target = invTarget;
+ }
- private ItemStack amount(ItemStack item, int amount) {
- item.setAmount(amount);
- return item;
- }
+ @Override
+ public String calculateName() {
+ return getName();
+ }
- public static class PartyMoraleItem extends InventoryItem {
- public PartyMoraleItem(ConfigurationSection config) {
- super(config);
- }
+ @Override
+ public void whenClicked(InventoryClickEvent event, InventoryItem item) {
+ if (item.hasFunction())
+ if (item.getFunction().equals("boost-next")) {
+ boostOffset++;
+ open();
- @Override
- public Placeholders getPlaceholders(GeneratedInventory inv, int n) {
- Placeholders holders = new Placeholders();
+ } else if (item.getFunction().equals("boost-previous")) {
+ boostOffset--;
+ open();
+ }
+ }
+ }
- int count = inv.getPlayerData().getParty().getOnlineMembers().size();
- holders.register("count", "" + count);
- for (StatModifier buff : MMOCore.plugin.partyManager.getBonuses())
- holders.register("buff_" + buff.getStat().toLowerCase(), buff.multiply(count - 1).toString());
+ private ItemStack amount(ItemStack item, int amount) {
+ item.setAmount(amount);
+ return item;
+ }
- return holders;
- }
+ public static class PartyMoraleItem extends InventoryItem {
+ public PartyMoraleItem(ConfigurationSection config) {
+ super(config);
+ }
- @Override
- public boolean canDisplay(GeneratedInventory inv) {
- AbstractParty party = inv.getPlayerData().getParty();
- return party != null && party.getOnlineMembers().size() > 1;
- }
- }
+ @Override
+ public Placeholders getPlaceholders(PlayerStatsInventory inv, int n) {
+ Placeholders holders = new Placeholders();
- public static class PlayerProfileItem extends InventoryItem {
- public PlayerProfileItem(ConfigurationSection config) {
- super(config);
- }
+ int count = inv.target.getParty().getOnlineMembers().size();
+ holders.register("count", "" + count);
+ for (StatModifier buff : MMOCore.plugin.partyManager.getBonuses())
+ holders.register("buff_" + buff.getStat().toLowerCase(), buff.multiply(count - 1).toString());
- @Override
- public ItemStack display(GeneratedInventory inv, int n) {
- ItemStack disp = super.display(inv, n);
- if (disp.getType() == VersionMaterial.PLAYER_HEAD.toMaterial()) {
- SkullMeta meta = (SkullMeta) disp.getItemMeta();
+ return holders;
+ }
- inv.dynamicallyUpdateItem(this, n, disp, current -> {
- meta.setOwningPlayer(inv.getPlayer());
- current.setItemMeta(meta);
- });
- }
- return disp;
- }
+ @Override
+ public boolean canDisplay(PlayerStatsInventory inv) {
+ AbstractParty party = inv.target.getParty();
+ return party != null && party.getOnlineMembers().size() > 1;
+ }
+ }
- @Override
- public Placeholders getPlaceholders(GeneratedInventory inv, int n) {
- PlayerData data = inv.getPlayerData();
- Placeholders holders = new Placeholders();
+ public static class PlayerProfileItem extends InventoryItem {
+ public PlayerProfileItem(ConfigurationSection config) {
+ super(config);
+ }
- int nextLevelExp = inv.getPlayerData().getLevelUpExperience();
- double ratio = (double) data.getExperience() / (double) nextLevelExp;
+ @Override
+ public ItemStack display(PlayerStatsInventory inv, int n) {
+ ItemStack disp = super.display(inv, n);
+ if (disp.getType() == VersionMaterial.PLAYER_HEAD.toMaterial()) {
+ SkullMeta meta = (SkullMeta) disp.getItemMeta();
+ inv.dynamicallyUpdateItem(this, n, disp, current -> {
+ meta.setOwningPlayer(inv.target.getPlayer());
+ current.setItemMeta(meta);
+ });
+ }
+ return disp;
+ }
- StringBuilder bar = new StringBuilder("" + ChatColor.BOLD);
- int chars = (int) (ratio * 20);
- for (int j = 0; j < 20; j++)
- bar.append(j == chars ? "" + ChatColor.WHITE + ChatColor.BOLD : "").append("|");
+ @Override
+ public Placeholders getPlaceholders(PlayerStatsInventory inv, int n) {
+ PlayerData data = inv.target;
+ Placeholders holders = new Placeholders();
- holders.register("percent", decimal.format(ratio * 100));
- holders.register("exp", MythicLib.plugin.getMMOConfig().decimal.format(data.getExperience()));
- holders.register("level", "" + data.getLevel());
- holders.register("class_points", "" + data.getClassPoints());
- holders.register("skill_points", "" + data.getSkillPoints());
- holders.register("attribute_points", "" + data.getAttributePoints());
- holders.register("progress", bar.toString());
- holders.register("next_level", "" + nextLevelExp);
- if (data.isOnline())
- holders.register("player", "" + data.getPlayer().getName());
- holders.register("class", "" + data.getProfess().getName());
+ int nextLevelExp = inv.target.getLevelUpExperience();
+ double ratio = (double) data.getExperience() / (double) nextLevelExp;
- return holders;
- }
- }
+ StringBuilder bar = new StringBuilder("" + ChatColor.BOLD);
+ int chars = (int) (ratio * 20);
+ for (int j = 0; j < 20; j++)
+ bar.append(j == chars ? "" + ChatColor.WHITE + ChatColor.BOLD : "").append("|");
- public class BoostItem extends SimplePlaceholderItem {
- private final InventoryItem noBoost, mainLevel, profession;
+ holders.register("percent", decimal.format(ratio * 100));
+ holders.register("exp", MythicLib.plugin.getMMOConfig().decimal.format(data.getExperience()));
+ holders.register("level", "" + data.getLevel());
+ holders.register("class_points", "" + data.getClassPoints());
+ holders.register("skill_points", "" + data.getSkillPoints());
+ holders.register("attribute_points", "" + data.getAttributePoints());
+ holders.register("progress", bar.toString());
+ holders.register("next_level", "" + nextLevelExp);
+ if (data.isOnline())
+ holders.register("player", "" + data.getPlayer().getName());
+ holders.register("class", "" + data.getProfess().getName());
- public BoostItem(ConfigurationSection config) {
- super(config);
+ return holders;
+ }
+ }
- ConfigurationSection noBoost = config.getConfigurationSection("no-boost");
- Validate.notNull(noBoost, "Could not load 'no-boost' config");
- this.noBoost = new SimplePlaceholderItem(noBoost);
+ public class BoostItem extends SimplePlaceholderItem {
+ private final InventoryItem noBoost, mainLevel, profession;
- ConfigurationSection mainLevel = config.getConfigurationSection("main-level");
- Validate.notNull(mainLevel, "Could not load 'main-level' config");
- this.mainLevel = new InventoryItem(mainLevel) {
+ public BoostItem(ConfigurationSection config) {
+ super(config);
- @Override
- public boolean hasDifferentDisplay() {
- return true;
- }
+ ConfigurationSection noBoost = config.getConfigurationSection("no-boost");
+ Validate.notNull(noBoost, "Could not load 'no-boost' config");
+ this.noBoost = new SimplePlaceholderItem(noBoost);
- @Override
- public Placeholders getPlaceholders(PlayerStatsInventory inv, int n) {
- Placeholders holders = new Placeholders();
- Booster boost = MMOCore.plugin.boosterManager.get(inv.boostOffset + n);
+ ConfigurationSection mainLevel = config.getConfigurationSection("main-level");
+ Validate.notNull(mainLevel, "Could not load 'main-level' config");
+ this.mainLevel = new InventoryItem(mainLevel) {
- holders.register("author", boost.hasAuthor() ? boost.getAuthor() : "Server");
- holders.register("value", (int) (boost.getExtra() * 100));
- holders.register("left", boost.isTimedOut() ?
- MMOCore.plugin.configManager.getSimpleMessage("booster-expired").message()
- : new DelayFormat(2).format(boost.getLeft()));
+ @Override
+ public boolean hasDifferentDisplay() {
+ return true;
+ }
- return holders;
- }
- };
+ @Override
+ public Placeholders getPlaceholders(PlayerStatsInventory inv, int n) {
+ Placeholders holders = new Placeholders();
+ Booster boost = MMOCore.plugin.boosterManager.get(inv.boostOffset + n);
- ConfigurationSection profession = config.getConfigurationSection("profession");
- Validate.notNull(profession, "Could not load 'profession' config");
- this.profession = new InventoryItem(profession) {
+ holders.register("author", boost.hasAuthor() ? boost.getAuthor() : "Server");
+ holders.register("value", (int) (boost.getExtra() * 100));
+ holders.register("left", boost.isTimedOut() ?
+ MMOCore.plugin.configManager.getSimpleMessage("booster-expired").message()
+ : new DelayFormat(2).format(boost.getLeft()));
- @Override
- public boolean hasDifferentDisplay() {
- return true;
- }
+ return holders;
+ }
+ };
- @Override
- public Placeholders getPlaceholders(PlayerStatsInventory inv, int n) {
- Placeholders holders = new Placeholders();
- Booster boost = MMOCore.plugin.boosterManager.get(inv.boostOffset + n);
+ ConfigurationSection profession = config.getConfigurationSection("profession");
+ Validate.notNull(profession, "Could not load 'profession' config");
+ this.profession = new InventoryItem(profession) {
- holders.register("author", boost.hasAuthor() ? boost.getAuthor() : "Server");
- holders.register("profession", boost.getProfession().getName());
- holders.register("value", (int) (boost.getExtra() * 100));
- holders.register("left", boost.isTimedOut() ?
- MMOCore.plugin.configManager.getSimpleMessage("booster-expired").message()
- : new DelayFormat(2).format(boost.getLeft()));
+ @Override
+ public boolean hasDifferentDisplay() {
+ return true;
+ }
- return holders;
- }
- };
- }
+ @Override
+ public Placeholders getPlaceholders(PlayerStatsInventory inv, int n) {
+ Placeholders holders = new Placeholders();
+ Booster boost = MMOCore.plugin.boosterManager.get(inv.boostOffset + n);
- @Override
- public boolean hasDifferentDisplay() {
- return true;
- }
+ holders.register("author", boost.hasAuthor() ? boost.getAuthor() : "Server");
+ holders.register("profession", boost.getProfession().getName());
+ holders.register("value", (int) (boost.getExtra() * 100));
+ holders.register("left", boost.isTimedOut() ?
+ MMOCore.plugin.configManager.getSimpleMessage("booster-expired").message()
+ : new DelayFormat(2).format(boost.getLeft()));
- @Override
- public ItemStack display(PlayerStatsInventory inv, int n) {
- int offset = inv.boostOffset;
- if (n + offset >= MMOCore.plugin.boosterManager.getActive().size())
- return noBoost.display(inv, n);
+ return holders;
+ }
+ };
+ }
- Booster boost = MMOCore.plugin.boosterManager.get(inv.boostOffset + n);
- return amount(boost.hasProfession() ? profession.display(inv, n) : mainLevel.display(inv, n), n + offset + 1);
- }
- }
+ @Override
+ public boolean hasDifferentDisplay() {
+ return true;
+ }
+
+ @Override
+ public ItemStack display(PlayerStatsInventory inv, int n) {
+ int offset = inv.boostOffset;
+ if (n + offset >= MMOCore.plugin.boosterManager.getActive().size())
+ return noBoost.display(inv, n);
+
+ Booster boost = MMOCore.plugin.boosterManager.get(inv.boostOffset + n);
+ return amount(boost.hasProfession() ? profession.display(inv, n) : mainLevel.display(inv, n), n + offset + 1);
+ }
+ }
}
diff --git a/src/main/java/net/Indyuce/mmocore/gui/api/GeneratedInventory.java b/src/main/java/net/Indyuce/mmocore/gui/api/GeneratedInventory.java
index 163ae7f5..85be0d26 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/api/GeneratedInventory.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/api/GeneratedInventory.java
@@ -2,8 +2,8 @@ package net.Indyuce.mmocore.gui.api;
import io.lumine.mythic.lib.MythicLib;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.TriggerItem;
import org.bukkit.Bukkit;
import org.bukkit.event.inventory.InventoryClickEvent;
diff --git a/src/main/java/net/Indyuce/mmocore/gui/eco/DepositMenu.java b/src/main/java/net/Indyuce/mmocore/gui/eco/DepositMenu.java
index f443e970..cc1f64e8 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/eco/DepositMenu.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/eco/DepositMenu.java
@@ -1,6 +1,10 @@
package net.Indyuce.mmocore.gui.eco;
+import io.lumine.mythic.lib.api.item.NBTItem;
+import io.lumine.mythic.lib.api.util.SmartGive;
import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.util.MMOCoreUtils;
+import net.Indyuce.mmocore.gui.api.PluginInventory;
import net.Indyuce.mmocore.util.item.SimpleItemBuilder;
import net.milkbowl.vault.economy.EconomyResponse;
import org.bukkit.Bukkit;
@@ -13,108 +17,107 @@ import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
-import net.Indyuce.mmocore.api.util.MMOCoreUtils;
-import net.Indyuce.mmocore.gui.api.PluginInventory;
-import io.lumine.mythic.lib.api.item.NBTItem;
-import io.lumine.mythic.lib.api.util.SmartGive;
-
public class DepositMenu extends PluginInventory {
- private ItemStack depositItem;
- private int deposit;
+ private ItemStack depositItem;
+ private int deposit;
- public DepositMenu(Player player) {
- super(player);
- }
+ /**
+ * Every time an item is clicked in the inventory, an inventory
+ * update is scheduled. If nothing happens for the next 10 ticks
+ * then the update is processed. If another item is clicked within
+ * this delay the task is cancelled and scheduled for later
+ */
+ private BukkitRunnable updateRunnable;
- @Override
- public Inventory getInventory() {
- Inventory inv = Bukkit.createInventory(this, 27, "Deposit");
+ public DepositMenu(Player player) {
+ super(player);
+ }
- inv.setItem(26, depositItem = new SimpleItemBuilder("DEPOSIT_ITEM").addPlaceholders("worth", "0").build());
+ @Override
+ public Inventory getInventory() {
+ Inventory inv = Bukkit.createInventory(this, 27, "Deposit");
+ updateDeposit(inv);
+ return inv;
+ }
- new BukkitRunnable() {
+ @Override
+ public void whenClicked(InventoryClickEvent event) {
+ if (event.getCurrentItem() == null || event.getCurrentItem().getType() == Material.AIR)
+ return;
- @Override
- public void run() {
- if (inv.getViewers().size() < 1) {
- cancel();
- return;
- }
+ if (event.getCurrentItem().isSimilar(depositItem)) {
+ event.setCancelled(true);
- updateDeposit(inv);
- }
- }.runTaskTimer(MMOCore.plugin, 0, 20);
- return inv;
- }
+ updateDeposit(event.getInventory());
+ if (deposit <= 0)
+ return;
- @Override
- public void whenClicked(InventoryClickEvent event) {
- // event.setCancelled(true);
- if (event.getCurrentItem() == null || event.getCurrentItem().getType() == Material.AIR)
- return;
+ EconomyResponse response = MMOCore.plugin.economy.getEconomy().depositPlayer(player, deposit);
+ if (!response.transactionSuccess())
+ return;
- if (event.getCurrentItem().isSimilar(depositItem)) {
- event.setCancelled(true);
+ event.getInventory().clear();
+ player.closeInventory();
+ player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2);
+ MMOCore.plugin.configManager.getSimpleMessage("deposit", "worth", String.valueOf(deposit)).send(player);
+ return;
+ }
- updateDeposit(event.getInventory());
- if (deposit <= 0)
- return;
+ int worth = NBTItem.get(event.getCurrentItem()).getInteger("RpgWorth");
+ if (worth < 1)
+ event.setCancelled(true);
+ else
+ scheduleUpdate(event.getInventory());
+ }
- EconomyResponse response = MMOCore.plugin.economy.getEconomy().depositPlayer(player, deposit);
- if (!response.transactionSuccess())
- return;
+ @Override
+ public void whenClosed(InventoryCloseEvent event) {
- event.getInventory().clear();
- player.closeInventory();
- player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2);
- MMOCore.plugin.configManager.getSimpleMessage("deposit", "worth", "" + deposit).send(player);
- return;
- }
+ // Cancel runnable
+ if (updateRunnable != null)
+ updateRunnable.cancel();
- int worth = NBTItem.get(event.getCurrentItem()).getInteger("RpgWorth");
- if (worth < 1) {
- event.setCancelled(true);
- }
+ // Give all items back
+ SmartGive smart = new SmartGive(player);
+ for (int j = 0; j < 26; j++) {
+ ItemStack item = event.getInventory().getItem(j);
+ if (item != null)
+ smart.give(item);
+ }
+ }
- // in deposit menu
- // if (event.getRawSlot() < 27) {
- // int empty = player.getInventory().firstEmpty();
- // if (empty < 0)
- // return;
- //
- // player.playSound(player.getLocation(), Sound.ENTITY_SHULKER_TELEPORT,
- // 1, 2);
- // player.getInventory().addItem(event.getCurrentItem());
- // event.setCurrentItem(null);
- // updateDeposit(event.getInventory());
- // return;
- // }
+ private BukkitRunnable newUpdateRunnable(Inventory inv) {
+ return new BukkitRunnable() {
- // in player inventory
- // int empty = event.getInventory().firstEmpty();
- // if (empty < 0)
- // return;
- //
- // player.playSound(player.getLocation(),
- // Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2);
- // event.getInventory().addItem(event.getCurrentItem());
- // event.setCurrentItem(null);
- // updateDeposit(event.getInventory());
- // return;
- }
+ @Override
+ public void run() {
+ updateDeposit(inv);
+ }
+ };
+ }
- @Override
- public void whenClosed(InventoryCloseEvent event) {
- SmartGive smart = new SmartGive(player);
- for (int j = 0; j < 26; j++) {
- ItemStack item = event.getInventory().getItem(j);
- if (item != null)
- smart.give(item);
- }
- }
+ private void scheduleUpdate(Inventory inv) {
+ if (updateRunnable != null)
+ updateRunnable.cancel();
- private void updateDeposit(Inventory inv) {
- deposit = MMOCoreUtils.getWorth(inv.getContents());
- inv.setItem(26, depositItem = new SimpleItemBuilder("DEPOSIT_ITEM").addPlaceholders("worth", "" + deposit).build());
- }
+ updateRunnable = new BukkitRunnable() {
+
+ @Override
+ public void run() {
+ updateRunnable = null;
+ updateDeposit(inv);
+ }
+ };
+ updateRunnable.runTaskLater(MMOCore.plugin, 10);
+ }
+
+ private void updateDeposit(Inventory inv) {
+ if (updateRunnable != null) {
+ updateRunnable.cancel();
+ updateRunnable = null;
+ }
+
+ deposit = MMOCoreUtils.getWorth(inv.getContents());
+ inv.setItem(26, depositItem = new SimpleItemBuilder("DEPOSIT_ITEM").addPlaceholders("worth", String.valueOf(deposit)).build());
+ }
}
diff --git a/src/main/java/net/Indyuce/mmocore/gui/social/friend/EditableFriendList.java b/src/main/java/net/Indyuce/mmocore/gui/social/friend/EditableFriendList.java
index c222a255..fbb4f953 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/social/friend/EditableFriendList.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/social/friend/EditableFriendList.java
@@ -1,15 +1,15 @@
package net.Indyuce.mmocore.gui.social.friend;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.gui.api.GeneratedInventory;
-import net.Indyuce.mmocore.gui.api.item.InventoryItem;
-import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
import net.Indyuce.mmocore.api.player.PlayerActivity;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.util.input.PlayerInput.InputType;
import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
import net.Indyuce.mmocore.gui.api.EditableInventory;
+import net.Indyuce.mmocore.gui.api.GeneratedInventory;
+import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.Placeholders;
+import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
import net.Indyuce.mmocore.manager.InventoryManager;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
@@ -130,8 +130,8 @@ public class EditableFriendList extends EditableInventory {
if (inv.getPlayerData().getFriends().size() <= n)
return super.display(inv, n);
- ItemStack disp = Bukkit.getOfflinePlayer(inv.getPlayerData().getFriends().get(n)).isOnline() ? online.display(inv, n) : offline.display(inv, n);
- Player friend = Bukkit.getPlayer(inv.getPlayerData().getFriends().get(n));
+ final OfflinePlayer friend = Bukkit.getOfflinePlayer(inv.getPlayerData().getFriends().get(n));
+ ItemStack disp = (friend.isOnline() ? online : offline).display(inv, n);
ItemMeta meta = disp.getItemMeta();
meta.getPersistentDataContainer().set(UUID_NAMESPACEDKEY, PersistentDataType.STRING, friend.getUniqueId().toString());
diff --git a/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyView.java b/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyView.java
index e15d038a..ec740dcd 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyView.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyView.java
@@ -1,14 +1,14 @@
package net.Indyuce.mmocore.gui.social.party;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.util.input.PlayerInput;
-import net.Indyuce.mmocore.gui.api.GeneratedInventory;
-import net.Indyuce.mmocore.gui.api.item.InventoryItem;
-import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.api.util.input.PlayerInput;
import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
import net.Indyuce.mmocore.gui.api.EditableInventory;
+import net.Indyuce.mmocore.gui.api.GeneratedInventory;
+import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.Placeholders;
+import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
import net.Indyuce.mmocore.party.provided.Party;
import org.apache.commons.lang.Validate;
import org.bukkit.*;
@@ -148,7 +148,7 @@ public class EditablePartyView extends EditableInventory {
return;
}
- MMOCore.plugin.configManager.newPlayerInput(player, PlayerInput.InputType.PARTY_INVITE, (input) -> {
+ MMOCore.plugin.configManager.newPlayerInput(player, PlayerInput.InputType.PARTY_INVITE, input -> {
Player target = Bukkit.getPlayer(input);
if (target == null) {
MMOCore.plugin.configManager.getSimpleMessage("not-online-player", "player", input).send(player);
@@ -172,8 +172,9 @@ public class EditablePartyView extends EditableInventory {
return;
}
- if (Math.abs(targetData.getLevel() - party.getLevel()) > MMOCore.plugin.configManager.maxPartyLevelDifference) {
- MMOCore.plugin.configManager.getSimpleMessage("high-level-difference", "player", target.getName()).send(player);
+ int levelDifference = Math.abs(targetData.getLevel() - party.getLevel());
+ if (levelDifference > MMOCore.plugin.configManager.maxPartyLevelDifference) {
+ MMOCore.plugin.configManager.getSimpleMessage("high-level-difference", "player", target.getName(), "diff", String.valueOf(levelDifference)).send(player);
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1);
open();
return;
diff --git a/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java b/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java
index aee6211b..70d6a3d5 100644
--- a/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java
+++ b/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java
@@ -1,7 +1,7 @@
package net.Indyuce.mmocore.listener;
+import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.UtilityMethods;
-import io.lumine.mythic.utils.Schedulers;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.block.BlockInfo;
import net.Indyuce.mmocore.api.block.VanillaBlockType;
@@ -136,7 +136,7 @@ public class BlockListener implements Listener {
* Finally enable block regen.
*/
if (info.hasRegen())
- Schedulers.sync().runLater(() -> MMOCore.plugin.mineManager.initialize(info.startRegeneration(Bukkit.createBlockData(savedData), block.getLocation()), !temporaryBlock), 1);
+ Bukkit.getScheduler().runTaskLater(MythicLib.plugin, () -> MMOCore.plugin.mineManager.initialize(info.startRegeneration(Bukkit.createBlockData(savedData), block.getLocation()), !temporaryBlock), 1);
}
/**
@@ -184,9 +184,9 @@ public class BlockListener implements Listener {
}
}
- /*
- * Allows to mark cobblestone generated by cobblestone generators so that
- * exp is not gained by these blocks
+ /**
+ * Allows to mark cobblestone generated by cobblestone generators
+ * so that experience is not gained by these blocks
*/
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void cobblestoneGeneratorHandling(BlockFormEvent event) {
@@ -195,7 +195,7 @@ public class BlockListener implements Listener {
if (MMOCore.plugin.configManager.cobbleGeneratorXP) return;
if (event.getBlock().getType() == Material.WATER || event.getBlock().getType() == Material.LAVA)
- if (event.getNewState().getType() == Material.COBBLESTONE || event.getNewState().getType() == Material.OBSIDIAN)
+ if (MythicLib.plugin.getVersion().getWrapper().isGeneratorOutput(event.getNewState().getType()))
event.getNewState().setMetadata("player_placed", new FixedMetadataValue(MMOCore.plugin, true));
}
diff --git a/src/main/java/net/Indyuce/mmocore/listener/option/PlayerProfileCheck.java b/src/main/java/net/Indyuce/mmocore/listener/option/PlayerProfileCheck.java
index eab9afe3..5ff87df0 100644
--- a/src/main/java/net/Indyuce/mmocore/listener/option/PlayerProfileCheck.java
+++ b/src/main/java/net/Indyuce/mmocore/listener/option/PlayerProfileCheck.java
@@ -8,7 +8,6 @@ import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEntityEvent;
-import org.bukkit.inventory.Inventory;
public class PlayerProfileCheck implements Listener {
@@ -17,14 +16,6 @@ public class PlayerProfileCheck implements Listener {
if (event.getRightClicked().getType() != EntityType.PLAYER || !event.getPlayer().isSneaking() || !MythicLib.plugin.getEntities().canTarget(event.getPlayer(), event.getRightClicked(), InteractionType.SUPPORT_ACTION))
return;
- /*
- * This works because the PlayerStats class DOES NOT utilize
- * at all the player instance saved in the InventoryClickEvent
- *
- * Opening inventories like that to other players does NOT
- * necessarily works for any other custom inventory.
- * */
- Inventory inv = InventoryManager.PLAYER_STATS.newInventory(PlayerData.get(event.getRightClicked().getUniqueId())).getInventory();
- event.getPlayer().openInventory(inv);
+ InventoryManager.PLAYER_STATS.newInventory(PlayerData.get(event.getRightClicked().getUniqueId()), PlayerData.get(event.getPlayer())).open();
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/listener/option/RedirectVanillaExp.java b/src/main/java/net/Indyuce/mmocore/listener/option/RedirectVanillaExp.java
index 68df53bd..b7d37027 100644
--- a/src/main/java/net/Indyuce/mmocore/listener/option/RedirectVanillaExp.java
+++ b/src/main/java/net/Indyuce/mmocore/listener/option/RedirectVanillaExp.java
@@ -1,23 +1,20 @@
package net.Indyuce.mmocore.listener.option;
+import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.EXPSource;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerExpChangeEvent;
-import net.Indyuce.mmocore.api.player.PlayerData;
-
public class RedirectVanillaExp implements Listener {
- private final double ratio;
+ private final double ratio;
- public RedirectVanillaExp(double ratio) {
- this.ratio = ratio;
- }
+ public RedirectVanillaExp(double ratio) {
+ this.ratio = ratio;
+ }
- @EventHandler
- public void a(PlayerExpChangeEvent event) {
- double a = (event.getAmount() * ratio);
- if (a > 0)
- PlayerData.get(event.getPlayer()).giveExperience(a, EXPSource.VANILLA);
- }
+ @EventHandler
+ public void a(PlayerExpChangeEvent event) {
+ PlayerData.get(event.getPlayer()).giveExperience(event.getAmount() * ratio, EXPSource.VANILLA);
+ }
}
diff --git a/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java b/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java
index c9ca4bbf..fb990c21 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java
@@ -23,7 +23,7 @@ import java.util.logging.Level;
public class ConfigManager {
public final CommandVerbose commandVerbose = new CommandVerbose();
- public boolean overrideVanillaExp, canCreativeCast, cobbleGeneratorXP, saveDefaultClassInfo, attributesAsClassInfo;
+ public boolean overrideVanillaExp, canCreativeCast, cobbleGeneratorXP, saveDefaultClassInfo, attributesAsClassInfo, splitProfessionExp;
public String partyChatPrefix, noSkillBoundPlaceholder;
public ChatColor staminaFull, staminaHalf, staminaEmpty;
public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown, globalSkillCooldown;
@@ -92,7 +92,7 @@ public class ConfigManager {
commandVerbose.reload(MMOCore.plugin.getConfig().getConfigurationSection("command-verbose"));
messages = new ConfigFile("messages").getConfig();
- chatInput = MMOCore.plugin.getConfig().getBoolean("use-chat-input");
+ chatInput = true; // MMOCore.plugin.getConfig().getBoolean("use-chat-input")
partyChatPrefix = MMOCore.plugin.getConfig().getString("party.chat-prefix");
combatLogTimer = MMOCore.plugin.getConfig().getInt("combat-log.timer") * 1000L;
lootChestExpireTime = Math.max(MMOCore.plugin.getConfig().getInt("loot-chests.chest-expire-time"), 1) * 20;
@@ -102,6 +102,7 @@ public class ConfigManager {
lootChestsChanceWeight = MMOCore.plugin.getConfig().getDouble("chance-stat-weight.loot-chests");
fishingDropsChanceWeight = MMOCore.plugin.getConfig().getDouble("chance-stat-weight.fishing-drops");
maxPartyLevelDifference = MMOCore.plugin.getConfig().getInt("party.max-level-difference");
+ splitProfessionExp = MMOCore.plugin.getConfig().getBoolean("party.profession-exp-split");
staminaFull = getColorOrDefault("stamina-whole", ChatColor.GREEN);
staminaHalf = getColorOrDefault("stamina-half", ChatColor.DARK_GREEN);
@@ -147,7 +148,7 @@ public class ConfigManager {
}
public SimpleMessage getSimpleMessage(String key, String... placeholders) {
- String format = messages.getString(key, "");
+ String format = messages.getString(key, "{MessageNotFound:\"" + key + "\"}");
for (int j = 0; j < placeholders.length - 1; j += 2)
format = format.replace("{" + placeholders[j] + "}", placeholders[j + 1]);
return new SimpleMessage(MythicLib.plugin.parseColors(format));
diff --git a/src/main/java/net/Indyuce/mmocore/player/playerclass/ClassTrigger.java b/src/main/java/net/Indyuce/mmocore/player/playerclass/ClassTrigger.java
index a18649f8..4d5183f2 100644
--- a/src/main/java/net/Indyuce/mmocore/player/playerclass/ClassTrigger.java
+++ b/src/main/java/net/Indyuce/mmocore/player/playerclass/ClassTrigger.java
@@ -12,7 +12,6 @@ import io.lumine.mythic.lib.skill.result.SkillResult;
import io.lumine.mythic.lib.skill.trigger.TriggerMetadata;
import io.lumine.mythic.lib.skill.trigger.TriggerType;
import io.lumine.mythic.lib.util.configobject.ConfigObject;
-import io.lumine.mythic.lib.util.configobject.LineConfigObject;
import net.Indyuce.mmocore.listener.ClassTriggers;
import org.apache.commons.lang.Validate;
@@ -43,7 +42,7 @@ public class ClassTrigger {
type = ClassTriggerType.valueOf(UtilityMethods.enumName(triggerTypeString));
for (String key : mechanicStringList) {
- ConfigObject config = new LineConfigObject(new MMOLineConfig(key));
+ ConfigObject config = new MMOLineConfig(key);
Mechanic mechanic = MythicLib.plugin.getSkills().loadMechanic(config);
skill.getMechanics().add(mechanic);
}
diff --git a/src/main/java/net/Indyuce/mmocore/skill/CastableSkill.java b/src/main/java/net/Indyuce/mmocore/skill/CastableSkill.java
index f3813ac6..dacfabe9 100644
--- a/src/main/java/net/Indyuce/mmocore/skill/CastableSkill.java
+++ b/src/main/java/net/Indyuce/mmocore/skill/CastableSkill.java
@@ -82,7 +82,8 @@ public class CastableSkill extends Skill {
casterData.giveStamina(-getModifier("stamina"), PlayerResourceUpdateEvent.UpdateReason.SKILL_COST);
}
- casterData.setLastActivity(PlayerActivity.CAST_SKILL);
+ if (!getTrigger().isPassive())
+ casterData.setLastActivity(PlayerActivity.CAST_SKILL);
}
@Override
diff --git a/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/ExperienceMechanic.java b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/ExperienceMechanic.java
new file mode 100644
index 00000000..61ae176e
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/ExperienceMechanic.java
@@ -0,0 +1,46 @@
+package net.Indyuce.mmocore.skill.custom.mechanic;
+
+import io.lumine.mythic.lib.skill.SkillMetadata;
+import io.lumine.mythic.lib.skill.custom.mechanic.type.TargetMechanic;
+import io.lumine.mythic.lib.util.DoubleFormula;
+import io.lumine.mythic.lib.util.configobject.ConfigObject;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.experience.EXPSource;
+import net.Indyuce.mmocore.experience.SimpleExperienceObject;
+import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
+import org.apache.commons.lang.Validate;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+public class ExperienceMechanic extends TargetMechanic {
+ @NotNull
+ private final DoubleFormula amount;
+ @NotNull
+ private final EXPSource source;
+ @NotNull
+ private final ExperienceDispenser dispenser;
+
+ public ExperienceMechanic(ConfigObject config) {
+ super(config);
+
+ config.validateKeys("amount");
+ amount = config.getDoubleFormula("amount");
+
+ if (config.contains("profession")) {
+ String id = config.getString("profession").toLowerCase().replace("_", "-");
+ Validate.isTrue(MMOCore.plugin.professionManager.has(id), "Could not find profession");
+ dispenser = MMOCore.plugin.professionManager.get(id);
+ } else
+ dispenser = new SimpleExperienceObject();
+ source = config.contains("source") ? EXPSource.valueOf(config.getString("source").toUpperCase()) : EXPSource.QUEST;
+ }
+
+ @Override
+ public void cast(SkillMetadata meta, Entity target) {
+ Validate.isTrue(target instanceof Player, "Target is not a player");
+ PlayerData targetData = PlayerData.get(target.getUniqueId());
+ dispenser.giveExperience(targetData, amount.evaluate(meta), null, source);
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/ManaMechanic.java b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/ManaMechanic.java
index ebd6e8b6..49f93831 100644
--- a/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/ManaMechanic.java
+++ b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/ManaMechanic.java
@@ -13,6 +13,7 @@ import org.bukkit.entity.Player;
public class ManaMechanic extends TargetMechanic {
private final DoubleFormula amount;
+ private final Operation operation;
private final PlayerResourceUpdateEvent.UpdateReason reason;
public ManaMechanic(ConfigObject config) {
@@ -22,12 +23,18 @@ public class ManaMechanic extends TargetMechanic {
amount = new DoubleFormula(config.getString("amount"));
reason = PlayerResourceUpdateEvent.UpdateReason.valueOf(UtilityMethods.enumName(config.getString("reason", "CUSTOM")));
+ operation = config.contains("operation") ? Operation.valueOf(config.getString("operation").toUpperCase()) : Operation.GIVE;
}
@Override
public void cast(SkillMetadata meta, Entity target) {
Validate.isTrue(target instanceof Player, "Target is not a player");
PlayerData targetData = PlayerData.get(target.getUniqueId());
- targetData.giveMana(amount.evaluate(meta), reason);
+ if (operation == Operation.GIVE)
+ targetData.giveMana(amount.evaluate(meta), reason);
+ else if (operation == Operation.SET)
+ targetData.setMana(amount.evaluate(meta));
+ else if (operation == Operation.TAKE)
+ targetData.giveMana(-amount.evaluate(meta), reason);
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/Operation.java b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/Operation.java
new file mode 100644
index 00000000..ea05f52c
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/Operation.java
@@ -0,0 +1,7 @@
+package net.Indyuce.mmocore.skill.custom.mechanic;
+
+public enum Operation {
+ GIVE,
+ SET,
+ TAKE
+}
\ No newline at end of file
diff --git a/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StaminaMechanic.java b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StaminaMechanic.java
index 3d6e4bd8..88f28384 100644
--- a/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StaminaMechanic.java
+++ b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StaminaMechanic.java
@@ -13,6 +13,7 @@ import org.bukkit.entity.Player;
public class StaminaMechanic extends TargetMechanic {
private final DoubleFormula amount;
+ private final Operation operation;
private final PlayerResourceUpdateEvent.UpdateReason reason;
public StaminaMechanic(ConfigObject config) {
@@ -22,12 +23,18 @@ public class StaminaMechanic extends TargetMechanic {
amount = new DoubleFormula(config.getString("amount"));
reason = PlayerResourceUpdateEvent.UpdateReason.valueOf(UtilityMethods.enumName(config.getString("reason", "CUSTOM")));
+ operation = config.contains("operation") ? Operation.valueOf(config.getString("operation").toUpperCase()) : Operation.GIVE;
}
@Override
public void cast(SkillMetadata meta, Entity target) {
Validate.isTrue(target instanceof Player, "Target is not a player");
PlayerData targetData = PlayerData.get(target.getUniqueId());
- targetData.giveStamina(amount.evaluate(meta), reason);
+ if (operation == Operation.GIVE)
+ targetData.giveStamina(amount.evaluate(meta), reason);
+ else if (operation == Operation.SET)
+ targetData.setStamina(amount.evaluate(meta));
+ else if (operation == Operation.TAKE)
+ targetData.giveStamina(-amount.evaluate(meta), reason);
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StelliumMechanic.java b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StelliumMechanic.java
index 92ecb179..e104bbcb 100644
--- a/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StelliumMechanic.java
+++ b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StelliumMechanic.java
@@ -13,6 +13,7 @@ import org.bukkit.entity.Player;
public class StelliumMechanic extends TargetMechanic {
private final DoubleFormula amount;
+ private final Operation operation;
private final PlayerResourceUpdateEvent.UpdateReason reason;
public StelliumMechanic(ConfigObject config) {
@@ -22,12 +23,18 @@ public class StelliumMechanic extends TargetMechanic {
amount = new DoubleFormula(config.getString("amount"));
reason = PlayerResourceUpdateEvent.UpdateReason.valueOf(UtilityMethods.enumName(config.getString("reason", "CUSTOM")));
+ operation = config.contains("operation") ? Operation.valueOf(config.getString("operation").toUpperCase()) : Operation.GIVE;
}
@Override
public void cast(SkillMetadata meta, Entity target) {
Validate.isTrue(target instanceof Player, "Target is not a player");
PlayerData targetData = PlayerData.get(target.getUniqueId());
- targetData.giveStellium(amount.evaluate(meta), reason);
+ if (operation == Operation.GIVE)
+ targetData.giveStellium(amount.evaluate(meta), reason);
+ else if (operation == Operation.SET)
+ targetData.setStellium(amount.evaluate(meta));
+ else if (operation == Operation.TAKE)
+ targetData.giveStellium(-amount.evaluate(meta), reason);
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Neptune_Gift.java b/src/main/java/net/Indyuce/mmocore/skill/list/Neptune_Gift.java
index bf45e0f4..71c036f3 100644
--- a/src/main/java/net/Indyuce/mmocore/skill/list/Neptune_Gift.java
+++ b/src/main/java/net/Indyuce/mmocore/skill/list/Neptune_Gift.java
@@ -5,7 +5,6 @@ import io.lumine.mythic.lib.skill.SkillMetadata;
import io.lumine.mythic.lib.skill.handler.SkillHandler;
import io.lumine.mythic.lib.skill.result.def.SimpleSkillResult;
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
-import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -29,7 +28,6 @@ public class Neptune_Gift extends SkillHandler implements Lis
@EventHandler
public void a(PlayerResourceUpdateEvent event) {
- PlayerData data = event.getData();
if (event.getPlayer().getLocation().getBlock().getType() == Material.WATER) {
PassiveSkill skill = event.getData().getMMOPlayerData().getPassiveSkillMap().getSkill(this);
if (skill == null)
diff --git a/src/main/java/net/Indyuce/mmocore/util/HashableLocation.java b/src/main/java/net/Indyuce/mmocore/util/HashableLocation.java
index 0ef2336e..1bc63bd6 100644
--- a/src/main/java/net/Indyuce/mmocore/util/HashableLocation.java
+++ b/src/main/java/net/Indyuce/mmocore/util/HashableLocation.java
@@ -2,6 +2,7 @@ package net.Indyuce.mmocore.util;
import org.bukkit.Location;
import org.bukkit.World;
+import org.jetbrains.annotations.NotNull;
import java.util.Objects;
@@ -9,7 +10,7 @@ public class HashableLocation {
private final World world;
private final int x, y, z;
- public HashableLocation(Location loc) {
+ public HashableLocation(@NotNull Location loc) {
this.world = loc.getWorld();
this.x = loc.getBlockX();
this.y = loc.getBlockY();
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index 93027bb8..d7eb3cdb 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -159,6 +159,9 @@ party:
# that feature.
max-level-difference: 3
+ # When enabled, being in a party also splits profession exp
+ profession-exp-split: false
+
# Redirects vanilla experience obtained to MMOCore
# class experience. You can define the % of the vanilla
# experience that is being transfered as MMOCore exp.
diff --git a/src/main/resources/default/gui/attribute-view.yml b/src/main/resources/default/gui/attribute-view.yml
index a93b8d6b..444a33e2 100644
--- a/src/main/resources/default/gui/attribute-view.yml
+++ b/src/main/resources/default/gui/attribute-view.yml
@@ -32,7 +32,7 @@ items:
- ''
- '&8When Leveled Up:'
- '&7 +{buff_weapon_damage}% Weapon Damage (&a+{total_weapon_damage}%&7)'
- - '&7 +{buff_max_health}% Max Health (&a+{total_max_health}&7)'
+ - '&7 +{buff_max_health}% Max Health (&a+{total_max_health}%&7)'
- ''
- '&eClick to level up for 1 attribute point.'
- '&eShift-Click to level up for {shift_points} attribute points.'
diff --git a/src/main/resources/default/messages.yml b/src/main/resources/default/messages.yml
index 5ff5d69a..f15c0711 100644
--- a/src/main/resources/default/messages.yml
+++ b/src/main/resources/default/messages.yml
@@ -110,7 +110,7 @@ already-in-party: '&c{player} is already in your party.'
party-invite:
- '{"text":""}'
- '{"text":"&6{player} &ehas invited you to their party!"}'
-- '[{"text":" ","hoverEvent":{}},{"text":"&8[&a&lACCEPT&8]","clickEvent":{"action":"run_command","value":"/party accept {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to accept!"}},{"text":"&r ","hoverEvent":{}},{"text":"&8[&c&lDENY&8]","clickEvent":{"action":"run_command","value":"/party deny {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to deny."}}]'
+- '[{"text":" "},{"text":"&8[&a&lACCEPT&8]","clickEvent":{"action":"run_command","value":"/party accept {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to accept!"}},{"text":"&r "},{"text":"&8[&c&lDENY&8]","clickEvent":{"action":"run_command","value":"/party deny {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to deny."}}]'
- '{"text":""}'
party-is-full: '&cSorry, your party is full.'
party-joined: '&eYou successfully joined &6{owner}&e''s party.'
@@ -118,7 +118,7 @@ party-joined-other: '&6{player}&e joined your party!'
transfer-party-ownership: '&eYou were transfered the party ownership.'
kick-from-party: '&eYou successfully kicked &6{player}&e.'
party-invite-cooldown: '&cPlease wait {cooldown} before inviting {player}.'
-high-level-difference: '&cYou cannot invite {player} as the level difference is too high.'
+high-level-difference: '&cYou cannot invite {player} as the level difference is too high ({diff}).'
# Guilds
guild-chat: '&a[{tag}] {player}: {message}'
@@ -127,7 +127,7 @@ already-in-guild: '&c{player} is already in your guild.'
guild-invite:
- '{"text":""}'
- '{"text":"&6{player} &ehas invited you to their guild!"}'
-- '[{"text":" ","hoverEvent":{}},{"text":"&8[&a&lACCEPT&8]","clickEvent":{"action":"run_command","value":"/guild accept {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to accept!"}},{"text":"&r ","hoverEvent":{}},{"text":"&8[&c&lDENY&8]","clickEvent":{"action":"run_command","value":"/guild deny {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to deny."}}]'
+- '[{"text":" "},{"text":"&8[&a&lACCEPT&8]","clickEvent":{"action":"run_command","value":"/guild accept {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to accept!"}},{"text":"&r "},{"text":"&8[&c&lDENY&8]","clickEvent":{"action":"run_command","value":"/guild deny {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to deny."}}]'
- '{"text":""}'
#guild-is-full: '&cSorry, your guild is full.' -Unused right now
guild-joined: '&eYou successfully joined &6{owner}&e''s guild.'