From 9a315e9431cafda1fc68cf6954af7a772863b30d Mon Sep 17 00:00:00 2001 From: Indyuce Date: Thu, 21 Apr 2022 20:45:07 +0200 Subject: [PATCH 01/39] Fixed default attribute configs --- src/main/resources/default/gui/attribute-view.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/default/gui/attribute-view.yml b/src/main/resources/default/gui/attribute-view.yml index 49c1187a..304eeda4 100644 --- a/src/main/resources/default/gui/attribute-view.yml +++ b/src/main/resources/default/gui/attribute-view.yml @@ -31,7 +31,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.' - '&e◆ Current Attribute Points: {attribute_points}' @@ -49,7 +49,7 @@ items: - '&8When Leveled Up:' - '&7 +{buff_physical_damage}% Physical Damage (&a+{total_physical_damage}%&7)' - '&7 +{buff_projectile_damage}% Projectile Damage (&a+{total_projectile_damage}%&7)' - - '&7 +{buff_attack_speed} Attack Speed (&a+{total_attack_speed}&7)' + - '&7 +{buff_attack_speed}% Attack Speed (&a+{total_attack_speed}&7)' - '' - '&eClick to level up for 1 attribute point.' - '&e◆ Current Attribute Points: {attribute_points}' From 93377b6027b56a50038e2d67e19b7f54b1d2caea Mon Sep 17 00:00:00 2001 From: Indyuce Date: Mon, 25 Apr 2022 21:09:01 +0200 Subject: [PATCH 02/39] Fixed chest tier chance rolling --- .../Indyuce/mmocore/loot/chest/ChestTier.java | 7 +++++-- .../mmocore/loot/chest/LootChestRegion.java | 19 ++++++++++++------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/ChestTier.java b/src/main/java/net/Indyuce/mmocore/loot/chest/ChestTier.java index 770c7986..de9ea2a3 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/chest/ChestTier.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/ChestTier.java @@ -10,8 +10,7 @@ public class ChestTier { private final TierEffect effect; private final ScalingFormula capacity; private final DropTable table; - - public final double chance; + private final double chance; public ChestTier(ConfigurationSection config) { effect = config.isConfigurationSection("effect") ? new TierEffect(config.getConfigurationSection("effect")) : null; @@ -24,6 +23,10 @@ public class ChestTier { return capacity.calculate(player.getLevel()); } + public double getChance() { + return chance; + } + public DropTable getDropTable() { return table; } diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java index ef7e8217..c234d155 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java @@ -119,14 +119,19 @@ public class LootChestRegion { // TODO stat to increase chance to get higher tiers? public ChestTier rollTier() { - double s = 0; - for (ChestTier tier : tiers) { - if (random.nextDouble() < tier.chance / (1 - s)) - return tier; - s += tier.chance; - } + // Calculate sum of all chances and then normalize + double norm = 0; + for (ChestTier tier : tiers) + norm += tier.getChance(); - return tiers.stream().findAny().orElse(null); + Validate.isTrue(norm > 0, "No tier was found"); + + double sum = 0; + for (ChestTier tier : tiers) + if (random.nextDouble() < (sum += tier.getChance()) / norm) + return tier; + + throw new RuntimeException("Could not roll random chest tier"); } public Location getRandomLocation(Location center) { From 1765b15707c6ccf1056b251376a8c55f5f454eae Mon Sep 17 00:00:00 2001 From: Indyuce Date: Tue, 26 Apr 2022 14:35:12 +0200 Subject: [PATCH 03/39] Improved party target restriction --- .../java/net/Indyuce/mmocore/MMOCore.java | 6 ++-- .../comp/MMOCoreTargetRestriction.java | 28 ------------------- .../party/PartyMemberTargetRestriction.java | 20 +++++++++++++ .../party/provided/MMOCorePartyModule.java | 1 - .../provided}/PartyListener.java | 25 +---------------- 5 files changed, 24 insertions(+), 56 deletions(-) delete mode 100644 src/main/java/net/Indyuce/mmocore/comp/MMOCoreTargetRestriction.java create mode 100644 src/main/java/net/Indyuce/mmocore/party/PartyMemberTargetRestriction.java rename src/main/java/net/Indyuce/mmocore/{listener => party/provided}/PartyListener.java (61%) diff --git a/src/main/java/net/Indyuce/mmocore/MMOCore.java b/src/main/java/net/Indyuce/mmocore/MMOCore.java index bb02fa74..cd21f590 100644 --- a/src/main/java/net/Indyuce/mmocore/MMOCore.java +++ b/src/main/java/net/Indyuce/mmocore/MMOCore.java @@ -12,7 +12,6 @@ import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource; import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.api.util.debug.DebugMode; import net.Indyuce.mmocore.command.*; -import net.Indyuce.mmocore.comp.MMOCoreTargetRestriction; import net.Indyuce.mmocore.comp.citizens.CitizenInteractEventListener; import net.Indyuce.mmocore.comp.citizens.CitizensMMOLoader; import net.Indyuce.mmocore.comp.mythicmobs.MythicHook; @@ -41,6 +40,7 @@ import net.Indyuce.mmocore.manager.profession.*; import net.Indyuce.mmocore.manager.social.BoosterManager; import net.Indyuce.mmocore.manager.social.PartyManager; import net.Indyuce.mmocore.manager.social.RequestManager; +import net.Indyuce.mmocore.party.PartyMemberTargetRestriction; import net.Indyuce.mmocore.party.PartyModule; import net.Indyuce.mmocore.party.PartyModuleType; import net.Indyuce.mmocore.party.provided.MMOCorePartyModule; @@ -116,8 +116,8 @@ public class MMOCore extends LuminePlugin { return; } - // Register target restrictions due to MMOCore in MythicLib - MythicLib.plugin.getEntities().registerRestriction(new MMOCoreTargetRestriction()); + // Register MMOCore-specific target restrictions + MythicLib.plugin.getEntities().registerRestriction(new PartyMemberTargetRestriction()); // Register extra objective, drop items... if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null) diff --git a/src/main/java/net/Indyuce/mmocore/comp/MMOCoreTargetRestriction.java b/src/main/java/net/Indyuce/mmocore/comp/MMOCoreTargetRestriction.java deleted file mode 100644 index 5935b582..00000000 --- a/src/main/java/net/Indyuce/mmocore/comp/MMOCoreTargetRestriction.java +++ /dev/null @@ -1,28 +0,0 @@ -package net.Indyuce.mmocore.comp; - -import io.lumine.mythic.lib.comp.target.InteractionType; -import io.lumine.mythic.lib.comp.target.TargetRestriction; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.party.AbstractParty; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; - -import java.util.Optional; - -public class MMOCoreTargetRestriction implements TargetRestriction { - - @Override - public boolean canTarget(Player player, LivingEntity target, InteractionType interaction) { - - if (interaction.isOffense() && target instanceof Player && PlayerData.has(target.getUniqueId())) { - PlayerData targetData = PlayerData.get(target.getUniqueId()); - - // Check for the same party - AbstractParty party = targetData.getParty(); - if (party != null && party.hasMember(player)) - return false; - } - - return true; - } -} diff --git a/src/main/java/net/Indyuce/mmocore/party/PartyMemberTargetRestriction.java b/src/main/java/net/Indyuce/mmocore/party/PartyMemberTargetRestriction.java new file mode 100644 index 00000000..d2a6989f --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/party/PartyMemberTargetRestriction.java @@ -0,0 +1,20 @@ +package net.Indyuce.mmocore.party; + +import io.lumine.mythic.lib.comp.target.InteractionType; +import io.lumine.mythic.lib.comp.target.TargetRestriction; +import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.player.PlayerData; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; + +public class PartyMemberTargetRestriction implements TargetRestriction { + + @Override + public boolean canTarget(Player player, LivingEntity livingEntity, InteractionType interactionType) { + if (!interactionType.isOffense() || !(livingEntity instanceof Player) || livingEntity.hasMetadata("NPC")) + return true; + + AbstractParty party = MMOCore.plugin.partyModule.getParty(PlayerData.get(player)); + return party == null || !party.hasMember((Player) livingEntity); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/party/provided/MMOCorePartyModule.java b/src/main/java/net/Indyuce/mmocore/party/provided/MMOCorePartyModule.java index 98ad8656..3c0155cb 100644 --- a/src/main/java/net/Indyuce/mmocore/party/provided/MMOCorePartyModule.java +++ b/src/main/java/net/Indyuce/mmocore/party/provided/MMOCorePartyModule.java @@ -2,7 +2,6 @@ package net.Indyuce.mmocore.party.provided; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.listener.PartyListener; import net.Indyuce.mmocore.party.PartyModule; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; diff --git a/src/main/java/net/Indyuce/mmocore/listener/PartyListener.java b/src/main/java/net/Indyuce/mmocore/party/provided/PartyListener.java similarity index 61% rename from src/main/java/net/Indyuce/mmocore/listener/PartyListener.java rename to src/main/java/net/Indyuce/mmocore/party/provided/PartyListener.java index f5ed1be4..10d0a69d 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/PartyListener.java +++ b/src/main/java/net/Indyuce/mmocore/party/provided/PartyListener.java @@ -1,16 +1,10 @@ -package net.Indyuce.mmocore.listener; +package net.Indyuce.mmocore.party.provided; -import io.lumine.mythic.lib.api.event.PlayerAttackEvent; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.event.social.PartyChatEvent; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.manager.ConfigManager.SimpleMessage; -import net.Indyuce.mmocore.party.AbstractParty; -import net.Indyuce.mmocore.party.provided.MMOCorePartyModule; -import net.Indyuce.mmocore.party.provided.Party; import org.bukkit.Bukkit; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -45,21 +39,4 @@ public class PartyListener implements Listener { party.getOnlineMembers().forEach(member -> format.send(member.getPlayer())); }); } - - /** - * Cancel damage of players from the same party - * - * @deprecated This should be useful with the {@link io.lumine.mythic.lib.comp.target.TargetRestriction} update - */ - @Deprecated - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void b(PlayerAttackEvent event) { - LivingEntity entity = event.getEntity(); - if (entity instanceof Player && !entity.hasMetadata("NPC")) { - PlayerData targetData = PlayerData.get((Player) event.getEntity()); - AbstractParty party = targetData.getParty(); - if (party != null && party.hasMember(event.getData().getPlayer())) - event.setCancelled(true); - } - } } From b92125c039efea56d017559742c792334e78e64d Mon Sep 17 00:00:00 2001 From: Guillaume Date: Thu, 28 Apr 2022 09:18:16 +0200 Subject: [PATCH 04/39] Add files --- .../java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java b/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java index 686b78a3..c33637e8 100644 --- a/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java +++ b/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java @@ -111,6 +111,7 @@ public class KeyCombos implements Listener { return; } + // Adding pressed key CustomSkillCastingHandler casting = (CustomSkillCastingHandler) playerData.getSkillCasting(); casting.current.registerKey(event.getPressed()); From 41720d90486b07fa655fd1076daacbd840199838 Mon Sep 17 00:00:00 2001 From: Guillaume Date: Thu, 28 Apr 2022 13:43:33 +0200 Subject: [PATCH 05/39] Use PersistentDataCContainer instead of NBT, change the system of WayPoints with Djikstra Algorithm --- .../Indyuce/mmocore/gui/WaypointViewer.java | 24 ++- .../Indyuce/mmocore/waypoint/Waypoint.java | 148 +++++++++++++++++- src/main/resources/default/gui/waypoints.yml | 1 + 3 files changed, 164 insertions(+), 9 deletions(-) diff --git a/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java b/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java index 385db1ce..c8f59612 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java +++ b/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java @@ -1,7 +1,5 @@ package net.Indyuce.mmocore.gui; -import io.lumine.mythic.lib.api.item.ItemTag; -import io.lumine.mythic.lib.api.item.NBTItem; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerActivity; import net.Indyuce.mmocore.api.player.PlayerData; @@ -15,13 +13,16 @@ import net.Indyuce.mmocore.waypoint.Waypoint; import net.Indyuce.mmocore.waypoint.WaypointOption; import org.apache.commons.lang.Validate; import org.bukkit.Material; +import org.bukkit.NamespacedKey; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; import java.util.ArrayList; import java.util.List; -import java.util.Objects; public class WaypointViewer extends EditableInventory { public WaypointViewer() { @@ -103,13 +104,16 @@ public class WaypointViewer extends EditableInventory { return locked.display(inv, n); // Waypoints are not linked - if (inv.current != null && !inv.current.hasDestination(waypoint)) + if (inv.current != null && inv.current.getPath(waypoint)==null) return notLinked.display(inv, n); // Not dynamic waypoint if (inv.current == null && !waypoint.hasOption(WaypointOption.DYNAMIC)) return notDynamic.display(inv, n); + //Dynamic waypoint + if(waypoint.hasOption(WaypointOption.DYNAMIC)&&inv.current==null) + // Stellium cost if (waypoint.getCost(inv.current == null ? CostType.DYNAMIC_USE : CostType.NORMAL_USE) > inv.getPlayerData().getStellium()) return noStellium.display(inv, n); @@ -129,7 +133,11 @@ public class WaypointViewer extends EditableInventory { // If a player can teleport to another waypoint given his location Waypoint waypoint = inv.waypoints.get(inv.page * inv.getEditable().getByFunction("waypoint").getSlots().size() + n); - return NBTItem.get(disp).addTag(new ItemTag("waypointId", waypoint.getId())).toItem(); + ItemMeta meta=disp.getItemMeta(); + PersistentDataContainer container=meta.getPersistentDataContainer(); + container.set(new NamespacedKey(MMOCore.plugin,"waypointId"),PersistentDataType.STRING,waypoint.getId()); + disp.setItemMeta(meta); + return disp; } @Override @@ -149,6 +157,7 @@ public class WaypointViewer extends EditableInventory { public class WaypointViewerInventory extends GeneratedInventory { private final List waypoints = new ArrayList<>(MMOCore.plugin.waypointManager.getAll()); private final Waypoint current; + private final ArrayList paths; private final CostType waypointCostType; private int page; @@ -157,6 +166,7 @@ public class WaypointViewer extends EditableInventory { super(playerData, editable); this.current = current; + paths=current!=null? current.getAllPath() : null; this.waypointCostType = current == null ? CostType.DYNAMIC_USE : CostType.NORMAL_USE; } @@ -180,7 +190,9 @@ public class WaypointViewer extends EditableInventory { } if (item.getFunction().equals("waypoint")) { - String tag = NBTItem.get(event.getCurrentItem()).getString("waypointId"); + PersistentDataContainer container =event.getCurrentItem().getItemMeta().getPersistentDataContainer(); + String tag =container.get(new NamespacedKey(MMOCore.plugin,"wayPointId"), PersistentDataType.STRING); + if (tag.equals("")) return; diff --git a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java index f6d609b7..c33058e5 100644 --- a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java +++ b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java @@ -1,11 +1,13 @@ package net.Indyuce.mmocore.waypoint; +import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.player.Unlockable; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.craftbukkit.libs.jline.internal.Nullable; import org.bukkit.entity.Player; import java.util.*; @@ -21,7 +23,7 @@ public class Waypoint implements Unlockable { *

* If it's empty it can access any waypoint. */ - private final Set destinations = new HashSet<>(); + private final Map destinations = new HashMap<>(); /** * Waypoint options saved here. @@ -46,7 +48,14 @@ public class Waypoint implements Unlockable { for (WaypointOption option : WaypointOption.values()) options.put(option, config.getBoolean("option." + option.getPath(), option.getDefaultValue())); - destinations.addAll(config.getStringList("linked")); + //We load all the linked WayPoints + ConfigurationSection section=config.getConfigurationSection("linked"); + for(String key: section.getKeys(false)) { + destinations.put(key,config.getInt(key)); + } + + + //destinations.addAll(config.getStringList("linked")); } public String getId() { @@ -61,14 +70,90 @@ public class Waypoint implements Unlockable { return loc; } + /** * @param other Another waypoint * @return If any player standing on that waypoint can teleport to given waypoint */ + @Deprecated public boolean hasDestination(Waypoint other) { - return destinations.isEmpty() || destinations.contains(other.getId()); + return destinations.isEmpty() || destinations.keySet().contains(other.getId()); } + /** + * Checks directly if the waypoint is directly linked to the current one + * + * @return Integer.POSITIVE_INFINITY if the way point is not linked + */ + public int getSimpleCostDestination(Waypoint waypoint) { + if (!destinations.keySet().contains(waypoint.getId())) + return Integer.MAX_VALUE; + return destinations.get(waypoint.getId()); + } + + + public ArrayList getAllPath() { + //All the WayPoints that have been registered + ArrayList checkedPoints = new ArrayList<>(); + //All the path + ArrayList paths = new ArrayList(); + ArrayList pointsToCheck = new ArrayList<>(); + pointsToCheck.add(new PathInfo(this)); + + while (pointsToCheck.size() != 0) { + PathInfo checked = pointsToCheck.get(0); + pointsToCheck.remove(0); + paths.add(checked); + checkedPoints.add(checked.getFinalWaypoint()); + + for (String wayPointId : checked.getFinalWaypoint().destinations.keySet()) { + Waypoint toCheck = MMOCore.plugin.waypointManager.get(wayPointId); + if (!checkedPoints.contains(toCheck)) { + PathInfo toCheckInfo = checked.addWayPoint(toCheck); + //We keep pointsToCheck ordered + pointsToCheck = toCheckInfo.addInOrder(pointsToCheck); + } + } + } + return paths; + + } + + + @Nullable + public PathInfo getPath(Waypoint targetWaypoint) { + //All the WayPoints that have been registered + ArrayList checkedPoints = new ArrayList<>(); + //All the path + ArrayList paths = new ArrayList(); + ArrayList pointsToCheck = new ArrayList<>(); + pointsToCheck.add(new PathInfo(this)); + + while (pointsToCheck.size() != 0) { + PathInfo checked = pointsToCheck.get(0); + pointsToCheck.remove(0); + paths.add(checked); + checkedPoints.add(checked.getFinalWaypoint()); + + if(checked.getFinalWaypoint().equals(targetWaypoint)) + return checked; + + for (String wayPointId : checked.getFinalWaypoint().destinations.keySet()) { + Waypoint toCheck = MMOCore.plugin.waypointManager.get(wayPointId); + if (!checkedPoints.contains(toCheck)) { + PathInfo toCheckInfo = checked.addWayPoint(toCheck); + //We keep pointsToCheck ordered + pointsToCheck = toCheckInfo.addInOrder(pointsToCheck); + } + } + } + + //If no path has been found we return null + return null; + + } + + public double getCost(CostType type) { return costs.getOrDefault(type, 0d); } @@ -118,4 +203,61 @@ public class Waypoint implements Unlockable { return new Location(world, x, y, z, yaw, pitch); } + + public class PathInfo { + private final ArrayList waypoints; + private final int cost; + + public ArrayList getWaypoints() { + return waypoints; + } + + public int getCost() { + return cost; + } + + public PathInfo(Waypoint waypoint) { + this.waypoints = (ArrayList) Arrays.asList(waypoint); + cost = 0; + } + + + public ArrayList addInOrder(ArrayList pathInfos) { + int index = 0; + while (index < pathInfos.size()) { + if (cost < pathInfos.get(index).cost) { + pathInfos.set(index, this); + return pathInfos; + } + } + //If index==pathInfos.size() we add the waypoint at the end + pathInfos.add(this); + return pathInfos; + } + + + + public PathInfo(ArrayList waypoints, int cost) { + this.waypoints = waypoints; + this.cost = cost; + } + + public PathInfo addWayPoint(Waypoint waypoint) { + Validate.isTrue(!waypoints.contains(waypoint), "You can't create cyclic path"); + ArrayList newWaypoints = new ArrayList<>(); + newWaypoints.addAll(waypoints); + newWaypoints.add(waypoint); + int cost=this.cost+getFinalWaypoint().getSimpleCostDestination(waypoint); + return new PathInfo(newWaypoints,cost); + } + + + public Waypoint getInitialWaypoint() { + return waypoints.get(0); + } + + public Waypoint getFinalWaypoint() { + return waypoints.get(waypoints.size() - 1); + } + } } \ No newline at end of file diff --git a/src/main/resources/default/gui/waypoints.yml b/src/main/resources/default/gui/waypoints.yml index 074e6aca..10bf393d 100644 --- a/src/main/resources/default/gui/waypoints.yml +++ b/src/main/resources/default/gui/waypoints.yml @@ -61,6 +61,7 @@ items: lore: - '&7You can teleport to this waypoint.' + - '&7 Intermediary waypoints : {intermediary_waypoints}' - '&7Click to teleport for &b{current_cost} &7Stellium.' next: From c8096765b4401afd25b3927bceb01fa86ceb360c Mon Sep 17 00:00:00 2001 From: Guillaume Date: Thu, 28 Apr 2022 14:34:42 +0200 Subject: [PATCH 06/39] Changes in PlayerData for warp fonction and in WayPointViewer / gui/waypoints.yml --- .../mmocore/api/player/PlayerData.java | 12 ++-- .../Indyuce/mmocore/gui/WaypointViewer.java | 59 ++++++++++++------- .../Indyuce/mmocore/waypoint/Waypoint.java | 43 ++++++++++---- src/main/resources/default/gui/waypoints.yml | 6 +- 4 files changed, 78 insertions(+), 42 deletions(-) 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 0fae0302..dc9b8359 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java @@ -457,9 +457,9 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc * Teleports the player to a specific waypoint. This applies * the stellium waypoint cost and plays the teleport animation. * - * @param waypoint Target waypoint + * @param target Target waypoint */ - public void warp(Waypoint waypoint, CostType costType) { + public void warp(Waypoint source, Waypoint target, CostType costType) { /* * This cooldown is only used internally to make sure the player is not @@ -467,8 +467,10 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc * player waypoints data */ setLastActivity(PlayerActivity.USE_WAYPOINT); + Validate.isTrue(source!=null||costType!=CostType.NORMAL_USE,"You must precise a source to use normal waypoint" ); + final double cost = costType == CostType.DYNAMIC_USE ? target.getDynamicCost() : source.getCost(target); + - final double cost = waypoint.getCost(costType); giveStellium(-cost, PlayerResourceUpdateEvent.UpdateReason.USE_WAYPOINT); new BukkitRunnable() { @@ -491,7 +493,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc MMOCore.plugin.configManager.getSimpleMessage("warping-comencing", "left", "" + ((120 - t) / 20)).send(getPlayer()); if (t++ >= 100) { - getPlayer().teleport(waypoint.getLocation()); + getPlayer().teleport(target.getLocation()); getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 20, 1, false, false)); MMOCore.plugin.soundManager.getSound(SoundEvent.WARP_TELEPORT).playTo(getPlayer()); cancel(); @@ -869,7 +871,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc * checks if they could potentially upgrade to one of these * * @return If the player can change its current class to - * a subclass + * a subclass */ public boolean canChooseSubclass() { for (Subclass subclass : getProfess().getSubclasses()) diff --git a/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java b/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java index c8f59612..f913b127 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java +++ b/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java @@ -22,7 +22,9 @@ import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class WaypointViewer extends EditableInventory { public WaypointViewer() { @@ -65,8 +67,8 @@ public class WaypointViewer extends EditableInventory { } public class WaypointItem extends SimplePlaceholderItem { - private final SimplePlaceholderItem noWaypoint, locked; - private final WaypointItemHandler availWaypoint, notLinked, notDynamic, noStellium; + private final SimplePlaceholderItem noWaypoint, locked,notLinked,notDynamic; + private final WaypointItemHandler availWaypoint,noStellium; public WaypointItem(ConfigurationSection config) { super(Material.BARRIER, config); @@ -80,8 +82,8 @@ public class WaypointViewer extends EditableInventory { noWaypoint = new SimplePlaceholderItem(config.getConfigurationSection("no-waypoint")); locked = new SimplePlaceholderItem(config.getConfigurationSection("locked")); - notLinked = new WaypointItemHandler(config.getConfigurationSection("not-a-destination")); - notDynamic = new WaypointItemHandler(config.getConfigurationSection("not-dynamic")); + notLinked = new SimplePlaceholderItem(config.getConfigurationSection("not-a-destination")); + notDynamic = new SimplePlaceholderItem(config.getConfigurationSection("not-dynamic")); noStellium = new WaypointItemHandler(config.getConfigurationSection("not-enough-stellium")); availWaypoint = new WaypointItemHandler(config.getConfigurationSection("display")); } @@ -104,20 +106,23 @@ public class WaypointViewer extends EditableInventory { return locked.display(inv, n); // Waypoints are not linked - if (inv.current != null && inv.current.getPath(waypoint)==null) + if (inv.current != null && !inv.paths.containsKey(waypoint)) return notLinked.display(inv, n); // Not dynamic waypoint if (inv.current == null && !waypoint.hasOption(WaypointOption.DYNAMIC)) return notDynamic.display(inv, n); - //Dynamic waypoint - if(waypoint.hasOption(WaypointOption.DYNAMIC)&&inv.current==null) - // Stellium cost - if (waypoint.getCost(inv.current == null ? CostType.DYNAMIC_USE : CostType.NORMAL_USE) > inv.getPlayerData().getStellium()) + //Dynamic waypoint + if (waypoint.hasOption(WaypointOption.DYNAMIC) && inv.current == null && waypoint.getDynamicCost() > inv.getPlayerData().getStellium()) return noStellium.display(inv, n); + //Normal cost + if (inv.current != null && inv.paths.get(waypoint).getCost() > inv.getPlayerData().getStellium()) + return noStellium.display(inv, n); + + return availWaypoint.display(inv, n); } } @@ -133,9 +138,9 @@ public class WaypointViewer extends EditableInventory { // If a player can teleport to another waypoint given his location Waypoint waypoint = inv.waypoints.get(inv.page * inv.getEditable().getByFunction("waypoint").getSlots().size() + n); - ItemMeta meta=disp.getItemMeta(); - PersistentDataContainer container=meta.getPersistentDataContainer(); - container.set(new NamespacedKey(MMOCore.plugin,"waypointId"),PersistentDataType.STRING,waypoint.getId()); + ItemMeta meta = disp.getItemMeta(); + PersistentDataContainer container = meta.getPersistentDataContainer(); + container.set(new NamespacedKey(MMOCore.plugin, "waypointId"), PersistentDataType.STRING, waypoint.getId()); disp.setItemMeta(meta); return disp; } @@ -146,9 +151,10 @@ public class WaypointViewer extends EditableInventory { Waypoint waypoint = inv.waypoints.get(inv.page * inv.getByFunction("waypoint").getSlots().size() + n); holders.register("name", waypoint.getName()); - holders.register("current_cost", decimal.format(waypoint.getCost(inv.waypointCostType))); - holders.register("normal_cost", decimal.format(waypoint.getCost(CostType.NORMAL_USE))); - holders.register("dynamic_cost", decimal.format(waypoint.getCost(CostType.DYNAMIC_USE))); + holders.register("current_cost", decimal.format(inv.waypointCostType.equals(CostType.DYNAMIC_USE) ? waypoint.getDynamicCost() : inv.paths.get(waypoint).getCost())); + holders.register("normal_cost", decimal.format(inv.paths.get(waypoint).getCost())); + holders.register("dynamic_cost", decimal.format(waypoint.getDynamicCost())); + holders.register("intermediary_waypoints", inv.paths.get(waypoint).displayIntermediaryWayPoints()); return holders; } @@ -157,7 +163,7 @@ public class WaypointViewer extends EditableInventory { public class WaypointViewerInventory extends GeneratedInventory { private final List waypoints = new ArrayList<>(MMOCore.plugin.waypointManager.getAll()); private final Waypoint current; - private final ArrayList paths; + private final Map paths = new HashMap<>(); private final CostType waypointCostType; private int page; @@ -166,7 +172,11 @@ public class WaypointViewer extends EditableInventory { super(playerData, editable); this.current = current; - paths=current!=null? current.getAllPath() : null; + if (current != null) { + for (Waypoint.PathInfo pathInfo : current.getAllPath()) + paths.put(pathInfo.getFinalWaypoint(), pathInfo); + } + this.waypointCostType = current == null ? CostType.DYNAMIC_USE : CostType.NORMAL_USE; } @@ -190,8 +200,8 @@ public class WaypointViewer extends EditableInventory { } if (item.getFunction().equals("waypoint")) { - PersistentDataContainer container =event.getCurrentItem().getItemMeta().getPersistentDataContainer(); - String tag =container.get(new NamespacedKey(MMOCore.plugin,"wayPointId"), PersistentDataType.STRING); + PersistentDataContainer container = event.getCurrentItem().getItemMeta().getPersistentDataContainer(); + String tag = container.get(new NamespacedKey(MMOCore.plugin, "wayPointId"), PersistentDataType.STRING); if (tag.equals("")) return; @@ -210,7 +220,7 @@ public class WaypointViewer extends EditableInventory { } // Waypoint does not have target as destination - if (current != null && !current.hasDestination(waypoint)) { + if (current != null && current.getPath(waypoint)==null) { MMOCore.plugin.configManager.getSimpleMessage("cannot-teleport-to").send(player); return; } @@ -223,7 +233,8 @@ public class WaypointViewer extends EditableInventory { // Stellium cost CostType costType = current == null ? CostType.DYNAMIC_USE : CostType.NORMAL_USE; - double left = waypoint.getCost(costType) - playerData.getStellium(); + double withdraw = current == null ? waypoint.getDynamicCost() : paths.get(waypoint).getCost(); + double left = withdraw - playerData.getStellium(); if (left > 0) { MMOCore.plugin.configManager.getSimpleMessage("not-enough-stellium", "more", decimal.format(left)).send(player); return; @@ -233,7 +244,11 @@ public class WaypointViewer extends EditableInventory { return; player.closeInventory(); - playerData.warp(waypoint, costType); + if (current == null) + playerData.warp(null, waypoint, costType); + else + playerData.warp(current, waypoint, costType); + } } } diff --git a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java index c33058e5..da7696f5 100644 --- a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java +++ b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java @@ -33,8 +33,21 @@ public class Waypoint implements Unlockable { /** * Stellium cost for each action (0 being the default cost) */ + private final double dynamicCost,setSpawnCost; private final Map costs = new HashMap<>(); + public double getDynamicCost() { + return dynamicCost; + } + + public double getSetSpawnCost() { + return setSpawnCost; + } + + public double getCost(Waypoint waypoint) { + return getPath(waypoint).cost; + } + public Waypoint(ConfigurationSection config) { id = Objects.requireNonNull(config, "Could not load config section").getName(); name = Objects.requireNonNull(config.getString("name"), "Could not load waypoint name"); @@ -42,8 +55,9 @@ public class Waypoint implements Unlockable { loc = readLocation(Objects.requireNonNull(config.getString("location"), "Could not read location")); radiusSquared = Math.pow(config.getDouble("radius"), 2); - for (CostType costType : CostType.values()) - costs.put(costType, config.getDouble("cost." + costType.getPath())); + dynamicCost=config.getDouble("cost.dynamic-use"); + setSpawnCost=config.getDouble("cost.set-spawnpoint"); + for (WaypointOption option : WaypointOption.values()) options.put(option, config.getBoolean("option." + option.getPath(), option.getDefaultValue())); @@ -85,7 +99,7 @@ public class Waypoint implements Unlockable { * * @return Integer.POSITIVE_INFINITY if the way point is not linked */ - public int getSimpleCostDestination(Waypoint waypoint) { + private int getSimpleCostDestination(Waypoint waypoint) { if (!destinations.keySet().contains(waypoint.getId())) return Integer.MAX_VALUE; return destinations.get(waypoint.getId()); @@ -153,11 +167,6 @@ public class Waypoint implements Unlockable { } - - public double getCost(CostType type) { - return costs.getOrDefault(type, 0d); - } - public boolean hasOption(WaypointOption option) { return options.get(option); } @@ -206,13 +215,13 @@ public class Waypoint implements Unlockable { public class PathInfo { private final ArrayList waypoints; - private final int cost; + private final double cost; public ArrayList getWaypoints() { return waypoints; } - public int getCost() { + public double getCost() { return cost; } @@ -237,17 +246,27 @@ public class Waypoint implements Unlockable { - public PathInfo(ArrayList waypoints, int cost) { + public PathInfo(ArrayList waypoints, double cost) { this.waypoints = waypoints; this.cost = cost; } + public String displayIntermediaryWayPoints() { + if(waypoints.size()<=2) + return ""; + String result=""; + for(int i=1;i newWaypoints = new ArrayList<>(); newWaypoints.addAll(waypoints); newWaypoints.add(waypoint); - int cost=this.cost+getFinalWaypoint().getSimpleCostDestination(waypoint); + double cost=this.cost+getFinalWaypoint().getSimpleCostDestination(waypoint); return new PathInfo(newWaypoints,cost); } diff --git a/src/main/resources/default/gui/waypoints.yml b/src/main/resources/default/gui/waypoints.yml index 10bf393d..aa696e33 100644 --- a/src/main/resources/default/gui/waypoints.yml +++ b/src/main/resources/default/gui/waypoints.yml @@ -34,7 +34,7 @@ items: lore: - '&7You cannot teleport as the two waypoints are not linked.' - - '&7Teleporting costs &b&l{normal_cost}&7/&b&l{dynamic_cost} &7Stellium.' + # When you cannot teleport to a non dynamic waypoint not-dynamic: @@ -43,9 +43,9 @@ items: lore: - '&7You cannot teleport as you are not standing on a waypoint.' - - '&7Teleporting costs &b&l{normal_cost}&7/&b&l{dynamic_cost} &7Stellium.' - # When you cannot teleport to a non dynamic waypoint + + # When you don't have enough stellium not-enough-stellium: name: '&a{name}' item: ENDER_PEARL From e41749135e15c7cfd3836b50c85ecb71e643743c Mon Sep 17 00:00:00 2001 From: Guillaume Date: Wed, 4 May 2022 11:22:00 +0200 Subject: [PATCH 07/39] Debug waypoints Added Luck and did changes on roolChestTier for LootChest Added possibility to have conditions on dynamic waypoints Added intermediary waypoints even when using dynamic waypoints. --- .../mmocore/api/load/DefaultMMOLoader.java | 9 +- .../mmocore/api/player/PlayerData.java | 6 +- .../mmocore/api/player/stats/StatType.java | 1 + .../Indyuce/mmocore/gui/WaypointViewer.java | 82 +++++++++++------ .../mmocore/loot/chest/LootChestRegion.java | 21 +++-- .../condition/DistanceCondition.java | 39 ++++++++ .../Indyuce/mmocore/waypoint/Waypoint.java | 91 ++++++++++++++----- src/main/resources/default/gui/waypoints.yml | 9 +- .../resources/default/professions/fishing.yml | 2 +- src/main/resources/default/stats.yml | 5 + src/main/resources/default/waypoints.yml | 21 +++-- 11 files changed, 209 insertions(+), 77 deletions(-) create mode 100644 src/main/java/net/Indyuce/mmocore/loot/droptable/condition/DistanceCondition.java diff --git a/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java b/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java index 7b8857b7..074b123d 100644 --- a/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java +++ b/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java @@ -1,16 +1,12 @@ package net.Indyuce.mmocore.api.load; import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; +import net.Indyuce.mmocore.loot.droptable.condition.*; import org.bukkit.configuration.ConfigurationSection; import net.Indyuce.mmocore.api.block.BlockType; import net.Indyuce.mmocore.api.block.SkullBlockType; import net.Indyuce.mmocore.api.block.VanillaBlockType; -import net.Indyuce.mmocore.loot.droptable.condition.BiomeCondition; -import net.Indyuce.mmocore.loot.droptable.condition.Condition; -import net.Indyuce.mmocore.loot.droptable.condition.LevelCondition; -import net.Indyuce.mmocore.loot.droptable.condition.PermissionCondition; -import net.Indyuce.mmocore.loot.droptable.condition.WorldCondition; import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem; import net.Indyuce.mmocore.loot.droptable.dropitem.DropTableDropItem; import net.Indyuce.mmocore.loot.droptable.dropitem.GoldDropItem; @@ -109,6 +105,9 @@ public class DefaultMMOLoader extends MMOLoader { @Override public Condition loadCondition(MMOLineConfig config) { + if(config.getKey().equals("distance")) + return new DistanceCondition(config); + if (config.getKey().equals("world")) return new WorldCondition(config); 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 dc9b8359..75c9d6bc 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java @@ -459,7 +459,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc * * @param target Target waypoint */ - public void warp(Waypoint source, Waypoint target, CostType costType) { + public void warp(Waypoint target, double cost) { /* * This cooldown is only used internally to make sure the player is not @@ -467,10 +467,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc * player waypoints data */ setLastActivity(PlayerActivity.USE_WAYPOINT); - Validate.isTrue(source!=null||costType!=CostType.NORMAL_USE,"You must precise a source to use normal waypoint" ); - final double cost = costType == CostType.DYNAMIC_USE ? target.getDynamicCost() : source.getCost(target); - - giveStellium(-cost, PlayerResourceUpdateEvent.UpdateReason.USE_WAYPOINT); new BukkitRunnable() { diff --git a/src/main/java/net/Indyuce/mmocore/api/player/stats/StatType.java b/src/main/java/net/Indyuce/mmocore/api/player/stats/StatType.java index cfc69000..9f66f9bf 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/stats/StatType.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/stats/StatType.java @@ -61,6 +61,7 @@ public enum StatType { // Utility ADDITIONAL_EXPERIENCE, COOLDOWN_REDUCTION, + CHANCE, // Damage-type based stats MAGIC_DAMAGE, diff --git a/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java b/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java index f913b127..5bfa25f6 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java +++ b/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java @@ -12,6 +12,7 @@ import net.Indyuce.mmocore.waypoint.CostType; import net.Indyuce.mmocore.waypoint.Waypoint; import net.Indyuce.mmocore.waypoint.WaypointOption; import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.configuration.ConfigurationSection; @@ -21,10 +22,7 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class WaypointViewer extends EditableInventory { public WaypointViewer() { @@ -67,8 +65,9 @@ public class WaypointViewer extends EditableInventory { } public class WaypointItem extends SimplePlaceholderItem { - private final SimplePlaceholderItem noWaypoint, locked,notLinked,notDynamic; - private final WaypointItemHandler availWaypoint,noStellium; + private final SimplePlaceholderItem noWaypoint, locked; + private final WaypointItemHandler availWaypoint, noStellium, notLinked, notDynamic, currentWayPoint; + public WaypointItem(ConfigurationSection config) { super(Material.BARRIER, config); @@ -77,15 +76,18 @@ public class WaypointViewer extends EditableInventory { Validate.notNull(config.getConfigurationSection("locked"), "Could not load 'locked' config"); Validate.notNull(config.getConfigurationSection("not-a-destination"), "Could not load 'not-a-destination' config"); Validate.notNull(config.getConfigurationSection("not-dynamic"), "Could not load 'not-dynamic' config"); + Validate.notNull(config.getConfigurationSection("current-waypoint"), "Could not load 'current-waypoint' config"); Validate.notNull(config.getConfigurationSection("not-enough-stellium"), "Could not load 'not-enough-stellium' config"); Validate.notNull(config.getConfigurationSection("display"), "Could not load 'display' config"); + noWaypoint = new SimplePlaceholderItem(config.getConfigurationSection("no-waypoint")); locked = new SimplePlaceholderItem(config.getConfigurationSection("locked")); - notLinked = new SimplePlaceholderItem(config.getConfigurationSection("not-a-destination")); - notDynamic = new SimplePlaceholderItem(config.getConfigurationSection("not-dynamic")); - noStellium = new WaypointItemHandler(config.getConfigurationSection("not-enough-stellium")); - availWaypoint = new WaypointItemHandler(config.getConfigurationSection("display")); + notLinked = new WaypointItemHandler(config.getConfigurationSection("not-a-destination"), true); + notDynamic = new WaypointItemHandler(config.getConfigurationSection("not-dynamic"), true); + currentWayPoint = new WaypointItemHandler(config.getConfigurationSection("current-waypoint"), true); + noStellium = new WaypointItemHandler(config.getConfigurationSection("not-enough-stellium"), false); + availWaypoint = new WaypointItemHandler(config.getConfigurationSection("display"), false); } @Override @@ -102,6 +104,10 @@ public class WaypointViewer extends EditableInventory { // Locked waypoint? Waypoint waypoint = inv.waypoints.get(index); + if (inv.current != null && inv.current.equals(waypoint)) + return currentWayPoint.display(inv, n); + + if (!inv.getPlayerData().hasWaypoint(waypoint)) return locked.display(inv, n); @@ -109,17 +115,13 @@ public class WaypointViewer extends EditableInventory { if (inv.current != null && !inv.paths.containsKey(waypoint)) return notLinked.display(inv, n); + // Not dynamic waypoint - if (inv.current == null && !waypoint.hasOption(WaypointOption.DYNAMIC)) + if (inv.current == null && !inv.paths.containsKey(waypoint)) return notDynamic.display(inv, n); - - //Dynamic waypoint - if (waypoint.hasOption(WaypointOption.DYNAMIC) && inv.current == null && waypoint.getDynamicCost() > inv.getPlayerData().getStellium()) - return noStellium.display(inv, n); - //Normal cost - if (inv.current != null && inv.paths.get(waypoint).getCost() > inv.getPlayerData().getStellium()) + if (inv.paths.get(waypoint).getCost() > inv.getPlayerData().getStellium()) return noStellium.display(inv, n); @@ -128,8 +130,11 @@ public class WaypointViewer extends EditableInventory { } public class WaypointItemHandler extends InventoryItem { - public WaypointItemHandler(ConfigurationSection config) { + private final boolean onlyName; + + public WaypointItemHandler(ConfigurationSection config, boolean onlyName) { super(config); + this.onlyName = onlyName; } @Override @@ -151,10 +156,12 @@ public class WaypointViewer extends EditableInventory { Waypoint waypoint = inv.waypoints.get(inv.page * inv.getByFunction("waypoint").getSlots().size() + n); holders.register("name", waypoint.getName()); - holders.register("current_cost", decimal.format(inv.waypointCostType.equals(CostType.DYNAMIC_USE) ? waypoint.getDynamicCost() : inv.paths.get(waypoint).getCost())); - holders.register("normal_cost", decimal.format(inv.paths.get(waypoint).getCost())); - holders.register("dynamic_cost", decimal.format(waypoint.getDynamicCost())); - holders.register("intermediary_waypoints", inv.paths.get(waypoint).displayIntermediaryWayPoints()); + if (!onlyName) { + holders.register("current_cost",inv.paths.get(waypoint).getCost()); + holders.register("normal_cost", decimal.format(inv.paths.containsKey(waypoint) ? inv.paths.get(waypoint).getCost() : Double.POSITIVE_INFINITY)); + holders.register("dynamic_cost", decimal.format(waypoint.getDynamicCost())); + holders.register("intermediary_waypoints", inv.paths.containsKey(waypoint) ? inv.paths.get(waypoint).displayIntermediaryWayPoints(inv.waypointCostType.equals(CostType.DYNAMIC_USE)) : "none"); + } return holders; } @@ -176,6 +183,23 @@ public class WaypointViewer extends EditableInventory { for (Waypoint.PathInfo pathInfo : current.getAllPath()) paths.put(pathInfo.getFinalWaypoint(), pathInfo); } + if (current == null) { + //We first check all the dynamic waypoints + for (Waypoint waypoint : waypoints) { + if (waypoint.canHaveDynamicUse(playerData.getPlayer())) + paths.put(waypoint,new Waypoint.PathInfo(waypoint, waypoint.getDynamicCost())); + } + //Iterate through all the dynamic points and find all the points it is linked to and the path + HashSet waypointSet = new HashSet<>(paths.keySet()); + for (Waypoint source : waypointSet) { + for (Waypoint.PathInfo target : source.getAllPath()) { + if (!paths.containsKey(target.getFinalWaypoint()) || paths.get(target.getFinalWaypoint()).getCost() > target.getCost()) { + paths.put(target.getFinalWaypoint(), target); + } + } + } + + } this.waypointCostType = current == null ? CostType.DYNAMIC_USE : CostType.NORMAL_USE; } @@ -201,7 +225,8 @@ public class WaypointViewer extends EditableInventory { if (item.getFunction().equals("waypoint")) { PersistentDataContainer container = event.getCurrentItem().getItemMeta().getPersistentDataContainer(); - String tag = container.get(new NamespacedKey(MMOCore.plugin, "wayPointId"), PersistentDataType.STRING); + String tag = container.has(new NamespacedKey(MMOCore.plugin, "waypointId"), PersistentDataType.STRING) ? + container.get(new NamespacedKey(MMOCore.plugin, "waypointId"), PersistentDataType.STRING) : ""; if (tag.equals("")) return; @@ -220,20 +245,20 @@ public class WaypointViewer extends EditableInventory { } // Waypoint does not have target as destination - if (current != null && current.getPath(waypoint)==null) { + if (current != null && current.getPath(waypoint) == null) { MMOCore.plugin.configManager.getSimpleMessage("cannot-teleport-to").send(player); return; } // Not dynamic waypoint - if (current == null && !waypoint.hasOption(WaypointOption.DYNAMIC)) { + if (current == null && !paths.containsKey(waypoint)) { MMOCore.plugin.configManager.getSimpleMessage("not-dynamic-waypoint").send(player); return; } // Stellium cost CostType costType = current == null ? CostType.DYNAMIC_USE : CostType.NORMAL_USE; - double withdraw = current == null ? waypoint.getDynamicCost() : paths.get(waypoint).getCost(); + double withdraw = paths.get(waypoint).getCost(); double left = withdraw - playerData.getStellium(); if (left > 0) { MMOCore.plugin.configManager.getSimpleMessage("not-enough-stellium", "more", decimal.format(left)).send(player); @@ -244,10 +269,7 @@ public class WaypointViewer extends EditableInventory { return; player.closeInventory(); - if (current == null) - playerData.warp(null, waypoint, costType); - else - playerData.warp(current, waypoint, costType); + playerData.warp(waypoint, withdraw); } } diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java index ef7e8217..6e265a3b 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java @@ -4,6 +4,7 @@ import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.event.LootChestSpawnEvent; import net.Indyuce.mmocore.api.player.PlayerActivity; import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.loot.LootBuilder; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; @@ -85,7 +86,7 @@ public class LootChestRegion { player.setLastActivity(PlayerActivity.LOOT_CHEST_SPAWN); // First randomly determine the chest tier - ChestTier tier = rollTier(); + ChestTier tier = rollTier(player); // Find a random location, 20 trials max Location location = getRandomLocation(player.getPlayer().getLocation()); @@ -116,14 +117,22 @@ public class LootChestRegion { MMOCore.plugin.lootChests.register(lootChest); } - // TODO stat to increase chance to get higher tiers? - public ChestTier rollTier() { + public ChestTier rollTier(PlayerData player) { + double chance = player.getStats().getStat(StatType.CHANCE); - double s = 0; + //chance=0 ->the tier.chance remains the same + //chance ->+inf -> the tier.chance becomes the same for everyone, uniform law + //chance=8-> tierChance=sqrt(tierChance) + double sum = 0; for (ChestTier tier : tiers) { - if (random.nextDouble() < tier.chance / (1 - s)) + sum += Math.pow(tier.chance, 1 / Math.pow((1 + chance),1/3)); + } + + double s=0; + for (ChestTier tier : tiers) { + s+=Math.pow(tier.chance, 1 / Math.pow((1 + chance),1/3))/sum; + if (random.nextDouble() < s) return tier; - s += tier.chance; } return tiers.stream().findAny().orElse(null); diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/DistanceCondition.java b/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/DistanceCondition.java new file mode 100644 index 00000000..486ce977 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/DistanceCondition.java @@ -0,0 +1,39 @@ +package net.Indyuce.mmocore.loot.droptable.condition; + +import io.lumine.mythic.lib.api.MMOLineConfig; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.generator.WorldInfo; + + +import java.util.stream.Collectors; + +public class DistanceCondition extends Condition{ + private final Location location; + private final double distance; + + public DistanceCondition(MMOLineConfig config) { + super(config); + Validate.isTrue(config.contains("world")); + Validate.isTrue(config.contains("x")); + Validate.isTrue(config.contains("y")); + Validate.isTrue(config.contains("z")); + Validate.isTrue(config.contains("distance")); + Validate.isTrue(Bukkit.getWorld(config.getString("world"))!=null,"This world doesn't exist"); + location=new Location(Bukkit.getWorld(config.getString("world")),config.getDouble("x"), + config.getDouble("y"),config.getDouble("z")); + distance=config.getDouble("distance"); + } + + @Override + public boolean isMet(ConditionInstance entity) { + Entity entity1=entity.getEntity(); + return entity1.getWorld().equals(location.getWorld())&&location.distance(entity1.getLocation()) dynamicUseConditions = new ArrayList<>(); + private final Map costs = new HashMap<>(); public double getDynamicCost() { @@ -55,21 +62,39 @@ public class Waypoint implements Unlockable { loc = readLocation(Objects.requireNonNull(config.getString("location"), "Could not read location")); radiusSquared = Math.pow(config.getDouble("radius"), 2); - dynamicCost=config.getDouble("cost.dynamic-use"); - setSpawnCost=config.getDouble("cost.set-spawnpoint"); + dynamicCost = config.getDouble("cost.dynamic-use"); + setSpawnCost = config.getDouble("cost.set-spawnpoint"); for (WaypointOption option : WaypointOption.values()) options.put(option, config.getBoolean("option." + option.getPath(), option.getDefaultValue())); //We load all the linked WayPoints - ConfigurationSection section=config.getConfigurationSection("linked"); - for(String key: section.getKeys(false)) { - destinations.put(key,config.getInt(key)); + if (config.contains("linked")) { + ConfigurationSection section = config.getConfigurationSection("linked"); + for (String key : section.getKeys(false)) { + destinations.put(key, section.getInt(key)); + } } + if (config.contains("conditions")) { + List conditions = config.getStringList("conditions"); + for (String condition : conditions) { + dynamicUseConditions.add(MMOCore.plugin.loadManager.loadCondition(new MMOLineConfig(condition))); + } - //destinations.addAll(config.getStringList("linked")); + } + } + + public boolean canHaveDynamicUse(Player player) { + if (!options.get(WaypointOption.DYNAMIC)) + return false; + + for (Condition condition : dynamicUseConditions) { + if (!condition.isMet(new ConditionInstance(player))) + return false; + } + return true; } public String getId() { @@ -149,7 +174,7 @@ public class Waypoint implements Unlockable { paths.add(checked); checkedPoints.add(checked.getFinalWaypoint()); - if(checked.getFinalWaypoint().equals(targetWaypoint)) + if (checked.getFinalWaypoint().equals(targetWaypoint)) return checked; for (String wayPointId : checked.getFinalWaypoint().destinations.keySet()) { @@ -213,7 +238,7 @@ public class Waypoint implements Unlockable { return new Location(world, x, y, z, yaw, pitch); } - public class PathInfo { + public static class PathInfo { private final ArrayList waypoints; private final double cost; @@ -226,10 +251,15 @@ public class Waypoint implements Unlockable { } public PathInfo(Waypoint waypoint) { - this.waypoints = (ArrayList) Arrays.asList(waypoint); + this.waypoints = new ArrayList<>(); + this.waypoints.add(waypoint); cost = 0; } - + public PathInfo(Waypoint waypoint,double cost) { + this.waypoints = new ArrayList<>(); + this.waypoints.add(waypoint); + this.cost = cost; + } public ArrayList addInOrder(ArrayList pathInfos) { int index = 0; @@ -238,6 +268,7 @@ public class Waypoint implements Unlockable { pathInfos.set(index, this); return pathInfos; } + index++; } //If index==pathInfos.size() we add the waypoint at the end pathInfos.add(this); @@ -245,29 +276,43 @@ public class Waypoint implements Unlockable { } - - public PathInfo(ArrayList waypoints, double cost) { - this.waypoints = waypoints; + public PathInfo(List waypoints, double cost) { + this.waypoints = new ArrayList<>(waypoints); this.cost = cost; } - public String displayIntermediaryWayPoints() { - if(waypoints.size()<=2) - return ""; - String result=""; - for(int i=1;i newWaypoints = new ArrayList<>(); newWaypoints.addAll(waypoints); newWaypoints.add(waypoint); - double cost=this.cost+getFinalWaypoint().getSimpleCostDestination(waypoint); - return new PathInfo(newWaypoints,cost); + double cost = this.cost + getFinalWaypoint().getSimpleCostDestination(waypoint); + return new PathInfo(newWaypoints, cost); } diff --git a/src/main/resources/default/gui/waypoints.yml b/src/main/resources/default/gui/waypoints.yml index aa696e33..ff58f2c2 100644 --- a/src/main/resources/default/gui/waypoints.yml +++ b/src/main/resources/default/gui/waypoints.yml @@ -45,6 +45,13 @@ items: - '&7You cannot teleport as you are not standing on a waypoint.' + current-waypoint: + name: '&a{name}' + item: ENDER_PEARL + + lore: + - '&7The waypoint you are standing at.' + # When you don't have enough stellium not-enough-stellium: name: '&a{name}' @@ -61,7 +68,7 @@ items: lore: - '&7You can teleport to this waypoint.' - - '&7 Intermediary waypoints : {intermediary_waypoints}' + - '&7Intermediary waypoints : {intermediary_waypoints}' - '&7Click to teleport for &b{current_cost} &7Stellium.' next: diff --git a/src/main/resources/default/professions/fishing.yml b/src/main/resources/default/professions/fishing.yml index c26e6a6a..ed2b9985 100644 --- a/src/main/resources/default/professions/fishing.yml +++ b/src/main/resources/default/professions/fishing.yml @@ -22,7 +22,7 @@ exp-sources: {} on-fish: overriding-drop-table: conditions: - - 'region{name=swamp}' + - 'biome{name=swamp}' # When drop table is read, one of these # items will be selected randomly. diff --git a/src/main/resources/default/stats.yml b/src/main/resources/default/stats.yml index 1c9ef218..21fdee82 100644 --- a/src/main/resources/default/stats.yml +++ b/src/main/resources/default/stats.yml @@ -58,6 +58,11 @@ default: COOLDOWN_REDUCTION: base: 0 per-level: 0 + + #Increases chance to have rare loot chests + CHANCE: + base: 0 + per-level: 0 # Dealt by skills SKILL_DAMAGE: diff --git a/src/main/resources/default/waypoints.yml b/src/main/resources/default/waypoints.yml index 59999359..1de64a36 100644 --- a/src/main/resources/default/waypoints.yml +++ b/src/main/resources/default/waypoints.yml @@ -17,8 +17,6 @@ spawn: # Stellium cost in order to use the waypoint. # Stellium is like stamina however it's not used # by skills and regens much slower than mana. - normal-use: 3 - # Cost when not standing on any waypoint. dynamic-use: 5 @@ -42,12 +40,12 @@ spawn: default: true # All the waypoints you can teleport to when standing - # on that waypoint. If that list is empty you are able + # on that waypoint. And the cost needed to travel to his pointIf that list is empty you are able # to teleport to any waypoint linked: - - spawn1 - - spawn2 - - forest + spawn1: 4 + spawn2: 5 + spawn1: name: Spawn1 @@ -62,6 +60,15 @@ spawn1: # on any waypoint (waypoint must be unlocked). dynamic: true + ##Not necessary if the waypoint doesn't allow dynamic use + ##The conditions for the dynamic-use of the waypoint + conditions: + - 'distance{world=world;x=69;y=71;z=163;distance=500}' + + + linked: + spawn: 4 + spawn2: name: Spawn2 location: 'world 69 71 136 136 0' @@ -70,3 +77,5 @@ spawn2: normal-use: 3 option: enable-menu: false + linked: + spawn: 3 From 5a2e05bb1283adcb5c30d3a9d8ebfa4003d62490 Mon Sep 17 00:00:00 2001 From: Guillaume Date: Wed, 4 May 2022 11:31:12 +0200 Subject: [PATCH 08/39] More debug for waypoints --- .../Indyuce/mmocore/gui/WaypointViewer.java | 19 +++++++++++-------- .../Indyuce/mmocore/waypoint/Waypoint.java | 7 ++++++- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java b/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java index 5bfa25f6..1f68d5ac 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java +++ b/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java @@ -157,7 +157,7 @@ public class WaypointViewer extends EditableInventory { Waypoint waypoint = inv.waypoints.get(inv.page * inv.getByFunction("waypoint").getSlots().size() + n); holders.register("name", waypoint.getName()); if (!onlyName) { - holders.register("current_cost",inv.paths.get(waypoint).getCost()); + holders.register("current_cost", inv.paths.get(waypoint).getCost()); holders.register("normal_cost", decimal.format(inv.paths.containsKey(waypoint) ? inv.paths.get(waypoint).getCost() : Double.POSITIVE_INFINITY)); holders.register("dynamic_cost", decimal.format(waypoint.getDynamicCost())); holders.register("intermediary_waypoints", inv.paths.containsKey(waypoint) ? inv.paths.get(waypoint).displayIntermediaryWayPoints(inv.waypointCostType.equals(CostType.DYNAMIC_USE)) : "none"); @@ -184,17 +184,20 @@ public class WaypointViewer extends EditableInventory { paths.put(pathInfo.getFinalWaypoint(), pathInfo); } if (current == null) { + + //Iterate through all the dynamic points and find all the points it is linked to and the path + HashMap dynamicPoints = new HashMap<>(); //We first check all the dynamic waypoints for (Waypoint waypoint : waypoints) { - if (waypoint.canHaveDynamicUse(playerData.getPlayer())) - paths.put(waypoint,new Waypoint.PathInfo(waypoint, waypoint.getDynamicCost())); + if (waypoint.canHaveDynamicUse(playerData.getPlayer())) { + paths.put(waypoint, new Waypoint.PathInfo(waypoint, waypoint.getDynamicCost())); + dynamicPoints.put(waypoint, waypoint.getDynamicCost()); + } } - //Iterate through all the dynamic points and find all the points it is linked to and the path - HashSet waypointSet = new HashSet<>(paths.keySet()); - for (Waypoint source : waypointSet) { + for(Waypoint source: dynamicPoints.keySet()){ for (Waypoint.PathInfo target : source.getAllPath()) { - if (!paths.containsKey(target.getFinalWaypoint()) || paths.get(target.getFinalWaypoint()).getCost() > target.getCost()) { - paths.put(target.getFinalWaypoint(), target); + if (!paths.containsKey(target.getFinalWaypoint()) || paths.get(target.getFinalWaypoint()).getCost() > target.getCost()+dynamicPoints.get(source)) { + paths.put(target.getFinalWaypoint(), target.addCost(dynamicPoints.get(source))); } } } diff --git a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java index 6c6b7074..b19ca467 100644 --- a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java +++ b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java @@ -240,7 +240,7 @@ public class Waypoint implements Unlockable { public static class PathInfo { private final ArrayList waypoints; - private final double cost; + private double cost; public ArrayList getWaypoints() { return waypoints; @@ -261,6 +261,11 @@ public class Waypoint implements Unlockable { this.cost = cost; } + public PathInfo addCost(double cost) { + this.cost+=cost; + return this; + } + public ArrayList addInOrder(ArrayList pathInfos) { int index = 0; while (index < pathInfos.size()) { From a13987cac903d744bf3520b9295cb86bc07afde3 Mon Sep 17 00:00:00 2001 From: Indyuce Date: Thu, 5 May 2022 22:22:56 +0200 Subject: [PATCH 09/39] giveExperience does nothing if exp is negative --- src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java | 3 +++ .../java/net/Indyuce/mmocore/experience/PlayerProfessions.java | 2 ++ 2 files changed, 5 insertions(+) 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 0fae0302..3827cad3 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java @@ -532,6 +532,9 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc * @param splitExp Should the exp be split among party members */ public void giveExperience(double value, EXPSource source, @Nullable Location hologramLocation, boolean splitExp) { + if (value <= 0) + return; + if (hasReachedMaxLevel()) { setExperience(0); return; diff --git a/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java b/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java index f7dd9963..1c84c39e 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java +++ b/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java @@ -157,6 +157,8 @@ public class PlayerProfessions { public void giveExperience(Profession profession, double value, EXPSource source, @Nullable Location hologramLocation) { Validate.isTrue(playerData.isOnline(), "Cannot give experience to offline player"); + if (value <= 0) + return; if (hasReachedMaxLevel(profession)) { setExperience(profession, 0); From 285e753a0236bd2ac74b4b2949ffd50cbcfcd16d Mon Sep 17 00:00:00 2001 From: Guillaume Date: Sat, 7 May 2022 18:30:25 +0200 Subject: [PATCH 10/39] Changes in the skills GUI. --- .../net/Indyuce/mmocore/gui/SkillList.java | 184 ++++++++---------- src/main/resources/default/gui/skill-list.yml | 180 +++++++++-------- src/main/resources/default/gui/waypoints.yml | 2 +- 3 files changed, 175 insertions(+), 191 deletions(-) diff --git a/src/main/java/net/Indyuce/mmocore/gui/SkillList.java b/src/main/java/net/Indyuce/mmocore/gui/SkillList.java index a60e027d..af983f3c 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/SkillList.java +++ b/src/main/java/net/Indyuce/mmocore/gui/SkillList.java @@ -11,6 +11,7 @@ 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.SkillManager; import net.Indyuce.mmocore.skill.ClassSkill; import net.Indyuce.mmocore.skill.RegisteredSkill; import org.apache.commons.lang.Validate; @@ -38,8 +39,6 @@ public class SkillList extends EditableInventory { if (function.equals("skill")) return new SkillItem(config); - if (function.equals("switch")) - return new SwitchItem(config); if (function.equals("level")) return new LevelItem(config); @@ -49,7 +48,7 @@ public class SkillList extends EditableInventory { @Override public Placeholders getPlaceholders(SkillViewerInventory inv, int n) { - RegisteredSkill selected = inv.selected.getSkill(); + RegisteredSkill selected = inv.selected==null?null:inv.selected.getSkill(); Placeholders holders = new Placeholders(); holders.register("skill_caps", selected.getName().toUpperCase()); @@ -59,10 +58,6 @@ public class SkillList extends EditableInventory { return holders; } - @Override - public boolean canDisplay(SkillViewerInventory inv) { - return !inv.binding; - } }; if (function.equals("slot")) @@ -74,7 +69,7 @@ public class SkillList extends EditableInventory { @Override public Placeholders getPlaceholders(SkillViewerInventory inv, int n) { - RegisteredSkill selected = inv.selected.getSkill(); + RegisteredSkill selected = inv.selected==null?null:inv.selected.getSkill(); RegisteredSkill skill = inv.getPlayerData().hasSkillBound(n) ? inv.getPlayerData().getBoundSkill(n).getSkill() : null; Placeholders holders = new Placeholders(); @@ -82,7 +77,7 @@ public class SkillList extends EditableInventory { holders.register("skill", skill == null ? none : skill.getName()); holders.register("index", "" + (n + 1)); holders.register("slot", MMOCoreUtils.intToRoman(n + 1)); - holders.register("selected", selected.getName()); + holders.register("selected", selected==null?none:selected.getName()); return holders; } @@ -102,16 +97,28 @@ public class SkillList extends EditableInventory { return item; } - @Override - public boolean canDisplay(SkillViewerInventory inv) { - return inv.binding; - } - @Override public boolean hasDifferentDisplay() { return true; } }; + if (function.equals("previous")) + return new SimplePlaceholderItem(config) { + + @Override + public boolean canDisplay(SkillViewerInventory inv) { + return inv.page > 0; + } + }; + if (function.equals("next")) { + return new SimplePlaceholderItem(config) { + + @Override + public boolean canDisplay(SkillViewerInventory inv) { + return inv.page < inv.skills.size() / 12; + } + }; + } return new SimplePlaceholderItem(config); } @@ -120,30 +127,6 @@ public class SkillList extends EditableInventory { return new SkillViewerInventory(data, this); } - public class SwitchItem extends SimplePlaceholderItem { - private final SimplePlaceholderItem binding, upgrading; - - public SwitchItem(ConfigurationSection config) { - super(config); - - Validate.isTrue(config.contains("binding"), "Config must have 'binding'"); - Validate.isTrue(config.contains("upgrading"), "Config must have 'upgrading'"); - - binding = new SimplePlaceholderItem(config.getConfigurationSection("binding")); - upgrading = new SimplePlaceholderItem(config.getConfigurationSection("upgrading")); - } - - @Override - public ItemStack display(SkillViewerInventory inv, int n) { - return inv.binding ? upgrading.display(inv) : binding.display(inv); - } - - @Override - public boolean canDisplay(SkillViewerInventory inv) { - return true; - } - } - public class LevelItem extends InventoryItem { private final int offset; @@ -189,24 +172,21 @@ public class SkillList extends EditableInventory { return NBTItem.get(item).addTag(new ItemTag("skillId", skill.getSkill().getHandler().getId())).toItem(); } + @Override public Placeholders getPlaceholders(SkillViewerInventory inv, int n) { return new Placeholders(); } - @Override - public boolean canDisplay(SkillViewerInventory inv) { - return !inv.binding; - } + } public class SkillItem extends InventoryItem { - private final int selectedSkillSlot; + public SkillItem(ConfigurationSection config) { super(Material.BARRIER, config); - selectedSkillSlot = config.getInt("selected-slot"); } @Override @@ -220,12 +200,16 @@ public class SkillList extends EditableInventory { /* * calculate placeholders */ - ClassSkill skill = inv.skills.get(mod(n + inv.getPlayerData().skillGuiDisplayOffset, inv.skills.size())); + int index=n+inv.skillSlots.size()*inv.page; + if(index>=inv.skills.size()) + return new ItemStack(Material.AIR); + + ClassSkill skill = inv.skills.get(index); Placeholders holders = getPlaceholders(inv.getPlayerData(), skill); List lore = new ArrayList<>(getLore()); - int index = lore.indexOf("{lore}"); + index = lore.indexOf("{lore}"); lore.remove(index); List skillLore = skill.calculateLore(inv.getPlayerData()); for (int j = 0; j < skillLore.size(); j++) @@ -272,8 +256,9 @@ public class SkillList extends EditableInventory { private final List skillSlots; private final List slotSlots; - private boolean binding; + //The skill the player Selected private ClassSkill selected; + private int page = 0; public SkillViewerInventory(PlayerData playerData, EditableInventory editable) { super(playerData, editable); @@ -281,24 +266,23 @@ public class SkillList extends EditableInventory { skills = new ArrayList<>(playerData.getProfess().getSkills()); skillSlots = getEditable().getByFunction("skill").getSlots(); slotSlots = getEditable().getByFunction("slot").getSlots(); + selected=skills.get(page*skillSlots.size()); } @Override public String calculateName() { - return getName(); + return getName().replace("{skill}", selected.getSkill().getName()); } @Override public void open() { - int selectedSkillSlot = ((SkillItem) getEditable().getByFunction("skill")).selectedSkillSlot; - selected = skills.get(mod(selectedSkillSlot + playerData.skillGuiDisplayOffset, skills.size())); - super.open(); } @Override public void whenClicked(InventoryClickEvent event, InventoryItem item) { + /* if (skillSlots.contains(event.getRawSlot()) && event.getRawSlot() != ((SkillItem) getEditable().getByFunction("skill")).selectedSkillSlot) { player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); @@ -306,24 +290,26 @@ public class SkillList extends EditableInventory { open(); return; } + */ + + if (item.getFunction().equals("skill")) { + int index = skillSlots.size() * page + skillSlots.indexOf(event.getRawSlot()); + player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); + selected = skills.get(index); + open(); + return; + } if (item.getFunction().equals("previous")) { player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); - playerData.skillGuiDisplayOffset = (playerData.skillGuiDisplayOffset - 1) % skills.size(); + page--; open(); return; } if (item.getFunction().equals("next")) { player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); - playerData.skillGuiDisplayOffset = (playerData.skillGuiDisplayOffset + 1) % skills.size(); - open(); - return; - } - - if (item.getFunction().equals("switch")) { - player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); - binding = !binding; + page++; open(); return; } @@ -331,51 +317,50 @@ public class SkillList extends EditableInventory { /* * binding or unbinding skills. */ - if (binding) { - for (int index = 0; index < slotSlots.size(); index++) { - int slot = slotSlots.get(index); - if (event.getRawSlot() == slot) { + if (item.getFunction().equals("slot")) { + int index = slotSlots.indexOf(event.getRawSlot()); - // unbind if there is a current spell. - if (event.getAction() == InventoryAction.PICKUP_HALF) { - if (!playerData.hasSkillBound(index)) { - MMOCore.plugin.configManager.getSimpleMessage("no-skill-bound").send(player); - player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); - return; - } - player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2); - playerData.unbindSkill(index); - open(); - return; - } - - if (selected == null) - return; - - if (selected.getSkill().getTrigger().isPassive()) { - MMOCore.plugin.configManager.getSimpleMessage("not-active-skill").send(player); - player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); - return; - } - - if (!playerData.hasSkillUnlocked(selected)) { - MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player); - player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); - return; - } - - player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2); - playerData.setBoundSkill(index, selected); - open(); + // unbind if there is a current spell. + if (event.getAction() == InventoryAction.PICKUP_HALF) { + if (!playerData.hasSkillBound(index)) { + MMOCore.plugin.configManager.getSimpleMessage("no-skill-bound").send(player); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); return; } + + player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2); + playerData.unbindSkill(index); + open(); + return; } - /* - * upgrading a player skill - */ - } else if (item.getFunction().equals("upgrade")) { + if (selected == null) + return; + + if (selected.getSkill().getTrigger().isPassive()) { + MMOCore.plugin.configManager.getSimpleMessage("not-active-skill").send(player); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); + return; + } + + if (!playerData.hasSkillUnlocked(selected)) { + MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); + return; + } + + player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2); + playerData.setBoundSkill(index, selected); + open(); + return; + } + + + /* + * upgrading a player skill + */ + if (item.getFunction().equals("upgrade")) { if (!playerData.hasSkillUnlocked(selected)) { MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player); player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); @@ -402,6 +387,7 @@ public class SkillList extends EditableInventory { open(); } } + } private int mod(int x, int n) { diff --git a/src/main/resources/default/gui/skill-list.yml b/src/main/resources/default/gui/skill-list.yml index 60993b92..04dc88a6 100644 --- a/src/main/resources/default/gui/skill-list.yml +++ b/src/main/resources/default/gui/skill-list.yml @@ -1,97 +1,95 @@ - # GUI display name -name: Your Skills +name: 'Selected Skill: &6{skill}' # Number of slots in your inventory. Must be # between 9 and 54 and must be a multiple of 9. -slots: 45 +slots: 54 items: - skill: - slots: [11,12,13,14,15] - - # Index from 'slots' of the skill - # currently selected in the GUI - selected-slot: 2 - - function: skill - name: '&a{skill} &6[{level}]' - lore: - - '' - - '{unlocked}&a✔ Requires Level {unlock}' - - '{locked}&c✖ Requires Level {unlock}' - - '{max_level}&e✔ Maximum Level Hit!' - - '' - - '{lore}' - next: - slots: [16] - function: next - item: PLAYER_HEAD - texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTliZjMyOTJlMTI2YTEwNWI1NGViYTcxM2FhMWIxNTJkNTQxYTFkODkzODgyOWM1NjM2NGQxNzhlZDIyYmYifX19 - name: '&aNext' - lore: {} - previous: - slots: [10] - function: previous - item: PLAYER_HEAD - texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYmQ2OWUwNmU1ZGFkZmQ4NGU1ZjNkMWMyMTA2M2YyNTUzYjJmYTk0NWVlMWQ0ZDcxNTJmZGM1NDI1YmMxMmE5In19fQ== - name: '&aPrevious' - lore: {} - switch: - slots: [28] - function: switch - item: PLAYER_HEAD - binding: - item: PINK_STAINED_GLASS - name: '&aSwitch to Binding' - lore: {} - upgrading: - item: PINK_STAINED_GLASS - name: '&aSwitch to Upgrading' - lore: {} - skill-slot: - slots: [29,30,31,32,33,34] - function: slot - item: BOOK - - # Material used when the slot is empty - empty-item: GRAY_DYE - - name: '&aSkill Slot {slot}' - no-skill: '&cNone' - lore: - - '&7Current Skill: &6{skill}' - - '' - - '&7&oCast this spell by pressing [F] followed' - - '&7&oby the keybind displayed on the action bar.' - - '' - - '&e► Left click to bind {selected}.' - - '&e► Right click to unbind.' - skill-level: - slots: [29,30,31,32,33,34] - function: level - - # Skill level offset, should be changed - # according to the amount of inventory - # slots the skill-level item occupies. - offset: 2 - - # Item displayed if the skill level is - # too low to display a level item in the GUI - too-low: - item: AIR - - item: LIME_DYE - name: '&a{skill} Level {roman}' - lore: - - '' - - '{lore}' - upgrade: - slots: [31] - function: upgrade - item: GREEN_STAINED_GLASS_PANE - name: '&a&lUPGRADE {skill_caps}' - lore: - - '&7Costs 1 skill point.' - - '' - - '&eCurrent Skill Points: {skill_points}' + skill: + slots: [ 10,11,12,19,20,21,28,29,30,37,38,39] + + function: skill + name: '&a{skill} &6[{level}]' + lore: + - '' + - '{unlocked}&a✔ Requires Level {unlock}' + - '{locked}&c✖ Requires Level {unlock}' + - '{max_level}&e✔ Maximum Level Hit!' + - '' + - '{lore}' + next: + slots: [ 47 ] + function: next + item: PLAYER_HEAD + texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTliZjMyOTJlMTI2YTEwNWI1NGViYTcxM2FhMWIxNTJkNTQxYTFkODkzODgyOWM1NjM2NGQxNzhlZDIyYmYifX19 + name: '&aNext' + lore: { } + previous: + slots: [ 2 ] + function: previous + item: PLAYER_HEAD + texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYmQ2OWUwNmU1ZGFkZmQ4NGU1ZjNkMWMyMTA2M2YyNTUzYjJmYTk0NWVlMWQ0ZDcxNTJmZGM1NDI1YmMxMmE5In19fQ== + name: '&aPrevious' + lore: { } + + + #switch: + # + # slots: [28] + # function: switch + # item: PLAYER_HEAD + # binding: + # item: PINK_STAINED_GLASS + # name: '&aSwitch to Binding' + # lore: {} + # upgrading: + # item: PINK_STAINED_GLASS + # name: '&aSwitch to Upgrading' + # lore: {} + skill-slot: + slots: [ 8,17,26,35,44,53 ] + function: slot + item: BOOK + + # Material used when the slot is empty + empty-item: GRAY_DYE + + name: '&aSkill Slot {slot}' + no-skill: '&cNone' + lore: + - '&7Current Skill: &6{skill}' + - '' + - '&7&oCast this spell by pressing [F] followed' + - '&7&oby the keybind displayed on the action bar.' + - '' + - '&e► Left click to bind {selected}.' + - '&e► Right click to unbind.' + skill-level: + slots: [ 6,15,24,33,42,51 ] + function: level + + # Skill level offset, should be changed + # according to the amount of inventory + # slots the skill-level item occupies. + offset: 2 + + # Item displayed if the skill level is + # too low to display a level item in the GUI + too-low: + item: AIR + + item: LIME_DYE + name: '&a{skill} Level {roman}' + lore: + - '' + - '{lore}' + upgrade: + slots: [ 15 ] + function: upgrade + item: GREEN_STAINED_GLASS_PANE + name: '&a&lUPGRADE {skill_caps}' + lore: + - '&7Costs 1 skill point.' + - '' + - '&eCurrent Skill Points: {skill_points}' diff --git a/src/main/resources/default/gui/waypoints.yml b/src/main/resources/default/gui/waypoints.yml index ff58f2c2..cd90f0c8 100644 --- a/src/main/resources/default/gui/waypoints.yml +++ b/src/main/resources/default/gui/waypoints.yml @@ -68,7 +68,7 @@ items: lore: - '&7You can teleport to this waypoint.' - - '&7Intermediary waypoints : {intermediary_waypoints}' + - '&7Intermediary waypoints: {intermediary_waypoints}' - '&7Click to teleport for &b{current_cost} &7Stellium.' next: From b7e3959ae66e5af1a75a0e40af239faa49a978bf Mon Sep 17 00:00:00 2001 From: Guillaume Date: Sat, 7 May 2022 18:32:01 +0200 Subject: [PATCH 11/39] Taming,Moving,DamageTaken,DamageDealt,Riding,Playing,Climbing,Projectile Experience Sources. --- .../source/ClimbExperienceSource.java | 66 ++++++++++ .../source/DamageDealtExperienceSource.java | 72 +++++++++++ .../source/DamageTakenExperienceSource.java | 62 ++++++++++ .../source/MoveExperienceSource.java | 80 ++++++++++++ .../source/PlayingExperienceSource.java | 88 ++++++++++++++ .../source/ProjectileExperienceSource.java | 114 ++++++++++++++++++ .../source/RideExperienceSource.java | 65 ++++++++++ .../source/TamingExperienceSource.java | 47 ++++++++ 8 files changed, 594 insertions(+) create mode 100644 src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java create mode 100644 src/main/java/net/Indyuce/mmocore/experience/source/DamageDealtExperienceSource.java create mode 100644 src/main/java/net/Indyuce/mmocore/experience/source/DamageTakenExperienceSource.java create mode 100644 src/main/java/net/Indyuce/mmocore/experience/source/MoveExperienceSource.java create mode 100644 src/main/java/net/Indyuce/mmocore/experience/source/PlayingExperienceSource.java create mode 100644 src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java create mode 100644 src/main/java/net/Indyuce/mmocore/experience/source/RideExperienceSource.java create mode 100644 src/main/java/net/Indyuce/mmocore/experience/source/TamingExperienceSource.java diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java new file mode 100644 index 00000000..4ae857b1 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java @@ -0,0 +1,66 @@ +package net.Indyuce.mmocore.experience.source; + +import io.lumine.mythic.lib.api.MMOLineConfig; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; +import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; +import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; +import org.apache.commons.lang.Validate; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerMoveEvent; + +public class ClimbExperienceSource extends SpecificExperienceSource { + //Can be Ladder,Vines,Twisting Vines,Weeping Vines. + private final Material type; + + /** + *Gives Experience when a player climbs on a ladder, a vine, a twisting vine or a weeping vine depending + * on the type precised (if no type is precised it will give xp for the 4) + * The xp given depends on the vertical distance travelled, the random amount given correspond + * to the xp when you climb, one block + */ + public ClimbExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + //If no type precised Ladder and all vines types work + if (!config.contains("type")) + type = null; + else { + String str = config.getString("type").toUpperCase().replace("-", "_"); + Validate.isTrue(str.equals("ladder") || + str.equals("vines") || str.equals("twisting-vines") || str.equals("weeping-vines"), + "The type must be ladder, vine, twisted-vines or weeping-vines"); + type = Material.valueOf(str); + } + + + } + + + @Override + public ExperienceSourceManager newManager() { + return new ExperienceSourceManager() { + @EventHandler + public void onClimb(PlayerMoveEvent e) { + if(e.getPlayer().hasMetadata("NPC")) + return; + PlayerData playerData=PlayerData.get(e.getPlayer()); + double delta=e.getTo().getY()-e.getFrom().getY(); + if(delta>0) { + for(ClimbExperienceSource source:getSources()) { + if(source.matchesParameter(playerData,e.getTo().getBlock().getType())) + source.giveExperience(playerData,delta,null); + } + } + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, Material material) { + if (type == null) + return material.equals(Material.LADDER) || material.equals(Material.VINE) || + material.equals(Material.WEEPING_VINES) || material.equals(Material.TWISTING_VINES); + return type.equals(material); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/DamageDealtExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/DamageDealtExperienceSource.java new file mode 100644 index 00000000..b87dd880 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/DamageDealtExperienceSource.java @@ -0,0 +1,72 @@ +package net.Indyuce.mmocore.experience.source; + +import io.lumine.mythic.lib.api.MMOLineConfig; +import io.lumine.mythic.lib.api.event.PlayerAttackEvent; +import io.lumine.mythic.lib.damage.DamagePacket; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; +import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; +import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; +import org.apache.commons.lang.Validate; +import org.bukkit.event.EventHandler; +import scala.Enumeration; + +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Collectors; + +public class DamageDealtExperienceSource extends SpecificExperienceSource { + private final DamageType type; + + /** + *Gives experience when a player deals damage of a certain type. If no type is given it will give xp for all + * the damage type. The random value you give correspond to the xp you get per damage dealt. + */ + + public DamageDealtExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + if (!config.contains("damage-type")) + type = null; + else { + String str = config.getString("damage-type").toUpperCase().replace("-", "_"); + //Checks if the damage type correspond to a value of the damage type enum + Validate.isTrue(Arrays.stream(DamageType.values()).map(Objects::toString).collect(Collectors.toList()).contains(str), + "damage-type value not allowed. Damage type value allowed: magic, physical, weapon, skill, projectile," + + " unarmed, on-hit, minion, dot."); + type = DamageType.valueOf(str); + + }} + + @Override + public ExperienceSourceManager newManager() { + return new ExperienceSourceManager() { + @EventHandler + public void onDamageDealt(PlayerAttackEvent e) { + if(e.getPlayer().hasMetadata("NPC")) + return; + PlayerData playerData=PlayerData.get(e.getPlayer()); + for(DamagePacket packet:e.getDamage().getPackets()) { + for(DamageType damageType:packet.getTypes()) { + + for(DamageDealtExperienceSource source: getSources()) { + if(source.matchesParameter(playerData,damageType)) + source.giveExperience(playerData, packet.getFinalValue(), null); + } + } + + } + + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, DamageType damageType) { + if(type==null) + return true; + else + return type.equals(damageType); + } + +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/DamageTakenExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/DamageTakenExperienceSource.java new file mode 100644 index 00000000..3c2f31c5 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/DamageTakenExperienceSource.java @@ -0,0 +1,62 @@ +package net.Indyuce.mmocore.experience.source; + +import io.lumine.mythic.lib.api.MMOLineConfig; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; +import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; +import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; +import org.apache.commons.lang.Validate; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; + +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Collectors; + +public class DamageTakenExperienceSource extends SpecificExperienceSource { + private final EntityDamageEvent.DamageCause cause; + + /** + *Gives experience when a player takes damage from a certain cause. If no cause is given it will give xp for all + * the damage causes. The random value you give correspond to the xp you get per damage taken. + */ + public DamageTakenExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + if(!config.contains("damage-cause")) + cause=null; + else { + String str = config.getString("damage-cause").toUpperCase().replace("-", "_"); + //Checks if the damage type correspond to a value of the damage type enum + Validate.isTrue(Arrays.stream(EntityDamageEvent.DamageCause.values()).map(Objects::toString).collect(Collectors.toList()).contains(str), + "damage-type value not allowed. Go check at all the Damage Causes in EntityDamageEvent.DamageCause enum."); + cause = EntityDamageEvent.DamageCause.valueOf(str); + } + } + + @Override + public ExperienceSourceManager newManager() { + return new ExperienceSourceManager() { + @EventHandler + public void onDamageTaken(EntityDamageEvent e) { + if (e.getEntity() instanceof Player && !e.getEntity().hasMetadata("NPC")) { + double amount = e.getDamage(); + PlayerData playerData = PlayerData.get((OfflinePlayer) e.getEntity()); + for (DamageTakenExperienceSource source : getSources()) { + if(source.matchesParameter(playerData,e.getCause())) + source.giveExperience(playerData, amount, null); + } + } + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, EntityDamageEvent.DamageCause damageCause) { + if(cause==null) + return true; + return damageCause.equals(cause); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/MoveExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/MoveExperienceSource.java new file mode 100644 index 00000000..505f311b --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/MoveExperienceSource.java @@ -0,0 +1,80 @@ +package net.Indyuce.mmocore.experience.source; + +import com.mojang.datafixers.types.Func; +import io.lumine.mythic.lib.api.MMOLineConfig; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; +import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; +import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; +import org.apache.commons.lang.Validate; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerMoveEvent; +import org.xml.sax.SAXParseException; + +import java.util.Arrays; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class MoveExperienceSource extends SpecificExperienceSource { + MovingType type; + + + + public MoveExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + if (!config.contains("moving-type")) + type = null; + else { + String str = config.getString("moving-type").toUpperCase().replace("-", "_"); + //Checks if the damage type correspond to a value of the damage type enum + Validate.isTrue(Arrays.stream(MoveExperienceSource.MovingType.values()).map(Objects::toString).collect(Collectors.toList()).contains(str), + "moving-type value not allowed. Moving type values allowed: sneaking, flying, swimming, sprinting, walking."); + type = MovingType.valueOf(str); + } + } + + @Override + public ExperienceSourceManager newManager() { + return new ExperienceSourceManager() { + @EventHandler + public void onMove(PlayerMoveEvent e) { + if(e.getPlayer().hasMetadata("NPC")) + return; + Player player=e.getPlayer(); + PlayerData playerData =PlayerData.get(player); + for(MoveExperienceSource source:getSources()) { + if(source.matchesParameter(playerData,null)) { + giveExperience(playerData,e.getTo().distance(e.getFrom()),null); + } + } + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, Object obj) { + return type.matches(player.getPlayer()); + } + + public enum MovingType { + SNEAKING(Player::isSneaking), + FLYING(Player::isFlying), + SWIMMING(Player::isSwimming), + SPRINTING(Player::isSprinting), + WALKING((p) -> !p.isSneaking() && !p.isSprinting() && !p.isFlying() && !p.isSwimming()); + + private final Function matching; + + MovingType(Function matching) { + this.matching = matching; + } + + public boolean matches(Player player) { + return matching.apply(player); + } + + } +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/PlayingExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/PlayingExperienceSource.java new file mode 100644 index 00000000..63dd4344 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/PlayingExperienceSource.java @@ -0,0 +1,88 @@ +package net.Indyuce.mmocore.experience.source; + +import io.lumine.mythic.bukkit.BukkitAdapter; +import io.lumine.mythic.lib.api.MMOLineConfig; +import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; +import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; +import net.Indyuce.mmocore.loot.chest.RegionBounds; +import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.scheduler.BukkitRunnable; + +public class PlayingExperienceSource extends SpecificExperienceSource { + + private final World world; + private final double x1, x2, z1, z2; + + /** + * Experience source giving the specified amount of xp to all the players online each second in certain world bounds. + *If no bounds are given, it will give the xp to every player online. + */ + public PlayingExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + + if (!config.contains("world")) + world = null; + else { + String name = config.getString("world"); + Validate.notNull(world = Bukkit.getWorld(name), "Could not find world " + config.getString("world")); + } + if (!config.contains("x1") || !config.contains("x2")) { + x1 = Double.NEGATIVE_INFINITY; + x2 = Double.POSITIVE_INFINITY; + } else { + x1 = Math.min(config.getInt("x1"), config.getInt("x2")); + x2 = Math.max(config.getInt("x1"), config.getInt("x2")); + } + if (!config.contains("z1") || !config.contains("z2")) { + z1 = Double.NEGATIVE_INFINITY; + z2 = Double.POSITIVE_INFINITY; + } else { + z1 = Math.min(config.getInt("z1"), config.getInt("z2")); + z2 = Math.max(config.getInt("z1"), config.getInt("z2")); + } + } + + @Override + public ExperienceSourceManager newManager() { + return new PlayingExperienceSourceManager(); + + } + + @Override + public boolean matchesParameter(PlayerData player, Object obj) { + if (world == null) + return true; + Location location = player.getPlayer().getLocation(); + return location.getWorld().equals(world) && location.getX() > x1 && location.getX() < x2 + && location.getZ() > z1 && location.getZ() < z2; + } + + + private class PlayingExperienceSourceManager extends ExperienceSourceManager { + + public PlayingExperienceSourceManager() { + new BukkitRunnable() { + + @Override + public void run() { + Bukkit.getOnlinePlayers().forEach((player) -> { + if (!player.hasMetadata("NPC")) { + PlayerData playerData = PlayerData.get(player); + for (PlayingExperienceSource source : getSources()) { + if (source.matchesParameter(playerData, null)) + giveExperience(playerData, 1, null); + } + } + }); + } + + }.runTaskTimer(MMOCore.plugin, 0, 20); + } + } +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java new file mode 100644 index 00000000..b912354d --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java @@ -0,0 +1,114 @@ +package net.Indyuce.mmocore.experience.source; + +import de.schlichtherle.key.passwd.swing.BasicUnknownKeyFeedback; +import io.lumine.mythic.core.skills.mechanics.ShootMechanic; +import io.lumine.mythic.lib.api.MMOLineConfig; +import me.glaremasters.guilds.utils.BackupUtils; +import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; +import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; +import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; +import org.apache.commons.lang.Validate; +import org.bukkit.Location; +import org.bukkit.entity.*; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Locale; + +public class ProjectileExperienceSource extends SpecificExperienceSource { + + ProjectileType projectileType; + + public ProjectileExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + Validate.isTrue(config.contains("type")); + projectileType = ProjectileType.valueOf(config.getString("type").toUpperCase().replace("-", "_")); + } + + @Override + public ExperienceSourceManager newManager() { + + return new ExperienceSourceManager() { + HashMap projectiles = new HashMap<>(); + + @EventHandler + public void onHit(EntityDamageByEntityEvent e) { + Entity entity = e.getDamager(); + if (e.getEntity() instanceof Projectile) { + Projectile projectile = (Projectile) e.getDamager(); + if (projectile.getShooter() instanceof Player && !((Player) projectile.getShooter()).hasMetadata("NPC")) { + Player player = (Player) projectile.getShooter(); + PlayerData playerData = PlayerData.get(player); + Validate.isTrue(projectiles.containsKey(projectile)); + double distance = projectiles.get(projectile).distance(e.getDamager().getLocation()); + for (ProjectileExperienceSource source : getSources()) { + if (source.matchesParameter(playerData, projectile)) + source.giveExperience(playerData, e.getFinalDamage() * distance, null); + } + + + } + } + + } + + //Mark every arrow with the the location at which it was shot to calculate the distance + @EventHandler + public void onLaunch(ProjectileLaunchEvent e) { + if (e.getEntity().getShooter() instanceof Player && e.getEntity() instanceof Arrow) { + Player player = (Player) e.getEntity().getShooter(); + if (player.hasMetadata("NPC")) + return; + + + projectiles.put(e.getEntity(), e.getLocation()); + //Remove the projectile 15 s after it was launched + new BukkitRunnable() { + @Override + public void run() { + projectiles.remove(e.getEntity()); + } + }.runTaskLater(MMOCore.plugin, 15 * 20L); + + + } + } + + }; + } + + @Override + public boolean matchesParameter(PlayerData player, Projectile projectile) { + return projectileType.matches(projectile); + } + + + public enum ProjectileType { + ARROW(Arrow.class), + TRIDENT(Trident.class), + FIREBALL(Fireball.class), + FISH_HOOK(FishHook.class), + ; + + private final Class clazz; + + ProjectileType(Class clazz) { + this.clazz = clazz; + } + + public Class getType() { + return clazz; + } + + public boolean matches(Projectile projectile) { + return projectile.getClass().isAssignableFrom(getType()); + } + } + +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/RideExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/RideExperienceSource.java new file mode 100644 index 00000000..f4a2c472 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/RideExperienceSource.java @@ -0,0 +1,65 @@ +package net.Indyuce.mmocore.experience.source; + +import io.lumine.mythic.lib.api.MMOLineConfig; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; +import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; +import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; +import org.apache.commons.lang.Validate; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerMoveEvent; + +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Collectors; + +public class RideExperienceSource extends SpecificExperienceSource> { + private final EntityType type; + + /** + *Gives experience when a player moves riding a certain entity. If no entity type is given it will give xp if you move + *while riding an entity whatever it is. + *The random value you give correspond to the xp you get per block travelled while riding. + */ + public RideExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + if (!config.contains("entity-type")) + type = null; + else { + String str = config.getString("entity-type").toUpperCase().replace("-", "_"); + Validate.isTrue(Arrays.stream(EntityType.values()).map(Objects::toString).collect(Collectors.toList()).contains(str), + "The entity-type must correspond to an entity that exist in the game."); + type=EntityType.valueOf(str); + } + + } + + @Override + public ExperienceSourceManager newManager() { + return new ExperienceSourceManager() { + @EventHandler + public void onRide(PlayerMoveEvent e) { + if (e.getPlayer().hasMetadata("NPC")) + return; + PlayerData playerData=PlayerData.get(e.getPlayer()); + if(e.getPlayer().isInsideVehicle()) { + Entity vehicle=e.getPlayer().getVehicle(); + for(RideExperienceSource source:getSources()) { + if(source.matchesParameter(playerData,vehicle.getClass())) + giveExperience(playerData,e.getFrom().distance(e.getTo()),null); + } + } + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, Class obj) { + if(type==null) + return true; + return type.getEntityClass().isAssignableFrom(obj); + } + +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/TamingExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/TamingExperienceSource.java new file mode 100644 index 00000000..a5ea2e3a --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/TamingExperienceSource.java @@ -0,0 +1,47 @@ +package net.Indyuce.mmocore.experience.source; + +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; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.bukkit.entity.Wolf; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +import javax.swing.text.html.parser.Entity; + +public class TamingExperienceSource extends SpecificExperienceSource { + + + public TamingExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + } + + @Override + public ExperienceSourceManager newManager() { + return new ExperienceSourceManager() { + @EventHandler + public void onWolfHit(EntityDamageByEntityEvent e) { + if(e.getDamager() instanceof Wolf) { + Wolf wolf= (Wolf) e.getDamager(); + if(wolf.getOwner() instanceof Player &&!((Player) wolf.getOwner()).hasMetadata("NPC")) { + PlayerData playerData=PlayerData.get((OfflinePlayer) wolf.getOwner()); + for(TamingExperienceSource source:getSources()) { + source.giveExperience(playerData,e.getDamage(), MMOCoreUtils.getCenterLocation(e.getEntity())); + } + } + } + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, Object obj) { + return false; + } +} From 2411dae63177efcf2e902e46d85ab8c4b45b1123 Mon Sep 17 00:00:00 2001 From: Guillaume Date: Sun, 8 May 2022 11:14:58 +0200 Subject: [PATCH 12/39] Debug for all the experience source. Added VanillaExperience & Resource ExperienceSource and added inCombat for Playing Experience Source. --- .../mmocore/api/load/DefaultMMOLoader.java | 219 ++++++++++-------- .../ProfessionExperienceDispenser.java | 2 +- .../source/ClimbExperienceSource.java | 35 +-- .../source/DamageDealtExperienceSource.java | 6 +- .../source/DamageTakenExperienceSource.java | 30 ++- .../source/MoveExperienceSource.java | 20 +- ...eSource.java => PlayExperienceSource.java} | 24 +- .../source/ProjectileExperienceSource.java | 42 ++-- .../source/ResourceExperienceSource.java | 63 +++++ .../source/RideExperienceSource.java | 7 +- ...eSource.java => TameExperienceSource.java} | 13 +- .../VanillaExperienceExperienceSource.java | 39 ++++ .../source/type/SpecificExperienceSource.java | 4 + 13 files changed, 332 insertions(+), 172 deletions(-) rename src/main/java/net/Indyuce/mmocore/experience/source/{PlayingExperienceSource.java => PlayExperienceSource.java} (78%) create mode 100644 src/main/java/net/Indyuce/mmocore/experience/source/ResourceExperienceSource.java rename src/main/java/net/Indyuce/mmocore/experience/source/{TamingExperienceSource.java => TameExperienceSource.java} (75%) create mode 100644 src/main/java/net/Indyuce/mmocore/experience/source/VanillaExperienceExperienceSource.java diff --git a/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java b/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java index 074b123d..970c2c09 100644 --- a/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java +++ b/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java @@ -1,6 +1,7 @@ package net.Indyuce.mmocore.api.load; import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; +import net.Indyuce.mmocore.experience.source.*; import net.Indyuce.mmocore.loot.droptable.condition.*; import org.bukkit.configuration.ConfigurationSection; @@ -12,15 +13,6 @@ import net.Indyuce.mmocore.loot.droptable.dropitem.DropTableDropItem; import net.Indyuce.mmocore.loot.droptable.dropitem.GoldDropItem; import net.Indyuce.mmocore.loot.droptable.dropitem.NoteDropItem; import net.Indyuce.mmocore.loot.droptable.dropitem.VanillaDropItem; -import net.Indyuce.mmocore.experience.source.BrewPotionExperienceSource; -import net.Indyuce.mmocore.experience.source.CraftItemExperienceSource; -import net.Indyuce.mmocore.experience.source.EnchantItemExperienceSource; -import net.Indyuce.mmocore.experience.source.FishItemExperienceSource; -import net.Indyuce.mmocore.experience.source.KillMobExperienceSource; -import net.Indyuce.mmocore.experience.source.MineBlockExperienceSource; -import net.Indyuce.mmocore.experience.source.PlaceBlockExperienceSource; -import net.Indyuce.mmocore.experience.source.RepairItemExperienceSource; -import net.Indyuce.mmocore.experience.source.SmeltItemExperienceSource; import net.Indyuce.mmocore.experience.source.type.ExperienceSource; import net.Indyuce.mmocore.api.quest.objective.ClickonObjective; import net.Indyuce.mmocore.api.quest.objective.GoToObjective; @@ -40,130 +32,157 @@ import io.lumine.mythic.lib.api.MMOLineConfig; public class DefaultMMOLoader extends MMOLoader { - @Override - public Trigger loadTrigger(MMOLineConfig config) { - if (config.getKey().equals("message")) - return new MessageTrigger(config); + @Override + public Trigger loadTrigger(MMOLineConfig config) { + if (config.getKey().equals("message")) + return new MessageTrigger(config); - if (config.getKey().equals("sound") || config.getKey().equals("playsound")) - return new SoundTrigger(config); + if (config.getKey().equals("sound") || config.getKey().equals("playsound")) + return new SoundTrigger(config); - if (config.getKey().equals("mana")) - return new ManaTrigger(config); + if (config.getKey().equals("mana")) + return new ManaTrigger(config); - if (config.getKey().equals("stamina")) - return new StaminaTrigger(config); - - if (config.getKey().equals("stellium")) - return new StelliumTrigger(config); + if (config.getKey().equals("stamina")) + return new StaminaTrigger(config); - if (config.getKey().equals("command")) - return new CommandTrigger(config); + if (config.getKey().equals("stellium")) + return new StelliumTrigger(config); - if (config.getKey().equals("item") || config.getKey().equals("vanilla")) - return new ItemTrigger(config); + if (config.getKey().equals("command")) + return new CommandTrigger(config); - if (config.getKey().equals("exp") || config.getKey().equals("experience")) - return new ExperienceTrigger(config); + if (config.getKey().equals("item") || config.getKey().equals("vanilla")) + return new ItemTrigger(config); - return null; - } + if (config.getKey().equals("exp") || config.getKey().equals("experience")) + return new ExperienceTrigger(config); - @Override - public DropItem loadDropItem(MMOLineConfig config) { - if (config.getKey().equals("droptable")) - return new DropTableDropItem(config); + return null; + } - if (config.getKey().equals("vanilla")) - return new VanillaDropItem(config); + @Override + public DropItem loadDropItem(MMOLineConfig config) { + if (config.getKey().equals("droptable")) + return new DropTableDropItem(config); - if (config.getKey().equals("note")) - return new NoteDropItem(config); + if (config.getKey().equals("vanilla")) + return new VanillaDropItem(config); - if (config.getKey().equals("gold") || config.getKey().equals("coin")) - return new GoldDropItem(config); + if (config.getKey().equals("note")) + return new NoteDropItem(config); - return null; - } + if (config.getKey().equals("gold") || config.getKey().equals("coin")) + return new GoldDropItem(config); - @Override - public Objective loadObjective(MMOLineConfig config, ConfigurationSection section) { - if (config.getKey().equals("goto")) - return new GoToObjective(section, config); + return null; + } - if (config.getKey().equals("mineblock")) - return new MineBlockObjective(section, config); + @Override + public Objective loadObjective(MMOLineConfig config, ConfigurationSection section) { + if (config.getKey().equals("goto")) + return new GoToObjective(section, config); - if (config.getKey().equals("killmob")) - return new KillMobObjective(section, config); + if (config.getKey().equals("mineblock")) + return new MineBlockObjective(section, config); - if (config.getKey().equals("clickon")) - return new ClickonObjective(section, config); + if (config.getKey().equals("killmob")) + return new KillMobObjective(section, config); - return null; - } + if (config.getKey().equals("clickon")) + return new ClickonObjective(section, config); - @Override - public Condition loadCondition(MMOLineConfig config) { - if(config.getKey().equals("distance")) - return new DistanceCondition(config); + return null; + } - if (config.getKey().equals("world")) - return new WorldCondition(config); + @Override + public Condition loadCondition(MMOLineConfig config) { + if (config.getKey().equals("distance")) + return new DistanceCondition(config); - if (config.getKey().equals("biome")) - return new BiomeCondition(config); + if (config.getKey().equals("world")) + return new WorldCondition(config); - if (config.getKey().equals("level")) - return new LevelCondition(config); - - if (config.getKey().equals("permission")) - return new PermissionCondition(config); + if (config.getKey().equals("biome")) + return new BiomeCondition(config); - return null; - } + if (config.getKey().equals("level")) + return new LevelCondition(config); - @Override - public ExperienceSource loadExperienceSource(MMOLineConfig config, ExperienceDispenser dispenser) { - if (config.getKey().equals("fishitem")) - return new FishItemExperienceSource(dispenser, config); + if (config.getKey().equals("permission")) + return new PermissionCondition(config); - if (config.getKey().equals("killmob")) - return new KillMobExperienceSource(dispenser, config); + return null; + } - if (config.getKey().equals("mineblock")) - return new MineBlockExperienceSource(dispenser, config); + @Override + public ExperienceSource loadExperienceSource(MMOLineConfig config, ExperienceDispenser dispenser) { + if (config.getKey().equals("resource")) + return new ResourceExperienceSource(dispenser, config); - if (config.getKey().equals("placeblock")) - return new PlaceBlockExperienceSource(dispenser, config); + if (config.getKey().equals("vanillaexperience")) + return new VanillaExperienceExperienceSource(dispenser, config); - if (config.getKey().equals("brewpotion")) - return new BrewPotionExperienceSource(dispenser, config); + if (config.getKey().equals("climb")) + return new ClimbExperienceSource(dispenser, config); - if (config.getKey().equals("smeltitem")) - return new SmeltItemExperienceSource(dispenser, config); + if (config.getKey().equals("damagedealt")) + return new DamageDealtExperienceSource(dispenser, config); - if (config.getKey().equals("enchantitem")) - return new EnchantItemExperienceSource(dispenser, config); + if (config.getKey().equals("damagetaken")) + return new DamageTakenExperienceSource(dispenser, config); - if (config.getKey().equals("repairitem")) - return new RepairItemExperienceSource(dispenser, config); + if (config.getKey().equals("move")) + return new MoveExperienceSource(dispenser, config); - if (config.getKey().equals("craftitem")) - return new CraftItemExperienceSource(dispenser, config); + if (config.getKey().equals("play")) + return new PlayExperienceSource(dispenser, config); - return null; - } + if (config.getKey().equals("projectile")) + return new ProjectileExperienceSource(dispenser, config); - @Override - public BlockType loadBlockType(MMOLineConfig config) { + if (config.getKey().equals("ride")) + return new RideExperienceSource(dispenser, config); - if (config.getKey().equalsIgnoreCase("vanilla")) - return new VanillaBlockType(config); - - if (config.getKey().equalsIgnoreCase("skull") || config.getKey().equals("head") || config.getKey().equals("playerhead")) - return new SkullBlockType(config); + if (config.getKey().equals("tame")) + return new TameExperienceSource(dispenser, config); - return null; - } + if (config.getKey().equals("killmob")) + return new KillMobExperienceSource(dispenser, config); + + if (config.getKey().equals("mineblock")) + return new MineBlockExperienceSource(dispenser, config); + + if (config.getKey().equals("placeblock")) + return new PlaceBlockExperienceSource(dispenser, config); + + if (config.getKey().equals("brewpotion")) + return new BrewPotionExperienceSource(dispenser, config); + + if (config.getKey().equals("smeltitem")) + return new SmeltItemExperienceSource(dispenser, config); + + if (config.getKey().equals("enchantitem")) + return new EnchantItemExperienceSource(dispenser, config); + + if (config.getKey().equals("repairitem")) + return new RepairItemExperienceSource(dispenser, config); + + if (config.getKey().equals("craftitem")) + return new CraftItemExperienceSource(dispenser, config); + + return null; + } + + @Override + public BlockType loadBlockType(MMOLineConfig config) { + + if (config.getKey().equalsIgnoreCase("vanilla")) + return new VanillaBlockType(config); + + if (config.getKey().equalsIgnoreCase("skull") || config.getKey().equals("head") || config.getKey().equals("playerhead")) + return new SkullBlockType(config); + + return null; + } } diff --git a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ProfessionExperienceDispenser.java b/src/main/java/net/Indyuce/mmocore/experience/dispenser/ProfessionExperienceDispenser.java index af385fc1..273a05b2 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ProfessionExperienceDispenser.java +++ b/src/main/java/net/Indyuce/mmocore/experience/dispenser/ProfessionExperienceDispenser.java @@ -16,7 +16,7 @@ public class ProfessionExperienceDispenser implements ExperienceDispenser { @Override public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, EXPSource source) { hologramLocation = !profession.getOption(Profession.ProfessionOption.EXP_HOLOGRAMS) ? null - : hologramLocation == null ? getPlayerLocation(playerData) : hologramLocation; + : hologramLocation; playerData.getCollectionSkills().giveExperience(profession, experience, EXPSource.SOURCE, hologramLocation); } diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java index 4ae857b1..5e0c79c6 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java @@ -6,16 +6,18 @@ import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.util.Vector; public class ClimbExperienceSource extends SpecificExperienceSource { //Can be Ladder,Vines,Twisting Vines,Weeping Vines. private final Material type; /** - *Gives Experience when a player climbs on a ladder, a vine, a twisting vine or a weeping vine depending + * Gives Experience when a player climbs on a ladder, a vine, a twisting vine or a weeping vine depending * on the type precised (if no type is precised it will give xp for the 4) * The xp given depends on the vertical distance travelled, the random amount given correspond * to the xp when you climb, one block @@ -27,9 +29,10 @@ public class ClimbExperienceSource extends SpecificExperienceSource { type = null; else { String str = config.getString("type").toUpperCase().replace("-", "_"); - Validate.isTrue(str.equals("ladder") || - str.equals("vines") || str.equals("twisting-vines") || str.equals("weeping-vines"), - "The type must be ladder, vine, twisted-vines or weeping-vines"); + Validate.isTrue(str.equals("LADDER") || + str.equals("VINE") || str.equals("TWISTING_VINES_PLANT") || str.equals("WEEPING_VINES"), + "ClimbExperienceSource problem: The type must be ladder, vine, twisted-vines or weeping-vines"); + type = Material.valueOf(str); } @@ -42,14 +45,14 @@ public class ClimbExperienceSource extends SpecificExperienceSource { return new ExperienceSourceManager() { @EventHandler public void onClimb(PlayerMoveEvent e) { - if(e.getPlayer().hasMetadata("NPC")) + if (e.getPlayer().hasMetadata("NPC")) return; - PlayerData playerData=PlayerData.get(e.getPlayer()); - double delta=e.getTo().getY()-e.getFrom().getY(); - if(delta>0) { - for(ClimbExperienceSource source:getSources()) { - if(source.matchesParameter(playerData,e.getTo().getBlock().getType())) - source.giveExperience(playerData,delta,null); + PlayerData playerData = PlayerData.get(e.getPlayer()); + double delta = e.getTo().getY() - e.getFrom().getY(); + if (delta > 0) { + for (ClimbExperienceSource source : getSources()) { + if (source.matchesParameter(playerData, e.getFrom().getBlock().getType())) + source.giveExperience(playerData, delta, null); } } } @@ -60,7 +63,13 @@ public class ClimbExperienceSource extends SpecificExperienceSource { public boolean matchesParameter(PlayerData player, Material material) { if (type == null) return material.equals(Material.LADDER) || material.equals(Material.VINE) || - material.equals(Material.WEEPING_VINES) || material.equals(Material.TWISTING_VINES); - return type.equals(material); + material.equals(Material.WEEPING_VINES) || material.equals(Material.TWISTING_VINES) || + material.equals(Material.WEEPING_VINES_PLANT) || material.equals(Material.TWISTING_VINES_PLANT); + if (type.equals(Material.WEEPING_VINES)) + return material.equals(Material.WEEPING_VINES) || material.equals(Material.WEEPING_VINES_PLANT); + if (type.equals(Material.TWISTING_VINES)) + return material.equals(Material.TWISTING_VINES) || material.equals(Material.TWISTING_VINES_PLANT); + return material.equals(type); + } } diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/DamageDealtExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/DamageDealtExperienceSource.java index b87dd880..8ebd1363 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/DamageDealtExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/DamageDealtExperienceSource.java @@ -26,13 +26,13 @@ public class DamageDealtExperienceSource extends SpecificExperienceSource !p.isSneaking() && !p.isSprinting() && !p.isFlying() && !p.isSwimming()); + SNEAK(Player::isSneaking), + FLY((p)->p.isFlying()||p.isGliding()), + SWIM((p)->p.getLocation().getBlock().isLiquid()), + SPRINT(Player::isSprinting), + WALK((p) -> !p.isSneaking() && !p.isSprinting() && !p.isFlying() && !p.getLocation().getBlock().isLiquid()); private final Function matching; @@ -73,7 +75,7 @@ public class MoveExperienceSource extends SpecificExperienceSource { } public boolean matches(Player player) { - return matching.apply(player); + return !player.isInsideVehicle()&&matching.apply(player); } } diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/PlayingExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/PlayExperienceSource.java similarity index 78% rename from src/main/java/net/Indyuce/mmocore/experience/source/PlayingExperienceSource.java rename to src/main/java/net/Indyuce/mmocore/experience/source/PlayExperienceSource.java index 63dd4344..d95e6a7b 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/PlayingExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/PlayExperienceSource.java @@ -1,12 +1,10 @@ package net.Indyuce.mmocore.experience.source; -import io.lumine.mythic.bukkit.BukkitAdapter; import io.lumine.mythic.lib.api.MMOLineConfig; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; -import net.Indyuce.mmocore.loot.chest.RegionBounds; import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; @@ -14,17 +12,24 @@ import org.bukkit.Location; import org.bukkit.World; import org.bukkit.scheduler.BukkitRunnable; -public class PlayingExperienceSource extends SpecificExperienceSource { +public class PlayExperienceSource extends SpecificExperienceSource { private final World world; private final double x1, x2, z1, z2; + private final boolean inCombat; /** * Experience source giving the specified amount of xp to all the players online each second in certain world bounds. - *If no bounds are given, it will give the xp to every player online. + * If no bounds are given, it will give the xp to every player online. You can also specifiy if the player + * has to be inCombat or not to get the xp. */ - public PlayingExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + public PlayExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { super(dispenser, config); + if (!config.contains("in-combat")) + inCombat = false; + else { + inCombat = config.getBoolean("in-combat"); + } if (!config.contains("world")) world = null; @@ -49,13 +54,16 @@ public class PlayingExperienceSource extends SpecificExperienceSource { } @Override - public ExperienceSourceManager newManager() { + public ExperienceSourceManager newManager() { return new PlayingExperienceSourceManager(); } @Override public boolean matchesParameter(PlayerData player, Object obj) { + if (inCombat && !player.isInCombat()) + return false; + if (world == null) return true; Location location = player.getPlayer().getLocation(); @@ -64,7 +72,7 @@ public class PlayingExperienceSource extends SpecificExperienceSource { } - private class PlayingExperienceSourceManager extends ExperienceSourceManager { + private class PlayingExperienceSourceManager extends ExperienceSourceManager { public PlayingExperienceSourceManager() { new BukkitRunnable() { @@ -74,7 +82,7 @@ public class PlayingExperienceSource extends SpecificExperienceSource { Bukkit.getOnlinePlayers().forEach((player) -> { if (!player.hasMetadata("NPC")) { PlayerData playerData = PlayerData.get(player); - for (PlayingExperienceSource source : getSources()) { + for (PlayExperienceSource source : getSources()) { if (source.matchesParameter(playerData, null)) giveExperience(playerData, 1, null); } diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java index b912354d..ac2029bd 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java @@ -10,6 +10,7 @@ import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.*; import org.bukkit.event.EventHandler; @@ -17,18 +18,26 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.ProjectileLaunchEvent; import org.bukkit.scheduler.BukkitRunnable; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Locale; +import java.util.function.Function; +import java.util.stream.Collectors; public class ProjectileExperienceSource extends SpecificExperienceSource { - ProjectileType projectileType; + private final ProjectileType projectileType; public ProjectileExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { super(dispenser, config); - Validate.isTrue(config.contains("type")); - projectileType = ProjectileType.valueOf(config.getString("type").toUpperCase().replace("-", "_")); + if(!config.contains("type")) + projectileType=null; + else { + String str=config.getString("type").toUpperCase().replace("-", "_"); + Validate.isTrue(Arrays.stream(ProjectileType.values()).map(ProjectileType::toString).collect(Collectors.toList()).contains(str)); + projectileType = ProjectileType.valueOf(str); + } } @Override @@ -39,8 +48,8 @@ public class ProjectileExperienceSource extends SpecificExperienceSource p instanceof Arrow), + TRIDENT((p)-> p instanceof Trident), + FIREBALL((p)-> p instanceof Fireball), + FISH_HOOK((p)-> p instanceof FishHook), ; - private final Class clazz; + private final Function matching; - ProjectileType(Class clazz) { - this.clazz = clazz; + ProjectileType(Function matching) { + this.matching=matching; } - public Class getType() { - return clazz; - } public boolean matches(Projectile projectile) { - return projectile.getClass().isAssignableFrom(getType()); + return matching.apply(projectile); } } diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/ResourceExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/ResourceExperienceSource.java new file mode 100644 index 00000000..5b615af9 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/ResourceExperienceSource.java @@ -0,0 +1,63 @@ +package net.Indyuce.mmocore.experience.source; + +import io.lumine.mythic.lib.api.MMOLineConfig; +import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource; +import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; +import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; +import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; +import org.apache.commons.lang.Validate; +import org.bukkit.event.EventHandler; + +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Collectors; + +public class ResourceExperienceSource extends SpecificExperienceSource { + private final PlayerResource resource; + + + /** + * Gives experience when the player uses a specific resoure. If no resource is precised it will trigger for + * mana, stamina and stellium. The amount specified si the xp given per resource consummed. + */ + public ResourceExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + if (!config.contains("resource")) + resource = null; + else { + String str = config.getString("resource").toUpperCase().replace("-", "_"); + Validate.isTrue(str.equals("MANA") || str.equals("STELLIUM") || str.equals("STAMINA"), + "ResourceExperienceSource problem: The resource can only be mana, stamina or STELLIUM"); + resource = PlayerResource.valueOf(str); + } + + + } + + @Override + public ExperienceSourceManager newManager() { + return new ExperienceSourceManager() { + @EventHandler + public void onResource(PlayerResourceUpdateEvent e) { + if (e.getPlayer().hasMetadata("NPC")) + return; + + PlayerData playerData = PlayerData.get(e.getPlayer()); + if(e.getAmount()<0) + for (ResourceExperienceSource source : getSources()) { + if (source.matchesParameter(playerData, e.getResource())) + source.giveExperience(playerData, -e.getAmount(), null); + } + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, PlayerResource obj) { + if (resource == null) + return !obj.equals(PlayerResource.HEALTH); + return resource.equals(obj); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/RideExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/RideExperienceSource.java index f4a2c472..5f10376e 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/RideExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/RideExperienceSource.java @@ -6,6 +6,7 @@ import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.event.EventHandler; @@ -25,12 +26,12 @@ public class RideExperienceSource extends SpecificExperienceSource newManager() { - return new ExperienceSourceManager() { + public ExperienceSourceManager newManager() { + return new ExperienceSourceManager() { @EventHandler public void onWolfHit(EntityDamageByEntityEvent e) { if(e.getDamager() instanceof Wolf) { Wolf wolf= (Wolf) e.getDamager(); if(wolf.getOwner() instanceof Player &&!((Player) wolf.getOwner()).hasMetadata("NPC")) { PlayerData playerData=PlayerData.get((OfflinePlayer) wolf.getOwner()); - for(TamingExperienceSource source:getSources()) { + for(TameExperienceSource source:getSources()) { source.giveExperience(playerData,e.getDamage(), MMOCoreUtils.getCenterLocation(e.getEntity())); } } diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/VanillaExperienceExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/VanillaExperienceExperienceSource.java new file mode 100644 index 00000000..f4eb3d22 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/VanillaExperienceExperienceSource.java @@ -0,0 +1,39 @@ +package net.Indyuce.mmocore.experience.source; + +import io.lumine.mythic.lib.api.MMOLineConfig; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; +import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; +import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; +import org.apache.commons.lang.Validate; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerExpChangeEvent; + +public class VanillaExperienceExperienceSource extends SpecificExperienceSource { + + + public VanillaExperienceExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + } + + @Override + public ExperienceSourceManager newManager() { + return new ExperienceSourceManager() { + @EventHandler + public void onExp(PlayerExpChangeEvent e) { + if(e.getPlayer().hasMetadata("NPC")) + return; + PlayerData playerData=PlayerData.get(e.getPlayer()); + for(VanillaExperienceExperienceSource source:getSources()) { + if(source.matchesParameter(playerData,null)) + giveExperience(playerData,e.getAmount(),null); + } + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, Object obj) { + return true; + } +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/type/SpecificExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/type/SpecificExperienceSource.java index 6e62560c..b6b0dd9a 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/type/SpecificExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/type/SpecificExperienceSource.java @@ -5,11 +5,13 @@ import net.Indyuce.mmocore.experience.EXPSource; import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.util.math.formula.RandomAmount; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.jetbrains.annotations.Nullable; public abstract class SpecificExperienceSource extends ExperienceSource { private final RandomAmount amount; + double counter = 0; /** * Used to register experience sources with SPECIFIC experience outputs. @@ -42,6 +44,8 @@ public abstract class SpecificExperienceSource extends ExperienceSource { * @param hologramLocation Location used to display the exp hologram */ public void giveExperience(PlayerData player, double multiplier, @Nullable Location hologramLocation) { + counter+=rollAmount() * multiplier; + Bukkit.broadcastMessage("Gave xp " + counter+ " from " + this.getClass().getSimpleName()); getDispenser().giveExperience(player, rollAmount() * multiplier, hologramLocation, EXPSource.SOURCE); } } From f806705d8f4f7eb51850feb95037771d88cf4229 Mon Sep 17 00:00:00 2001 From: Guillaume Date: Mon, 9 May 2022 09:07:35 +0200 Subject: [PATCH 13/39] Debug for all the experience source. Added VanillaExperience & Resource ExperienceSource and added inCombat for Playing Experience Source. --- .../condition/BiomeCondition.java | 2 +- .../condition/Condition.java | 2 +- .../condition/ConditionInstance.java | 2 +- .../condition/DistanceCondition.java | 7 +-- .../condition/LevelCondition.java | 2 +- .../condition/PermissionCondition.java | 2 +- .../condition/WorldCondition.java | 2 +- .../api/event/PlayerExperienceGainEvent.java | 8 +-- .../mmocore/api/load/DefaultMMOLoader.java | 2 +- .../Indyuce/mmocore/api/load/MMOLoader.java | 2 +- .../mmocore/api/player/PlayerData.java | 7 +-- .../mmocore/comp/region/RegionCondition.java | 4 +- .../comp/region/WorldGuardMMOLoader.java | 2 +- .../mmocore/experience/PlayerProfessions.java | 23 ++++---- .../source/ClimbExperienceSource.java | 8 +-- .../source/DamageDealtExperienceSource.java | 26 ++++----- .../source/MoveExperienceSource.java | 23 ++++---- .../source/ProjectileExperienceSource.java | 24 ++++----- .../source/ResourceExperienceSource.java | 1 - .../source/RideExperienceSource.java | 40 ++++++++------ .../source/type/SpecificExperienceSource.java | 6 +-- .../mmocore/listener/BlockListener.java | 2 +- .../listener/profession/FishingListener.java | 2 +- .../mmocore/loot/chest/LootChestRegion.java | 9 ++-- .../mmocore/loot/droptable/DropTable.java | 6 +-- .../loot/droptable/dropitem/DropItem.java | 53 ++++++++++--------- .../droptable/dropitem/DropTableDropItem.java | 2 +- .../mmocore/manager/MMOLoadManager.java | 2 +- .../profession/CustomBlockManager.java | 5 +- .../manager/profession/FishingManager.java | 25 ++++++--- .../Indyuce/mmocore/waypoint/Waypoint.java | 6 +-- 31 files changed, 163 insertions(+), 144 deletions(-) rename src/main/java/net/Indyuce/mmocore/{loot/droptable => api}/condition/BiomeCondition.java (91%) rename src/main/java/net/Indyuce/mmocore/{loot/droptable => api}/condition/Condition.java (84%) rename src/main/java/net/Indyuce/mmocore/{loot/droptable => api}/condition/ConditionInstance.java (93%) rename src/main/java/net/Indyuce/mmocore/{loot/droptable => api}/condition/DistanceCondition.java (88%) rename src/main/java/net/Indyuce/mmocore/{loot/droptable => api}/condition/LevelCondition.java (93%) rename src/main/java/net/Indyuce/mmocore/{loot/droptable => api}/condition/PermissionCondition.java (90%) rename src/main/java/net/Indyuce/mmocore/{loot/droptable => api}/condition/WorldCondition.java (90%) diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/BiomeCondition.java b/src/main/java/net/Indyuce/mmocore/api/condition/BiomeCondition.java similarity index 91% rename from src/main/java/net/Indyuce/mmocore/loot/droptable/condition/BiomeCondition.java rename to src/main/java/net/Indyuce/mmocore/api/condition/BiomeCondition.java index 7da08703..a90cbbac 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/BiomeCondition.java +++ b/src/main/java/net/Indyuce/mmocore/api/condition/BiomeCondition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.loot.droptable.condition; +package net.Indyuce.mmocore.api.condition; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/Condition.java b/src/main/java/net/Indyuce/mmocore/api/condition/Condition.java similarity index 84% rename from src/main/java/net/Indyuce/mmocore/loot/droptable/condition/Condition.java rename to src/main/java/net/Indyuce/mmocore/api/condition/Condition.java index d1445364..8f302a9a 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/Condition.java +++ b/src/main/java/net/Indyuce/mmocore/api/condition/Condition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.loot.droptable.condition; +package net.Indyuce.mmocore.api.condition; import io.lumine.mythic.lib.api.MMOLineConfig; diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/ConditionInstance.java b/src/main/java/net/Indyuce/mmocore/api/condition/ConditionInstance.java similarity index 93% rename from src/main/java/net/Indyuce/mmocore/loot/droptable/condition/ConditionInstance.java rename to src/main/java/net/Indyuce/mmocore/api/condition/ConditionInstance.java index 937b9475..93a9688f 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/ConditionInstance.java +++ b/src/main/java/net/Indyuce/mmocore/api/condition/ConditionInstance.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.loot.droptable.condition; +package net.Indyuce.mmocore.api.condition; import java.util.List; import java.util.stream.Stream; diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/DistanceCondition.java b/src/main/java/net/Indyuce/mmocore/api/condition/DistanceCondition.java similarity index 88% rename from src/main/java/net/Indyuce/mmocore/loot/droptable/condition/DistanceCondition.java rename to src/main/java/net/Indyuce/mmocore/api/condition/DistanceCondition.java index 486ce977..9b52203e 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/DistanceCondition.java +++ b/src/main/java/net/Indyuce/mmocore/api/condition/DistanceCondition.java @@ -1,15 +1,10 @@ -package net.Indyuce.mmocore.loot.droptable.condition; +package net.Indyuce.mmocore.api.condition; import io.lumine.mythic.lib.api.MMOLineConfig; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.World; import org.bukkit.entity.Entity; -import org.bukkit.generator.WorldInfo; - - -import java.util.stream.Collectors; public class DistanceCondition extends Condition{ private final Location location; diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/LevelCondition.java b/src/main/java/net/Indyuce/mmocore/api/condition/LevelCondition.java similarity index 93% rename from src/main/java/net/Indyuce/mmocore/loot/droptable/condition/LevelCondition.java rename to src/main/java/net/Indyuce/mmocore/api/condition/LevelCondition.java index e3fe2a0d..9d121e7b 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/LevelCondition.java +++ b/src/main/java/net/Indyuce/mmocore/api/condition/LevelCondition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.loot.droptable.condition; +package net.Indyuce.mmocore.api.condition; import net.Indyuce.mmocore.api.player.PlayerData; import io.lumine.mythic.lib.api.MMOLineConfig; diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/PermissionCondition.java b/src/main/java/net/Indyuce/mmocore/api/condition/PermissionCondition.java similarity index 90% rename from src/main/java/net/Indyuce/mmocore/loot/droptable/condition/PermissionCondition.java rename to src/main/java/net/Indyuce/mmocore/api/condition/PermissionCondition.java index 0d009b44..f6bd9f58 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/PermissionCondition.java +++ b/src/main/java/net/Indyuce/mmocore/api/condition/PermissionCondition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.loot.droptable.condition; +package net.Indyuce.mmocore.api.condition; import io.lumine.mythic.lib.api.MMOLineConfig; import org.bukkit.entity.Player; diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/WorldCondition.java b/src/main/java/net/Indyuce/mmocore/api/condition/WorldCondition.java similarity index 90% rename from src/main/java/net/Indyuce/mmocore/loot/droptable/condition/WorldCondition.java rename to src/main/java/net/Indyuce/mmocore/api/condition/WorldCondition.java index 35e6341d..1985f732 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/WorldCondition.java +++ b/src/main/java/net/Indyuce/mmocore/api/condition/WorldCondition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.loot.droptable.condition; +package net.Indyuce.mmocore.api.condition; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/net/Indyuce/mmocore/api/event/PlayerExperienceGainEvent.java b/src/main/java/net/Indyuce/mmocore/api/event/PlayerExperienceGainEvent.java index 72ed5928..bd48b40d 100644 --- a/src/main/java/net/Indyuce/mmocore/api/event/PlayerExperienceGainEvent.java +++ b/src/main/java/net/Indyuce/mmocore/api/event/PlayerExperienceGainEvent.java @@ -16,14 +16,14 @@ public class PlayerExperienceGainEvent extends PlayerDataEvent implements Cancel private final Profession profession; private final EXPSource source; - private int experience; + private double experience; private boolean cancelled; - public PlayerExperienceGainEvent(PlayerData player, int experience, EXPSource source) { + public PlayerExperienceGainEvent(PlayerData player, double experience, EXPSource source) { this(player, null, experience, source); } - public PlayerExperienceGainEvent(PlayerData player, @Nullable Profession profession, int experience, EXPSource source) { + public PlayerExperienceGainEvent(PlayerData player, @Nullable Profession profession, double experience, EXPSource source) { super(player); this.profession = profession; @@ -31,7 +31,7 @@ public class PlayerExperienceGainEvent extends PlayerDataEvent implements Cancel this.source = source; } - public int getExperience() { + public double getExperience() { return experience; } diff --git a/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java b/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java index 970c2c09..09524a8c 100644 --- a/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java +++ b/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java @@ -2,7 +2,7 @@ package net.Indyuce.mmocore.api.load; import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; import net.Indyuce.mmocore.experience.source.*; -import net.Indyuce.mmocore.loot.droptable.condition.*; +import net.Indyuce.mmocore.api.condition.*; import org.bukkit.configuration.ConfigurationSection; import net.Indyuce.mmocore.api.block.BlockType; diff --git a/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java b/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java index c3065e0e..91489e44 100644 --- a/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java +++ b/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java @@ -2,7 +2,7 @@ package net.Indyuce.mmocore.api.load; import io.lumine.mythic.lib.api.MMOLineConfig; import net.Indyuce.mmocore.api.block.BlockType; -import net.Indyuce.mmocore.loot.droptable.condition.Condition; +import net.Indyuce.mmocore.api.condition.Condition; import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem; import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; import net.Indyuce.mmocore.experience.source.type.ExperienceSource; 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 75c9d6bc..13a84cf9 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java @@ -70,7 +70,8 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc */ @Nullable private PlayerClass profess; - private int level, experience, classPoints, skillPoints, attributePoints, attributeReallocationPoints;// skillReallocationPoints, + private int level, classPoints, skillPoints, attributePoints, attributeReallocationPoints;// skillReallocationPoints, + private double experience; private double mana, stamina, stellium; private Guild guild; private SkillCastingHandler skillCasting; @@ -547,7 +548,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc member.giveExperience(value, EXPSource.PARTY_SHARING, null, false); } - PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(this, (int) value, source); + PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(this, value, source); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) return; @@ -588,7 +589,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc refreshVanillaExp(); } - public int getExperience() { + public double getExperience() { return experience; } diff --git a/src/main/java/net/Indyuce/mmocore/comp/region/RegionCondition.java b/src/main/java/net/Indyuce/mmocore/comp/region/RegionCondition.java index dbe80a15..21e9bd7a 100644 --- a/src/main/java/net/Indyuce/mmocore/comp/region/RegionCondition.java +++ b/src/main/java/net/Indyuce/mmocore/comp/region/RegionCondition.java @@ -3,8 +3,8 @@ package net.Indyuce.mmocore.comp.region; import java.util.Arrays; import java.util.List; -import net.Indyuce.mmocore.loot.droptable.condition.Condition; -import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance; +import net.Indyuce.mmocore.api.condition.Condition; +import net.Indyuce.mmocore.api.condition.ConditionInstance; import io.lumine.mythic.lib.api.MMOLineConfig; public class RegionCondition extends Condition { diff --git a/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java b/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java index 0c771cf7..949f2335 100644 --- a/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java +++ b/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java @@ -1,6 +1,6 @@ package net.Indyuce.mmocore.comp.region; -import net.Indyuce.mmocore.loot.droptable.condition.Condition; +import net.Indyuce.mmocore.api.condition.Condition; import net.Indyuce.mmocore.api.load.MMOLoader; import io.lumine.mythic.lib.api.MMOLineConfig; diff --git a/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java b/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java index f7dd9963..887e45b0 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java +++ b/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java @@ -26,7 +26,7 @@ import java.util.Map; import java.util.Map.Entry; public class PlayerProfessions { - private final Map exp = new HashMap<>(); + private final Map exp = new HashMap<>(); private final Map level = new HashMap<>(); private final PlayerData playerData; @@ -41,7 +41,7 @@ public class PlayerProfessions { public PlayerProfessions load(ConfigurationSection config) { for (String key : config.getKeys(false)) if (MMOCore.plugin.professionManager.has(key)) { - exp.put(key, config.getInt(key + ".exp")); + exp.put(key, config.getDouble(key + ".exp")); level.put(key, config.getInt(key + ".level")); } @@ -89,7 +89,7 @@ public class PlayerProfessions { for (Entry entry : obj.entrySet()) if (MMOCore.plugin.professionManager.has(entry.getKey())) { JsonObject value = entry.getValue().getAsJsonObject(); - exp.put(entry.getKey(), value.get("exp").getAsInt()); + exp.put(entry.getKey(), value.get("exp").getAsDouble()); level.put(entry.getKey(), value.get("level").getAsInt()); } @@ -111,11 +111,11 @@ public class PlayerProfessions { return getLevel(profession.getId()); } - public int getExperience(String id) { - return exp.getOrDefault(id, 0); + public double getExperience(String id) { + return exp.getOrDefault(id, 0.); } - public int getExperience(Profession profession) { + public double getExperience(Profession profession) { return getExperience(profession.getId()); } @@ -136,7 +136,7 @@ public class PlayerProfessions { level.put(profession.getId(), Math.max(1, current - value)); } - public void setExperience(Profession profession, int value) { + public void setExperience(Profession profession, double value) { exp.put(profession.getId(), value); } @@ -147,7 +147,7 @@ public class PlayerProfessions { giveExperience(profession, total, source); } - public void giveExperience(Profession profession, int value, EXPSource source) { + public void giveExperience(Profession profession, double value, EXPSource source) { giveExperience(profession, value, source, null); } @@ -172,13 +172,14 @@ public class PlayerProfessions { if (hologramLocation != null) MMOCoreUtils.displayIndicator(hologramLocation.add(.5, 1.5, .5), MMOCore.plugin.configManager.getSimpleMessage("exp-hologram", "exp", "" + value).message()); - PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(playerData, profession, (int) value, source); + PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(playerData, profession, value, source); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) return; - exp.put(profession.getId(), Math.max(0, exp.getOrDefault(profession.getId(), 0) + event.getExperience())); - int needed, exp, level, oldLevel = getLevel(profession); + exp.put(profession.getId(), Math.max(0, exp.getOrDefault(profession.getId(), 0.) + event.getExperience())); + int level, oldLevel = getLevel(profession); + double needed,exp; /* * Loop for exp overload when leveling up, will continue diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java index 5e0c79c6..c26ebd0a 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java @@ -45,11 +45,11 @@ public class ClimbExperienceSource extends SpecificExperienceSource { return new ExperienceSourceManager() { @EventHandler public void onClimb(PlayerMoveEvent e) { - if (e.getPlayer().hasMetadata("NPC")) - return; - PlayerData playerData = PlayerData.get(e.getPlayer()); - double delta = e.getTo().getY() - e.getFrom().getY(); + double delta=e.getTo().getBlockY()-e.getFrom().getBlockY(); if (delta > 0) { + if (e.getPlayer().hasMetadata("NPC")) + return; + PlayerData playerData = PlayerData.get(e.getPlayer()); for (ClimbExperienceSource source : getSources()) { if (source.matchesParameter(playerData, e.getFrom().getBlock().getType())) source.giveExperience(playerData, delta, null); diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/DamageDealtExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/DamageDealtExperienceSource.java index 8ebd1363..7e1c91ac 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/DamageDealtExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/DamageDealtExperienceSource.java @@ -20,7 +20,7 @@ public class DamageDealtExperienceSource extends SpecificExperienceSource newManager() { return new ExperienceSourceManager() { @EventHandler public void onDamageDealt(PlayerAttackEvent e) { - if(e.getPlayer().hasMetadata("NPC")) - return; - PlayerData playerData=PlayerData.get(e.getPlayer()); - for(DamagePacket packet:e.getDamage().getPackets()) { - for(DamageType damageType:packet.getTypes()) { - - for(DamageDealtExperienceSource source: getSources()) { - if(source.matchesParameter(playerData,damageType)) - source.giveExperience(playerData, packet.getFinalValue(), null); + PlayerData playerData = PlayerData.get(e.getPlayer()); + for (DamageDealtExperienceSource source : getSources()) { + double value = 0; + for (DamagePacket packet : e.getDamage().getPackets()) { + for (DamageType damageType : packet.getTypes()) { + if (source.matchesParameter(playerData, damageType)) + value += packet.getFinalValue(); } - } + } + source.giveExperience(playerData, value, null); } } @@ -63,7 +63,7 @@ public class DamageDealtExperienceSource extends SpecificExperienceSource() { @EventHandler public void onMove(PlayerMoveEvent e) { - if(e.getPlayer().hasMetadata("NPC")) - return; - Player player=e.getPlayer(); - - PlayerData playerData =PlayerData.get(player); - for(MoveExperienceSource source:getSources()) { - if(source.matchesParameter(playerData,null)) { - giveExperience(playerData,e.getTo().distance(e.getFrom()),null); + double deltax=e.getTo().getBlockX()-e.getFrom().getBlockX(); + double deltay=e.getTo().getBlockY()-e.getFrom().getBlockY(); + double deltaz=e.getTo().getBlockZ()-e.getFrom().getBlockZ(); + if(deltax!=0&&deltay!=0&&deltaz!=0) { + double delta=Math.sqrt(deltax*deltax+deltay*deltay+deltaz*deltaz); + if(e.getPlayer().hasMetadata("NPC")) + return; + Player player=e.getPlayer(); + PlayerData playerData =PlayerData.get(player); + for(MoveExperienceSource source:getSources()) { + if(source.matchesParameter(playerData,null)) { + giveExperience(playerData,delta,null); + } } } } @@ -58,7 +63,7 @@ public class MoveExperienceSource extends SpecificExperienceSource { @Override public boolean matchesParameter(PlayerData player, Object obj) { - return type.matches(player.getPlayer()); + return type==null||type.matches(player.getPlayer()); } public enum MovingType { diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java index ac2029bd..6a2960c6 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java @@ -31,10 +31,10 @@ public class ProjectileExperienceSource extends SpecificExperienceSource p instanceof Arrow), - TRIDENT((p)-> p instanceof Trident), - FIREBALL((p)-> p instanceof Fireball), - FISH_HOOK((p)-> p instanceof FishHook), - ; + ARROW((p) -> p instanceof Arrow), + TRIDENT((p) -> p instanceof Trident); - private final Function matching; + private final Function matching; - ProjectileType(Function matching) { - this.matching=matching; + ProjectileType(Function matching) { + this.matching = matching; } diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/ResourceExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/ResourceExperienceSource.java index 5b615af9..7b9463d3 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/ResourceExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/ResourceExperienceSource.java @@ -43,7 +43,6 @@ public class ResourceExperienceSource extends SpecificExperienceSource> { +public class RideExperienceSource extends SpecificExperienceSource { private final EntityType type; /** - *Gives experience when a player moves riding a certain entity. If no entity type is given it will give xp if you move - *while riding an entity whatever it is. - *The random value you give correspond to the xp you get per block travelled while riding. + * Gives experience when a player moves riding a certain entity. If no entity type is given it will give xp if you move + * while riding an entity whatever it is. + * The random value you give correspond to the xp you get per block travelled while riding. */ public RideExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { super(dispenser, config); @@ -32,7 +32,7 @@ public class RideExperienceSource extends SpecificExperienceSource() { @EventHandler public void onRide(PlayerMoveEvent e) { - if (e.getPlayer().hasMetadata("NPC")) - return; - PlayerData playerData=PlayerData.get(e.getPlayer()); - if(e.getPlayer().isInsideVehicle()) { - Entity vehicle=e.getPlayer().getVehicle(); - for(RideExperienceSource source:getSources()) { - if(source.matchesParameter(playerData,vehicle.getClass())) - giveExperience(playerData,e.getFrom().distance(e.getTo()),null); + + if (e.getPlayer().isInsideVehicle()) { + double deltax = e.getTo().getBlockX() - e.getFrom().getBlockX(); + double deltay = e.getTo().getBlockY() - e.getFrom().getBlockY(); + double deltaz = e.getTo().getBlockZ() - e.getFrom().getBlockZ(); + if (deltax != 0 && deltay != 0 && deltaz != 0) { + double delta = Math.sqrt(deltax * deltax + deltay * deltay + deltaz * deltaz); + if (e.getPlayer().hasMetadata("NPC")) + return; + PlayerData playerData = PlayerData.get(e.getPlayer()); + Entity vehicle = e.getPlayer().getVehicle(); + for (RideExperienceSource source : getSources()) { + if (source.matchesParameter(playerData, vehicle.getType())) + giveExperience(playerData, e.getFrom().distance(e.getTo()), null); + } } } } + }; } @Override - public boolean matchesParameter(PlayerData player, Class obj) { - if(type==null) + public boolean matchesParameter(PlayerData player, EntityType obj) { + if (type == null) return true; - return type.getEntityClass().isAssignableFrom(obj); + return type.equals(obj); } } diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/type/SpecificExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/type/SpecificExperienceSource.java index b6b0dd9a..05cf0b3d 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/type/SpecificExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/type/SpecificExperienceSource.java @@ -29,8 +29,8 @@ public abstract class SpecificExperienceSource extends ExperienceSource { return amount; } - public int rollAmount() { - return amount.calculateInt(); + public double rollAmount() { + return amount.calculate(); } /** @@ -44,8 +44,6 @@ public abstract class SpecificExperienceSource extends ExperienceSource { * @param hologramLocation Location used to display the exp hologram */ public void giveExperience(PlayerData player, double multiplier, @Nullable Location hologramLocation) { - counter+=rollAmount() * multiplier; - Bukkit.broadcastMessage("Gave xp " + counter+ " from " + this.getClass().getSimpleName()); getDispenser().giveExperience(player, rollAmount() * multiplier, hologramLocation, EXPSource.SOURCE); } } diff --git a/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java b/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java index 3553deca..e9dc299b 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java +++ b/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java @@ -11,7 +11,7 @@ import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.experience.source.MineBlockExperienceSource; import net.Indyuce.mmocore.loot.LootBuilder; -import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance; +import net.Indyuce.mmocore.api.condition.ConditionInstance; import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; diff --git a/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java b/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java index 19ec3c4f..fe678f07 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java +++ b/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java @@ -80,7 +80,7 @@ public class FishingListener implements Listener { public FishingData(Player player, FishHook hook, FishingDropTable table) { this.location = hook.getLocation(); - this.caught = table.getRandomItem(); + this.caught = table.getRandomItem(PlayerData.get(player)); this.playerData = PlayerData.get(this.player = player); this.hook = hook; diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java index 6e265a3b..99773f8a 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java @@ -125,17 +125,18 @@ public class LootChestRegion { //chance=8-> tierChance=sqrt(tierChance) double sum = 0; for (ChestTier tier : tiers) { - sum += Math.pow(tier.chance, 1 / Math.pow((1 + chance),1/3)); + sum += Math.pow(tier.chance, 1 / Math.log(1 + chance)); } - + double randomCoefficient=random.nextDouble(); double s=0; for (ChestTier tier : tiers) { s+=Math.pow(tier.chance, 1 / Math.pow((1 + chance),1/3))/sum; - if (random.nextDouble() < s) + if (randomCoefficient < s) return tier; } - return tiers.stream().findAny().orElse(null); + + throw new NullPointerException("Could not find item in the tier list"); } public Location getRandomLocation(Location center) { diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java b/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java index 1cce3177..dd8e4db2 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java +++ b/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java @@ -5,8 +5,8 @@ import java.util.List; import java.util.Set; import java.util.logging.Level; -import net.Indyuce.mmocore.loot.droptable.condition.Condition; -import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance; +import net.Indyuce.mmocore.api.condition.Condition; +import net.Indyuce.mmocore.api.condition.ConditionInstance; import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem; import org.apache.commons.lang.Validate; import org.bukkit.configuration.ConfigurationSection; @@ -73,7 +73,7 @@ public class DropTable extends PostLoadObject { public List collect(LootBuilder builder) { for (DropItem item : drops) - if (item.rollChance() && builder.getCapacity() >= item.getWeight()) { + if (item.rollChance(builder.getEntity()) && builder.getCapacity() >= item.getWeight()) { item.collect(builder); builder.reduceCapacity(item.getWeight()); } diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropItem.java b/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropItem.java index 05d99b44..143ebbca 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropItem.java +++ b/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropItem.java @@ -2,41 +2,46 @@ package net.Indyuce.mmocore.loot.droptable.dropitem; import java.util.Random; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.loot.LootBuilder; import net.Indyuce.mmocore.api.util.math.formula.RandomAmount; import io.lumine.mythic.lib.api.MMOLineConfig; public abstract class DropItem { - protected static final Random random = new Random(); + protected static final Random random = new Random(); - private final double chance, weight; - private final RandomAmount amount; + private final double chance, weight; + private final RandomAmount amount; - public DropItem(MMOLineConfig config) { - chance = config.args().length > 0 ? Double.parseDouble(config.args()[0]) : 1; - amount = config.args().length > 1 ? new RandomAmount(config.args()[1]) : new RandomAmount(1, 1); - weight = config.args().length > 2 ? Double.parseDouble(config.args()[2]) : 0; - } + public DropItem(MMOLineConfig config) { + chance = config.args().length > 0 ? Double.parseDouble(config.args()[0]) : 1; + amount = config.args().length > 1 ? new RandomAmount(config.args()[1]) : new RandomAmount(1, 1); + weight = config.args().length > 2 ? Double.parseDouble(config.args()[2]) : 0; + } - public RandomAmount getAmount() { - return amount; - } + public RandomAmount getAmount() { + return amount; + } - public double getChance() { - return chance; - } + public double getChance() { + return chance; + } - public double getWeight() { - return weight; - } + public double getWeight() { + return weight; + } - public int rollAmount() { - return amount.calculateInt(); - } + public int rollAmount() { + return amount.calculateInt(); + } - public boolean rollChance() { - return random.nextDouble() < chance; - } + /** + * If the player chance is 0 the random value will remain the same. When he get lucks the chance gets closer to one. + */ + public boolean rollChance(PlayerData player) { + return Math.pow(random.nextDouble(), 1 / Math.log(1 + player.getStats().getStat(StatType.CHANCE))) < chance; + } - public abstract void collect(LootBuilder builder); + public abstract void collect(LootBuilder builder); } diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropTableDropItem.java b/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropTableDropItem.java index 02123b38..5b52a5a5 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropTableDropItem.java +++ b/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropTableDropItem.java @@ -3,7 +3,7 @@ package net.Indyuce.mmocore.loot.droptable.dropitem; import io.lumine.mythic.lib.api.MMOLineConfig; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.loot.droptable.DropTable; -import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance; +import net.Indyuce.mmocore.api.condition.ConditionInstance; import net.Indyuce.mmocore.loot.LootBuilder; import net.Indyuce.mmocore.api.player.PlayerData; import org.apache.commons.lang.Validate; diff --git a/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java b/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java index 67f7c279..6f397d4f 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java @@ -11,7 +11,7 @@ import org.bukkit.configuration.ConfigurationSection; import com.google.gson.JsonParseException; import net.Indyuce.mmocore.api.block.BlockType; -import net.Indyuce.mmocore.loot.droptable.condition.Condition; +import net.Indyuce.mmocore.api.condition.Condition; import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem; import net.Indyuce.mmocore.experience.source.type.ExperienceSource; import net.Indyuce.mmocore.api.load.DefaultMMOLoader; diff --git a/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java b/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java index c6e72d9e..8264da46 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java @@ -7,11 +7,10 @@ import net.Indyuce.mmocore.api.block.BlockInfo.RegeneratingBlock; import net.Indyuce.mmocore.api.block.BlockType; import net.Indyuce.mmocore.api.block.SkullBlockType; import net.Indyuce.mmocore.api.block.VanillaBlockType; -import net.Indyuce.mmocore.loot.droptable.condition.Condition; -import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance; +import net.Indyuce.mmocore.api.condition.Condition; +import net.Indyuce.mmocore.api.condition.ConditionInstance; import net.Indyuce.mmocore.api.util.MMOCoreUtils; import io.lumine.mythic.lib.api.MMOLineConfig; -import net.Indyuce.mmocore.manager.profession.SpecificProfessionManager; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.block.Block; diff --git a/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java b/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java index aa9e1738..d2d94a37 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java @@ -2,8 +2,10 @@ package net.Indyuce.mmocore.manager.profession; import io.lumine.mythic.lib.api.MMOLineConfig; import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.loot.droptable.condition.Condition; -import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.api.player.stats.StatType; +import net.Indyuce.mmocore.api.condition.Condition; +import net.Indyuce.mmocore.api.condition.ConditionInstance; import net.Indyuce.mmocore.loot.droptable.dropitem.fishing.FishingDropItem; import org.apache.commons.lang.Validate; import org.bukkit.configuration.ConfigurationSection; @@ -90,12 +92,23 @@ public class FishingManager extends SpecificProfessionManager { return conditions; } - public FishingDropItem getRandomItem() { - double randomCoefficient = RANDOM.nextDouble() * maxWeight; + /** + * The Fishing Drop Item is calculated randomly bu the chance stat will make + * low weight items more likely to be caught. + */ + public FishingDropItem getRandomItem(PlayerData player) { + double chance = player.getStats().getStat(StatType.CHANCE); - for (FishingDropItem item : items) - if ((randomCoefficient -= item.getItem().getWeight()) <= 0) + //chance=0 ->the tier.chance remains the same + //chance ->+inf -> the tier.chance becomes the same for everyone, uniform law + //chance=8-> tierChance=sqrt(tierChance) + double sum = 0; + double randomCoefficient=RANDOM.nextDouble(); + for (FishingDropItem item : items) { + sum += Math.pow(item.getItem().getWeight(), 1 / Math.log(1 + chance)); + if(sum Date: Mon, 9 May 2022 09:21:15 +0200 Subject: [PATCH 14/39] Debug for all the experience source. Added VanillaExperience & Resource ExperienceSource and added inCombat for Playing Experience Source. --- .../java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java | 1 - src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java | 2 +- .../java/net/Indyuce/mmocore/comp/region/RegionCondition.java | 4 ++-- .../net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java | 2 +- src/main/java/net/Indyuce/mmocore/listener/BlockListener.java | 2 +- .../mmocore/{api => loot}/condition/BiomeCondition.java | 2 +- .../Indyuce/mmocore/{api => loot}/condition/Condition.java | 2 +- .../mmocore/{api => loot}/condition/ConditionInstance.java | 2 +- .../mmocore/{api => loot}/condition/DistanceCondition.java | 2 +- .../mmocore/{api => loot}/condition/LevelCondition.java | 2 +- .../mmocore/{api => loot}/condition/PermissionCondition.java | 2 +- .../mmocore/{api => loot}/condition/WorldCondition.java | 2 +- .../java/net/Indyuce/mmocore/loot/droptable/DropTable.java | 4 ++-- .../mmocore/loot/droptable/dropitem/DropTableDropItem.java | 2 +- src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java | 2 +- .../mmocore/manager/profession/CustomBlockManager.java | 4 ++-- .../Indyuce/mmocore/manager/profession/FishingManager.java | 4 ++-- src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java | 4 ++-- 18 files changed, 22 insertions(+), 23 deletions(-) rename src/main/java/net/Indyuce/mmocore/{api => loot}/condition/BiomeCondition.java (92%) rename src/main/java/net/Indyuce/mmocore/{api => loot}/condition/Condition.java (86%) rename src/main/java/net/Indyuce/mmocore/{api => loot}/condition/ConditionInstance.java (95%) rename src/main/java/net/Indyuce/mmocore/{api => loot}/condition/DistanceCondition.java (96%) rename src/main/java/net/Indyuce/mmocore/{api => loot}/condition/LevelCondition.java (94%) rename src/main/java/net/Indyuce/mmocore/{api => loot}/condition/PermissionCondition.java (92%) rename src/main/java/net/Indyuce/mmocore/{api => loot}/condition/WorldCondition.java (91%) diff --git a/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java b/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java index 09524a8c..a2c8389a 100644 --- a/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java +++ b/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java @@ -2,7 +2,6 @@ package net.Indyuce.mmocore.api.load; import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; import net.Indyuce.mmocore.experience.source.*; -import net.Indyuce.mmocore.api.condition.*; import org.bukkit.configuration.ConfigurationSection; import net.Indyuce.mmocore.api.block.BlockType; diff --git a/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java b/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java index 91489e44..10ca9c12 100644 --- a/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java +++ b/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java @@ -2,7 +2,7 @@ package net.Indyuce.mmocore.api.load; import io.lumine.mythic.lib.api.MMOLineConfig; import net.Indyuce.mmocore.api.block.BlockType; -import net.Indyuce.mmocore.api.condition.Condition; +import net.Indyuce.mmocore.loot.condition.Condition; import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem; import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; import net.Indyuce.mmocore.experience.source.type.ExperienceSource; diff --git a/src/main/java/net/Indyuce/mmocore/comp/region/RegionCondition.java b/src/main/java/net/Indyuce/mmocore/comp/region/RegionCondition.java index 21e9bd7a..4f2876c2 100644 --- a/src/main/java/net/Indyuce/mmocore/comp/region/RegionCondition.java +++ b/src/main/java/net/Indyuce/mmocore/comp/region/RegionCondition.java @@ -3,8 +3,8 @@ package net.Indyuce.mmocore.comp.region; import java.util.Arrays; import java.util.List; -import net.Indyuce.mmocore.api.condition.Condition; -import net.Indyuce.mmocore.api.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.condition.Condition; +import net.Indyuce.mmocore.loot.condition.ConditionInstance; import io.lumine.mythic.lib.api.MMOLineConfig; public class RegionCondition extends Condition { diff --git a/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java b/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java index 949f2335..d1903d70 100644 --- a/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java +++ b/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java @@ -1,6 +1,6 @@ package net.Indyuce.mmocore.comp.region; -import net.Indyuce.mmocore.api.condition.Condition; +import net.Indyuce.mmocore.loot.condition.Condition; import net.Indyuce.mmocore.api.load.MMOLoader; import io.lumine.mythic.lib.api.MMOLineConfig; diff --git a/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java b/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java index e9dc299b..1346b23f 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java +++ b/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java @@ -11,7 +11,7 @@ import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.experience.source.MineBlockExperienceSource; import net.Indyuce.mmocore.loot.LootBuilder; -import net.Indyuce.mmocore.api.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.condition.ConditionInstance; import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; diff --git a/src/main/java/net/Indyuce/mmocore/api/condition/BiomeCondition.java b/src/main/java/net/Indyuce/mmocore/loot/condition/BiomeCondition.java similarity index 92% rename from src/main/java/net/Indyuce/mmocore/api/condition/BiomeCondition.java rename to src/main/java/net/Indyuce/mmocore/loot/condition/BiomeCondition.java index a90cbbac..ae2f9922 100644 --- a/src/main/java/net/Indyuce/mmocore/api/condition/BiomeCondition.java +++ b/src/main/java/net/Indyuce/mmocore/loot/condition/BiomeCondition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.api.condition; +package net.Indyuce.mmocore.loot.condition; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/net/Indyuce/mmocore/api/condition/Condition.java b/src/main/java/net/Indyuce/mmocore/loot/condition/Condition.java similarity index 86% rename from src/main/java/net/Indyuce/mmocore/api/condition/Condition.java rename to src/main/java/net/Indyuce/mmocore/loot/condition/Condition.java index 8f302a9a..c925c1ba 100644 --- a/src/main/java/net/Indyuce/mmocore/api/condition/Condition.java +++ b/src/main/java/net/Indyuce/mmocore/loot/condition/Condition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.api.condition; +package net.Indyuce.mmocore.loot.condition; import io.lumine.mythic.lib.api.MMOLineConfig; diff --git a/src/main/java/net/Indyuce/mmocore/api/condition/ConditionInstance.java b/src/main/java/net/Indyuce/mmocore/loot/condition/ConditionInstance.java similarity index 95% rename from src/main/java/net/Indyuce/mmocore/api/condition/ConditionInstance.java rename to src/main/java/net/Indyuce/mmocore/loot/condition/ConditionInstance.java index 93a9688f..d74a0454 100644 --- a/src/main/java/net/Indyuce/mmocore/api/condition/ConditionInstance.java +++ b/src/main/java/net/Indyuce/mmocore/loot/condition/ConditionInstance.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.api.condition; +package net.Indyuce.mmocore.loot.condition; import java.util.List; import java.util.stream.Stream; diff --git a/src/main/java/net/Indyuce/mmocore/api/condition/DistanceCondition.java b/src/main/java/net/Indyuce/mmocore/loot/condition/DistanceCondition.java similarity index 96% rename from src/main/java/net/Indyuce/mmocore/api/condition/DistanceCondition.java rename to src/main/java/net/Indyuce/mmocore/loot/condition/DistanceCondition.java index 9b52203e..de9cef5e 100644 --- a/src/main/java/net/Indyuce/mmocore/api/condition/DistanceCondition.java +++ b/src/main/java/net/Indyuce/mmocore/loot/condition/DistanceCondition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.api.condition; +package net.Indyuce.mmocore.loot.condition; import io.lumine.mythic.lib.api.MMOLineConfig; import org.apache.commons.lang.Validate; diff --git a/src/main/java/net/Indyuce/mmocore/api/condition/LevelCondition.java b/src/main/java/net/Indyuce/mmocore/loot/condition/LevelCondition.java similarity index 94% rename from src/main/java/net/Indyuce/mmocore/api/condition/LevelCondition.java rename to src/main/java/net/Indyuce/mmocore/loot/condition/LevelCondition.java index 9d121e7b..087a379f 100644 --- a/src/main/java/net/Indyuce/mmocore/api/condition/LevelCondition.java +++ b/src/main/java/net/Indyuce/mmocore/loot/condition/LevelCondition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.api.condition; +package net.Indyuce.mmocore.loot.condition; import net.Indyuce.mmocore.api.player.PlayerData; import io.lumine.mythic.lib.api.MMOLineConfig; diff --git a/src/main/java/net/Indyuce/mmocore/api/condition/PermissionCondition.java b/src/main/java/net/Indyuce/mmocore/loot/condition/PermissionCondition.java similarity index 92% rename from src/main/java/net/Indyuce/mmocore/api/condition/PermissionCondition.java rename to src/main/java/net/Indyuce/mmocore/loot/condition/PermissionCondition.java index f6bd9f58..6a97e8ab 100644 --- a/src/main/java/net/Indyuce/mmocore/api/condition/PermissionCondition.java +++ b/src/main/java/net/Indyuce/mmocore/loot/condition/PermissionCondition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.api.condition; +package net.Indyuce.mmocore.loot.condition; import io.lumine.mythic.lib.api.MMOLineConfig; import org.bukkit.entity.Player; diff --git a/src/main/java/net/Indyuce/mmocore/api/condition/WorldCondition.java b/src/main/java/net/Indyuce/mmocore/loot/condition/WorldCondition.java similarity index 91% rename from src/main/java/net/Indyuce/mmocore/api/condition/WorldCondition.java rename to src/main/java/net/Indyuce/mmocore/loot/condition/WorldCondition.java index 1985f732..955d0289 100644 --- a/src/main/java/net/Indyuce/mmocore/api/condition/WorldCondition.java +++ b/src/main/java/net/Indyuce/mmocore/loot/condition/WorldCondition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.api.condition; +package net.Indyuce.mmocore.loot.condition; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java b/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java index dd8e4db2..aa7a602d 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java +++ b/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java @@ -5,8 +5,8 @@ import java.util.List; import java.util.Set; import java.util.logging.Level; -import net.Indyuce.mmocore.api.condition.Condition; -import net.Indyuce.mmocore.api.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.condition.Condition; +import net.Indyuce.mmocore.loot.condition.ConditionInstance; import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem; import org.apache.commons.lang.Validate; import org.bukkit.configuration.ConfigurationSection; diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropTableDropItem.java b/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropTableDropItem.java index 5b52a5a5..4f21174c 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropTableDropItem.java +++ b/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropTableDropItem.java @@ -3,7 +3,7 @@ package net.Indyuce.mmocore.loot.droptable.dropitem; import io.lumine.mythic.lib.api.MMOLineConfig; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.loot.droptable.DropTable; -import net.Indyuce.mmocore.api.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.condition.ConditionInstance; import net.Indyuce.mmocore.loot.LootBuilder; import net.Indyuce.mmocore.api.player.PlayerData; import org.apache.commons.lang.Validate; diff --git a/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java b/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java index 6f397d4f..4b9e4444 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java @@ -11,7 +11,7 @@ import org.bukkit.configuration.ConfigurationSection; import com.google.gson.JsonParseException; import net.Indyuce.mmocore.api.block.BlockType; -import net.Indyuce.mmocore.api.condition.Condition; +import net.Indyuce.mmocore.loot.condition.Condition; import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem; import net.Indyuce.mmocore.experience.source.type.ExperienceSource; import net.Indyuce.mmocore.api.load.DefaultMMOLoader; diff --git a/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java b/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java index 8264da46..57ddf5f7 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java @@ -7,8 +7,8 @@ import net.Indyuce.mmocore.api.block.BlockInfo.RegeneratingBlock; import net.Indyuce.mmocore.api.block.BlockType; import net.Indyuce.mmocore.api.block.SkullBlockType; import net.Indyuce.mmocore.api.block.VanillaBlockType; -import net.Indyuce.mmocore.api.condition.Condition; -import net.Indyuce.mmocore.api.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.condition.Condition; +import net.Indyuce.mmocore.loot.condition.ConditionInstance; import net.Indyuce.mmocore.api.util.MMOCoreUtils; import io.lumine.mythic.lib.api.MMOLineConfig; import org.bukkit.Bukkit; diff --git a/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java b/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java index d2d94a37..133de2ee 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java @@ -4,8 +4,8 @@ import io.lumine.mythic.lib.api.MMOLineConfig; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.stats.StatType; -import net.Indyuce.mmocore.api.condition.Condition; -import net.Indyuce.mmocore.api.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.condition.Condition; +import net.Indyuce.mmocore.loot.condition.ConditionInstance; import net.Indyuce.mmocore.loot.droptable.dropitem.fishing.FishingDropItem; import org.apache.commons.lang.Validate; import org.bukkit.configuration.ConfigurationSection; diff --git a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java index bbbd1ab3..288a8796 100644 --- a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java +++ b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java @@ -2,8 +2,8 @@ package net.Indyuce.mmocore.waypoint; import io.lumine.mythic.lib.api.MMOLineConfig; import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.condition.Condition; -import net.Indyuce.mmocore.api.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.condition.Condition; +import net.Indyuce.mmocore.loot.condition.ConditionInstance; import net.Indyuce.mmocore.player.Unlockable; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; From 68b309ec611c59fbfcbfc9a989056106b13f2716 Mon Sep 17 00:00:00 2001 From: Guillaume Date: Mon, 9 May 2022 18:59:17 +0200 Subject: [PATCH 15/39] Debug for all the experience source. Added VanillaExperience & Resource ExperienceSource and added inCombat for Playing Experience Source. --- pom.xml | 11 ++++ .../mmocore/api/load/DefaultMMOLoader.java | 5 +- .../Indyuce/mmocore/api/load/MMOLoader.java | 2 +- .../mmocore/api/player/PlayerData.java | 4 +- .../player/profess/SavedClassInformation.java | 13 +++-- .../mmocore/comp/region/RegionCondition.java | 4 +- .../comp/region/WorldGuardMMOLoader.java | 2 +- .../mmocore/experience/PlayerProfessions.java | 2 +- .../dispenser/ClassExperienceDispenser.java | 2 +- .../experience/droptable/ExperienceItem.java | 13 ++++- .../source/BrewPotionExperienceSource.java | 2 +- .../source/EatExperienceSource.java | 58 +++++++++++++++++++ .../source/EnchantItemExperienceSource.java | 2 +- .../source/ProjectileExperienceSource.java | 19 ++++-- .../source/RepairItemExperienceSource.java | 2 +- .../VanillaExperienceExperienceSource.java | 39 ------------- .../mmocore/listener/BlockListener.java | 2 +- .../listener/option/RedirectVanillaExp.java | 2 +- .../{ => chest}/condition/BiomeCondition.java | 2 +- .../loot/{ => chest}/condition/Condition.java | 2 +- .../condition/ConditionInstance.java | 2 +- .../condition/DistanceCondition.java | 2 +- .../{ => chest}/condition/LevelCondition.java | 2 +- .../condition/PermissionCondition.java | 2 +- .../{ => chest}/condition/WorldCondition.java | 2 +- .../mmocore/loot/droptable/DropTable.java | 4 +- .../droptable/dropitem/DropTableDropItem.java | 2 +- .../mmocore/manager/MMOLoadManager.java | 2 +- .../profession/CustomBlockManager.java | 4 +- .../manager/profession/FishingManager.java | 4 +- .../manager/social/BoosterManager.java | 4 +- .../Indyuce/mmocore/waypoint/Waypoint.java | 4 +- .../drop-tables/example-drop-tables.yml | 2 +- 33 files changed, 136 insertions(+), 88 deletions(-) create mode 100644 src/main/java/net/Indyuce/mmocore/experience/source/EatExperienceSource.java delete mode 100644 src/main/java/net/Indyuce/mmocore/experience/source/VanillaExperienceExperienceSource.java rename src/main/java/net/Indyuce/mmocore/loot/{ => chest}/condition/BiomeCondition.java (92%) rename src/main/java/net/Indyuce/mmocore/loot/{ => chest}/condition/Condition.java (85%) rename src/main/java/net/Indyuce/mmocore/loot/{ => chest}/condition/ConditionInstance.java (94%) rename src/main/java/net/Indyuce/mmocore/loot/{ => chest}/condition/DistanceCondition.java (95%) rename src/main/java/net/Indyuce/mmocore/loot/{ => chest}/condition/LevelCondition.java (94%) rename src/main/java/net/Indyuce/mmocore/loot/{ => chest}/condition/PermissionCondition.java (91%) rename src/main/java/net/Indyuce/mmocore/loot/{ => chest}/condition/WorldCondition.java (90%) diff --git a/pom.xml b/pom.xml index e0540704..0805f2c8 100644 --- a/pom.xml +++ b/pom.xml @@ -39,10 +39,21 @@ + + org.apache.maven.plugins + maven-jar-plugin + 2.3.1 + + C:\Users\guill\Minecraft Server\Server\plugins + + + + org.apache.maven.plugins maven-compiler-plugin 3.8.1 + 9 9 diff --git a/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java b/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java index a2c8389a..9ec22aca 100644 --- a/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java +++ b/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java @@ -2,12 +2,14 @@ package net.Indyuce.mmocore.api.load; import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; import net.Indyuce.mmocore.experience.source.*; +import net.Indyuce.mmocore.loot.chest.condition.*; import org.bukkit.configuration.ConfigurationSection; import net.Indyuce.mmocore.api.block.BlockType; import net.Indyuce.mmocore.api.block.SkullBlockType; import net.Indyuce.mmocore.api.block.VanillaBlockType; import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem; + import net.Indyuce.mmocore.loot.droptable.dropitem.DropTableDropItem; import net.Indyuce.mmocore.loot.droptable.dropitem.GoldDropItem; import net.Indyuce.mmocore.loot.droptable.dropitem.NoteDropItem; @@ -119,9 +121,6 @@ public class DefaultMMOLoader extends MMOLoader { if (config.getKey().equals("resource")) return new ResourceExperienceSource(dispenser, config); - if (config.getKey().equals("vanillaexperience")) - return new VanillaExperienceExperienceSource(dispenser, config); - if (config.getKey().equals("climb")) return new ClimbExperienceSource(dispenser, config); diff --git a/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java b/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java index 10ca9c12..c1bed441 100644 --- a/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java +++ b/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java @@ -2,7 +2,7 @@ package net.Indyuce.mmocore.api.load; import io.lumine.mythic.lib.api.MMOLineConfig; import net.Indyuce.mmocore.api.block.BlockType; -import net.Indyuce.mmocore.loot.condition.Condition; +import net.Indyuce.mmocore.loot.chest.condition.Condition; import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem; import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; import net.Indyuce.mmocore.experience.source.type.ExperienceSource; 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 13a84cf9..a5ed447a 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java @@ -321,7 +321,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc giveExperience(total, source); } - public void setExperience(int value) { + public void setExperience(double value) { experience = Math.max(0, value); refreshVanillaExp(); } @@ -517,7 +517,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc * @param value Experience to give the player * @param source How the player earned experience */ - public void giveExperience(int value, EXPSource source) { + public void giveExperience(double value, EXPSource source) { giveExperience(value, source, null, true); } diff --git a/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java b/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java index 21bed8f3..f5d2698e 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java @@ -17,13 +17,14 @@ import net.Indyuce.mmocore.skill.RegisteredSkill; import net.Indyuce.mmocore.manager.data.PlayerDataManager.DefaultPlayerData; public class SavedClassInformation { - private final int level, experience, skillPoints, attributePoints, attributeReallocationPoints; + private final int level, skillPoints, attributePoints, attributeReallocationPoints; + private final double experience; private final Map attributes; private final Map skills; public SavedClassInformation(ConfigurationSection config) { level = config.getInt("level"); - experience = config.getInt("experience"); + experience = config.getDouble("experience"); skillPoints = config.getInt("skill-points"); attributePoints = config.getInt("attribute-points"); attributeReallocationPoints = config.getInt("attribute-realloc-points"); @@ -38,7 +39,7 @@ public class SavedClassInformation { public SavedClassInformation(JsonObject json) { level = json.get("level").getAsInt(); - experience = json.get("experience").getAsInt(); + experience = json.get("experience").getAsDouble(); skillPoints = json.get("skill-points").getAsInt(); attributePoints = json.get("attribute-points").getAsInt(); attributeReallocationPoints = json.get("attribute-realloc-points").getAsInt(); @@ -63,11 +64,11 @@ public class SavedClassInformation { this(data.getLevel(), 0, data.getSkillPoints(), data.getAttributePoints(), data.getAttrReallocPoints()); } - public SavedClassInformation(int level, int experience, int skillPoints, int attributePoints, int attributeReallocationPoints) { + public SavedClassInformation(int level, double experience, int skillPoints, int attributePoints, int attributeReallocationPoints) { this(level, experience, skillPoints, attributePoints, attributeReallocationPoints, new HashMap<>(), new HashMap<>()); } - private SavedClassInformation(int level, int experience, int skillPoints, int attributePoints, int attributeReallocationPoints, + private SavedClassInformation(int level, double experience, int skillPoints, int attributePoints, int attributeReallocationPoints, Map attributes, Map skills) { this.level = level; this.experience = experience; @@ -82,7 +83,7 @@ public class SavedClassInformation { return level; } - public int getExperience() { + public double getExperience() { return experience; } diff --git a/src/main/java/net/Indyuce/mmocore/comp/region/RegionCondition.java b/src/main/java/net/Indyuce/mmocore/comp/region/RegionCondition.java index 4f2876c2..c8b8a9d0 100644 --- a/src/main/java/net/Indyuce/mmocore/comp/region/RegionCondition.java +++ b/src/main/java/net/Indyuce/mmocore/comp/region/RegionCondition.java @@ -3,8 +3,8 @@ package net.Indyuce.mmocore.comp.region; import java.util.Arrays; import java.util.List; -import net.Indyuce.mmocore.loot.condition.Condition; -import net.Indyuce.mmocore.loot.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.chest.condition.Condition; +import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance; import io.lumine.mythic.lib.api.MMOLineConfig; public class RegionCondition extends Condition { diff --git a/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java b/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java index d1903d70..735ebda6 100644 --- a/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java +++ b/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java @@ -1,6 +1,6 @@ package net.Indyuce.mmocore.comp.region; -import net.Indyuce.mmocore.loot.condition.Condition; +import net.Indyuce.mmocore.loot.chest.condition.Condition; import net.Indyuce.mmocore.api.load.MMOLoader; import io.lumine.mythic.lib.api.MMOLineConfig; diff --git a/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java b/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java index 887e45b0..d8a1ab21 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java +++ b/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java @@ -196,7 +196,7 @@ public class PlayerProfessions { this.exp.put(profession.getId(), exp - needed); this.level.put(profession.getId(), level + 1); check = true; - playerData.giveExperience((int) profession.getExperience().calculate(level), null); + playerData.giveExperience(profession.getExperience().calculate(level), null); } if (check) { diff --git a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ClassExperienceDispenser.java b/src/main/java/net/Indyuce/mmocore/experience/dispenser/ClassExperienceDispenser.java index 8be7dfe0..917f7b14 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ClassExperienceDispenser.java +++ b/src/main/java/net/Indyuce/mmocore/experience/dispenser/ClassExperienceDispenser.java @@ -17,7 +17,7 @@ public class ClassExperienceDispenser implements ExperienceDispenser { @Override public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, EXPSource source) { hologramLocation = !MMOCore.plugin.getConfig().getBoolean("display-main-class-exp-holograms") ? null - : hologramLocation == null ? getPlayerLocation(playerData) : hologramLocation; + : hologramLocation; playerData.giveExperience(experience, source, hologramLocation, true); } 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 e676156b..4ba8028c 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java +++ b/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java @@ -13,7 +13,10 @@ 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 double claimChance, failReduction; private final List triggers; @@ -23,6 +26,7 @@ public class ExperienceItem { * 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 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. @@ -32,19 +36,22 @@ 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, double claimChance, double failReduction, List triggers) { + public ExperienceItem(String id, int period, int firstTrigger,double claimChance, double failReduction, List triggers) { this.id = id; this.period = period; this.claimChance = claimChance; this.failReduction = failReduction; this.triggers = triggers; + this.firstTrigger=firstTrigger; } public ExperienceItem(ConfigurationSection config) { Validate.notNull(config, "Config cannot be null"); Validate.isTrue(config.contains("triggers")); id = config.getName(); - period = config.getInt("period", 1); + + period = config.getInt("period", 0); + firstTrigger=config.getInt("first-trigger",period); claimChance = config.getDouble("chance", 100) / 100; failReduction = config.getDouble("fail-reduction", 80) / 100; triggers = new ArrayList<>(); @@ -64,7 +71,7 @@ public class ExperienceItem { * account the randomness factor from the 'chance' parameter */ public boolean roll(int professionLevel, int timesCollected) { - int claimsRequired = professionLevel - (timesCollected + 1) * period; + int claimsRequired = professionLevel+1 - (firstTrigger-+timesCollected * period); if (claimsRequired < 1) return false; diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/BrewPotionExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/BrewPotionExperienceSource.java index a5c085b7..a0f6b5bf 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/BrewPotionExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/BrewPotionExperienceSource.java @@ -168,7 +168,7 @@ public class BrewPotionExperienceSource extends ExperienceSource { */ // exp += getTotal(mapEffectDurations()); - getDispenser().giveExperience(PlayerData.get(player), (int) exp * multiplier, null, EXPSource.SOURCE); + getDispenser().giveExperience(PlayerData.get(player), exp * multiplier, player.getLocation(), EXPSource.SOURCE); } } } diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/EatExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/EatExperienceSource.java new file mode 100644 index 00000000..b6db5451 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/EatExperienceSource.java @@ -0,0 +1,58 @@ +package net.Indyuce.mmocore.experience.source; + +import io.lumine.mythic.lib.api.MMOLineConfig; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; +import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; +import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; +import org.apache.commons.lang3.Validate; +import org.bukkit.Material; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.inventory.ItemStack; + +public class EatExperienceSource extends SpecificExperienceSource { + private final Material type; + + /** + * Gives xp when you eat a certain type of food. If not type is given it will give xp from all the food sources. + * The amount of xp given is the xp per food regenerated. + */ + public EatExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + if(!config.contains("type")) + type=null; + else { + Material material=Material.valueOf(config.getString("type").toUpperCase().replace("-","_")); + Validate.isTrue(material!=null,"You must precise a valid material!"); + type=material; + } + } + + @Override + public ExperienceSourceManager newManager() { + return new ExperienceSourceManager() { + + @EventHandler + public void a(FoodLevelChangeEvent e) { + if (!(e.getEntity() instanceof Player) || e.getEntity().hasMetadata("NPC")) + return; + PlayerData playerData = PlayerData.get((OfflinePlayer) e.getEntity()); + for (EatExperienceSource source : getSources()) { + if (source.matchesParameter(playerData, e.getItem())) + source.giveExperience(playerData, e.getFoodLevel(), null); + } + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, ItemStack obj) { + if(type==null) + return true; + return type.equals(obj.getType()); + } + +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/EnchantItemExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/EnchantItemExperienceSource.java index aae363b1..3a9c334d 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/EnchantItemExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/EnchantItemExperienceSource.java @@ -60,7 +60,7 @@ public class EnchantItemExperienceSource extends ExperienceSource { double exp = 0; for (Entry entry : applicableEnchants.entrySet()) exp += MMOCore.plugin.enchantManager.getBaseExperience(entry.getKey()) * entry.getValue(); - getDispenser().giveExperience(player, (int) exp, event.getEnchantBlock().getLocation(), EXPSource.SOURCE); + getDispenser().giveExperience(player, exp, event.getEnchantBlock().getLocation(), EXPSource.SOURCE); } } }; diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java index 6a2960c6..49647b70 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java @@ -15,6 +15,7 @@ import org.bukkit.Location; import org.bukkit.entity.*; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.ProjectileHitEvent; import org.bukkit.event.entity.ProjectileLaunchEvent; import org.bukkit.scheduler.BukkitRunnable; @@ -47,14 +48,23 @@ public class ProjectileExperienceSource extends SpecificExperienceSource projectiles = new HashMap<>(); @EventHandler - public void onHit(EntityDamageByEntityEvent e) { + public void onHit(ProjectileHitEvent e) { + if (e.getHitBlock() != null && projectiles.containsKey(e.getEntity())) + projectiles.remove(e.getEntity()); - if (e.getDamager() instanceof Projectile) { - Projectile projectile = (Projectile) e.getDamager(); + } + + @EventHandler + public void onDamage(EntityDamageByEntityEvent e) { + + if (e.getEntity() instanceof Projectile) { + Projectile projectile = (Projectile) e.getEntity(); + if(!projectiles.containsKey(projectile)) + return; if (projectile.getShooter() instanceof Player && !((Player) projectile.getShooter()).hasMetadata("NPC")) { Player player = (Player) projectile.getShooter(); PlayerData playerData = PlayerData.get(player); - double distance = projectiles.get(projectile).distance(e.getDamager().getLocation()); + double distance = projectiles.get(projectile).distance(e.getEntity().getLocation()); for (ProjectileExperienceSource source : getSources()) { if (source.matchesParameter(playerData, projectile)) source.giveExperience(playerData, e.getFinalDamage() * distance, null); @@ -62,6 +72,7 @@ public class ProjectileExperienceSource extends SpecificExperienceSource { */ double exp = MMOCore.plugin.smithingManager.getBaseExperience(item.getType()) * Math.max(0, ((Damageable) old.getItemMeta()).getDamage() - ((Damageable) item.getItemMeta()).getDamage()) / 100; - getDispenser().giveExperience(data, (int) exp, null, EXPSource.SOURCE); + getDispenser().giveExperience(data, exp, data.getPlayer().getLocation(), EXPSource.SOURCE); } } } diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/VanillaExperienceExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/VanillaExperienceExperienceSource.java deleted file mode 100644 index f4eb3d22..00000000 --- a/src/main/java/net/Indyuce/mmocore/experience/source/VanillaExperienceExperienceSource.java +++ /dev/null @@ -1,39 +0,0 @@ -package net.Indyuce.mmocore.experience.source; - -import io.lumine.mythic.lib.api.MMOLineConfig; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; -import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; -import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; -import org.apache.commons.lang.Validate; -import org.bukkit.event.EventHandler; -import org.bukkit.event.player.PlayerExpChangeEvent; - -public class VanillaExperienceExperienceSource extends SpecificExperienceSource { - - - public VanillaExperienceExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { - super(dispenser, config); - } - - @Override - public ExperienceSourceManager newManager() { - return new ExperienceSourceManager() { - @EventHandler - public void onExp(PlayerExpChangeEvent e) { - if(e.getPlayer().hasMetadata("NPC")) - return; - PlayerData playerData=PlayerData.get(e.getPlayer()); - for(VanillaExperienceExperienceSource source:getSources()) { - if(source.matchesParameter(playerData,null)) - giveExperience(playerData,e.getAmount(),null); - } - } - }; - } - - @Override - public boolean matchesParameter(PlayerData player, Object obj) { - return true; - } -} diff --git a/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java b/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java index 1346b23f..2ff6c505 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java +++ b/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java @@ -11,7 +11,7 @@ import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.experience.source.MineBlockExperienceSource; import net.Indyuce.mmocore.loot.LootBuilder; -import net.Indyuce.mmocore.loot.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance; import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; 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 7f697c80..49a19c45 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/option/RedirectVanillaExp.java +++ b/src/main/java/net/Indyuce/mmocore/listener/option/RedirectVanillaExp.java @@ -16,7 +16,7 @@ public class RedirectVanillaExp implements Listener { @EventHandler public void a(PlayerExpChangeEvent event) { - int a = (int) (event.getAmount() * ratio); + double a = (event.getAmount() * ratio); if (a > 0) PlayerData.get(event.getPlayer()).giveExperience(a, EXPSource.VANILLA); } diff --git a/src/main/java/net/Indyuce/mmocore/loot/condition/BiomeCondition.java b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/BiomeCondition.java similarity index 92% rename from src/main/java/net/Indyuce/mmocore/loot/condition/BiomeCondition.java rename to src/main/java/net/Indyuce/mmocore/loot/chest/condition/BiomeCondition.java index ae2f9922..1c55c5fc 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/condition/BiomeCondition.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/BiomeCondition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.loot.condition; +package net.Indyuce.mmocore.loot.chest.condition; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/net/Indyuce/mmocore/loot/condition/Condition.java b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/Condition.java similarity index 85% rename from src/main/java/net/Indyuce/mmocore/loot/condition/Condition.java rename to src/main/java/net/Indyuce/mmocore/loot/chest/condition/Condition.java index c925c1ba..b924cea2 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/condition/Condition.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/Condition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.loot.condition; +package net.Indyuce.mmocore.loot.chest.condition; import io.lumine.mythic.lib.api.MMOLineConfig; diff --git a/src/main/java/net/Indyuce/mmocore/loot/condition/ConditionInstance.java b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/ConditionInstance.java similarity index 94% rename from src/main/java/net/Indyuce/mmocore/loot/condition/ConditionInstance.java rename to src/main/java/net/Indyuce/mmocore/loot/chest/condition/ConditionInstance.java index d74a0454..1666ee8e 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/condition/ConditionInstance.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/ConditionInstance.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.loot.condition; +package net.Indyuce.mmocore.loot.chest.condition; import java.util.List; import java.util.stream.Stream; diff --git a/src/main/java/net/Indyuce/mmocore/loot/condition/DistanceCondition.java b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/DistanceCondition.java similarity index 95% rename from src/main/java/net/Indyuce/mmocore/loot/condition/DistanceCondition.java rename to src/main/java/net/Indyuce/mmocore/loot/chest/condition/DistanceCondition.java index de9cef5e..21e46f8f 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/condition/DistanceCondition.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/DistanceCondition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.loot.condition; +package net.Indyuce.mmocore.loot.chest.condition; import io.lumine.mythic.lib.api.MMOLineConfig; import org.apache.commons.lang.Validate; diff --git a/src/main/java/net/Indyuce/mmocore/loot/condition/LevelCondition.java b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/LevelCondition.java similarity index 94% rename from src/main/java/net/Indyuce/mmocore/loot/condition/LevelCondition.java rename to src/main/java/net/Indyuce/mmocore/loot/chest/condition/LevelCondition.java index 087a379f..c448c96c 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/condition/LevelCondition.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/LevelCondition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.loot.condition; +package net.Indyuce.mmocore.loot.chest.condition; import net.Indyuce.mmocore.api.player.PlayerData; import io.lumine.mythic.lib.api.MMOLineConfig; diff --git a/src/main/java/net/Indyuce/mmocore/loot/condition/PermissionCondition.java b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/PermissionCondition.java similarity index 91% rename from src/main/java/net/Indyuce/mmocore/loot/condition/PermissionCondition.java rename to src/main/java/net/Indyuce/mmocore/loot/chest/condition/PermissionCondition.java index 6a97e8ab..47d9c0b8 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/condition/PermissionCondition.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/PermissionCondition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.loot.condition; +package net.Indyuce.mmocore.loot.chest.condition; import io.lumine.mythic.lib.api.MMOLineConfig; import org.bukkit.entity.Player; diff --git a/src/main/java/net/Indyuce/mmocore/loot/condition/WorldCondition.java b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/WorldCondition.java similarity index 90% rename from src/main/java/net/Indyuce/mmocore/loot/condition/WorldCondition.java rename to src/main/java/net/Indyuce/mmocore/loot/chest/condition/WorldCondition.java index 955d0289..97c58cc4 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/condition/WorldCondition.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/WorldCondition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.loot.condition; +package net.Indyuce.mmocore.loot.chest.condition; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java b/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java index aa7a602d..c8588074 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java +++ b/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java @@ -5,8 +5,8 @@ import java.util.List; import java.util.Set; import java.util.logging.Level; -import net.Indyuce.mmocore.loot.condition.Condition; -import net.Indyuce.mmocore.loot.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.chest.condition.Condition; +import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance; import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem; import org.apache.commons.lang.Validate; import org.bukkit.configuration.ConfigurationSection; diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropTableDropItem.java b/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropTableDropItem.java index 4f21174c..e6c160f2 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropTableDropItem.java +++ b/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropTableDropItem.java @@ -3,7 +3,7 @@ package net.Indyuce.mmocore.loot.droptable.dropitem; import io.lumine.mythic.lib.api.MMOLineConfig; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.loot.droptable.DropTable; -import net.Indyuce.mmocore.loot.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance; import net.Indyuce.mmocore.loot.LootBuilder; import net.Indyuce.mmocore.api.player.PlayerData; import org.apache.commons.lang.Validate; diff --git a/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java b/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java index 4b9e4444..666ba042 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java @@ -11,7 +11,7 @@ import org.bukkit.configuration.ConfigurationSection; import com.google.gson.JsonParseException; import net.Indyuce.mmocore.api.block.BlockType; -import net.Indyuce.mmocore.loot.condition.Condition; +import net.Indyuce.mmocore.loot.chest.condition.Condition; import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem; import net.Indyuce.mmocore.experience.source.type.ExperienceSource; import net.Indyuce.mmocore.api.load.DefaultMMOLoader; diff --git a/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java b/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java index 57ddf5f7..5b69846d 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java @@ -7,8 +7,8 @@ import net.Indyuce.mmocore.api.block.BlockInfo.RegeneratingBlock; import net.Indyuce.mmocore.api.block.BlockType; import net.Indyuce.mmocore.api.block.SkullBlockType; import net.Indyuce.mmocore.api.block.VanillaBlockType; -import net.Indyuce.mmocore.loot.condition.Condition; -import net.Indyuce.mmocore.loot.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.chest.condition.Condition; +import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance; import net.Indyuce.mmocore.api.util.MMOCoreUtils; import io.lumine.mythic.lib.api.MMOLineConfig; import org.bukkit.Bukkit; diff --git a/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java b/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java index 133de2ee..93a5a73f 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java @@ -4,8 +4,8 @@ import io.lumine.mythic.lib.api.MMOLineConfig; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.stats.StatType; -import net.Indyuce.mmocore.loot.condition.Condition; -import net.Indyuce.mmocore.loot.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.chest.condition.Condition; +import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance; import net.Indyuce.mmocore.loot.droptable.dropitem.fishing.FishingDropItem; import org.apache.commons.lang.Validate; import org.bukkit.configuration.ConfigurationSection; diff --git a/src/main/java/net/Indyuce/mmocore/manager/social/BoosterManager.java b/src/main/java/net/Indyuce/mmocore/manager/social/BoosterManager.java index df9ae3a2..113b99ba 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/social/BoosterManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/social/BoosterManager.java @@ -58,8 +58,8 @@ public class BoosterManager { return d; } - public int calculateExp(Profession profession, double exp) { - return (int) (exp * getMultiplier(profession)); + public double calculateExp(Profession profession, double exp) { + return (exp * getMultiplier(profession)); } /** diff --git a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java index 288a8796..6395ea81 100644 --- a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java +++ b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java @@ -2,8 +2,8 @@ package net.Indyuce.mmocore.waypoint; import io.lumine.mythic.lib.api.MMOLineConfig; import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.loot.condition.Condition; -import net.Indyuce.mmocore.loot.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.chest.condition.Condition; +import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance; import net.Indyuce.mmocore.player.Unlockable; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; diff --git a/src/main/resources/default/drop-tables/example-drop-tables.yml b/src/main/resources/default/drop-tables/example-drop-tables.yml index 25894aaf..4faf4e78 100644 --- a/src/main/resources/default/drop-tables/example-drop-tables.yml +++ b/src/main/resources/default/drop-tables/example-drop-tables.yml @@ -8,7 +8,7 @@ diamond-drop-table: items: - 'vanilla{type=DIAMOND} 1 1-3' - # - 'mmoitem{type=material;id=RARE_DIAMOND} .1 1-3' + # - 'mmoitem{type=material;id=RARE_DIAMOND;period=} .1 1-3' - 'droptable{id=other-drop-table} .1' other-drop-table: From 13c04695944cfbde74ce3f324840ede30f0d849e Mon Sep 17 00:00:00 2001 From: Indyuce Date: Fri, 20 May 2022 17:42:48 +0200 Subject: [PATCH 16/39] Tier rolling cleanup --- .../mmocore/loot/chest/LootChestRegion.java | 37 +++++++++++++------ .../condition/PermissionCondition.java | 4 +- .../mmocore/manager/ConfigManager.java | 2 + src/main/resources/config.yml | 12 ++++++ 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java index 6e265a3b..8e6afc9a 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java @@ -14,6 +14,7 @@ import org.bukkit.block.Chest; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; import java.util.*; import java.util.logging.Level; @@ -117,25 +118,39 @@ public class LootChestRegion { MMOCore.plugin.lootChests.register(lootChest); } + /** + * @param player Player rolling the tier + * @return A randomly picked tiers taking into account tier spawn rates + * and the player Chance attribute + */ + @NotNull public ChestTier rollTier(PlayerData player) { - double chance = player.getStats().getStat(StatType.CHANCE); + double chance = player.getStats().getStat(StatType.CHANCE) * MMOCore.plugin.configManager.lootChestsChanceWeight; - //chance=0 ->the tier.chance remains the same - //chance ->+inf -> the tier.chance becomes the same for everyone, uniform law - //chance=8-> tierChance=sqrt(tierChance) double sum = 0; - for (ChestTier tier : tiers) { - sum += Math.pow(tier.chance, 1 / Math.pow((1 + chance),1/3)); - } + for (ChestTier tier : tiers) + sum += getTierCoefficient(tier.getChance(), chance); + Validate.isTrue(sum > 0, "No chest tier was found"); - double s=0; + double cummulated = 0; for (ChestTier tier : tiers) { - s+=Math.pow(tier.chance, 1 / Math.pow((1 + chance),1/3))/sum; - if (random.nextDouble() < s) + cummulated += getTierCoefficient(tier.getChance(), chance); + if (random.nextDouble() < cummulated / sum) return tier; } - return tiers.stream().findAny().orElse(null); + throw new RuntimeException("Could not roll chest tier"); + } + + private static final double CHANCE_COEF = 7 / 100; + + /** + * - Chance = 0 | tier coefficient is left unchanged. + * - Chance -> +oo | all tier coefficients are the same (1) + * - Chance = 50 | coefficients become their square roots + */ + private double getTierCoefficient(double initialTierChance, double chance) { + return Math.pow(initialTierChance, 1 / Math.pow(1 + CHANCE_COEF * chance, 1 / 3)); } public Location getRandomLocation(Location center) { diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/PermissionCondition.java b/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/PermissionCondition.java index 0d009b44..43967da5 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/PermissionCondition.java +++ b/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/PermissionCondition.java @@ -15,8 +15,6 @@ public class PermissionCondition extends Condition { @Override public boolean isMet(ConditionInstance entity) { - if (entity.getEntity() instanceof Player) - return entity.getEntity().hasPermission(perm); - return false; + return entity.getEntity() instanceof Player && entity.getEntity().hasPermission(perm); } } diff --git a/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java b/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java index 96a41f87..bcc54190 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java @@ -27,6 +27,7 @@ public class ConfigManager { public String partyChatPrefix, noSkillBoundPlaceholder; public ChatColor staminaFull, staminaHalf, staminaEmpty; public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown, globalSkillCooldown; + public double lootChestsChanceWeight; private final FileConfiguration messages; private final boolean chatInput; @@ -97,6 +98,7 @@ public class ConfigManager { lootChestPlayerCooldown = (long) MMOCore.plugin.getConfig().getDouble("player-cooldown") * 1000L; globalSkillCooldown = MMOCore.plugin.getConfig().getLong("global-skill-cooldown") * 50; noSkillBoundPlaceholder = getSimpleMessage("no-skill-placeholder").message(); + lootChestsChanceWeight = MMOCore.plugin.getConfig().getDouble("chance-stat-weight.loot-chests"); staminaFull = getColorOrDefault("stamina-whole", ChatColor.GREEN); staminaHalf = getColorOrDefault("stamina-half", ChatColor.DARK_GREEN); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index adce82fd..5611ba68 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -58,6 +58,18 @@ protect-custom-mine: false # - parties_and_friends party-plugin: mmocore +# MythicLib introduces a CHANCE stat that is used in +# several different systems in MMOCore. By changing these +# weights you can define how much the Chance stat impacts +# the different features implemented by MMOCore +# +# e.g setting some weight to 2 will DOUBLE the effect of +# the chance stat in one particular system. The weights are +# all set to 1 by default, this option is really server specific +chance-stat-weight: + + loot-chests: 1 + # Whether blocks generated with a "cobblegenerator" should # provide the player with experience points or not should-cobblestone-generators-give-exp: false From a2630824c9eb4e97f7ec8b860dbdb35c76bbc5e6 Mon Sep 17 00:00:00 2001 From: Guillaume Date: Sun, 22 May 2022 14:15:13 +0200 Subject: [PATCH 17/39] Modules for Quests in MMOCore. --- pom.xml | 27 +++++++++ .../java/net/Indyuce/mmocore/MMOCore.java | 14 +++++ .../Indyuce/mmocore/quest/AbstractQuest.java | 1 + .../mmocore/quest/MMOCoreQuestModule.java | 40 +++++++++++++ .../Indyuce/mmocore/quest/QuestModule.java | 16 ------ .../mmocore/quest/QuestModuleType.java | 35 ++++++++++++ .../quest/compat/BeautyQuestModule.java | 47 ++++++++++++++++ .../quest/compat/BlackVeinQuestsModule.java | 53 ++++++++++++++++++ .../quest/compat/QuestCreatorModule.java | 56 +++++++++++++++++++ .../mmocore/quest/compat/QuestModule.java | 18 ++++++ src/main/resources/config.yml | 10 ++++ 11 files changed, 301 insertions(+), 16 deletions(-) create mode 100644 src/main/java/net/Indyuce/mmocore/quest/MMOCoreQuestModule.java delete mode 100644 src/main/java/net/Indyuce/mmocore/quest/QuestModule.java create mode 100644 src/main/java/net/Indyuce/mmocore/quest/QuestModuleType.java create mode 100644 src/main/java/net/Indyuce/mmocore/quest/compat/BeautyQuestModule.java create mode 100644 src/main/java/net/Indyuce/mmocore/quest/compat/BlackVeinQuestsModule.java create mode 100644 src/main/java/net/Indyuce/mmocore/quest/compat/QuestCreatorModule.java create mode 100644 src/main/java/net/Indyuce/mmocore/quest/compat/QuestModule.java diff --git a/pom.xml b/pom.xml index 0805f2c8..51b355ac 100644 --- a/pom.xml +++ b/pom.xml @@ -226,6 +226,33 @@ provided + + + me.blackvein + Quests + 4.4.1-b340 + provided + + + fr.skytasul.quests + BeautyQuests + 0.19.5 + provided + + + com.guillaumevdn + QuestCreator + 6.39.0 + provided + + + com.guillaumevdn + GCore + 8.39.0 + provided + + + com.massivecraft diff --git a/src/main/java/net/Indyuce/mmocore/MMOCore.java b/src/main/java/net/Indyuce/mmocore/MMOCore.java index bb02fa74..df5b7dcf 100644 --- a/src/main/java/net/Indyuce/mmocore/MMOCore.java +++ b/src/main/java/net/Indyuce/mmocore/MMOCore.java @@ -230,6 +230,19 @@ public class MMOCore extends LuminePlugin { DebugMode.enableActionBar(); } + // Load quest module + try { + String questPluginName = UtilityMethods.enumName(getConfig().getString("quest-plugin")); + PartyModuleType moduleType = PartyModuleType.valueOf(questPluginName); + Validate.isTrue(moduleType.isValid(), "Plugin '" + moduleType.name() + "' is not installed"); + partyModule = moduleType.provideModule(); + } catch (RuntimeException exception) { + getLogger().log(Level.WARNING, "Could not initialize quest module: " + exception.getMessage()); + partyModule = new MMOCorePartyModule(); + } + + + // Load party module try { String partyPluginName = UtilityMethods.enumName(getConfig().getString("party-plugin")); @@ -241,6 +254,7 @@ public class MMOCore extends LuminePlugin { partyModule = new MMOCorePartyModule(); } + // Skill casting try { SkillCastingMode mode = SkillCastingMode.valueOf(UtilityMethods.enumName(getConfig().getString("skill-casting.mode"))); diff --git a/src/main/java/net/Indyuce/mmocore/quest/AbstractQuest.java b/src/main/java/net/Indyuce/mmocore/quest/AbstractQuest.java index a326f10f..075ae470 100644 --- a/src/main/java/net/Indyuce/mmocore/quest/AbstractQuest.java +++ b/src/main/java/net/Indyuce/mmocore/quest/AbstractQuest.java @@ -3,4 +3,5 @@ package net.Indyuce.mmocore.quest; public interface AbstractQuest { public String getName(); + public String getId(); } diff --git a/src/main/java/net/Indyuce/mmocore/quest/MMOCoreQuestModule.java b/src/main/java/net/Indyuce/mmocore/quest/MMOCoreQuestModule.java new file mode 100644 index 00000000..1af7fdbc --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/quest/MMOCoreQuestModule.java @@ -0,0 +1,40 @@ +package net.Indyuce.mmocore.quest; + +import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.quest.Quest; +import net.Indyuce.mmocore.quest.compat.QuestModule; +import org.bukkit.entity.Player; + +public class MMOCoreQuestModule implements QuestModule { + @Override + public AbstractQuest getQuestOrThrow(String id) { + Quest quest=MMOCore.plugin.questManager.get(id); + if(quest==null) + return null; + return new MMOCoreQuest(quest); + } + + @Override + public boolean hasCompletedQuest(String quest, Player player) { + return false; + } + + public class MMOCoreQuest implements AbstractQuest { + Quest quest; + + public MMOCoreQuest(Quest quest) { + + this.quest = quest; + } + + @Override + public String getName() { + return null; + } + + @Override + public String getId() { + return null; + } + } +} diff --git a/src/main/java/net/Indyuce/mmocore/quest/QuestModule.java b/src/main/java/net/Indyuce/mmocore/quest/QuestModule.java deleted file mode 100644 index 1089f1db..00000000 --- a/src/main/java/net/Indyuce/mmocore/quest/QuestModule.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.Indyuce.mmocore.quest; - -import net.Indyuce.mmocore.api.player.PlayerData; - -public interface QuestModule> { - - /** - * @return Quest with given name - */ - public T getQuestOrThrow(String id); - - /** - * @return Info about the completed quests from a specific player - */ - public U getQuestData(PlayerData playerData); -} diff --git a/src/main/java/net/Indyuce/mmocore/quest/QuestModuleType.java b/src/main/java/net/Indyuce/mmocore/quest/QuestModuleType.java new file mode 100644 index 00000000..7bcd4bfa --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/quest/QuestModuleType.java @@ -0,0 +1,35 @@ +package net.Indyuce.mmocore.quest; + +import net.Indyuce.mmocore.party.PartyModule; +import net.Indyuce.mmocore.quest.compat.BeautyQuestModule; +import net.Indyuce.mmocore.quest.compat.BlackVeinQuestsModule; +import net.Indyuce.mmocore.quest.compat.QuestCreatorModule; +import net.Indyuce.mmocore.quest.compat.QuestModule; +import org.bukkit.Bukkit; + +import javax.inject.Provider; + +public enum QuestModuleType { + MMOCORE("MMOCore",MMOCoreQuestModule::new), + QUESTS("Quests", BlackVeinQuestsModule::new), + BEAUTY_QUEST("Beauty Quests", BeautyQuestModule::new), + QUEST_CREATOR("Quest Creator", QuestCreatorModule::new); + + + + private final String pluginName; + private final Provider provider; + + QuestModuleType(String pluginName, Provider provider) { + this.pluginName = pluginName; + this.provider = provider; + } + + public boolean isValid() { + return Bukkit.getPluginManager().getPlugin(pluginName) != null; + } + + public QuestModule provideModule() { + return provider.get(); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/quest/compat/BeautyQuestModule.java b/src/main/java/net/Indyuce/mmocore/quest/compat/BeautyQuestModule.java new file mode 100644 index 00000000..e1e4f720 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/quest/compat/BeautyQuestModule.java @@ -0,0 +1,47 @@ +package net.Indyuce.mmocore.quest.compat; + +import fr.skytasul.quests.api.QuestsAPI; +import fr.skytasul.quests.players.PlayerAccount; +import fr.skytasul.quests.players.PlayerQuestDatas; +import fr.skytasul.quests.players.PlayersManager; +import fr.skytasul.quests.structure.Quest; +import net.Indyuce.mmocore.quest.AbstractQuest; +import org.bukkit.entity.Player; + +public class BeautyQuestModule implements QuestModule { + + + @Override + public BeautyQuestQuest getQuestOrThrow(String questId) { + Quest quest=QuestsAPI.getQuests().getQuest(Integer.parseInt(questId)); + return quest==null?null:new BeautyQuestQuest(quest); + } + + @Override + public boolean hasCompletedQuest(String questId, Player player) { + PlayerAccount account=PlayersManager.getPlayerAccount(player); + PlayerQuestDatas quest=account.getQuestDatas(QuestsAPI.getQuests().getQuest(Integer.parseInt(questId))); + return quest.isFinished(); + } + + + + public class BeautyQuestQuest implements AbstractQuest { + + Quest quest; + + public BeautyQuestQuest(Quest quest) { + this.quest = quest; + } + + @Override + public String getName() { + return quest.getName(); + } + + @Override + public String getId() { + return ""+quest.getID(); + } + } +} diff --git a/src/main/java/net/Indyuce/mmocore/quest/compat/BlackVeinQuestsModule.java b/src/main/java/net/Indyuce/mmocore/quest/compat/BlackVeinQuestsModule.java new file mode 100644 index 00000000..413dc22d --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/quest/compat/BlackVeinQuestsModule.java @@ -0,0 +1,53 @@ +package net.Indyuce.mmocore.quest.compat; + +import me.blackvein.quests.Quest; +import me.blackvein.quests.Quester; +import me.blackvein.quests.Quests; +import net.Indyuce.mmocore.quest.AbstractQuest; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + + +public class BlackVeinQuestsModule implements QuestModule { + private final Quests plugin = (Quests) Bukkit.getPluginManager().getPlugin("Quests"); + + + + @Override + public BlackVeinQuestQuest getQuestOrThrow(String id) { + Quests plugin = (Quests) Bukkit.getPluginManager().getPlugin("Quests"); + return plugin.getQuestById(id)==null?null:new BlackVeinQuestQuest(plugin.getQuestById(id)); + } + + + @Override + public boolean hasCompletedQuest(String questId, Player player) { + Quester quester = plugin.getQuester(player.getUniqueId()); + + for(Quest quest:quester.getCompletedQuests()) { + if(quest.getId().equals(questId)) + return true; + } + return false; + } + + + public class BlackVeinQuestQuest implements AbstractQuest { + private final Quest quest; + + public BlackVeinQuestQuest(Quest quest) { + this.quest = quest; + } + + @Override + public String getName() { + return quest.getName(); + } + + @Override + public String getId() { + return quest.getId(); + } + } + +} diff --git a/src/main/java/net/Indyuce/mmocore/quest/compat/QuestCreatorModule.java b/src/main/java/net/Indyuce/mmocore/quest/compat/QuestCreatorModule.java new file mode 100644 index 00000000..adade213 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/quest/compat/QuestCreatorModule.java @@ -0,0 +1,56 @@ +package net.Indyuce.mmocore.quest.compat; + +import com.guillaumevdn.questcreator.ConfigQC; +import com.guillaumevdn.questcreator.data.user.QuestHistoryElement; +import com.guillaumevdn.questcreator.data.user.UserQC; +import com.guillaumevdn.questcreator.lib.model.ElementModel; +import com.guillaumevdn.questcreator.lib.quest.QuestEndType; +import net.Indyuce.mmocore.quest.AbstractQuest; +import org.apache.commons.lang.Validate; +import org.bukkit.entity.Player; +import java.util.Arrays; +import java.util.List; + +public class QuestCreatorModule implements QuestModule{ + + @Override + public QuestCreatorQuest getQuestOrThrow(String id) { + return new QuestCreatorQuest(id); + } + + @Override + public boolean hasCompletedQuest(String questId, Player player) { + UserQC playerData=UserQC.cachedOrNull(player); + Validate.notNull(playerData,"QuestCreator User hasn't been loaded!"); + //Gets all the quests the player has succeeded at + List elements=playerData.getQuestHistory().getElements(questId, Arrays.asList(QuestEndType.SUCCESS),0); + for(QuestHistoryElement el:elements) { + if(el.getModelId().equals(questId)) + return true; + } + return false; + } + + + /** + *QC ElementModel corresponds to our quest and their quests correspond to our Quest progress class + */ + + public class QuestCreatorQuest implements AbstractQuest { + ElementModel questModel; + + public QuestCreatorQuest(String modelId) { + questModel=ConfigQC.models.getElement(modelId).orNull(); + } + + @Override + public String getName() { + return questModel.getDisplayName().getId(); + } + + @Override + public String getId() { + return questModel.getId(); + } + } +} diff --git a/src/main/java/net/Indyuce/mmocore/quest/compat/QuestModule.java b/src/main/java/net/Indyuce/mmocore/quest/compat/QuestModule.java new file mode 100644 index 00000000..d4cae6b4 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/quest/compat/QuestModule.java @@ -0,0 +1,18 @@ +package net.Indyuce.mmocore.quest.compat; + +import net.Indyuce.mmocore.quest.AbstractQuest; +import org.bukkit.entity.Player; + +public interface QuestModule { + + /** + * @return Quest with given name + */ + public T getQuestOrThrow(String id); + + /** + * @return If a specific player did a certain quest + */ + public boolean hasCompletedQuest(String quest, Player player); + +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index adce82fd..682afb46 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -58,6 +58,16 @@ protect-custom-mine: false # - parties_and_friends party-plugin: mmocore +## Edit the plugin handling parties here. +## Supported values (just copy and paste): +## - mmocore +## - beauty_quest +## - quest_creator +## - quests +quest-plugin: mmocore + + + # Whether blocks generated with a "cobblegenerator" should # provide the player with experience points or not should-cobblestone-generators-give-exp: false From a7e3f9554fdd598bccd42d1f12072fd0d46b18e7 Mon Sep 17 00:00:00 2001 From: Indyuce Date: Sun, 22 May 2022 16:49:53 +0200 Subject: [PATCH 18/39] Loot chest O(1) lookup time --- .../mmocore/api/player/PlayerData.java | 20 ++-- .../listener/LootableChestsListener.java | 42 ++++--- .../Indyuce/mmocore/loot/chest/LootChest.java | 27 +++-- .../mmocore/manager/LootChestManager.java | 107 +++++++++--------- .../Indyuce/mmocore/player/Unlockable.java | 8 +- .../net/Indyuce/mmocore/skill/ClassSkill.java | 4 + .../mmocore/skill/RegisteredSkill.java | 8 +- .../tree/modifier/UnlockSkillModifier.java | 28 +++++ .../mmocore/util/item/HashableLocation.java | 51 +++++++++ 9 files changed, 202 insertions(+), 93 deletions(-) create mode 100644 src/main/java/net/Indyuce/mmocore/tree/modifier/UnlockSkillModifier.java create mode 100644 src/main/java/net/Indyuce/mmocore/util/item/HashableLocation.java 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 f2ed5051..9bb4c523 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java @@ -1,15 +1,11 @@ package net.Indyuce.mmocore.api.player; -import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.api.player.MMOPlayerData; import io.lumine.mythic.lib.player.TemporaryPlayerData; import io.lumine.mythic.lib.player.cooldown.CooldownMap; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.ConfigMessage; import net.Indyuce.mmocore.api.SoundEvent; -import net.Indyuce.mmocore.player.Unlockable; -import net.Indyuce.mmocore.waypoint.CostType; -import net.Indyuce.mmocore.waypoint.Waypoint; import net.Indyuce.mmocore.api.event.PlayerExperienceGainEvent; import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent; import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent; @@ -25,7 +21,6 @@ import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.api.quest.PlayerQuests; import net.Indyuce.mmocore.api.util.Closable; import net.Indyuce.mmocore.api.util.MMOCoreUtils; -import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect; import net.Indyuce.mmocore.experience.EXPSource; import net.Indyuce.mmocore.experience.ExperienceObject; import net.Indyuce.mmocore.experience.ExperienceTableClaimer; @@ -33,11 +28,14 @@ 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.party.AbstractParty; import net.Indyuce.mmocore.party.provided.Party; +import net.Indyuce.mmocore.player.Unlockable; import net.Indyuce.mmocore.skill.ClassSkill; 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.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.TextComponent; @@ -88,8 +86,9 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc /** * Saves all the items that have been unlocked so far by - * the player. This can be used by other plugins by - * implementing the {@link Unlockable} interface + * the player. This is used for: + * - waypoints + * - skills * * @see {@link Unlockable} */ @@ -289,8 +288,11 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc return guild != null; } + /** + * @return If the item is unlocked by the player + */ public boolean hasUnlocked(Unlockable unlockable) { - throw new RuntimeException("Not implemented yet"); + return unlockedItems.contains(unlockable.getUnlockNamespacedKey()); } /** @@ -299,7 +301,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc * @return If the item was already unlocked when calling this method */ public boolean unlock(Unlockable unlockable) { - throw new RuntimeException("Not implemented yet"); + return unlockedItems.add(unlockable.getUnlockNamespacedKey()); } public void setLevel(int level) { diff --git a/src/main/java/net/Indyuce/mmocore/listener/LootableChestsListener.java b/src/main/java/net/Indyuce/mmocore/listener/LootableChestsListener.java index b7f837d3..06cdf5ad 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/LootableChestsListener.java +++ b/src/main/java/net/Indyuce/mmocore/listener/LootableChestsListener.java @@ -1,22 +1,36 @@ package net.Indyuce.mmocore.listener; -import org.bukkit.block.Chest; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.InventoryCloseEvent; - import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.loot.chest.LootChest; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Chest; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; public class LootableChestsListener implements Listener { - @EventHandler - public void a(InventoryCloseEvent event) { - if (!(event.getInventory().getHolder() instanceof Chest)) - return; - Chest chest = (Chest) event.getInventory().getHolder(); - LootChest lootChest = MMOCore.plugin.lootChests.getChest(chest.getLocation()); - if (lootChest != null) - lootChest.expire(true); - } + @EventHandler + public void expireOnClose(InventoryCloseEvent event) { + if (!(event.getInventory().getHolder() instanceof Chest)) + return; + + Chest chest = (Chest) event.getInventory().getHolder(); + LootChest lootChest = MMOCore.plugin.lootChests.getChest(chest.getLocation()); + if (lootChest != null) + lootChest.expire(true); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH) + public void noBreaking(BlockBreakEvent event) { + Block block = event.getBlock(); + if (block.getType() == Material.CHEST) { + LootChest lootChest = MMOCore.plugin.lootChests.getChest(block.getLocation()); + if (lootChest != null) + event.setCancelled(true); + } + } } diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChest.java b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChest.java index 8c6d2ed3..b5d636e7 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChest.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChest.java @@ -2,6 +2,7 @@ package net.Indyuce.mmocore.loot.chest; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.SoundEvent; +import net.Indyuce.mmocore.util.item.HashableLocation; import org.apache.commons.lang.Validate; import org.bukkit.Location; import org.bukkit.Material; @@ -52,7 +53,7 @@ public class LootChest { public boolean hasPlayerNearby() { for (Player player : block.loc.getWorld().getPlayers()) - if (player.getLocation().distanceSquared(block.loc) < 625) + if (player.getLocation().distanceSquared(block.loc.bukkit()) < 625) return true; return false; } @@ -78,8 +79,8 @@ public class LootChest { // If a player is responsible of closing the chest, close it with sound if (player) { - MMOCore.plugin.soundManager.getSound(SoundEvent.CLOSE_LOOT_CHEST).playAt(block.loc); - block.loc.getWorld().spawnParticle(Particle.CRIT, block.loc.clone().add(.5, .5, .5), 16, 0, 0, 0, .5); + MMOCore.plugin.soundManager.getSound(SoundEvent.CLOSE_LOOT_CHEST).playAt(block.loc.bukkit()); + block.loc.getWorld().spawnParticle(Particle.CRIT, block.loc.bukkit().add(.5, .5, .5), 16, 0, 0, 0, .5); } /* @@ -87,7 +88,7 @@ public class LootChest { * off and accumulate on the ground (+during dev phase) */ else - ((Chest) block.loc.getBlock().getState()).getBlockInventory().clear(); + ((Chest) block.loc.bukkit().getBlock().getState()).getBlockInventory().clear(); block.restore(); if (effectRunnable != null) @@ -97,22 +98,28 @@ public class LootChest { public static class ReplacedBlock { private final Material material; private final BlockData data; - private final Location loc; + private final HashableLocation loc; public ReplacedBlock(Block block) { this.material = block.getType(); this.data = block.getBlockData(); - this.loc = block.getLocation(); + this.loc = new HashableLocation(block.getLocation()); } + public HashableLocation getLocation() { + return loc; + } + + @Deprecated public boolean matches(Location loc) { - return this.loc.getWorld().equals(loc.getWorld()) && this.loc.getBlockX() == loc.getBlockX() && this.loc.getBlockY() == loc.getBlockY() - && this.loc.getBlockZ() == loc.getBlockZ(); + return this.loc.getWorld().equals(loc.getWorld()) && this.loc.getX() == loc.getBlockX() && this.loc.getY() == loc.getBlockY() + && this.loc.getZ() == loc.getBlockZ(); } public void restore() { - loc.getBlock().setType(material); - loc.getBlock().setBlockData(data); + Block block = loc.bukkit().getBlock(); + block.setType(material); + block.setBlockData(data); } } } diff --git a/src/main/java/net/Indyuce/mmocore/manager/LootChestManager.java b/src/main/java/net/Indyuce/mmocore/manager/LootChestManager.java index 4dab3230..c0cc59bc 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/LootChestManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/LootChestManager.java @@ -1,33 +1,36 @@ package net.Indyuce.mmocore.manager; -import java.util.*; -import java.util.logging.Level; - -import org.bukkit.Location; -import org.bukkit.configuration.file.FileConfiguration; - import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.ConfigFile; import net.Indyuce.mmocore.loot.chest.LootChest; import net.Indyuce.mmocore.loot.chest.LootChestRegion; +import net.Indyuce.mmocore.util.item.HashableLocation; +import org.bukkit.Location; +import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.logging.Level; + public class LootChestManager implements MMOCoreManager { - /** - * Active loot chests in the server - */ - private final Set active = new HashSet<>(); + /** + * Active loot chests in the server + */ + private final Map active = new HashMap<>(); - /** - * Registered loot chest regions - */ - private final Map regions = new HashMap<>(); + /** + * Registered loot chest regions + */ + private final Map regions = new HashMap<>(); - public boolean hasRegion(String id) { - return regions.containsKey(id); - } + public boolean hasRegion(String id) { + return regions.containsKey(id); + } /** * @return Region with specific identifier @@ -38,48 +41,42 @@ public class LootChestManager implements MMOCoreManager { return Objects.requireNonNull(regions.get(id), "Could not find region with ID '" + id + "'"); } - public Collection getRegions() { - return regions.values(); - } + public Collection getRegions() { + return regions.values(); + } - public Set getActive() { - return active; - } + public Collection getActive() { + return active.values(); + } - public void register(LootChest chest) { - active.add(chest); - } + public void register(LootChest chest) { + active.put(chest.getBlock().getLocation(), chest); + } - public void unregister(LootChest chest) { - active.remove(chest); - } + public void unregister(LootChest chest) { + active.remove(chest.getBlock().getLocation()); + } - @Nullable - public LootChest getChest(Location loc) { + @Nullable + public LootChest getChest(Location loc) { + return active.get(new HashableLocation(loc)); + } - for (LootChest chest : active) - if (chest.getBlock().matches(loc)) - return chest; + @Override + public void initialize(boolean clearBefore) { + if (clearBefore) { + regions.values().forEach(region -> region.getRunnable().cancel()); + regions.clear(); + } - return null; - } - - @Override - public void initialize(boolean clearBefore) { - if (clearBefore) { - regions.values().forEach(region -> region.getRunnable().cancel()); - regions.clear(); - } - - FileConfiguration config = new ConfigFile("loot-chests").getConfig(); - for (String key : config.getKeys(false)) - try { - LootChestRegion region = new LootChestRegion(config.getConfigurationSection(key)); - regions.put(region.getId(), region); - } catch (IllegalArgumentException exception) { - MMOCore.plugin.getLogger().log(Level.WARNING, - "An error occured while trying to load loot chest region '" + key + "': " + exception.getMessage()); - } - - } + FileConfiguration config = new ConfigFile("loot-chests").getConfig(); + for (String key : config.getKeys(false)) + try { + LootChestRegion region = new LootChestRegion(config.getConfigurationSection(key)); + regions.put(region.getId(), region); + } catch (IllegalArgumentException exception) { + MMOCore.plugin.getLogger().log(Level.WARNING, + "An error occured while trying to load loot chest region '" + key + "': " + exception.getMessage()); + } + } } diff --git a/src/main/java/net/Indyuce/mmocore/player/Unlockable.java b/src/main/java/net/Indyuce/mmocore/player/Unlockable.java index 6940d1a1..9349f308 100644 --- a/src/main/java/net/Indyuce/mmocore/player/Unlockable.java +++ b/src/main/java/net/Indyuce/mmocore/player/Unlockable.java @@ -3,8 +3,8 @@ package net.Indyuce.mmocore.player; import net.Indyuce.mmocore.api.player.PlayerData; /** - * Some item that can be unlocked. ALl unlockable are saved in the same list in - * the player data. This useful list can be used for: + * Some item that can be unlocked. All unlockables are saved in the + * same list in the player data. This useful list can be used for: * - waypoints * - skill tree nodes * - skills using skill books? TODO @@ -15,8 +15,8 @@ import net.Indyuce.mmocore.api.player.PlayerData; public interface Unlockable { /** - * Format being used is the minecraft's default - * namespaced key format, e.g "skill_tree:strength_1_5" + * Format being used is the minecraft's default namespaced + * key format, e.g "skill_tree:strength_1_5" for readability */ String getUnlockNamespacedKey(); } diff --git a/src/main/java/net/Indyuce/mmocore/skill/ClassSkill.java b/src/main/java/net/Indyuce/mmocore/skill/ClassSkill.java index 1d72842b..841c76a2 100644 --- a/src/main/java/net/Indyuce/mmocore/skill/ClassSkill.java +++ b/src/main/java/net/Indyuce/mmocore/skill/ClassSkill.java @@ -4,6 +4,7 @@ import io.lumine.mythic.lib.api.player.EquipmentSlot; import io.lumine.mythic.lib.player.cooldown.CooldownObject; import io.lumine.mythic.lib.player.modifier.ModifierSource; import io.lumine.mythic.lib.player.skill.PassiveSkill; +import io.lumine.mythic.lib.skill.custom.condition.Condition; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.util.math.formula.IntegerLinearValue; import net.Indyuce.mmocore.api.util.math.formula.LinearValue; @@ -17,6 +18,9 @@ public class ClassSkill implements CooldownObject { private final int unlockLevel, maxSkillLevel; private final Map modifiers = new HashMap<>(); + @Deprecated + private final Set unlockConditions = new HashSet<>(); + /** * Class used to save information about skills IN A CLASS CONTEXT i.e at * which level the skill can be unlocked, etc. diff --git a/src/main/java/net/Indyuce/mmocore/skill/RegisteredSkill.java b/src/main/java/net/Indyuce/mmocore/skill/RegisteredSkill.java index 8fb2b970..0d5ada32 100644 --- a/src/main/java/net/Indyuce/mmocore/skill/RegisteredSkill.java +++ b/src/main/java/net/Indyuce/mmocore/skill/RegisteredSkill.java @@ -5,6 +5,7 @@ import io.lumine.mythic.lib.skill.handler.SkillHandler; import io.lumine.mythic.lib.skill.trigger.TriggerType; import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.api.util.math.formula.LinearValue; +import net.Indyuce.mmocore.player.Unlockable; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; @@ -15,7 +16,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; -public class RegisteredSkill { +public class RegisteredSkill implements Unlockable { private final SkillHandler handler; private final String name; private final Map defaultModifiers = new HashMap<>(); @@ -45,6 +46,11 @@ public class RegisteredSkill { this.triggerType = triggerType; } + @Override + public String getUnlockNamespacedKey() { + return "registered_skill:" + handler.getId().toLowerCase(); + } + public SkillHandler getHandler() { return handler; } diff --git a/src/main/java/net/Indyuce/mmocore/tree/modifier/UnlockSkillModifier.java b/src/main/java/net/Indyuce/mmocore/tree/modifier/UnlockSkillModifier.java new file mode 100644 index 00000000..570b8ab2 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/tree/modifier/UnlockSkillModifier.java @@ -0,0 +1,28 @@ +package net.Indyuce.mmocore.tree.modifier; + +import io.lumine.mythic.lib.api.player.EquipmentSlot; +import io.lumine.mythic.lib.api.player.MMOPlayerData; +import io.lumine.mythic.lib.player.modifier.ModifierSource; +import io.lumine.mythic.lib.player.modifier.PlayerModifier; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.skill.RegisteredSkill; +import org.apache.commons.lang.NotImplementedException; + +public class UnlockSkillModifier extends PlayerModifier { + private RegisteredSkill unlocked = null; + + public UnlockSkillModifier(String key, EquipmentSlot slot, ModifierSource source) { + super(key, slot, source); + } + + @Override + public void register(MMOPlayerData mmoPlayerData) { + PlayerData playerData = PlayerData.get(mmoPlayerData.getUniqueId()); + // playerData.unlock(unlocked); + } + + @Override + public void unregister(MMOPlayerData mmoPlayerData) { + throw new NotImplementedException(""); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/util/item/HashableLocation.java b/src/main/java/net/Indyuce/mmocore/util/item/HashableLocation.java new file mode 100644 index 00000000..1e910bbd --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/util/item/HashableLocation.java @@ -0,0 +1,51 @@ +package net.Indyuce.mmocore.util.item; + +import org.bukkit.Location; +import org.bukkit.World; + +import java.util.Objects; + +public class HashableLocation { + private final World world; + private final int x, y, z; + + public HashableLocation(Location loc) { + this.world = loc.getWorld(); + this.x = loc.getBlockX(); + this.y = loc.getBlockY(); + this.z = loc.getBlockZ(); + } + + public World getWorld() { + return world; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public int getZ() { + return z; + } + + public Location bukkit() { + return new Location(world, x, y, z); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + HashableLocation that = (HashableLocation) o; + return x == that.x && y == that.y && z == that.z && world.equals(that.world); + } + + @Override + public int hashCode() { + return Objects.hash(world, x, y, z); + } +} \ No newline at end of file From 758caf747db39e5b4e6e421434135a74e7f5225d Mon Sep 17 00:00:00 2001 From: Indyuce Date: Mon, 23 May 2022 11:10:02 +0200 Subject: [PATCH 19/39] Waypoints cleanup --- pom.xml | 4 - .../mmocore/api/player/PlayerData.java | 4 +- .../Indyuce/mmocore/gui/WaypointViewer.java | 56 ++-- .../mmocore/loot/chest/LootChestRegion.java | 10 +- .../mmocore/manager/WaypointManager.java | 7 + .../Indyuce/mmocore/waypoint/CostType.java | 30 --- .../Indyuce/mmocore/waypoint/Waypoint.java | 239 +++++------------- .../mmocore/waypoint/WaypointPath.java | 85 +++++++ src/main/resources/default/gui/waypoints.yml | 2 +- src/main/resources/default/waypoints.yml | 20 +- 10 files changed, 210 insertions(+), 247 deletions(-) delete mode 100644 src/main/java/net/Indyuce/mmocore/waypoint/CostType.java create mode 100644 src/main/java/net/Indyuce/mmocore/waypoint/WaypointPath.java diff --git a/pom.xml b/pom.xml index 51b355ac..85ecfca0 100644 --- a/pom.xml +++ b/pom.xml @@ -43,12 +43,8 @@ org.apache.maven.plugins maven-jar-plugin 2.3.1 - - C:\Users\guill\Minecraft Server\Server\plugins - - org.apache.maven.plugins maven-compiler-plugin 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 e2ca69ab..8b01f622 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java @@ -553,7 +553,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc member.giveExperience(value, EXPSource.PARTY_SHARING, null, false); } - PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(this, value, source); + PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(this, value, source); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) return; @@ -873,7 +873,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc * checks if they could potentially upgrade to one of these * * @return If the player can change its current class to - * a subclass + * a subclass */ public boolean canChooseSubclass() { for (Subclass subclass : getProfess().getSubclasses()) diff --git a/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java b/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java index 1f68d5ac..6dfbfb56 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java +++ b/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java @@ -8,11 +8,10 @@ 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.waypoint.CostType; import net.Indyuce.mmocore.waypoint.Waypoint; -import net.Indyuce.mmocore.waypoint.WaypointOption; +import net.Indyuce.mmocore.waypoint.WaypointPath; import org.apache.commons.lang.Validate; -import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.configuration.ConfigurationSection; @@ -21,8 +20,12 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; +import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class WaypointViewer extends EditableInventory { public WaypointViewer() { @@ -68,7 +71,6 @@ public class WaypointViewer extends EditableInventory { private final SimplePlaceholderItem noWaypoint, locked; private final WaypointItemHandler availWaypoint, noStellium, notLinked, notDynamic, currentWayPoint; - public WaypointItem(ConfigurationSection config) { super(Material.BARRIER, config); @@ -80,7 +82,6 @@ public class WaypointViewer extends EditableInventory { Validate.notNull(config.getConfigurationSection("not-enough-stellium"), "Could not load 'not-enough-stellium' config"); Validate.notNull(config.getConfigurationSection("display"), "Could not load 'display' config"); - noWaypoint = new SimplePlaceholderItem(config.getConfigurationSection("no-waypoint")); locked = new SimplePlaceholderItem(config.getConfigurationSection("locked")); notLinked = new WaypointItemHandler(config.getConfigurationSection("not-a-destination"), true); @@ -107,7 +108,6 @@ public class WaypointViewer extends EditableInventory { if (inv.current != null && inv.current.equals(waypoint)) return currentWayPoint.display(inv, n); - if (!inv.getPlayerData().hasWaypoint(waypoint)) return locked.display(inv, n); @@ -115,7 +115,6 @@ public class WaypointViewer extends EditableInventory { if (inv.current != null && !inv.paths.containsKey(waypoint)) return notLinked.display(inv, n); - // Not dynamic waypoint if (inv.current == null && !inv.paths.containsKey(waypoint)) return notDynamic.display(inv, n); @@ -124,7 +123,6 @@ public class WaypointViewer extends EditableInventory { if (inv.paths.get(waypoint).getCost() > inv.getPlayerData().getStellium()) return noStellium.display(inv, n); - return availWaypoint.display(inv, n); } } @@ -144,6 +142,16 @@ public class WaypointViewer extends EditableInventory { // If a player can teleport to another waypoint given his location Waypoint waypoint = inv.waypoints.get(inv.page * inv.getEditable().getByFunction("waypoint").getSlots().size() + n); ItemMeta meta = disp.getItemMeta(); + + // Add waypoint lore if not empty + if (!waypoint.getLore().isEmpty()) { + List lore = meta.getLore(); + Placeholders placeholders = new Placeholders(); + for (String str : waypoint.getLore()) + lore.add(0, ChatColor.GRAY + placeholders.apply(inv.getPlayer(), str)); + meta.setLore(lore); + } + PersistentDataContainer container = meta.getPersistentDataContainer(); container.set(new NamespacedKey(MMOCore.plugin, "waypointId"), PersistentDataType.STRING, waypoint.getId()); disp.setItemMeta(meta); @@ -160,7 +168,7 @@ public class WaypointViewer extends EditableInventory { holders.register("current_cost", inv.paths.get(waypoint).getCost()); holders.register("normal_cost", decimal.format(inv.paths.containsKey(waypoint) ? inv.paths.get(waypoint).getCost() : Double.POSITIVE_INFINITY)); holders.register("dynamic_cost", decimal.format(waypoint.getDynamicCost())); - holders.register("intermediary_waypoints", inv.paths.containsKey(waypoint) ? inv.paths.get(waypoint).displayIntermediaryWayPoints(inv.waypointCostType.equals(CostType.DYNAMIC_USE)) : "none"); + holders.register("intermediary_waypoints", inv.paths.containsKey(waypoint) ? inv.paths.get(waypoint).displayIntermediaryWayPoints(inv.isDynamicUse()) : "None"); } return holders; @@ -169,9 +177,9 @@ public class WaypointViewer extends EditableInventory { public class WaypointViewerInventory extends GeneratedInventory { private final List waypoints = new ArrayList<>(MMOCore.plugin.waypointManager.getAll()); + @Nullable private final Waypoint current; - private final Map paths = new HashMap<>(); - private final CostType waypointCostType; + private final Map paths = new HashMap<>(); private int page; @@ -179,32 +187,29 @@ public class WaypointViewer extends EditableInventory { super(playerData, editable); this.current = current; - if (current != null) { - for (Waypoint.PathInfo pathInfo : current.getAllPath()) + if (current != null) + for (WaypointPath pathInfo : current.getAllPath()) paths.put(pathInfo.getFinalWaypoint(), pathInfo); - } + if (current == null) { //Iterate through all the dynamic points and find all the points it is linked to and the path HashMap dynamicPoints = new HashMap<>(); //We first check all the dynamic waypoints for (Waypoint waypoint : waypoints) { - if (waypoint.canHaveDynamicUse(playerData.getPlayer())) { - paths.put(waypoint, new Waypoint.PathInfo(waypoint, waypoint.getDynamicCost())); + if (waypoint.mayBeUsedDynamically(playerData.getPlayer())) { + paths.put(waypoint, new WaypointPath(waypoint, waypoint.getDynamicCost())); dynamicPoints.put(waypoint, waypoint.getDynamicCost()); } } - for(Waypoint source: dynamicPoints.keySet()){ - for (Waypoint.PathInfo target : source.getAllPath()) { - if (!paths.containsKey(target.getFinalWaypoint()) || paths.get(target.getFinalWaypoint()).getCost() > target.getCost()+dynamicPoints.get(source)) { + for (Waypoint source : dynamicPoints.keySet()) { + for (WaypointPath target : source.getAllPath()) { + if (!paths.containsKey(target.getFinalWaypoint()) || paths.get(target.getFinalWaypoint()).getCost() > target.getCost() + dynamicPoints.get(source)) { paths.put(target.getFinalWaypoint(), target.addCost(dynamicPoints.get(source))); } } } - } - - this.waypointCostType = current == null ? CostType.DYNAMIC_USE : CostType.NORMAL_USE; } @Override @@ -212,6 +217,10 @@ public class WaypointViewer extends EditableInventory { return getName(); } + public boolean isDynamicUse() { + return current == null; + } + @Override public void whenClicked(InventoryClickEvent event, InventoryItem item) { if (item.getFunction().equals("next")) { @@ -260,7 +269,6 @@ public class WaypointViewer extends EditableInventory { } // Stellium cost - CostType costType = current == null ? CostType.DYNAMIC_USE : CostType.NORMAL_USE; double withdraw = paths.get(waypoint).getCost(); double left = withdraw - playerData.getStellium(); if (left > 0) { diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java index 8e6afc9a..6f455b3e 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java @@ -35,7 +35,7 @@ public class LootChestRegion { } }; - private static final Random random = new Random(); + private static final Random RANDOM = new Random(); public LootChestRegion(ConfigurationSection config) { Validate.notNull(config, "Could not load config"); @@ -110,7 +110,7 @@ public class LootChestRegion { location.getBlock().setType(Material.CHEST); Chest chest = (Chest) location.getBlock().getState(); tier.getDropTable().collect(builder).forEach(item -> { - Integer slot = slots.get(random.nextInt(slots.size())); + Integer slot = slots.get(RANDOM.nextInt(slots.size())); chest.getInventory().setItem(slot, item); slots.remove(slot); }); @@ -135,7 +135,7 @@ public class LootChestRegion { double cummulated = 0; for (ChestTier tier : tiers) { cummulated += getTierCoefficient(tier.getChance(), chance); - if (random.nextDouble() < cummulated / sum) + if (RANDOM.nextDouble() < cummulated / sum) return tier; } @@ -175,9 +175,9 @@ public class LootChestRegion { * Chooses a random direction and get the block in * that direction which has the same height as the player */ - double a = random.nextDouble() * 2 * Math.PI; + double a = RANDOM.nextDouble() * 2 * Math.PI; Vector dir = new Vector(Math.cos(a), 0, Math.sin(a)) - .multiply(algOptions.minRange + random.nextDouble() * (algOptions.maxRange - algOptions.minRange)); + .multiply(algOptions.minRange + RANDOM.nextDouble() * (algOptions.maxRange - algOptions.minRange)); Location random = center.add(dir); /* diff --git a/src/main/java/net/Indyuce/mmocore/manager/WaypointManager.java b/src/main/java/net/Indyuce/mmocore/manager/WaypointManager.java index 9ff105f0..f3b93d32 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/WaypointManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/WaypointManager.java @@ -55,5 +55,12 @@ public class WaypointManager implements MMOCoreManager { } catch (RuntimeException exception) { MMOCore.log(Level.WARNING, "Could not load waypoint '" + key + "': " + exception.getMessage()); } + + for (Waypoint waypoint : waypoints.values()) + try { + waypoint.postLoad(); + } catch (RuntimeException exception) { + MMOCore.log(Level.WARNING, "Could not post-load waypoint '" + waypoint.getId() + "': " + exception.getMessage()); + } } } diff --git a/src/main/java/net/Indyuce/mmocore/waypoint/CostType.java b/src/main/java/net/Indyuce/mmocore/waypoint/CostType.java deleted file mode 100644 index 6a0fefaa..00000000 --- a/src/main/java/net/Indyuce/mmocore/waypoint/CostType.java +++ /dev/null @@ -1,30 +0,0 @@ -package net.Indyuce.mmocore.waypoint; - -public enum CostType { - - /** - * When teleporting to this waypoint - */ - NORMAL_USE, - - /** - * When dynamically teleporting to this waypoint - */ - DYNAMIC_USE, - - /** - * When setting your spawn point to this waypoint. - */ - // SET_SPAWNPOINT - ; - - private final String path; - - CostType() { - this.path = name().toLowerCase().replace("_", "-"); - } - - public String getPath() { - return path; - } -} diff --git a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java index 6395ea81..e8d2695f 100644 --- a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java +++ b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java @@ -1,6 +1,7 @@ package net.Indyuce.mmocore.waypoint; import io.lumine.mythic.lib.api.MMOLineConfig; +import io.lumine.mythic.lib.api.util.PostLoadObject; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.loot.chest.condition.Condition; import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance; @@ -12,12 +13,15 @@ import org.bukkit.World; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.craftbukkit.libs.jline.internal.Nullable; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; import java.util.*; +import java.util.logging.Level; -public class Waypoint implements Unlockable { +public class Waypoint extends PostLoadObject implements Unlockable { private final String id, name; private final Location loc; + private final List lore; private final double radiusSquared; /** @@ -26,36 +30,21 @@ public class Waypoint implements Unlockable { *

* If it's empty it can access any waypoint. */ - private final Map destinations = new HashMap<>(); + private final Map destinations = new HashMap<>(); /** * Waypoint options saved here. */ private final Map options = new HashMap<>(); - - /** - * Stellium cost for each action (0 being the default cost) - */ private final double dynamicCost, setSpawnCost; - private final ArrayList dynamicUseConditions = new ArrayList<>(); - - private final Map costs = new HashMap<>(); - - public double getDynamicCost() { - return dynamicCost; - } - - public double getSetSpawnCost() { - return setSpawnCost; - } - - public double getCost(Waypoint waypoint) { - return getPath(waypoint).cost; - } + private final List dynamicUseConditions = new ArrayList<>(); public Waypoint(ConfigurationSection config) { + super(config); + id = Objects.requireNonNull(config, "Could not load config section").getName(); name = Objects.requireNonNull(config.getString("name"), "Could not load waypoint name"); + lore = Objects.requireNonNullElse(config.getStringList("lore"), new ArrayList<>()); loc = readLocation(Objects.requireNonNull(config.getString("location"), "Could not read location")); radiusSquared = Math.pow(config.getDouble("radius"), 2); @@ -63,36 +52,29 @@ public class Waypoint implements Unlockable { dynamicCost = config.getDouble("cost.dynamic-use"); setSpawnCost = config.getDouble("cost.set-spawnpoint"); - for (WaypointOption option : WaypointOption.values()) options.put(option, config.getBoolean("option." + option.getPath(), option.getDefaultValue())); - //We load all the linked WayPoints - if (config.contains("linked")) { - ConfigurationSection section = config.getConfigurationSection("linked"); - for (String key : section.getKeys(false)) { - destinations.put(key, section.getInt(key)); - } - } - if (config.contains("conditions")) { - List conditions = config.getStringList("conditions"); - for (String condition : conditions) { - dynamicUseConditions.add(MMOCore.plugin.loadManager.loadCondition(new MMOLineConfig(condition))); - - } - + if (config.contains("dynamic-conditions")) { + List conditions = config.getStringList("dynamic-conditions"); + for (String condition : conditions) + try { + dynamicUseConditions.add(MMOCore.plugin.loadManager.loadCondition(new MMOLineConfig(condition))); + } catch (RuntimeException exception) { + MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load condition '" + condition + "' from waypoint '" + id + "': " + exception.getMessage()); + } } } - public boolean canHaveDynamicUse(Player player) { - if (!options.get(WaypointOption.DYNAMIC)) - return false; + @Override + protected void whenPostLoaded(@NotNull ConfigurationSection config) { - for (Condition condition : dynamicUseConditions) { - if (!condition.isMet(new ConditionInstance(player))) - return false; + // Load waypoint network + if (config.contains("linked")) { + ConfigurationSection section = config.getConfigurationSection("linked"); + for (String key : section.getKeys(false)) + destinations.put(MMOCore.plugin.waypointManager.get(key), section.getInt(key)); } - return true; } public String getId() { @@ -103,71 +85,85 @@ public class Waypoint implements Unlockable { return name; } + public List getLore() { + return lore; + } + public Location getLocation() { return loc; } - /** * @param other Another waypoint * @return If any player standing on that waypoint can teleport to given waypoint */ @Deprecated public boolean hasDestination(Waypoint other) { - return destinations.isEmpty() || destinations.keySet().contains(other.getId()); + return destinations.isEmpty() || destinations.containsKey(other); + } + + public double getDynamicCost() { + return dynamicCost; + } + + public double getSetSpawnCost() { + return setSpawnCost; + } + + public boolean mayBeUsedDynamically(Player player) { + if (!options.get(WaypointOption.DYNAMIC)) + return false; + + for (Condition condition : dynamicUseConditions) + if (!condition.isMet(new ConditionInstance(player))) + return false; + + return true; } /** - * Checks directly if the waypoint is directly linked to the current one - * * @return Integer.POSITIVE_INFINITY if the way point is not linked + * If it is, cost of the instant travel between the two waypoints. */ - private int getSimpleCostDestination(Waypoint waypoint) { - if (!destinations.keySet().contains(waypoint.getId())) - return Integer.MAX_VALUE; - return destinations.get(waypoint.getId()); + public int getDirectCost(Waypoint waypoint) { + return destinations.getOrDefault(waypoint, Integer.MAX_VALUE); } - - public ArrayList getAllPath() { + public List getAllPath() { //All the WayPoints that have been registered - ArrayList checkedPoints = new ArrayList<>(); + List checkedPoints = new ArrayList<>(); //All the path - ArrayList paths = new ArrayList(); - ArrayList pointsToCheck = new ArrayList<>(); - pointsToCheck.add(new PathInfo(this)); + List paths = new ArrayList(); + List pointsToCheck = new ArrayList<>(); + pointsToCheck.add(new WaypointPath(this)); while (pointsToCheck.size() != 0) { - PathInfo checked = pointsToCheck.get(0); + WaypointPath checked = pointsToCheck.get(0); pointsToCheck.remove(0); paths.add(checked); checkedPoints.add(checked.getFinalWaypoint()); - for (String wayPointId : checked.getFinalWaypoint().destinations.keySet()) { - Waypoint toCheck = MMOCore.plugin.waypointManager.get(wayPointId); + for (Waypoint toCheck : checked.getFinalWaypoint().destinations.keySet()) if (!checkedPoints.contains(toCheck)) { - PathInfo toCheckInfo = checked.addWayPoint(toCheck); - //We keep pointsToCheck ordered + WaypointPath toCheckInfo = checked.addWayPoint(toCheck); + // We keep pointsToCheck ordered pointsToCheck = toCheckInfo.addInOrder(pointsToCheck); } - } } return paths; - } - @Nullable - public PathInfo getPath(Waypoint targetWaypoint) { + public WaypointPath getPath(Waypoint targetWaypoint) { //All the WayPoints that have been registered - ArrayList checkedPoints = new ArrayList<>(); + List checkedPoints = new ArrayList<>(); //All the path - ArrayList paths = new ArrayList(); - ArrayList pointsToCheck = new ArrayList<>(); - pointsToCheck.add(new PathInfo(this)); + List paths = new ArrayList(); + List pointsToCheck = new ArrayList<>(); + pointsToCheck.add(new WaypointPath(this)); while (pointsToCheck.size() != 0) { - PathInfo checked = pointsToCheck.get(0); + WaypointPath checked = pointsToCheck.get(0); pointsToCheck.remove(0); paths.add(checked); checkedPoints.add(checked.getFinalWaypoint()); @@ -175,19 +171,16 @@ public class Waypoint implements Unlockable { if (checked.getFinalWaypoint().equals(targetWaypoint)) return checked; - for (String wayPointId : checked.getFinalWaypoint().destinations.keySet()) { - Waypoint toCheck = MMOCore.plugin.waypointManager.get(wayPointId); + for (Waypoint toCheck : checked.getFinalWaypoint().destinations.keySet()) if (!checkedPoints.contains(toCheck)) { - PathInfo toCheckInfo = checked.addWayPoint(toCheck); - //We keep pointsToCheck ordered + WaypointPath toCheckInfo = checked.addWayPoint(toCheck); + // We keep pointsToCheck ordered pointsToCheck = toCheckInfo.addInOrder(pointsToCheck); } - } } //If no path has been found we return null return null; - } public boolean hasOption(WaypointOption option) { @@ -235,96 +228,4 @@ public class Waypoint implements Unlockable { return new Location(world, x, y, z, yaw, pitch); } - - public static class PathInfo { - private final ArrayList waypoints; - private double cost; - - public ArrayList getWaypoints() { - return waypoints; - } - - public double getCost() { - return cost; - } - - public PathInfo(Waypoint waypoint) { - this.waypoints = new ArrayList<>(); - this.waypoints.add(waypoint); - cost = 0; - } - public PathInfo(Waypoint waypoint,double cost) { - this.waypoints = new ArrayList<>(); - this.waypoints.add(waypoint); - this.cost = cost; - } - - public PathInfo addCost(double cost) { - this.cost+=cost; - return this; - } - - public ArrayList addInOrder(ArrayList pathInfos) { - int index = 0; - while (index < pathInfos.size()) { - if (cost < pathInfos.get(index).cost) { - pathInfos.set(index, this); - return pathInfos; - } - index++; - } - //If index==pathInfos.size() we add the waypoint at the end - pathInfos.add(this); - return pathInfos; - } - - - public PathInfo(List waypoints, double cost) { - this.waypoints = new ArrayList<>(waypoints); - this.cost = cost; - } - - /** - * - * @param dynamic We display the first waypoint if it is dynamic as it is an intermediary point - * @return - */ - public String displayIntermediaryWayPoints(boolean dynamic) { - String result = ""; - if(!dynamic) { - if (waypoints.size() <= 2) - return "none"; - for (int i = 1; i < waypoints.size() - 1; i++) { - result += waypoints.get(i).name + (i != waypoints.size() - 2 ? "," : ""); - } - - } - if(dynamic) { - if (waypoints.size() <= 1) - return "none"; - for (int i = 0; i < waypoints.size() - 1; i++) { - result += waypoints.get(i).name + (i != waypoints.size() - 2 ? "," : ""); - } - } - return result; - } - - public PathInfo addWayPoint(Waypoint waypoint) { - Validate.isTrue(!waypoints.contains(waypoint), "You can't create cyclic path"); - ArrayList newWaypoints = new ArrayList<>(); - newWaypoints.addAll(waypoints); - newWaypoints.add(waypoint); - double cost = this.cost + getFinalWaypoint().getSimpleCostDestination(waypoint); - return new PathInfo(newWaypoints, cost); - } - - - public Waypoint getInitialWaypoint() { - return waypoints.get(0); - } - - public Waypoint getFinalWaypoint() { - return waypoints.get(waypoints.size() - 1); - } - } } \ No newline at end of file diff --git a/src/main/java/net/Indyuce/mmocore/waypoint/WaypointPath.java b/src/main/java/net/Indyuce/mmocore/waypoint/WaypointPath.java new file mode 100644 index 00000000..e987eff5 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/waypoint/WaypointPath.java @@ -0,0 +1,85 @@ +package net.Indyuce.mmocore.waypoint; + +import java.util.ArrayList; +import java.util.List; + +public class WaypointPath { + private final List waypoints; + private double cost; + + public WaypointPath(Waypoint waypoint) { + this.waypoints = new ArrayList<>(); + this.waypoints.add(waypoint); + cost = 0; + } + + public WaypointPath(Waypoint waypoint, double cost) { + this.waypoints = new ArrayList<>(); + this.waypoints.add(waypoint); + this.cost = cost; + } + + public WaypointPath(List waypoints, double cost) { + this.waypoints = new ArrayList<>(waypoints); + this.cost = cost; + } + + public List getWaypoints() { + return waypoints; + } + + public double getCost() { + return cost; + } + + public WaypointPath addCost(double cost) { + this.cost += cost; + return this; + } + + public List addInOrder(List pathInfos) { + int index = 0; + while (index < pathInfos.size()) { + if (cost < pathInfos.get(index).cost) { + pathInfos.set(index, this); + return pathInfos; + } + index++; + } + // If index == pathInfos.size() add the waypoint at the end + pathInfos.add(this); + return pathInfos; + } + + + /** + * @param dynamic Display the first waypoint if it is dynamic as it is an intermediary point + * @return List with all + */ + public String displayIntermediaryWayPoints(boolean dynamic) { + int beginIndex = dynamic ? 0 : 1; + if (waypoints.size() <= beginIndex + 1) + return "None"; + + String result = ""; + for (int i = beginIndex; i < waypoints.size() - 1; i++) + result += waypoints.get(i).getName() + (i != waypoints.size() - 2 ? ", " : ""); + return result; + } + + public WaypointPath addWayPoint(Waypoint waypoint) { + List newWaypoints = new ArrayList<>(); + newWaypoints.addAll(waypoints); + newWaypoints.add(waypoint); + double cost = this.cost + getFinalWaypoint().getDirectCost(waypoint); + return new WaypointPath(newWaypoints, cost); + } + + public Waypoint getInitialWaypoint() { + return waypoints.get(0); + } + + public Waypoint getFinalWaypoint() { + return waypoints.get(waypoints.size() - 1); + } +} diff --git a/src/main/resources/default/gui/waypoints.yml b/src/main/resources/default/gui/waypoints.yml index cd90f0c8..56ade9b9 100644 --- a/src/main/resources/default/gui/waypoints.yml +++ b/src/main/resources/default/gui/waypoints.yml @@ -59,7 +59,7 @@ items: lore: - '&7You cannot teleport as you do not have enough Stellium.' - - '&7Teleporting costs &b&l{normal_cost}&7/&b&l{dynamic_cost} &7Stellium.' + - '&7Teleporting costs &b{normal_cost}&7/&b{dynamic_cost} &7Stellium.' # Displayed when the waypoint is unlocked and usable display: diff --git a/src/main/resources/default/waypoints.yml b/src/main/resources/default/waypoints.yml index 1de64a36..cb57e8fc 100644 --- a/src/main/resources/default/waypoints.yml +++ b/src/main/resources/default/waypoints.yml @@ -12,11 +12,11 @@ spawn: # Radius of waypoint around the specified location. radius: 2.0 + lore: {} + + # Cost for several specific actions cost: - # Stellium cost in order to use the waypoint. - # Stellium is like stamina however it's not used - # by skills and regens much slower than mana. # Cost when not standing on any waypoint. dynamic-use: 5 @@ -46,13 +46,11 @@ spawn: spawn1: 4 spawn2: 5 - spawn1: name: Spawn1 location: 'world 69 71 136 136 0' radius: 2.0 - cost: - normal-use: 3 + lore: {} option: default: false @@ -60,21 +58,19 @@ spawn1: # on any waypoint (waypoint must be unlocked). dynamic: true - ##Not necessary if the waypoint doesn't allow dynamic use - ##The conditions for the dynamic-use of the waypoint - conditions: + # Not necessary if the waypoint doesn't allow dynamic use + # The conditions for the dynamic-use of the waypoint + dynamic-conditions: - 'distance{world=world;x=69;y=71;z=163;distance=500}' - linked: spawn: 4 spawn2: name: Spawn2 + lore: {} location: 'world 69 71 136 136 0' radius: 3.0 - cost: - normal-use: 3 option: enable-menu: false linked: From 75a4b944b6e8db2b432623cab91b334e3900abaa Mon Sep 17 00:00:00 2001 From: Indyuce Date: Mon, 23 May 2022 11:29:45 +0200 Subject: [PATCH 20/39] Quest module fix --- .../Indyuce/mmocore/quest/AbstractQuest.java | 1 + .../mmocore/quest/QuestModuleType.java | 11 +++----- ...estModule.java => BeautyQuestsModule.java} | 15 +++++------ .../quest/compat/BlackVeinQuestsModule.java | 14 +++-------- .../quest/compat/QuestCreatorModule.java | 25 ++++++++++--------- .../mmocore/quest/compat/QuestModule.java | 5 ++-- 6 files changed, 30 insertions(+), 41 deletions(-) rename src/main/java/net/Indyuce/mmocore/quest/compat/{BeautyQuestModule.java => BeautyQuestsModule.java} (65%) diff --git a/src/main/java/net/Indyuce/mmocore/quest/AbstractQuest.java b/src/main/java/net/Indyuce/mmocore/quest/AbstractQuest.java index 075ae470..93316ec2 100644 --- a/src/main/java/net/Indyuce/mmocore/quest/AbstractQuest.java +++ b/src/main/java/net/Indyuce/mmocore/quest/AbstractQuest.java @@ -3,5 +3,6 @@ package net.Indyuce.mmocore.quest; public interface AbstractQuest { public String getName(); + public String getId(); } diff --git a/src/main/java/net/Indyuce/mmocore/quest/QuestModuleType.java b/src/main/java/net/Indyuce/mmocore/quest/QuestModuleType.java index 7bcd4bfa..4c7e0366 100644 --- a/src/main/java/net/Indyuce/mmocore/quest/QuestModuleType.java +++ b/src/main/java/net/Indyuce/mmocore/quest/QuestModuleType.java @@ -1,7 +1,6 @@ package net.Indyuce.mmocore.quest; -import net.Indyuce.mmocore.party.PartyModule; -import net.Indyuce.mmocore.quest.compat.BeautyQuestModule; +import net.Indyuce.mmocore.quest.compat.BeautyQuestsModule; import net.Indyuce.mmocore.quest.compat.BlackVeinQuestsModule; import net.Indyuce.mmocore.quest.compat.QuestCreatorModule; import net.Indyuce.mmocore.quest.compat.QuestModule; @@ -10,12 +9,10 @@ import org.bukkit.Bukkit; import javax.inject.Provider; public enum QuestModuleType { - MMOCORE("MMOCore",MMOCoreQuestModule::new), + MMOCORE("MMOCore", MMOCoreQuestModule::new), QUESTS("Quests", BlackVeinQuestsModule::new), - BEAUTY_QUEST("Beauty Quests", BeautyQuestModule::new), - QUEST_CREATOR("Quest Creator", QuestCreatorModule::new); - - + BEAUTY_QUEST("BeautyQuests", BeautyQuestsModule::new), + QUEST_CREATOR("QuestCreator", QuestCreatorModule::new); private final String pluginName; private final Provider provider; diff --git a/src/main/java/net/Indyuce/mmocore/quest/compat/BeautyQuestModule.java b/src/main/java/net/Indyuce/mmocore/quest/compat/BeautyQuestsModule.java similarity index 65% rename from src/main/java/net/Indyuce/mmocore/quest/compat/BeautyQuestModule.java rename to src/main/java/net/Indyuce/mmocore/quest/compat/BeautyQuestsModule.java index e1e4f720..b060cad3 100644 --- a/src/main/java/net/Indyuce/mmocore/quest/compat/BeautyQuestModule.java +++ b/src/main/java/net/Indyuce/mmocore/quest/compat/BeautyQuestsModule.java @@ -8,24 +8,21 @@ import fr.skytasul.quests.structure.Quest; import net.Indyuce.mmocore.quest.AbstractQuest; import org.bukkit.entity.Player; -public class BeautyQuestModule implements QuestModule { - +public class BeautyQuestsModule implements QuestModule { @Override public BeautyQuestQuest getQuestOrThrow(String questId) { - Quest quest=QuestsAPI.getQuests().getQuest(Integer.parseInt(questId)); - return quest==null?null:new BeautyQuestQuest(quest); + Quest quest = QuestsAPI.getQuests().getQuest(Integer.parseInt(questId)); + return quest == null ? null : new BeautyQuestQuest(quest); } @Override public boolean hasCompletedQuest(String questId, Player player) { - PlayerAccount account=PlayersManager.getPlayerAccount(player); - PlayerQuestDatas quest=account.getQuestDatas(QuestsAPI.getQuests().getQuest(Integer.parseInt(questId))); + PlayerAccount account = PlayersManager.getPlayerAccount(player); + PlayerQuestDatas quest = account.getQuestDatas(QuestsAPI.getQuests().getQuest(Integer.parseInt(questId))); return quest.isFinished(); } - - public class BeautyQuestQuest implements AbstractQuest { Quest quest; @@ -41,7 +38,7 @@ public class BeautyQuestModule implements QuestModule { private final Quests plugin = (Quests) Bukkit.getPluginManager().getPlugin("Quests"); - - @Override public BlackVeinQuestQuest getQuestOrThrow(String id) { Quests plugin = (Quests) Bukkit.getPluginManager().getPlugin("Quests"); - return plugin.getQuestById(id)==null?null:new BlackVeinQuestQuest(plugin.getQuestById(id)); + return plugin.getQuestById(id) == null ? null : new BlackVeinQuestQuest(plugin.getQuestById(id)); } - @Override public boolean hasCompletedQuest(String questId, Player player) { Quester quester = plugin.getQuester(player.getUniqueId()); - for(Quest quest:quester.getCompletedQuests()) { - if(quest.getId().equals(questId)) + for (Quest quest : quester.getCompletedQuests()) + if (quest.getId().equals(questId)) return true; - } + return false; } - public class BlackVeinQuestQuest implements AbstractQuest { private final Quest quest; @@ -49,5 +44,4 @@ public class BlackVeinQuestsModule implements QuestModule{ +public class QuestCreatorModule implements QuestModule { @Override public QuestCreatorQuest getQuestOrThrow(String id) { @@ -20,27 +21,27 @@ public class QuestCreatorModule implements QuestModule elements=playerData.getQuestHistory().getElements(questId, Arrays.asList(QuestEndType.SUCCESS),0); - for(QuestHistoryElement el:elements) { - if(el.getModelId().equals(questId)) + UserQC playerData = UserQC.cachedOrNull(player); + Validate.notNull(playerData, "QuestCreator User hasn't been loaded!"); + + // Gets all the quests the player has succeeded at + List elements = playerData.getQuestHistory().getElements(questId, Arrays.asList(QuestEndType.SUCCESS), 0); + for (QuestHistoryElement el : elements) + if (el.getModelId().equals(questId)) return true; - } + return false; } - /** - *QC ElementModel corresponds to our quest and their quests correspond to our Quest progress class + * QC ElementModel corresponds to our quest and their + * quests correspond to our Quest progress class */ - public class QuestCreatorQuest implements AbstractQuest { ElementModel questModel; public QuestCreatorQuest(String modelId) { - questModel=ConfigQC.models.getElement(modelId).orNull(); + questModel = ConfigQC.models.getElement(modelId).orNull(); } @Override diff --git a/src/main/java/net/Indyuce/mmocore/quest/compat/QuestModule.java b/src/main/java/net/Indyuce/mmocore/quest/compat/QuestModule.java index d4cae6b4..d569db22 100644 --- a/src/main/java/net/Indyuce/mmocore/quest/compat/QuestModule.java +++ b/src/main/java/net/Indyuce/mmocore/quest/compat/QuestModule.java @@ -6,13 +6,12 @@ import org.bukkit.entity.Player; public interface QuestModule { /** - * @return Quest with given name + * @return Quest with given identifier */ public T getQuestOrThrow(String id); /** - * @return If a specific player did a certain quest + * @return If a specific player has made a certain quest */ public boolean hasCompletedQuest(String quest, Player player); - } From c6a45d512014066cf5b19ea854a09e6909d0845e Mon Sep 17 00:00:00 2001 From: Indyuce Date: Mon, 23 May 2022 12:45:53 +0200 Subject: [PATCH 21/39] Deprecated exp dispensers --- pom.xml | 2 +- .../api/player/profess/PlayerClass.java | 21 ++++++++++---- .../api/quest/trigger/ExperienceTrigger.java | 7 ++--- .../mmocore/experience/ExperienceObject.java | 9 ++++-- .../mmocore/experience/Profession.java | 23 +++++++++++---- ...enser.java => SimpleExperienceObject.java} | 6 ++-- .../dispenser/ClassExperienceDispenser.java | 28 ------------------- .../dispenser/ExperienceDispenser.java | 5 ++-- .../ProfessionExperienceDispenser.java | 27 ------------------ 9 files changed, 49 insertions(+), 79 deletions(-) rename src/main/java/net/Indyuce/mmocore/experience/{dispenser/SimpleExperienceDispenser.java => SimpleExperienceObject.java} (79%) delete mode 100644 src/main/java/net/Indyuce/mmocore/experience/dispenser/ClassExperienceDispenser.java delete mode 100644 src/main/java/net/Indyuce/mmocore/experience/dispenser/ProfessionExperienceDispenser.java diff --git a/pom.xml b/pom.xml index 85ecfca0..4f0e60df 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 net.Indyuce MMOCore - 1.9.2 + 1.9.3 MMOCore Offer your players a brand new RPG experience!! 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 346a2b9a..cbd9dcc4 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,6 +8,7 @@ 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.api.player.PlayerData; import net.Indyuce.mmocore.api.player.profess.event.EventTrigger; import net.Indyuce.mmocore.api.player.profess.resource.ManaDisplayOptions; import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource; @@ -15,19 +16,18 @@ import net.Indyuce.mmocore.api.player.profess.resource.ResourceRegeneration; import net.Indyuce.mmocore.api.player.stats.StatType; 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.loot.chest.particle.CastingParticle; import net.Indyuce.mmocore.experience.ExpCurve; import net.Indyuce.mmocore.experience.ExperienceObject; import net.Indyuce.mmocore.experience.droptable.ExperienceTable; -import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; -import net.Indyuce.mmocore.experience.dispenser.ClassExperienceDispenser; import net.Indyuce.mmocore.experience.source.type.ExperienceSource; import net.Indyuce.mmocore.player.playerclass.ClassTrigger; import net.Indyuce.mmocore.player.playerclass.ClassTriggerType; import net.Indyuce.mmocore.skill.ClassSkill; import net.Indyuce.mmocore.skill.RegisteredSkill; import net.md_5.bungee.api.ChatColor; -import org.apache.commons.lang.Validate; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Particle; import org.bukkit.configuration.ConfigurationSection; @@ -156,10 +156,9 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject { } if (config.contains("main-exp-sources")) { - ExperienceDispenser dispenser = new ClassExperienceDispenser(this); for (String key : config.getStringList("main-exp-sources")) try { - ExperienceSource source = MMOCore.plugin.loadManager.loadExperienceSource(new MMOLineConfig(key), dispenser); + ExperienceSource source = MMOCore.plugin.loadManager.loadExperienceSource(new MMOLineConfig(key), this); MMOCore.plugin.experience.registerSource(source); } catch (IllegalArgumentException exception) { MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp source '" + key + "' from class '" @@ -299,6 +298,18 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject { return options.containsKey(option) ? options.get(option) : option.getDefault(); } + @Override + public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, EXPSource source) { + hologramLocation = !MMOCore.plugin.getConfig().getBoolean("display-main-class-exp-holograms") ? null + : hologramLocation; + playerData.giveExperience(experience, source, hologramLocation, true); + } + + @Override + public boolean shouldHandle(PlayerData playerData) { + return equals(playerData.getProfess()); + } + @Nullable @Deprecated public ClassTrigger getClassTrigger(ClassTriggerType type) { diff --git a/src/main/java/net/Indyuce/mmocore/api/quest/trigger/ExperienceTrigger.java b/src/main/java/net/Indyuce/mmocore/api/quest/trigger/ExperienceTrigger.java index 4a84e0b0..a7181940 100644 --- a/src/main/java/net/Indyuce/mmocore/api/quest/trigger/ExperienceTrigger.java +++ b/src/main/java/net/Indyuce/mmocore/api/quest/trigger/ExperienceTrigger.java @@ -1,8 +1,7 @@ package net.Indyuce.mmocore.api.quest.trigger; +import net.Indyuce.mmocore.experience.SimpleExperienceObject; import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; -import net.Indyuce.mmocore.experience.dispenser.ProfessionExperienceDispenser; -import net.Indyuce.mmocore.experience.dispenser.SimpleExperienceDispenser; import org.apache.commons.lang.Validate; import net.Indyuce.mmocore.MMOCore; @@ -28,9 +27,9 @@ public class ExperienceTrigger extends Trigger { if (config.contains("profession")) { String id = config.getString("profession").toLowerCase().replace("_", "-"); Validate.isTrue(MMOCore.plugin.professionManager.has(id), "Could not find profession"); - dispenser = new ProfessionExperienceDispenser(MMOCore.plugin.professionManager.get(id)); + dispenser = MMOCore.plugin.professionManager.get(id); } else - dispenser = new SimpleExperienceDispenser(); + dispenser = new SimpleExperienceObject(); amount = new RandomAmount(config.getString("amount")); source = config.contains("source") ? EXPSource.valueOf(config.getString("source").toUpperCase()) : EXPSource.QUEST; } diff --git a/src/main/java/net/Indyuce/mmocore/experience/ExperienceObject.java b/src/main/java/net/Indyuce/mmocore/experience/ExperienceObject.java index 3f9e6cc8..445e81c8 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/ExperienceObject.java +++ b/src/main/java/net/Indyuce/mmocore/experience/ExperienceObject.java @@ -1,16 +1,21 @@ package net.Indyuce.mmocore.experience; +import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; import net.Indyuce.mmocore.experience.droptable.ExperienceTable; import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; /** - * Either a profession or a class + * General implementation for professions and classes. + *

+ * An experience object is a type of object that can + * level up. It has an experience curve and table and + * can receive EXP * * @author jules */ -public interface ExperienceObject { +public interface ExperienceObject extends ExperienceDispenser { String getKey(); diff --git a/src/main/java/net/Indyuce/mmocore/experience/Profession.java b/src/main/java/net/Indyuce/mmocore/experience/Profession.java index ade8f4fb..42db02b1 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/Profession.java +++ b/src/main/java/net/Indyuce/mmocore/experience/Profession.java @@ -3,14 +3,15 @@ package net.Indyuce.mmocore.experience; import io.lumine.mythic.lib.api.MMOLineConfig; import io.lumine.mythic.lib.api.util.PostLoadObject; import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.util.math.formula.LinearValue; import net.Indyuce.mmocore.experience.droptable.ExperienceTable; -import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; -import net.Indyuce.mmocore.experience.dispenser.ProfessionExperienceDispenser; import org.apache.commons.lang.Validate; +import org.bukkit.Location; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.Map; @@ -63,16 +64,14 @@ public class Profession extends PostLoadObject implements ExperienceObject { maxLevel = config.getInt("max-level"); - if (config.contains("exp-sources")) { - ExperienceDispenser dispenser = new ProfessionExperienceDispenser(this); + if (config.contains("exp-sources")) for (String key : config.getStringList("exp-sources")) try { - MMOCore.plugin.experience.registerSource(MMOCore.plugin.loadManager.loadExperienceSource(new MMOLineConfig(key), dispenser)); + MMOCore.plugin.experience.registerSource(MMOCore.plugin.loadManager.loadExperienceSource(new MMOLineConfig(key), this)); } catch (IllegalArgumentException exception) { MMOCore.plugin.getLogger().log(Level.WARNING, "Could not register exp source '" + key + "' from profession '" + id + "': " + exception.getMessage()); } - } } @Override @@ -124,6 +123,18 @@ public class Profession extends PostLoadObject implements ExperienceObject { return Objects.requireNonNull(expTable, "Profession has no exp table"); } + @Override + public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, EXPSource source) { + hologramLocation = !getOption(Profession.ProfessionOption.EXP_HOLOGRAMS) ? null + : hologramLocation; + playerData.getCollectionSkills().giveExperience(this, experience, EXPSource.SOURCE, hologramLocation); + } + + @Override + public boolean shouldHandle(PlayerData playerData) { + return true; + } + public static enum ProfessionOption { /** diff --git a/src/main/java/net/Indyuce/mmocore/experience/dispenser/SimpleExperienceDispenser.java b/src/main/java/net/Indyuce/mmocore/experience/SimpleExperienceObject.java similarity index 79% rename from src/main/java/net/Indyuce/mmocore/experience/dispenser/SimpleExperienceDispenser.java rename to src/main/java/net/Indyuce/mmocore/experience/SimpleExperienceObject.java index fc99e73b..87e013c7 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/dispenser/SimpleExperienceDispenser.java +++ b/src/main/java/net/Indyuce/mmocore/experience/SimpleExperienceObject.java @@ -1,12 +1,12 @@ -package net.Indyuce.mmocore.experience.dispenser; +package net.Indyuce.mmocore.experience; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.experience.EXPSource; +import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; import org.bukkit.Location; import org.jetbrains.annotations.Nullable; -public class SimpleExperienceDispenser implements ExperienceDispenser { +public class SimpleExperienceObject implements ExperienceDispenser { @Override public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, EXPSource source) { diff --git a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ClassExperienceDispenser.java b/src/main/java/net/Indyuce/mmocore/experience/dispenser/ClassExperienceDispenser.java deleted file mode 100644 index 917f7b14..00000000 --- a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ClassExperienceDispenser.java +++ /dev/null @@ -1,28 +0,0 @@ -package net.Indyuce.mmocore.experience.dispenser; - -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.player.profess.PlayerClass; -import net.Indyuce.mmocore.experience.EXPSource; -import org.bukkit.Location; -import org.jetbrains.annotations.Nullable; - -public class ClassExperienceDispenser implements ExperienceDispenser { - private final PlayerClass profess; - - public ClassExperienceDispenser(PlayerClass profess) { - this.profess = profess; - } - - @Override - public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, EXPSource source) { - hologramLocation = !MMOCore.plugin.getConfig().getBoolean("display-main-class-exp-holograms") ? null - : hologramLocation; - playerData.giveExperience(experience, source, hologramLocation, true); - } - - @Override - public boolean shouldHandle(PlayerData playerData) { - return playerData.getProfess().equals(profess); - } -} diff --git a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ExperienceDispenser.java b/src/main/java/net/Indyuce/mmocore/experience/dispenser/ExperienceDispenser.java index 5ac9eac0..ad2ce255 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ExperienceDispenser.java +++ b/src/main/java/net/Indyuce/mmocore/experience/dispenser/ExperienceDispenser.java @@ -12,15 +12,14 @@ import org.jetbrains.annotations.Nullable; * experience given in a specific profession. Also being used to * monitor EXP holograms. */ +@Deprecated public interface ExperienceDispenser { /** * Called when experience is gained in main class/profession * * @param playerData Player gaining the experience - * @param experience Experience gained. Note that it is a double - * because it gets converted to an integer at - * the very last moment in MMOCore + * @param experience Experience gained * @param hologramLocation Location of displayed hologram. When set to null * and if exp holograms are enabled it will take the * player's location instead. diff --git a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ProfessionExperienceDispenser.java b/src/main/java/net/Indyuce/mmocore/experience/dispenser/ProfessionExperienceDispenser.java deleted file mode 100644 index 273a05b2..00000000 --- a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ProfessionExperienceDispenser.java +++ /dev/null @@ -1,27 +0,0 @@ -package net.Indyuce.mmocore.experience.dispenser; - -import net.Indyuce.mmocore.experience.EXPSource; -import net.Indyuce.mmocore.experience.Profession; -import net.Indyuce.mmocore.api.player.PlayerData; -import org.bukkit.Location; -import org.jetbrains.annotations.Nullable; - -public class ProfessionExperienceDispenser implements ExperienceDispenser { - private final Profession profession; - - public ProfessionExperienceDispenser(Profession profession) { - this.profession = profession; - } - - @Override - public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, EXPSource source) { - hologramLocation = !profession.getOption(Profession.ProfessionOption.EXP_HOLOGRAMS) ? null - : hologramLocation; - playerData.getCollectionSkills().giveExperience(profession, experience, EXPSource.SOURCE, hologramLocation); - } - - @Override - public boolean shouldHandle(PlayerData playerData) { - return true; - } -} From 31e8e42a1e7311b264e14c1ecd462df900f54df4 Mon Sep 17 00:00:00 2001 From: Indyuce Date: Mon, 23 May 2022 20:19:08 +0200 Subject: [PATCH 22/39] Support for placeholders in GUI names --- .../java/net/Indyuce/mmocore/gui/api/GeneratedInventory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 f01e98e2..85be0d26 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/api/GeneratedInventory.java +++ b/src/main/java/net/Indyuce/mmocore/gui/api/GeneratedInventory.java @@ -59,7 +59,7 @@ public abstract class GeneratedInventory extends PluginInventory { @Override public Inventory getInventory() { - Inventory inv = Bukkit.createInventory(this, editable.getSlots(), MythicLib.plugin.parseColors(calculateName())); + Inventory inv = Bukkit.createInventory(this, editable.getSlots(), MythicLib.plugin.getPlaceholderParser().parse(getPlayer(), calculateName())); for (InventoryItem item : editable.getItems()) if (item.canDisplay(this)) From 6f812545b77c866912964bc7f4d24ab395e494ce Mon Sep 17 00:00:00 2001 From: Indyuce Date: Mon, 23 May 2022 20:30:53 +0200 Subject: [PATCH 23/39] Fixed loot chests expiring --- .../java/net/Indyuce/mmocore/MMOCore.java | 17 ------------- .../Indyuce/mmocore/loot/chest/LootChest.java | 25 +++++++++++-------- .../mmocore/manager/ConfigManager.java | 2 +- 3 files changed, 15 insertions(+), 29 deletions(-) diff --git a/src/main/java/net/Indyuce/mmocore/MMOCore.java b/src/main/java/net/Indyuce/mmocore/MMOCore.java index aa2bec6f..1fd869fb 100644 --- a/src/main/java/net/Indyuce/mmocore/MMOCore.java +++ b/src/main/java/net/Indyuce/mmocore/MMOCore.java @@ -189,23 +189,6 @@ public class MMOCore extends LuminePlugin { } }.runTaskTimer(MMOCore.plugin, 100, 20); - /* - * Clean active loot chests every 5 minutes. Cannot register this runnable in - * the loot chest manager because it is instanced when the plugin loads - */ - new BukkitRunnable() { - public void run() { - Iterator iterator = lootChests.getActive().iterator(); - while (iterator.hasNext()) { - LootChest next = iterator.next(); - if (next.shouldExpire()) { - iterator.remove(); - next.expire(false); - } - } - } - }.runTaskTimer(this, 5 * 60 * 20, 5 * 60 * 20); - /* * For the sake of the lord, make sure they aren't using MMOItems Mana and * Stamina Addon...This should prevent a couple error reports produced by people diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChest.java b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChest.java index b5d636e7..5672b5eb 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChest.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChest.java @@ -10,7 +10,6 @@ import org.bukkit.Particle; import org.bukkit.block.Block; import org.bukkit.block.Chest; import org.bukkit.block.data.BlockData; -import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; import javax.annotation.Nullable; @@ -21,7 +20,7 @@ public class LootChest { private final ReplacedBlock block; @Nullable private final BukkitRunnable effectRunnable; - private final long date = System.currentTimeMillis(); + private final BukkitRunnable closeRunnable; private boolean active = true; @@ -37,6 +36,13 @@ public class LootChest { this.region = region; this.block = new ReplacedBlock(block); this.effectRunnable = tier.hasEffect() ? tier.getEffect().startNewRunnable(block.getLocation().add(.5, .5, .5)) : null; + closeRunnable = new BukkitRunnable() { + @Override + public void run() { + expire(false); + } + }; + closeRunnable.runTaskLater(MMOCore.plugin, MMOCore.plugin.configManager.lootChestExpireTime); } public ChestTier getTier() { @@ -51,15 +57,8 @@ public class LootChest { return region; } - public boolean hasPlayerNearby() { - for (Player player : block.loc.getWorld().getPlayers()) - if (player.getLocation().distanceSquared(block.loc.bukkit()) < 625) - return true; - return false; - } - - public boolean shouldExpire() { - return System.currentTimeMillis() - date > MMOCore.plugin.configManager.lootChestExpireTime; + public boolean isActive() { + return active; } /** @@ -77,6 +76,10 @@ public class LootChest { Validate.isTrue(active, "Chest has already expired"); active = false; + // Close runnable + if (!closeRunnable.isCancelled()) + closeRunnable.cancel(); + // If a player is responsible of closing the chest, close it with sound if (player) { MMOCore.plugin.soundManager.getSound(SoundEvent.CLOSE_LOOT_CHEST).playAt(block.loc.bukkit()); diff --git a/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java b/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java index bcc54190..137160c3 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java @@ -94,7 +94,7 @@ public class ConfigManager { chatInput = 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) * 1000L; + lootChestExpireTime = Math.max(MMOCore.plugin.getConfig().getInt("loot-chests.chest-expire-time"), 1) * 20; lootChestPlayerCooldown = (long) MMOCore.plugin.getConfig().getDouble("player-cooldown") * 1000L; globalSkillCooldown = MMOCore.plugin.getConfig().getLong("global-skill-cooldown") * 50; noSkillBoundPlaceholder = getSimpleMessage("no-skill-placeholder").message(); From 98dec0f4a2250c840a48f8c38760473ecab1341a Mon Sep 17 00:00:00 2001 From: Indyuce Date: Mon, 23 May 2022 20:42:29 +0200 Subject: [PATCH 24/39] Small refactor --- src/main/java/net/Indyuce/mmocore/loot/chest/LootChest.java | 2 +- src/main/java/net/Indyuce/mmocore/manager/LootChestManager.java | 2 +- .../net/Indyuce/mmocore/util/{item => }/HashableLocation.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename src/main/java/net/Indyuce/mmocore/util/{item => }/HashableLocation.java (96%) diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChest.java b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChest.java index 5672b5eb..3277d05e 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChest.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChest.java @@ -2,7 +2,7 @@ package net.Indyuce.mmocore.loot.chest; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.SoundEvent; -import net.Indyuce.mmocore.util.item.HashableLocation; +import net.Indyuce.mmocore.util.HashableLocation; import org.apache.commons.lang.Validate; import org.bukkit.Location; import org.bukkit.Material; diff --git a/src/main/java/net/Indyuce/mmocore/manager/LootChestManager.java b/src/main/java/net/Indyuce/mmocore/manager/LootChestManager.java index c0cc59bc..96317c16 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/LootChestManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/LootChestManager.java @@ -4,7 +4,7 @@ import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.ConfigFile; import net.Indyuce.mmocore.loot.chest.LootChest; import net.Indyuce.mmocore.loot.chest.LootChestRegion; -import net.Indyuce.mmocore.util.item.HashableLocation; +import net.Indyuce.mmocore.util.HashableLocation; import org.bukkit.Location; import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/net/Indyuce/mmocore/util/item/HashableLocation.java b/src/main/java/net/Indyuce/mmocore/util/HashableLocation.java similarity index 96% rename from src/main/java/net/Indyuce/mmocore/util/item/HashableLocation.java rename to src/main/java/net/Indyuce/mmocore/util/HashableLocation.java index 1e910bbd..0ef2336e 100644 --- a/src/main/java/net/Indyuce/mmocore/util/item/HashableLocation.java +++ b/src/main/java/net/Indyuce/mmocore/util/HashableLocation.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.util.item; +package net.Indyuce.mmocore.util; import org.bukkit.Location; import org.bukkit.World; From 0000b76d9694c8a507a14878bd026eae8d2f70c1 Mon Sep 17 00:00:00 2001 From: Indyuce Date: Tue, 24 May 2022 13:33:00 +0200 Subject: [PATCH 25/39] Waypoint books --- .../rpg/waypoint/ItemCommandTreeNode.java | 44 +++++++++++++++++++ .../waypoint/WaypointsCommandTreeNode.java | 1 + .../mmocore/listener/WaypointsListener.java | 16 ++++++- .../mmocore/manager/WaypointManager.java | 1 + .../mmocore/util/item/SkillBookBuilder.java | 29 ++++++++++++ .../util/item/WaypointBookBuilder.java | 30 +++++++++++++ src/main/resources/default/items.yml | 36 ++++++++++++--- src/main/resources/default/messages.yml | 1 + 8 files changed, 151 insertions(+), 7 deletions(-) create mode 100644 src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/ItemCommandTreeNode.java create mode 100644 src/main/java/net/Indyuce/mmocore/util/item/SkillBookBuilder.java create mode 100644 src/main/java/net/Indyuce/mmocore/util/item/WaypointBookBuilder.java diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/ItemCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/ItemCommandTreeNode.java new file mode 100644 index 00000000..d66f5eac --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/ItemCommandTreeNode.java @@ -0,0 +1,44 @@ +package net.Indyuce.mmocore.command.rpg.waypoint; + +import io.lumine.mythic.lib.api.util.SmartGive; +import io.lumine.mythic.lib.command.api.CommandTreeNode; +import io.lumine.mythic.lib.command.api.Parameter; +import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.util.item.WaypointBookBuilder; +import net.Indyuce.mmocore.waypoint.Waypoint; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class ItemCommandTreeNode extends CommandTreeNode { + public ItemCommandTreeNode(CommandTreeNode parent) { + super(parent, "item"); + + addParameter(new Parameter("", (explorer, list) -> MMOCore.plugin.waypointManager.getAll().forEach(way -> list.add(way.getId())))); + addParameter(Parameter.PLAYER); + } + + @Override + public CommandResult execute(CommandSender sender, String[] args) { + if (args.length < 4) + return CommandResult.THROW_USAGE; + + if (!MMOCore.plugin.waypointManager.has(args[2])) { + sender.sendMessage(ChatColor.RED + "Could not find waypoint " + args[2]); + return CommandResult.FAILURE; + } + + Player player = Bukkit.getPlayer(args[3]); + if (player == null) { + sender.sendMessage(ChatColor.RED + "Could not find player " + args[3]); + return CommandResult.FAILURE; + } + + Waypoint waypoint = MMOCore.plugin.waypointManager.get(args[2]); + new SmartGive(player).give(new WaypointBookBuilder(waypoint).build()); + sender.sendMessage(ChatColor.GOLD + "Gave " + player.getName() + ChatColor.YELLOW + " a waypoint book of " + ChatColor.GOLD + waypoint.getId() + + ChatColor.YELLOW + "."); + return CommandResult.SUCCESS; + } +} diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/WaypointsCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/WaypointsCommandTreeNode.java index 839f2995..48aeba29 100644 --- a/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/WaypointsCommandTreeNode.java +++ b/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/WaypointsCommandTreeNode.java @@ -11,6 +11,7 @@ public class WaypointsCommandTreeNode extends CommandTreeNode { addChild(new UnlockCommandTreeNode(this)); addChild(new OpenCommandTreeNode(this)); addChild(new TeleportCommandTreeNode(this)); + addChild(new ItemCommandTreeNode(this)); } @Override diff --git a/src/main/java/net/Indyuce/mmocore/listener/WaypointsListener.java b/src/main/java/net/Indyuce/mmocore/listener/WaypointsListener.java index f49dc3ca..c703c607 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/WaypointsListener.java +++ b/src/main/java/net/Indyuce/mmocore/listener/WaypointsListener.java @@ -52,7 +52,19 @@ public class WaypointsListener implements Listener { return; NBTItem nbtItem = NBTItem.get(event.getItem()); - if (Objects.equals(nbtItem.getString("MMOCoreItemId"), "WAYPOINT_BOOK")) - InventoryManager.WAYPOINTS.newInventory(PlayerData.get(event.getPlayer())).open(); + if (Objects.equals(nbtItem.getString("MMOCoreItemId"), "WAYPOINT_BOOK")) { + String waypointId = nbtItem.getString("WaypointBookId"); + Waypoint waypoint = MMOCore.plugin.waypointManager.get(waypointId); + if (waypoint == null) + return; + + PlayerData playerData = PlayerData.get(event.getPlayer()); + if (playerData.hasWaypoint(waypoint)) + return; + + playerData.unlockWaypoint(waypoint); + event.getItem().setAmount(event.getItem().getAmount() - 1); // Consume item + MMOCore.plugin.configManager.getSimpleMessage("new-waypoint-book", "waypoint", waypoint.getName()).send(event.getPlayer()); + } } } diff --git a/src/main/java/net/Indyuce/mmocore/manager/WaypointManager.java b/src/main/java/net/Indyuce/mmocore/manager/WaypointManager.java index f3b93d32..97bb5a00 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/WaypointManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/WaypointManager.java @@ -25,6 +25,7 @@ public class WaypointManager implements MMOCoreManager { return waypoints.containsKey(id); } + @Nullable public Waypoint get(String id) { return waypoints.get(id); } diff --git a/src/main/java/net/Indyuce/mmocore/util/item/SkillBookBuilder.java b/src/main/java/net/Indyuce/mmocore/util/item/SkillBookBuilder.java new file mode 100644 index 00000000..6c809a26 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/util/item/SkillBookBuilder.java @@ -0,0 +1,29 @@ +package net.Indyuce.mmocore.util.item; + +import io.lumine.mythic.lib.api.item.ItemTag; +import io.lumine.mythic.lib.api.item.NBTItem; +import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.skill.RegisteredSkill; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +@Deprecated +public class SkillBookBuilder extends AbstractItemBuilder { + private final RegisteredSkill skill; + + public SkillBookBuilder(RegisteredSkill skill) { + super(MMOCore.plugin.configItems.get("SKILL_BOOK")); + + this.skill = skill; + } + + @Override + public void whenBuildingMeta(ItemStack item, ItemMeta meta) { + + } + + @Override + public void whenBuildingNBT(NBTItem nbtItem) { + nbtItem.addTag(new ItemTag("SkillBookId", skill.getHandler().getId())); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/util/item/WaypointBookBuilder.java b/src/main/java/net/Indyuce/mmocore/util/item/WaypointBookBuilder.java new file mode 100644 index 00000000..d16aeeb0 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/util/item/WaypointBookBuilder.java @@ -0,0 +1,30 @@ +package net.Indyuce.mmocore.util.item; + +import io.lumine.mythic.lib.api.item.ItemTag; +import io.lumine.mythic.lib.api.item.NBTItem; +import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.waypoint.Waypoint; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +public class WaypointBookBuilder extends AbstractItemBuilder { + private final Waypoint waypoint; + + public WaypointBookBuilder(Waypoint waypoint) { + super(MMOCore.plugin.configItems.get("WAYPOINT_BOOK")); + + this.waypoint = waypoint; + + addPlaceholders("waypoint", waypoint.getName()); + } + + @Override + public void whenBuildingMeta(ItemStack item, ItemMeta meta) { + + } + + @Override + public void whenBuildingNBT(NBTItem nbtItem) { + nbtItem.addTag(new ItemTag("WaypointBookId", waypoint.getId())); + } +} diff --git a/src/main/resources/default/items.yml b/src/main/resources/default/items.yml index 05de0cbe..ab5b3967 100644 --- a/src/main/resources/default/items.yml +++ b/src/main/resources/default/items.yml @@ -1,3 +1,18 @@ +# The default item template, not used by MMOCore but it does +# indicates all the item options you can use to configure your items. +TEMPLATE: + item: BOOK + name: 'Your item name' + custom-model-data: 0 + damage: 0 + unbreakable: false + lore: + - 'This is your item lore' + - 'And that is the second line' + - 'This supports &acolors &7as well' + # For player heads only, that is the skull texture value + texture: 'eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOGUwYzUzN2EzZDAyMjlmNzMyZTlkMWY4NTRiMzc3YWQwNDA3NjE4ZmQwM2NkNGJiZTgwMzc2MjI0YTRmMWQxZSJ9fX0=' + GOLD_COIN: item: GOLD_NUGGET name: '&6Gold Coin' @@ -10,12 +25,23 @@ NOTE: lore: - '&eWorth: {worth}g' -WAYPOINT_BOOK: - item: ENCHANTED_BOOK - name: '&6Waypoints Book' +SKILL_POINT_BOOK: + item: book + name: '&6Skill Book' lore: - - '&7Waypoints are locations used to save your progress.' - - '&7This book gives you the ability to freely warp between these.' + - '&7Click to redeem one skill point.' + +SKILL_BOOK: + item: book + name: '&6Skill Book: {skill}' + lore: + - '&7Click to unlock {skill}' + +WAYPOINT_BOOK: + item: BOOK + name: '&6Waypoint Book: {waypoint}' + lore: + - '&7Click to unlock {waypoint}' DEPOSIT_ITEM: item: BOOK diff --git a/src/main/resources/default/messages.yml b/src/main/resources/default/messages.yml index 697ebaa9..b311b6ba 100644 --- a/src/main/resources/default/messages.yml +++ b/src/main/resources/default/messages.yml @@ -67,6 +67,7 @@ leave-combat: '%&aYou left combat.' # Waypoints new-waypoint: '%&eYou unlocked the &6{waypoint} &ewaypoint!' +new-waypoint-book: '%&eYou unlocked the &6{waypoint} &ewaypoint!' not-enough-stellium: '&cYou don''t have enough stellium: you need {more} more.' waypoint-cooldown: '&cPlease wait {cooldown} before using a waypoint again.' not-unlocked-waypoint: '&cYou have not unlocked that waypoint yet.' From 2c0f8094c0c614a6d93bf4f63413d915ae53c8d1 Mon Sep 17 00:00:00 2001 From: Indyuce Date: Tue, 24 May 2022 13:33:20 +0200 Subject: [PATCH 26/39] Reduced confusion for config items --- .../java/net/Indyuce/mmocore/util/item/ConfigItem.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/Indyuce/mmocore/util/item/ConfigItem.java b/src/main/java/net/Indyuce/mmocore/util/item/ConfigItem.java index f778f7b6..50693c73 100644 --- a/src/main/java/net/Indyuce/mmocore/util/item/ConfigItem.java +++ b/src/main/java/net/Indyuce/mmocore/util/item/ConfigItem.java @@ -1,11 +1,13 @@ package net.Indyuce.mmocore.util.item; +import io.lumine.mythic.lib.UtilityMethods; import org.apache.commons.lang.Validate; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import javax.annotation.Nullable; import java.util.List; +import java.util.Objects; public class ConfigItem { private final String name, id, texture; @@ -15,10 +17,12 @@ public class ConfigItem { private final boolean unbreakable; public ConfigItem(ConfigurationSection config) { - id = config.getName(); + id = UtilityMethods.enumName(config.getName()); name = config.getString("name"); lore = config.getStringList("lore"); - material = Material.valueOf(config.getString("item")); + String itemFormat = Objects.requireNonNull(config.getString("item"), "Could not find item material"); + Validate.isTrue(!itemFormat.contains(":"), "Invalid custom model data format, please use 'custom-model-data: X' instead"); + material = Material.valueOf(UtilityMethods.enumName(itemFormat)); Validate.notNull(name, "Name cannot be null"); Validate.notNull(lore, "Lore can be empty but not null"); From 28be26b9c8a9c57a78e0efd5ea8a1497b1064fa5 Mon Sep 17 00:00:00 2001 From: Indyuce Date: Tue, 24 May 2022 13:33:37 +0200 Subject: [PATCH 27/39] Attribute modifiers available in ML --- src/main/java/net/Indyuce/mmocore/MMOCore.java | 6 +++--- .../mmocore/api/player/attribute/AttributeModifier.java | 6 ++++-- .../net/Indyuce/mmocore/experience/ExperienceObject.java | 7 +++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/java/net/Indyuce/mmocore/MMOCore.java b/src/main/java/net/Indyuce/mmocore/MMOCore.java index 1fd869fb..5141e462 100644 --- a/src/main/java/net/Indyuce/mmocore/MMOCore.java +++ b/src/main/java/net/Indyuce/mmocore/MMOCore.java @@ -8,6 +8,7 @@ import io.lumine.mythic.utils.plugin.LuminePlugin; import net.Indyuce.mmocore.api.ConfigFile; import net.Indyuce.mmocore.api.PlayerActionBar; import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.api.player.attribute.AttributeModifier; import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource; import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.api.util.debug.DebugMode; @@ -31,7 +32,6 @@ import net.Indyuce.mmocore.listener.event.PlayerPressKeyListener; import net.Indyuce.mmocore.listener.option.*; import net.Indyuce.mmocore.listener.profession.FishingListener; import net.Indyuce.mmocore.listener.profession.PlayerCollectStats; -import net.Indyuce.mmocore.loot.chest.LootChest; import net.Indyuce.mmocore.manager.*; import net.Indyuce.mmocore.manager.data.DataProvider; import net.Indyuce.mmocore.manager.data.mysql.MySQLDataProvider; @@ -55,7 +55,6 @@ import org.jetbrains.annotations.NotNull; import java.io.File; import java.lang.reflect.Field; -import java.util.Iterator; import java.util.logging.Level; public class MMOCore extends LuminePlugin { @@ -116,8 +115,9 @@ public class MMOCore extends LuminePlugin { return; } - // Register MMOCore-specific target restrictions + // Register MMOCore-specific objects MythicLib.plugin.getEntities().registerRestriction(new PartyMemberTargetRestriction()); + MythicLib.plugin.getModifiers().registerModifierType("attribute", configObject -> new AttributeModifier(configObject)); // Register extra objective, drop items... if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null) diff --git a/src/main/java/net/Indyuce/mmocore/api/player/attribute/AttributeModifier.java b/src/main/java/net/Indyuce/mmocore/api/player/attribute/AttributeModifier.java index 108d3ebb..7dd53051 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/attribute/AttributeModifier.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/attribute/AttributeModifier.java @@ -12,6 +12,7 @@ import net.Indyuce.mmocore.api.player.PlayerData; import org.apache.commons.lang.Validate; import java.text.DecimalFormat; +import java.util.Objects; public class AttributeModifier extends PlayerModifier { private final String attribute; @@ -74,9 +75,10 @@ public class AttributeModifier extends PlayerModifier { public AttributeModifier(ConfigObject object) { super(object.getString("key"), EquipmentSlot.OTHER, ModifierSource.OTHER); + String str = Objects.requireNonNull(object.getString("value")); + type = str.toCharArray()[str.length() - 1] == '%' ? ModifierType.RELATIVE : ModifierType.FLAT; + value = Double.parseDouble(type == ModifierType.RELATIVE ? str.substring(0, str.length() - 1) : str); this.attribute = object.getString("attribute"); - this.value = object.getDouble("value"); - type = object.getBoolean("multiplicative", false) ? ModifierType.RELATIVE : ModifierType.FLAT; } public String getAttribute() { diff --git a/src/main/java/net/Indyuce/mmocore/experience/ExperienceObject.java b/src/main/java/net/Indyuce/mmocore/experience/ExperienceObject.java index 445e81c8..c14f0232 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/ExperienceObject.java +++ b/src/main/java/net/Indyuce/mmocore/experience/ExperienceObject.java @@ -7,11 +7,10 @@ import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; /** - * General implementation for professions and classes. + * General implementation for professions, classes and attributes. *

- * An experience object is a type of object that can - * level up. It has an experience curve and table and - * can receive EXP + * An experience object is a type of object that can level up. + * It has an experience curve and table and can receive EXP * * @author jules */ From f9cc6bfb33360b74fb818221afbe214a03c8c633 Mon Sep 17 00:00:00 2001 From: Indyuce Date: Tue, 24 May 2022 13:54:52 +0200 Subject: [PATCH 28/39] Class triggers small change --- .../net/Indyuce/mmocore/listener/ClassTriggers.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/Indyuce/mmocore/listener/ClassTriggers.java b/src/main/java/net/Indyuce/mmocore/listener/ClassTriggers.java index 44612aea..465b66cb 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/ClassTriggers.java +++ b/src/main/java/net/Indyuce/mmocore/listener/ClassTriggers.java @@ -52,7 +52,7 @@ public class ClassTriggers implements Listener { public void onAttack(PlayerAttackEvent event) { for (Map.Entry entry : damageTriggers.entrySet()) if (event.getDamage().hasType(entry.getKey())) - applyTriggers(event.getPlayer(), entry.getValue()); //, () -> new TriggerMetadata(event.getAttack(), event.getEntity()) + applyTriggers(event.getPlayer(), entry.getValue(), () -> new TriggerMetadata(event.getAttack(), event.getEntity())); } @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) @@ -88,6 +88,16 @@ public class ClassTriggers implements Listener { return applyTriggers(PlayerData.get(player), type, triggerMetaProvider); } + /** + * Apply class shortcut skills from a specific class trigger type. + * + * @param player Player triggering + * @param type Trigger type + * @param triggerMetaProvider Small optimization: if no shortcut skill is found + * with the corresponding trigger type, trigger meta + * is not calculated which saves computations + * @return Skill result or null if no shortcut skill was cast + */ @Nullable private SkillResult applyTriggers(PlayerData player, ClassTriggerType type, Provider triggerMetaProvider) { ClassTrigger trigger = player.getProfess().getClassTrigger(type); From 7d2af8d787053d7e8f3e36df44c1e15b923528d3 Mon Sep 17 00:00:00 2001 From: Indyuce Date: Tue, 24 May 2022 14:03:46 +0200 Subject: [PATCH 29/39] Addex exp tables to attributes --- .../api/player/attribute/PlayerAttribute.java | 126 +++++++++++++----- .../player/attribute/PlayerAttributes.java | 26 ++-- .../experience/droptable/ExperienceItem.java | 8 +- 3 files changed, 111 insertions(+), 49 deletions(-) diff --git a/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttribute.java b/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttribute.java index 8f714bf7..62352c55 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttribute.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttribute.java @@ -3,57 +3,109 @@ package net.Indyuce.mmocore.api.player.attribute; import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.api.stat.modifier.StatModifier; import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.player.PlayerData; +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; import org.apache.commons.lang.Validate; +import org.bukkit.Location; import org.bukkit.configuration.ConfigurationSection; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.HashSet; +import java.util.Objects; import java.util.Set; import java.util.logging.Level; -public class PlayerAttribute { - private final String id, name; - private final int max; +public class PlayerAttribute implements ExperienceObject { + private final String id, name; + private final int max; + private final ExperienceTable expTable; - /** - * Used to store stats using StatType, but attributes also need to access - * non basic MMOCore stats hence the string maps keys - */ - private final Set buffs = new HashSet<>(); + /** + * Used to store stats using StatType, but attributes also need to access + * non basic MMOCore stats hence the string maps keys + */ + private final Set buffs = new HashSet<>(); - public PlayerAttribute(ConfigurationSection config) { - Validate.notNull(config, "Could not load config"); - id = config.getName().toLowerCase().replace("_", "-").replace(" ", "-"); + public PlayerAttribute(ConfigurationSection config) { + Validate.notNull(config, "Could not load config"); + id = config.getName().toLowerCase().replace("_", "-").replace(" ", "-"); - name = MythicLib.plugin.parseColors(config.getString("name", "Attribute")); - max = config.contains("max-points") ? Math.max(1, config.getInt("max-points")) : 0; + name = MythicLib.plugin.parseColors(config.getString("name", "Attribute")); + max = config.contains("max-points") ? Math.max(1, config.getInt("max-points")) : 0; - if (config.contains("buff")) - for (String key : config.getConfigurationSection("buff").getKeys(false)) - try { - String stat = key.toUpperCase().replace("-", "_").replace(" ", "_"); - buffs.add(new StatModifier("attribute." + id, stat, config.getString("buff." + key))); - } catch (IllegalArgumentException exception) { - MMOCore.log(Level.WARNING, "Could not load buff '" + key + "' from attribute '" + id + "': " + exception.getMessage()); - } - } + if (config.contains("buff")) + for (String key : config.getConfigurationSection("buff").getKeys(false)) + try { + String stat = key.toUpperCase().replace("-", "_").replace(" ", "_"); + buffs.add(new StatModifier("attribute." + id, stat, config.getString("buff." + key))); + } catch (IllegalArgumentException exception) { + MMOCore.log(Level.WARNING, "Could not load buff '" + key + "' from attribute '" + id + "': " + exception.getMessage()); + } - public String getId() { - return id; - } + // Load exp table + ExperienceTable expTable = null; + if (config.contains("exp-table")) + try { + expTable = MMOCore.plugin.experience.loadExperienceTable(config.get("exp-table")); + } catch (RuntimeException exception) { + MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp table from class '" + id + "': " + exception.getMessage()); + } + this.expTable = expTable; + } - public String getName() { - return name; - } + public String getId() { + return id; + } - public boolean hasMax() { - return max > 0; - } + public String getName() { + return name; + } - public int getMax() { - return max; - } + public boolean hasMax() { + return max > 0; + } - public Set getBuffs() { - return buffs; - } + public int getMax() { + return max; + } + + public Set getBuffs() { + return buffs; + } + + @Override + public String getKey() { + return "attribute:" + getId().replace("-", "_"); + } + + @NotNull + @Override + public ExperienceTable getExperienceTable() { + return Objects.requireNonNull(expTable); + } + + @Override + public boolean hasExperienceTable() { + return expTable != null; + } + + @Nullable + @Override + public ExpCurve getExpCurve() { + throw new RuntimeException("Attributes don't have experience"); + } + + @Override + public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, @NotNull EXPSource source) { + throw new RuntimeException("Attributes don't have experience"); + } + + @Override + public boolean shouldHandle(PlayerData playerData) { + throw new RuntimeException("Attributes don't have experience"); + } } 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 2569d811..769e34ea 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,8 +129,17 @@ 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); } /* @@ -159,14 +168,14 @@ public class PlayerAttributes { return map.get(key); } - public void addModifier(String key, double value) { - addModifier(new AttributeModifier(key, id, value, ModifierType.FLAT, EquipmentSlot.OTHER, ModifierSource.OTHER)); + public AttributeModifier addModifier(String key, double value) { + return addModifier(new AttributeModifier(key, id, value, ModifierType.FLAT, EquipmentSlot.OTHER, ModifierSource.OTHER)); } - public void addModifier(AttributeModifier modifier) { - map.put(modifier.getKey(), modifier); - + public AttributeModifier addModifier(AttributeModifier modifier) { + AttributeModifier mod = map.put(modifier.getKey(), modifier); update(); + return mod; } public Set getKeys() { @@ -177,7 +186,7 @@ public class PlayerAttributes { return map.containsKey(key); } - public void removeModifier(String key) { + public AttributeModifier removeModifier(String key) { AttributeModifier mod = map.remove(key); /* @@ -190,12 +199,13 @@ public class PlayerAttributes { ((Closeable) mod).close(); update(); } + return mod; } public void update() { - PlayerAttribute attribute = MMOCore.plugin.attributeManager.get(id); + PlayerAttribute attr = MMOCore.plugin.attributeManager.get(id); int total = getTotal(); - attribute.getBuffs().forEach(buff -> buff.multiply(total).register(data.getMMOPlayerData())); + attr.getBuffs().forEach(buff -> buff.multiply(total).register(data.getMMOPlayerData())); } public String getId() { 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 4ba8028c..31698af7 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java +++ b/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java @@ -36,13 +36,13 @@ 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, 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.firstTrigger = firstTrigger; } public ExperienceItem(ConfigurationSection config) { @@ -51,7 +51,7 @@ public class ExperienceItem { id = config.getName(); period = config.getInt("period", 0); - firstTrigger=config.getInt("first-trigger",period); + firstTrigger = config.getInt("first-trigger", period); claimChance = config.getDouble("chance", 100) / 100; failReduction = config.getDouble("fail-reduction", 80) / 100; triggers = new ArrayList<>(); @@ -71,7 +71,7 @@ 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); + int claimsRequired = professionLevel + 1 - (firstTrigger - timesCollected * period); if (claimsRequired < 1) return false; From 1f344dbe029d712ce254618be6d7dc06e238cf89 Mon Sep 17 00:00:00 2001 From: Indyuce Date: Tue, 24 May 2022 15:27:03 +0200 Subject: [PATCH 30/39] Fixed skill list pagination --- .../net/Indyuce/mmocore/gui/SkillList.java | 33 ++++++------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/src/main/java/net/Indyuce/mmocore/gui/SkillList.java b/src/main/java/net/Indyuce/mmocore/gui/SkillList.java index af983f3c..1699f0ef 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/SkillList.java +++ b/src/main/java/net/Indyuce/mmocore/gui/SkillList.java @@ -11,10 +11,8 @@ 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.SkillManager; import net.Indyuce.mmocore.skill.ClassSkill; import net.Indyuce.mmocore.skill.RegisteredSkill; -import org.apache.commons.lang.Validate; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.Sound; @@ -39,7 +37,6 @@ public class SkillList extends EditableInventory { if (function.equals("skill")) return new SkillItem(config); - if (function.equals("level")) return new LevelItem(config); @@ -48,7 +45,7 @@ public class SkillList extends EditableInventory { @Override public Placeholders getPlaceholders(SkillViewerInventory inv, int n) { - RegisteredSkill selected = inv.selected==null?null:inv.selected.getSkill(); + RegisteredSkill selected = inv.selected == null ? null : inv.selected.getSkill(); Placeholders holders = new Placeholders(); holders.register("skill_caps", selected.getName().toUpperCase()); @@ -57,7 +54,6 @@ public class SkillList extends EditableInventory { return holders; } - }; if (function.equals("slot")) @@ -69,7 +65,7 @@ public class SkillList extends EditableInventory { @Override public Placeholders getPlaceholders(SkillViewerInventory inv, int n) { - RegisteredSkill selected = inv.selected==null?null:inv.selected.getSkill(); + RegisteredSkill selected = inv.selected == null ? null : inv.selected.getSkill(); RegisteredSkill skill = inv.getPlayerData().hasSkillBound(n) ? inv.getPlayerData().getBoundSkill(n).getSkill() : null; Placeholders holders = new Placeholders(); @@ -77,7 +73,7 @@ public class SkillList extends EditableInventory { holders.register("skill", skill == null ? none : skill.getName()); holders.register("index", "" + (n + 1)); holders.register("slot", MMOCoreUtils.intToRoman(n + 1)); - holders.register("selected", selected==null?none:selected.getName()); + holders.register("selected", selected == null ? none : selected.getName()); return holders; } @@ -115,7 +111,8 @@ public class SkillList extends EditableInventory { @Override public boolean canDisplay(SkillViewerInventory inv) { - return inv.page < inv.skills.size() / 12; + final int perPage = inv.skillSlots.size(); + return inv.page < (inv.skills.size() - 1) / perPage; } }; } @@ -172,21 +169,15 @@ public class SkillList extends EditableInventory { return NBTItem.get(item).addTag(new ItemTag("skillId", skill.getSkill().getHandler().getId())).toItem(); } - @Override public Placeholders getPlaceholders(SkillViewerInventory inv, int n) { return new Placeholders(); } - - } public class SkillItem extends InventoryItem { - - public SkillItem(ConfigurationSection config) { super(Material.BARRIER, config); - } @Override @@ -197,11 +188,9 @@ public class SkillList extends EditableInventory { @Override public ItemStack display(SkillViewerInventory inv, int n) { - /* - * calculate placeholders - */ - int index=n+inv.skillSlots.size()*inv.page; - if(index>=inv.skills.size()) + // Calculate placeholders + int index = n + inv.skillSlots.size() * inv.page; + if (index >= inv.skills.size()) return new ItemStack(Material.AIR); ClassSkill skill = inv.skills.get(index); @@ -222,9 +211,7 @@ public class SkillList extends EditableInventory { for (int j = 0; j < lore.size(); j++) lore.set(j, ChatColor.GRAY + holders.apply(inv.getPlayer(), lore.get(j))); - /* - * generate item - */ + // Generate item ItemStack item = skill.getSkill().getIcon(); ItemMeta meta = item.getItemMeta(); meta.setDisplayName(holders.apply(inv.getPlayer(), getName())); @@ -266,7 +253,7 @@ public class SkillList extends EditableInventory { skills = new ArrayList<>(playerData.getProfess().getSkills()); skillSlots = getEditable().getByFunction("skill").getSlots(); slotSlots = getEditable().getByFunction("slot").getSlots(); - selected=skills.get(page*skillSlots.size()); + selected = skills.get(page * skillSlots.size()); } @Override From 0648079232a1aec78141678313828b11d28899fc Mon Sep 17 00:00:00 2001 From: Indyuce Date: Sat, 28 May 2022 14:28:18 +0200 Subject: [PATCH 31/39] Fixed waypoint path calculation --- src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java index e8d2695f..7391f8a5 100644 --- a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java +++ b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java @@ -140,6 +140,10 @@ public class Waypoint extends PostLoadObject implements Unlockable { while (pointsToCheck.size() != 0) { WaypointPath checked = pointsToCheck.get(0); pointsToCheck.remove(0); + // If the point has already been checked, pass + if (checkedPoints.contains(checked.getFinalWaypoint())) + continue; + paths.add(checked); checkedPoints.add(checked.getFinalWaypoint()); @@ -165,6 +169,10 @@ public class Waypoint extends PostLoadObject implements Unlockable { while (pointsToCheck.size() != 0) { WaypointPath checked = pointsToCheck.get(0); pointsToCheck.remove(0); + // If the point has already been checked, pass + if (checkedPoints.contains(checked.getFinalWaypoint())) + continue; + paths.add(checked); checkedPoints.add(checked.getFinalWaypoint()); From eed3502029281d373955b915148c529131e7191c Mon Sep 17 00:00:00 2001 From: Indyuce Date: Sat, 28 May 2022 15:26:22 +0200 Subject: [PATCH 32/39] MMOCore now takes in stats from ML --- .../java/net/Indyuce/mmocore/MMOCore.java | 5 +- .../Indyuce/mmocore/api/PlayerActionBar.java | 121 +++++++++--------- .../mmocore/api/player/PlayerData.java | 15 +-- .../api/player/attribute/PlayerAttribute.java | 4 +- .../api/player/profess/PlayerClass.java | 25 ++-- .../profess/resource/PlayerResource.java | 17 ++- .../mmocore/api/player/stats/PlayerStats.java | 55 ++++---- .../mmocore/api/player/stats/StatType.java | 58 ++++----- .../api/util/math/formula/LinearValue.java | 12 ++ .../debug/StatModifiersCommandTreeNode.java | 17 +-- .../rpg/debug/StatValueCommandTreeNode.java | 61 ++++----- .../comp/placeholder/RPGPlaceholders.java | 16 +-- .../mmocore/experience/PlayerProfessions.java | 4 +- .../Indyuce/mmocore/gui/AttributeView.java | 6 +- .../net/Indyuce/mmocore/gui/PlayerStats.java | 54 +++++--- .../listener/profession/FishingListener.java | 7 +- .../profession/PlayerCollectStats.java | 26 ++-- .../mmocore/loot/chest/LootChestRegion.java | 3 +- .../loot/droptable/dropitem/DropItem.java | 3 +- .../Indyuce/mmocore/manager/StatManager.java | 71 ++++++++++ .../data/mysql/MySQLPlayerDataManager.java | 20 +-- .../data/yaml/YAMLPlayerDataManager.java | 7 +- .../manager/profession/FishingManager.java | 16 ++- .../mmocore/manager/social/PartyManager.java | 5 +- .../mmocore/player/stats/StatInfo.java | 71 ++++++++++ 25 files changed, 403 insertions(+), 296 deletions(-) create mode 100644 src/main/java/net/Indyuce/mmocore/manager/StatManager.java create mode 100644 src/main/java/net/Indyuce/mmocore/player/stats/StatInfo.java diff --git a/src/main/java/net/Indyuce/mmocore/MMOCore.java b/src/main/java/net/Indyuce/mmocore/MMOCore.java index 5141e462..04096c71 100644 --- a/src/main/java/net/Indyuce/mmocore/MMOCore.java +++ b/src/main/java/net/Indyuce/mmocore/MMOCore.java @@ -10,7 +10,6 @@ import net.Indyuce.mmocore.api.PlayerActionBar; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.attribute.AttributeModifier; import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource; -import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.api.util.debug.DebugMode; import net.Indyuce.mmocore.command.*; import net.Indyuce.mmocore.comp.citizens.CitizenInteractEventListener; @@ -77,6 +76,7 @@ public class MMOCore extends LuminePlugin { public final LootChestManager lootChests = new LootChestManager(); public final MMOLoadManager loadManager = new MMOLoadManager(); public final RestrictionManager restrictionManager = new RestrictionManager(); + public final StatManager statManager = new StatManager(); @Deprecated public final SkillTreeManager skillTreeManager = new SkillTreeManager(); @@ -385,6 +385,7 @@ public class MMOCore extends LuminePlugin { configManager = new ConfigManager(); + statManager.initialize(clearBefore); if (clearBefore) MythicLib.plugin.getSkills().initialize(true); skillManager.initialize(clearBefore); @@ -414,8 +415,6 @@ public class MMOCore extends LuminePlugin { if (getConfig().isConfigurationSection("action-bar")) actionBarManager.reload(getConfig().getConfigurationSection("action-bar")); - StatType.load(); - if (clearBefore) PlayerData.getAll().forEach(PlayerData::update); } diff --git a/src/main/java/net/Indyuce/mmocore/api/PlayerActionBar.java b/src/main/java/net/Indyuce/mmocore/api/PlayerActionBar.java index 594696b3..0dbd8859 100644 --- a/src/main/java/net/Indyuce/mmocore/api/PlayerActionBar.java +++ b/src/main/java/net/Indyuce/mmocore/api/PlayerActionBar.java @@ -1,73 +1,72 @@ package net.Indyuce.mmocore.api; -import java.text.DecimalFormat; - +import io.lumine.mythic.lib.MythicLib; +import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerActivity; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.player.stats.StatInfo; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; import org.bukkit.attribute.Attribute; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.scheduler.BukkitRunnable; -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.player.stats.StatType; -import net.md_5.bungee.api.ChatMessageType; -import net.md_5.bungee.api.chat.TextComponent; -import io.lumine.mythic.lib.MythicLib; +import java.text.DecimalFormat; public class PlayerActionBar extends BukkitRunnable { - boolean initialized = false; - - private ActionBarConfig config; - private DecimalFormat digit; - - public void reload(ConfigurationSection cfg) { - config = new ActionBarConfig(cfg); - digit = MythicLib.plugin.getMMOConfig().newDecimalFormat(config.digit); + boolean initialized = false; - if(!initialized && config.enabled) { - runTaskTimer(MMOCore.plugin, 0, config.ticks); - initialized = true; - } - } - - public long getTimeOut() { - return config.timeout; - } + private ActionBarConfig config; + private DecimalFormat digit; - @Override - public void run() { - for (PlayerData data : PlayerData.getAll()) - if (data.isOnline() && !data.getPlayer().isDead() && !data.isCasting() && data.getActivityTimeOut(PlayerActivity.ACTION_BAR_MESSAGE) == 0) { - data.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(MMOCore.plugin.placeholderParser.parse(data.getPlayer(), - MythicLib.plugin.parseColors((data.getProfess().hasActionBar() ? data.getProfess().getActionBar() : config.format) - .replace("{health}", digit.format(data.getPlayer().getHealth())) - .replace("{max_health}", "" + StatType.MAX_HEALTH.format(data.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue())) - .replace("{mana_icon}", data.getProfess().getManaDisplay().getIcon()) - .replace("{mana}", digit.format(data.getMana())) - .replace("{max_mana}", "" + StatType.MAX_MANA.format(data.getStats().getStat(StatType.MAX_MANA))) - .replace("{stamina}", digit.format(data.getStamina())) - .replace("{max_stamina}", "" + StatType.MAX_STAMINA.format(data.getStats().getStat(StatType.MAX_STAMINA))) - .replace("{stellium}", digit.format(data.getStellium())) - .replace("{max_stellium}", "" + StatType.MAX_STELLIUM.format(data.getStats().getStat(StatType.MAX_STELLIUM))) - .replace("{class}", data.getProfess().getName()) - .replace("{xp}", "" + data.getExperience()) - .replace("{armor}", "" + StatType.ARMOR.format(data.getPlayer().getAttribute(Attribute.GENERIC_ARMOR).getValue())) - .replace("{level}", "" + data.getLevel()) - .replace("{name}", data.getPlayer().getDisplayName()))))); - } - } - - private static class ActionBarConfig { - private final boolean enabled; - private final int ticks, timeout; - private final String digit, format; - - private ActionBarConfig(ConfigurationSection config) { - enabled = config.getBoolean("enabled", false); - timeout = config.getInt("", 60); - digit = config.getString("decimal", "0.#"); - ticks = config.getInt("ticks-to-update", 5); - format = config.getString("format", "please format me :c"); - } - } + public void reload(ConfigurationSection cfg) { + config = new ActionBarConfig(cfg); + digit = MythicLib.plugin.getMMOConfig().newDecimalFormat(config.digit); + + if (!initialized && config.enabled) { + runTaskTimer(MMOCore.plugin, 0, config.ticks); + initialized = true; + } + } + + public long getTimeOut() { + return config.timeout; + } + + @Override + public void run() { + for (PlayerData data : PlayerData.getAll()) + if (data.isOnline() && !data.getPlayer().isDead() && !data.isCasting() && data.getActivityTimeOut(PlayerActivity.ACTION_BAR_MESSAGE) == 0) { + data.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(MMOCore.plugin.placeholderParser.parse(data.getPlayer(), + MythicLib.plugin.parseColors((data.getProfess().hasActionBar() ? data.getProfess().getActionBar() : config.format) + .replace("{health}", digit.format(data.getPlayer().getHealth())) + .replace("{max_health}", StatInfo.valueOf("MAX_HEALTH").format(data.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue())) + .replace("{mana_icon}", data.getProfess().getManaDisplay().getIcon()) + .replace("{mana}", digit.format(data.getMana())) + .replace("{max_mana}", StatInfo.valueOf("MAX_MANA").format(data.getStats().getStat("MAX_MANA"))) + .replace("{stamina}", digit.format(data.getStamina())) + .replace("{max_stamina}", StatInfo.valueOf("MAX_STAMINA").format(data.getStats().getStat("MAX_STAMINA"))) + .replace("{stellium}", digit.format(data.getStellium())) + .replace("{max_stellium}", StatInfo.valueOf("MAX_STELLIUM").format(data.getStats().getStat("MAX_STELLIUM"))) + .replace("{class}", data.getProfess().getName()) + .replace("{xp}", "" + data.getExperience()) + .replace("{armor}", StatInfo.valueOf("ARMOR").format(data.getPlayer().getAttribute(Attribute.GENERIC_ARMOR).getValue())) + .replace("{level}", "" + data.getLevel()) + .replace("{name}", data.getPlayer().getDisplayName()))))); + } + } + + private static class ActionBarConfig { + private final boolean enabled; + private final int ticks, timeout; + private final String digit, format; + + private ActionBarConfig(ConfigurationSection config) { + enabled = config.getBoolean("enabled", false); + timeout = config.getInt("", 60); + digit = config.getString("decimal", "0.#"); + ticks = config.getInt("ticks-to-update", 5); + format = config.getString("format", "please format me :c"); + } + } } 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 8b01f622..8713d21f 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java @@ -17,7 +17,6 @@ import net.Indyuce.mmocore.api.player.profess.Subclass; import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource; import net.Indyuce.mmocore.api.player.social.FriendRequest; import net.Indyuce.mmocore.api.player.stats.PlayerStats; -import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.api.quest.PlayerQuests; import net.Indyuce.mmocore.api.util.Closable; import net.Indyuce.mmocore.api.util.MMOCoreUtils; @@ -542,7 +541,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc } value = MMOCore.plugin.boosterManager.calculateExp(null, value); - value *= 1 + getStats().getStat(StatType.ADDITIONAL_EXPERIENCE) / 100; + value *= 1 + getStats().getStat("ADDITIONAL_EXPERIENCE") / 100; // Splitting exp through party members AbstractParty party = getParty(); @@ -615,7 +614,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc public void giveMana(double amount, PlayerResourceUpdateEvent.UpdateReason reason) { // Avoid calling useless event - double max = getStats().getStat(StatType.MAX_MANA); + double max = getStats().getStat("MAX_MANA"); double newest = Math.max(0, Math.min(mana + amount, max)); if (mana == newest) return; @@ -640,7 +639,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc public void giveStamina(double amount, PlayerResourceUpdateEvent.UpdateReason reason) { // Avoid calling useless event - double max = getStats().getStat(StatType.MAX_STAMINA); + double max = getStats().getStat("MAX_STAMINA"); double newest = Math.max(0, Math.min(stamina + amount, max)); if (stamina == newest) return; @@ -665,7 +664,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc public void giveStellium(double amount, PlayerResourceUpdateEvent.UpdateReason reason) { // Avoid calling useless event - double max = getStats().getStat(StatType.MAX_STELLIUM); + double max = getStats().getStat("MAX_STELLIUM"); double newest = Math.max(0, Math.min(stellium + amount, max)); if (stellium == newest) return; @@ -700,15 +699,15 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc } public void setMana(double amount) { - mana = Math.max(0, Math.min(amount, getStats().getStat(StatType.MAX_MANA))); + mana = Math.max(0, Math.min(amount, getStats().getStat("MAX_MANA"))); } public void setStamina(double amount) { - stamina = Math.max(0, Math.min(amount, getStats().getStat(StatType.MAX_STAMINA))); + stamina = Math.max(0, Math.min(amount, getStats().getStat("MAX_STAMINA"))); } public void setStellium(double amount) { - stellium = Math.max(0, Math.min(amount, getStats().getStat(StatType.MAX_STELLIUM))); + stellium = Math.max(0, Math.min(amount, getStats().getStat("MAX_STELLIUM"))); } public boolean isFullyLoaded() { diff --git a/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttribute.java b/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttribute.java index 62352c55..af2f7ad5 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttribute.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttribute.java @@ -25,8 +25,8 @@ public class PlayerAttribute implements ExperienceObject { private final ExperienceTable expTable; /** - * Used to store stats using StatType, but attributes also need to access - * non basic MMOCore stats hence the string maps keys + * All buffs granted by an attribute. These are normalized and + * must be multiplied by the player level first */ private final Set buffs = new HashSet<>(); 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 cbd9dcc4..eb1fc759 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 @@ -13,17 +13,17 @@ import net.Indyuce.mmocore.api.player.profess.event.EventTrigger; import net.Indyuce.mmocore.api.player.profess.resource.ManaDisplayOptions; import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource; import net.Indyuce.mmocore.api.player.profess.resource.ResourceRegeneration; -import net.Indyuce.mmocore.api.player.stats.StatType; 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.loot.chest.particle.CastingParticle; import net.Indyuce.mmocore.experience.ExpCurve; import net.Indyuce.mmocore.experience.ExperienceObject; import net.Indyuce.mmocore.experience.droptable.ExperienceTable; import net.Indyuce.mmocore.experience.source.type.ExperienceSource; +import net.Indyuce.mmocore.loot.chest.particle.CastingParticle; import net.Indyuce.mmocore.player.playerclass.ClassTrigger; import net.Indyuce.mmocore.player.playerclass.ClassTriggerType; +import net.Indyuce.mmocore.player.stats.StatInfo; import net.Indyuce.mmocore.skill.ClassSkill; import net.Indyuce.mmocore.skill.RegisteredSkill; import net.md_5.bungee.api.ChatColor; @@ -51,7 +51,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject { private final ExpCurve expCurve; private final ExperienceTable expTable; - private final Map stats = new HashMap<>(); + private final Map stats = new HashMap<>(); private final Map skills = new LinkedHashMap<>(); private final List subclasses = new ArrayList<>(); @@ -124,7 +124,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject { if (config.contains("attributes")) for (String key : config.getConfigurationSection("attributes").getKeys(false)) try { - stats.put(StatType.valueOf(key.toUpperCase().replace("-", "_")), + stats.put(UtilityMethods.enumName(key), new LinearValue(config.getConfigurationSection("attributes." + key))); } catch (IllegalArgumentException exception) { MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load stat info '" + key + "' from class '" @@ -331,16 +331,11 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject { return eventTriggers.get(name); } - @Deprecated - public void setStat(StatType type, double base, double perLevel) { - setStat(type, new LinearValue(base, perLevel)); + public void setDefaultStatFormula(String type, LinearValue value) { + stats.put(UtilityMethods.enumName(type), value); } - public void setStat(StatType type, LinearValue value) { - stats.put(type, value); - } - - public double calculateStat(StatType stat, int level) { + public double calculateStat(String stat, int level) { return getStatInfo(stat).calculate(level); } @@ -396,8 +391,10 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject { return skills.values(); } - private LinearValue getStatInfo(StatType type) { - return stats.containsKey(type) ? stats.get(type) : type.getDefault(); + @NotNull + private LinearValue getStatInfo(String stat) { + LinearValue found = stats.get(stat); + return found == null ? StatInfo.valueOf(stat).getDefaultFormula() : found; } @Override diff --git a/src/main/java/net/Indyuce/mmocore/api/player/profess/resource/PlayerResource.java b/src/main/java/net/Indyuce/mmocore/api/player/profess/resource/PlayerResource.java index fcbec451..56aeb9b5 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/profess/resource/PlayerResource.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/profess/resource/PlayerResource.java @@ -3,7 +3,6 @@ package net.Indyuce.mmocore.api.player.profess.resource; import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.profess.ClassOption; -import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.api.quest.trigger.ManaTrigger; import org.bukkit.attribute.Attribute; @@ -20,27 +19,27 @@ public enum PlayerResource { (data, amount) -> data.getPlayer().setHealth(amount)), MANA(PlayerData::getMana, - data -> data.getStats().getStat(StatType.MAX_MANA), + data -> data.getStats().getStat("MAX_MANA"), (data, amount) -> data.giveMana(amount, PlayerResourceUpdateEvent.UpdateReason.REGENERATION), (data, amount) -> data.giveMana(amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND), (data, amount) -> data.giveMana(-amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND), (data, amount) -> data.setMana(amount)), STAMINA(PlayerData::getStamina, - data -> data.getStats().getStat(StatType.MAX_STAMINA), + data -> data.getStats().getStat("MAX_STAMINA"), (data, amount) -> data.giveStamina(amount, PlayerResourceUpdateEvent.UpdateReason.REGENERATION), (data, amount) -> data.giveStamina(amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND), (data, amount) -> data.giveStamina(-amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND), (data, amount) -> data.setStamina(amount)), STELLIUM(PlayerData::getStellium, - data -> data.getStats().getStat(StatType.MAX_STELLIUM), + data -> data.getStats().getStat("MAX_STELLIUM"), (data, amount) -> data.giveStellium(amount, PlayerResourceUpdateEvent.UpdateReason.REGENERATION), (data, amount) -> data.giveStellium(amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND), (data, amount) -> data.giveStellium(-amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND), (data, amount) -> data.setStellium(amount)); - private final StatType regenStat, maxRegenStat; + private final String regenStat, maxRegenStat; private final ClassOption offCombatRegen; private final Function current, max; private final BiConsumer regen; @@ -54,8 +53,8 @@ public enum PlayerResource { BiConsumer give, BiConsumer take, BiConsumer set) { - this.regenStat = StatType.valueOf(name() + "_REGENERATION"); - this.maxRegenStat = StatType.valueOf("MAX_" + name() + "_REGENERATION"); + this.regenStat = name() + "_REGENERATION"; + this.maxRegenStat = "MAX_" + name() + "_REGENERATION"; this.offCombatRegen = ClassOption.valueOf("OFF_COMBAT_" + name() + "_REGEN"); this.current = current; this.max = max; @@ -68,14 +67,14 @@ public enum PlayerResource { /** * @return Stat which corresponds to flat resource regeneration */ - public StatType getRegenStat() { + public String getRegenStat() { return regenStat; } /** * @return Stat which corresponds to resource regeneration scaling with the player's max health */ - public StatType getMaxRegenStat() { + public String getMaxRegenStat() { return maxRegenStat; } diff --git a/src/main/java/net/Indyuce/mmocore/api/player/stats/PlayerStats.java b/src/main/java/net/Indyuce/mmocore/api/player/stats/PlayerStats.java index be0912c7..0682683c 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/stats/PlayerStats.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/stats/PlayerStats.java @@ -8,17 +8,14 @@ import io.lumine.mythic.lib.player.modifier.ModifierSource; import io.lumine.mythic.lib.player.modifier.ModifierType; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.experience.Profession; +import net.Indyuce.mmocore.player.stats.StatInfo; import net.Indyuce.mmocore.skill.ClassSkill; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Locale; public class PlayerStats { private final PlayerData data; /** - * Utilclass to easily manipulate the MMOLib stat map + * Util class to easily manipulate the MMOLib stat map * * @param data Playerdata */ @@ -34,6 +31,7 @@ public class PlayerStats { return data.getMMOPlayerData().getStatMap(); } + @Deprecated public StatInstance getInstance(StatType stat) { return getMap().getInstance(stat.name()); } @@ -42,35 +40,26 @@ public class PlayerStats { return getMap().getInstance(stat); } - /** - * Allows for stat type enum to have dynamic professions. - * ID FORMAT: STAT_TYPE_HERE_PROFESSION_HERE - * - * @param type the type of stat - * @param profession the stat's specific permission - * @return instance of found stat - * @author Ehhthan - */ - @NotNull - public StatInstance getInstance(StatType type, @Nullable Profession profession) { - if (profession == null) - return getInstance(type); - else { - String id = (type.name() + '_' + profession.getId()).replace('-', '_').replace(' ', '_').toUpperCase(Locale.ROOT); - return getInstance(id); - } - } - - /* - * applies relative attributes on the base stat too - */ - public double getStat(StatType stat) { + public double getStat(String stat) { return getInstance(stat).getTotal(); } - public double getBase(StatType stat) { - return data.getProfess().calculateStat(stat, - stat.hasProfession() ? data.getCollectionSkills().getLevel(stat.getProfession()) : data.getLevel()); + /** + * MMOCore base stat value differs from the on in MythicLib. + *

+ * MythicLib: the base stat value is only defined for stats + * which are based on vanilla player attributes. It corresponds + * to the stat amount any player has with NO attribute modifier whatsoever. + *

+ * MMOCore: the base stat value corresponds to the stat amount + * the player CLASS grants. It can be similar or equal to the one + * in MMOCore but it really is completely different. + * + * @return MMOCore base stat value + */ + public double getBase(String stat) { + Profession profession = StatInfo.valueOf(stat).profession; + return data.getProfess().calculateStat(stat, profession == null ? data.getLevel() : data.getCollectionSkills().getLevel(profession)); } /** @@ -81,7 +70,7 @@ public class PlayerStats { * see {@link PlayerData#update()} for more info */ public synchronized void updateStats() { - for (StatType stat : StatType.values()) { + for (StatType stat : StatType.values()) { // TODO fix StatInstance instance = getMap().getInstance(stat.name()); StatInstance.ModifierPacket packet = instance.newPacket(); @@ -89,7 +78,7 @@ public class PlayerStats { packet.removeIf(str -> str.equals("mmocoreClass")); // Add newest one - double total = getBase(stat) - instance.getBase(); + double total = getBase(stat.name()) - instance.getBase(); if (total != 0) packet.addModifier(new StatModifier("mmocoreClass", stat.name(), total, ModifierType.FLAT, EquipmentSlot.OTHER, ModifierSource.OTHER)); diff --git a/src/main/java/net/Indyuce/mmocore/api/player/stats/StatType.java b/src/main/java/net/Indyuce/mmocore/api/player/stats/StatType.java index 9f66f9bf..6adbde42 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/stats/StatType.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/stats/StatType.java @@ -1,14 +1,14 @@ package net.Indyuce.mmocore.api.player.stats; -import io.lumine.mythic.lib.MythicLib; -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.ConfigFile; import net.Indyuce.mmocore.api.util.math.formula.LinearValue; import net.Indyuce.mmocore.experience.Profession; -import org.bukkit.configuration.file.FileConfiguration; +import net.Indyuce.mmocore.player.stats.StatInfo; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.text.DecimalFormat; +import java.util.Objects; +@Deprecated public enum StatType { // Vanilla stats @@ -87,17 +87,17 @@ public enum StatType { /** * Reduces amount of tugs needed to fish */ - FISHING_STRENGTH("fishing"), + FISHING_STRENGTH, /** * Chance of instant success when fishing */ - CRITICAL_FISHING_CHANCE("fishing"), + CRITICAL_FISHING_CHANCE, /** * Chance of crit fishing failure */ - CRITICAL_FISHING_FAILURE_CHANCE("fishing"), + CRITICAL_FISHING_FAILURE_CHANCE, /** * Chance of dropping more minerals when mining. @@ -114,49 +114,35 @@ public enum StatType { */ LUCK_OF_THE_FIELD; - private String profession; - - private LinearValue defaultInfo; - private DecimalFormat format; - - StatType() { - // Completely custom stat - } - - @SuppressWarnings("SameParameterValue") - StatType(String profession) { - this.profession = profession; - } - + @Deprecated public String getProfession() { - return profession; + return findProfession().getId(); } + @Deprecated + @Nullable public Profession findProfession() { - return MMOCore.plugin.professionManager.get(profession); + return StatInfo.valueOf(name()).profession; } + @Deprecated public boolean hasProfession() { - return profession != null; + return findProfession() != null; } + @Deprecated + @NotNull public LinearValue getDefault() { - return defaultInfo; + return StatInfo.valueOf(name()).getDefaultFormula(); } + @Deprecated public boolean matches(Profession profession) { - return this.profession != null && this.profession.equals(profession.getId()); + return Objects.equals(findProfession(), profession); } + @Deprecated public String format(double value) { - return format.format(value); - } - - public static void load() { - FileConfiguration config = new ConfigFile("stats").getConfig(); - for (StatType stat : values()) { - stat.defaultInfo = config.contains("default." + stat.name()) ? new LinearValue(config.getConfigurationSection("default." + stat.name())) : new LinearValue(0, 0); - stat.format = MythicLib.plugin.getMMOConfig().newDecimalFormat(config.contains("decimal-format." + stat.name()) ? config.getString("decimal-format." + stat.name()) : "0.#"); - } + return StatInfo.valueOf(name()).format(value); } } diff --git a/src/main/java/net/Indyuce/mmocore/api/util/math/formula/LinearValue.java b/src/main/java/net/Indyuce/mmocore/api/util/math/formula/LinearValue.java index 5bd0d5ef..972bf5b2 100644 --- a/src/main/java/net/Indyuce/mmocore/api/util/math/formula/LinearValue.java +++ b/src/main/java/net/Indyuce/mmocore/api/util/math/formula/LinearValue.java @@ -110,4 +110,16 @@ public class LinearValue { return value; } + + @Override + public String toString() { + return "LinearValue{" + + "base=" + base + + ", perLevel=" + perLevel + + ", min=" + min + + ", max=" + max + + ", hasmin=" + hasmin + + ", hasmax=" + hasmax + + '}'; + } } diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/debug/StatModifiersCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/debug/StatModifiersCommandTreeNode.java index 38de283c..d440e4ee 100644 --- a/src/main/java/net/Indyuce/mmocore/command/rpg/debug/StatModifiersCommandTreeNode.java +++ b/src/main/java/net/Indyuce/mmocore/command/rpg/debug/StatModifiersCommandTreeNode.java @@ -1,11 +1,11 @@ package net.Indyuce.mmocore.command.rpg.debug; +import io.lumine.mythic.lib.UtilityMethods; import io.lumine.mythic.lib.api.stat.StatInstance; import io.lumine.mythic.lib.api.stat.modifier.StatModifier; import io.lumine.mythic.lib.command.api.CommandTreeNode; import io.lumine.mythic.lib.command.api.Parameter; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.player.stats.StatType; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -15,10 +15,7 @@ public class StatModifiersCommandTreeNode extends CommandTreeNode { public StatModifiersCommandTreeNode(CommandTreeNode parent) { super(parent, "statmods"); - addParameter(new Parameter("", (explorer, list) -> { - for (StatType stat : StatType.values()) - list.add(stat.name()); - })); + addParameter(new Parameter("", (explorer, list) -> list.add("STAT_ID"))); } @Override @@ -32,15 +29,7 @@ public class StatModifiersCommandTreeNode extends CommandTreeNode { } PlayerData data = PlayerData.get((Player) sender); - StatType stat; - try { - stat = StatType.valueOf(args[2].toUpperCase().replace("-", "_").replace(" ", "_")); - } catch (IllegalArgumentException exception) { - sender.sendMessage(ChatColor.RED + "Could not find stat: " + args[2] + "."); - return CommandResult.FAILURE; - } - - StatInstance instance = data.getStats().getInstance(stat); + StatInstance instance = data.getStats().getInstance(UtilityMethods.enumName(args[2])); sender.sendMessage("Stat Modifiers (" + instance.getKeys().size() + "):"); for (String key : instance.getKeys()) { StatModifier mod = instance.getModifier(key); diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/debug/StatValueCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/debug/StatValueCommandTreeNode.java index f13d42a4..f582ab31 100644 --- a/src/main/java/net/Indyuce/mmocore/command/rpg/debug/StatValueCommandTreeNode.java +++ b/src/main/java/net/Indyuce/mmocore/command/rpg/debug/StatValueCommandTreeNode.java @@ -1,51 +1,36 @@ package net.Indyuce.mmocore.command.rpg.debug; +import io.lumine.mythic.lib.UtilityMethods; +import io.lumine.mythic.lib.command.api.CommandTreeNode; +import io.lumine.mythic.lib.command.api.Parameter; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.player.stats.StatInfo; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.player.stats.StatType; -import io.lumine.mythic.lib.command.api.CommandTreeNode; -import io.lumine.mythic.lib.command.api.Parameter; - public class StatValueCommandTreeNode extends CommandTreeNode { - public StatValueCommandTreeNode(CommandTreeNode parent) { - super(parent, "statvalue"); + public StatValueCommandTreeNode(CommandTreeNode parent) { + super(parent, "statvalue"); - addParameter(new Parameter("", (explorer, list) -> { - for (StatType stat : StatType.values()) - list.add(stat.name()); - })); - addParameter(new Parameter("(formatted)", (explorer, list) -> list.add("true"))); - } + addParameter(new Parameter("", (explorer, list) -> list.add("STAT_ID"))); + } - @Override - public CommandResult execute(CommandSender sender, String[] args) { - if (args.length < 3) - return CommandResult.THROW_USAGE; + @Override + public CommandResult execute(CommandSender sender, String[] args) { + if (args.length < 3) + return CommandResult.THROW_USAGE; - if (!(sender instanceof Player)) { - sender.sendMessage(ChatColor.RED + "This command can only be used by a player."); - return CommandResult.FAILURE; - } - PlayerData data = PlayerData.get((Player) sender); + if (!(sender instanceof Player)) { + sender.sendMessage(ChatColor.RED + "This command can only be used by a player."); + return CommandResult.FAILURE; + } + PlayerData data = PlayerData.get((Player) sender); - StatType stat; - try { - stat = StatType.valueOf(args[2].toUpperCase().replace("-", "_").replace(" ", "_")); - } catch (IllegalArgumentException exception) { - sender.sendMessage(ChatColor.RED + "Could not find stat: " + args[2] + "."); - return CommandResult.FAILURE; - } + StatInfo stat = StatInfo.valueOf(UtilityMethods.enumName(args[2])); + sender.sendMessage(DebugCommandTreeNode.commandPrefix + "Stat Value (" + ChatColor.BLUE + stat.name + ChatColor.WHITE + "): " + + ChatColor.GREEN + data.getStats().getStat(stat.name)); - if (args.length > 3 && args[3].equals("true")) - sender.sendMessage(DebugCommandTreeNode.commandPrefix + "Stat Value (" + ChatColor.BLUE + stat.name() + ChatColor.WHITE + "): " - + ChatColor.GREEN + stat.format(data.getStats().getStat(stat)) + ChatColor.WHITE + " *"); - else - sender.sendMessage(DebugCommandTreeNode.commandPrefix + "Stat Value (" + ChatColor.BLUE + stat.name() + ChatColor.WHITE + "): " - + ChatColor.GREEN + data.getStats().getStat(stat)); - - return CommandResult.SUCCESS; - } + return CommandResult.SUCCESS; + } } diff --git a/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java b/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java index dd9e3433..795ac3a1 100644 --- a/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java +++ b/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java @@ -5,7 +5,7 @@ import io.lumine.mythic.lib.api.util.AltChar; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.player.stats.StatType; +import net.Indyuce.mmocore.player.stats.StatInfo; import net.Indyuce.mmocore.api.quest.PlayerQuests; import net.Indyuce.mmocore.experience.PlayerProfessions; import net.Indyuce.mmocore.experience.Profession; @@ -72,11 +72,11 @@ public class RPGPlaceholders extends PlaceholderExpansion { } else if (identifier.equals("health") && player.isOnline()) { - return StatType.MAX_HEALTH.format(player.getPlayer().getHealth()); + return StatInfo.valueOf("MAX_HEALTH").format(player.getPlayer().getHealth()); } else if (identifier.equals("max_health") && player.isOnline()) { - return StatType.MAX_HEALTH.format(player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()); + return StatInfo.valueOf("MAX_HEALTH").format(player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()); } else if (identifier.equals("health_bar") && player.isOnline()) { @@ -153,7 +153,7 @@ public class RPGPlaceholders extends PlaceholderExpansion { return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getMana()); else if (identifier.equals("mana_bar")) { - return playerData.getProfess().getManaDisplay().generateBar(playerData.getMana(), playerData.getStats().getStat(StatType.MAX_MANA)); + return playerData.getProfess().getManaDisplay().generateBar(playerData.getMana(), playerData.getStats().getStat("MAX_MANA")); } else if (identifier.startsWith("exp_multiplier_")) { @@ -173,7 +173,7 @@ public class RPGPlaceholders extends PlaceholderExpansion { else if (identifier.equals("stamina_bar")) { StringBuilder format = new StringBuilder(); - double ratio = 20 * playerData.getStamina() / playerData.getStats().getStat(StatType.MAX_STAMINA); + double ratio = 20 * playerData.getStamina() / playerData.getStats().getStat("MAX_STAMINA"); for (double j = 1; j < 20; j++) format.append(ratio >= j ? MMOCore.plugin.configManager.staminaFull : ratio >= j - .5 ? MMOCore.plugin.configManager.staminaHalf : MMOCore.plugin.configManager.staminaEmpty) @@ -182,8 +182,8 @@ public class RPGPlaceholders extends PlaceholderExpansion { } else if (identifier.startsWith("stat_")) { - StatType type = StatType.valueOf(identifier.substring(5).toUpperCase()); - return type == null ? "Invalid Stat" : type.format(playerData.getStats().getStat(type)); + StatInfo info = StatInfo.valueOf(identifier.substring(5).toUpperCase()); + return info.format(playerData.getStats().getStat(info.name)); } else if (identifier.equals("stellium")) @@ -191,7 +191,7 @@ public class RPGPlaceholders extends PlaceholderExpansion { else if (identifier.equals("stellium_bar")) { StringBuilder format = new StringBuilder(); - double ratio = 20 * playerData.getStellium() / playerData.getStats().getStat(StatType.MAX_STELLIUM); + double ratio = 20 * playerData.getStellium() / playerData.getStats().getStat("MAX_STELLIUM"); for (double j = 1; j < 20; j++) format.append(ratio >= j ? ChatColor.BLUE : ratio >= j - .5 ? ChatColor.AQUA : ChatColor.WHITE).append(AltChar.listSquare); return format.toString(); diff --git a/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java b/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java index 2caddb5b..44f3552c 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java +++ b/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java @@ -4,13 +4,13 @@ import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import io.lumine.mythic.lib.MythicLib; +import io.lumine.mythic.lib.UtilityMethods; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.ConfigMessage; import net.Indyuce.mmocore.api.SoundEvent; import net.Indyuce.mmocore.api.event.PlayerExperienceGainEvent; import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect; import org.apache.commons.lang.Validate; @@ -168,7 +168,7 @@ public class PlayerProfessions { value = MMOCore.plugin.boosterManager.calculateExp(profession, value); // Adds functionality for additional experience per profession. - value *= 1 + playerData.getStats().getInstance(StatType.ADDITIONAL_EXPERIENCE, profession).getTotal() / 100; + value *= 1 + playerData.getStats().getInstance("ADDITIONAL_EXPERIENCE_" + UtilityMethods.enumName(profession.getId())).getTotal() / 100; // Display hologram if (hologramLocation != null) diff --git a/src/main/java/net/Indyuce/mmocore/gui/AttributeView.java b/src/main/java/net/Indyuce/mmocore/gui/AttributeView.java index 49e74717..058694a8 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/AttributeView.java +++ b/src/main/java/net/Indyuce/mmocore/gui/AttributeView.java @@ -13,6 +13,7 @@ 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.SoundManager; +import net.Indyuce.mmocore.player.stats.StatInfo; import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.event.inventory.InventoryClickEvent; @@ -66,8 +67,9 @@ public class AttributeView extends EditableInventory { holders.register("current", total); holders.register("attribute_points", inv.getPlayerData().getAttributePoints()); attribute.getBuffs().forEach(buff -> { - holders.register("buff_" + buff.getStat().toLowerCase(), buff.getValue()); - holders.register("total_" + buff.getStat().toLowerCase(), buff.multiply(total).getValue()); + 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; } diff --git a/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java b/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java index 0a870c26..63759744 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java +++ b/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java @@ -1,14 +1,15 @@ package net.Indyuce.mmocore.gui; +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.experience.Booster; -import net.Indyuce.mmocore.experience.Profession; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute; -import net.Indyuce.mmocore.api.player.stats.StatType; +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.gui.api.EditableInventory; import net.Indyuce.mmocore.gui.api.GeneratedInventory; import net.Indyuce.mmocore.gui.api.item.InventoryItem; @@ -18,10 +19,13 @@ import net.Indyuce.mmocore.party.AbstractParty; import org.apache.commons.lang.Validate; import org.bukkit.ChatColor; import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.SkullMeta; +import java.util.Objects; + public class PlayerStats extends EditableInventory { public PlayerStats() { super("player-stats"); @@ -78,7 +82,7 @@ public class PlayerStats extends EditableInventory { Placeholders holders = new Placeholders(); net.Indyuce.mmocore.api.player.stats.PlayerStats stats = inv.getPlayerData().getStats(); - double ratio = (double) inv.getPlayerData().getCollectionSkills().getExperience(profession) + double ratio = inv.getPlayerData().getCollectionSkills().getExperience(profession) / (double) inv.getPlayerData().getCollectionSkills().getLevelUpExperience(profession); String bar = "" + ChatColor.BOLD; @@ -91,9 +95,9 @@ public class PlayerStats extends EditableInventory { holders.register("level", "" + inv.getPlayerData().getCollectionSkills().getLevel(profession)); holders.register("xp", inv.getPlayerData().getCollectionSkills().getExperience(profession)); holders.register("percent", decimal.format(ratio * 100)); - for (StatType stat : StatType.values()) - if (stat.matches(profession)) - holders.register(stat.name().toLowerCase(), stat.format(stats.getStat(stat))); + 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; } @@ -113,21 +117,35 @@ public class PlayerStats extends EditableInventory { @Override public Placeholders getPlaceholders(GeneratedInventory inv, int n) { + return new Placeholders() { + final net.Indyuce.mmocore.api.player.stats.PlayerStats stats = inv.getPlayerData().getStats(); - net.Indyuce.mmocore.api.player.stats.PlayerStats stats = inv.getPlayerData().getStats(); - Placeholders holders = new Placeholders(); + 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; - for (StatType stat : StatType.values()) { - double base = stats.getBase(stat), total = stats.getStat(stat), extra = total - base; - holders.register(stat.name().toLowerCase(), stat.format(total)); - holders.register(stat.name().toLowerCase() + "_base", stat.format(base)); - holders.register(stat.name().toLowerCase() + "_extra", stat.format(extra)); - } + 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)); + } - for (PlayerAttribute attribute : MMOCore.plugin.attributeManager.getAll()) - holders.register("attribute_" + attribute.getId().replace("-", "_"), inv.getPlayerData().getAttributes().getAttribute(attribute)); + str = str.replace("{" + holder + "}", replaced); + } - return holders; + // External placeholders + return MMOCore.plugin.placeholderParser.parse(player, str); + } + }; } }; diff --git a/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java b/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java index fe678f07..50c1405c 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java +++ b/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java @@ -4,7 +4,6 @@ import io.lumine.mythic.lib.version.VersionSound; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.event.CustomPlayerFishEvent; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.experience.EXPSource; import net.Indyuce.mmocore.loot.LootBuilder; @@ -84,7 +83,7 @@ public class FishingListener implements Listener { this.playerData = PlayerData.get(this.player = player); this.hook = hook; - this.fishStrength = (int) Math.floor(caught.rollTugs() * (1 - PlayerData.get(player).getStats().getStat(StatType.FISHING_STRENGTH) / 100)); + this.fishStrength = (int) Math.floor(caught.rollTugs() * (1 - PlayerData.get(player).getStats().getStat("FISHING_STRENGTH") / 100)); this.experienceDropped = caught.rollExperience(); fishing.add(player.getUniqueId()); @@ -148,7 +147,7 @@ public class FishingListener implements Listener { return; } - if (currentPulls == 0 && RANDOM.nextDouble() < PlayerData.get(player).getStats().getStat(StatType.CRITICAL_FISHING_CHANCE) / 100) + if (currentPulls == 0 && RANDOM.nextDouble() < PlayerData.get(player).getStats().getStat("CRITICAL_FISHING_CHANCE") / 100) setCriticalFish(); // Check if enough pulls; if not, wait till the next fish event @@ -165,7 +164,7 @@ public class FishingListener implements Listener { (mainhand != null && mainhand.getType() == Material.FISHING_ROD) ? EquipmentSlot.HAND : EquipmentSlot.OFF_HAND, 1); // Critical fishing failure - if (!isCriticalFish() && RANDOM.nextDouble() < PlayerData.get(player).getStats().getStat(StatType.CRITICAL_FISHING_FAILURE_CHANCE) / 100) { + if (!isCriticalFish() && RANDOM.nextDouble() < PlayerData.get(player).getStats().getStat("CRITICAL_FISHING_FAILURE_CHANCE") / 100) { player.setVelocity(hook.getLocation().subtract(player.getLocation()).toVector().setY(0).multiply(3).setY(.5)); hook.getWorld().spawnParticle(Particle.SMOKE_NORMAL, location, 24, 0, 0, 0, .08); return; diff --git a/src/main/java/net/Indyuce/mmocore/listener/profession/PlayerCollectStats.java b/src/main/java/net/Indyuce/mmocore/listener/profession/PlayerCollectStats.java index ce81b963..795d6ed7 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/profession/PlayerCollectStats.java +++ b/src/main/java/net/Indyuce/mmocore/listener/profession/PlayerCollectStats.java @@ -1,7 +1,8 @@ package net.Indyuce.mmocore.listener.profession; -import java.util.Random; - +import io.lumine.mythic.lib.MythicLib; +import net.Indyuce.mmocore.api.event.CustomBlockMineEvent; +import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect; import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.entity.Player; @@ -11,10 +12,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import net.Indyuce.mmocore.api.event.CustomBlockMineEvent; -import net.Indyuce.mmocore.api.player.stats.StatType; -import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect; -import io.lumine.mythic.lib.MythicLib; +import java.util.Random; public class PlayerCollectStats implements Listener { private static final Random random = new Random(); @@ -23,26 +21,26 @@ public class PlayerCollectStats implements Listener { public void a(CustomBlockMineEvent event) { Player player = event.getPlayer(); - // give haste if right enchant - double h = event.getData().getStats().getStat(StatType.GATHERING_HASTE); + // Give haste if right enchant + double h = event.getData().getStats().getStat("GATHERING_HASTE"); if (h > 0 && random.nextDouble() < h * .045) { new SmallParticleEffect(player, Particle.SPELL_INSTANT); player.removePotionEffect(PotionEffectType.FAST_DIGGING); player.addPotionEffect(new PotionEffect(PotionEffectType.FAST_DIGGING, (int) (10 * h), (int) (1 + h / 7))); } - // drop more items if fortune enchant - double f = event.getData().getStats().getStat(StatType.FORTUNE); + // Drop more items if fortune enchant + double f = event.getData().getStats().getStat("FORTUNE"); if (f > 0 && random.nextDouble() < f * .045) { int a = (int) (1.5 * Math.sqrt(f / 1.1)); for (ItemStack item : event.getDrops()) item.setAmount(item.getAmount() + a); } - if(MythicLib.plugin.getVersion().getWrapper().isCropFullyGrown(event.getBlock())) - { - // drop more items if fortune enchant - double l = event.getData().getStats().getStat(StatType.LUCK_OF_THE_FIELD); + if (MythicLib.plugin.getVersion().getWrapper().isCropFullyGrown(event.getBlock())) { + + // Drop more CROP items + double l = event.getData().getStats().getStat("LUCK_OF_THE_FIELD"); if (l > 0 && random.nextDouble() < l * .045) { int a = (int) (1.5 * Math.sqrt(l / 1.1)); Location loc = event.getBlock().getLocation().add(.5, .1, .5); diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java index 6f455b3e..8b39522e 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java @@ -4,7 +4,6 @@ import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.event.LootChestSpawnEvent; import net.Indyuce.mmocore.api.player.PlayerActivity; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.loot.LootBuilder; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; @@ -125,7 +124,7 @@ public class LootChestRegion { */ @NotNull public ChestTier rollTier(PlayerData player) { - double chance = player.getStats().getStat(StatType.CHANCE) * MMOCore.plugin.configManager.lootChestsChanceWeight; + double chance = player.getStats().getStat("CHANCE") * MMOCore.plugin.configManager.lootChestsChanceWeight; double sum = 0; for (ChestTier tier : tiers) diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropItem.java b/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropItem.java index 143ebbca..8febb7bb 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropItem.java +++ b/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropItem.java @@ -3,7 +3,6 @@ package net.Indyuce.mmocore.loot.droptable.dropitem; import java.util.Random; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.loot.LootBuilder; import net.Indyuce.mmocore.api.util.math.formula.RandomAmount; import io.lumine.mythic.lib.api.MMOLineConfig; @@ -40,7 +39,7 @@ public abstract class DropItem { * If the player chance is 0 the random value will remain the same. When he get lucks the chance gets closer to one. */ public boolean rollChance(PlayerData player) { - return Math.pow(random.nextDouble(), 1 / Math.log(1 + player.getStats().getStat(StatType.CHANCE))) < chance; + return Math.pow(random.nextDouble(), 1 / Math.log(1 + player.getStats().getStat("CHANCE"))) < chance; } public abstract void collect(LootBuilder builder); diff --git a/src/main/java/net/Indyuce/mmocore/manager/StatManager.java b/src/main/java/net/Indyuce/mmocore/manager/StatManager.java new file mode 100644 index 00000000..ee23b9d6 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/manager/StatManager.java @@ -0,0 +1,71 @@ +package net.Indyuce.mmocore.manager; + +import io.lumine.mythic.lib.MythicLib; +import net.Indyuce.mmocore.api.ConfigFile; +import net.Indyuce.mmocore.player.stats.StatInfo; +import net.Indyuce.mmocore.api.util.math.formula.LinearValue; +import net.Indyuce.mmocore.experience.Profession; +import org.bukkit.configuration.file.FileConfiguration; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.text.DecimalFormat; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +public class StatManager implements MMOCoreManager { + private final Map loaded = new HashMap<>(); + + @Override + public void initialize(boolean clearBefore) { + if (clearBefore) + loaded.clear(); + + FileConfiguration config = new ConfigFile("stats").getConfig(); + + // Read decimal formats + for (String key : config.getConfigurationSection("decimal-format").getKeys(false)) + registerDecimalFormat(key, MythicLib.plugin.getMMOConfig().newDecimalFormat(config.getString("decimal-format." + key))); + + // Read default formulas + for (String key : config.getConfigurationSection("default").getKeys(false)) + registerDefaultFormula(key, new LinearValue(config.getConfigurationSection("default." + key))); + } + + public Collection getLoaded() { + return loaded.values(); + } + + @Nullable + public StatInfo getInfo(String stat) { + return loaded.get(stat); + } + + public void registerProfession(String stat, Profession profession) { + compute(stat).profession = profession; + } + + public void registerDefaultFormula(String stat, LinearValue defaultFormula) { + compute(stat).defaultInfo = defaultFormula; + } + + public void registerDecimalFormat(String stat, DecimalFormat format) { + compute(stat).format = format; + } + + /** + * @return A stat info for the specified stat. If it doesn't + * exist when method is called, it is registered into the map + */ + @NotNull + private StatInfo compute(String stat) { + StatInfo found = loaded.get(stat); + if (found != null) + return found; + + StatInfo newInfo = new StatInfo(stat); + loaded.put(stat, newInfo); + return newInfo; + } +} diff --git a/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLPlayerDataManager.java b/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLPlayerDataManager.java index df083d7a..66d5ed47 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLPlayerDataManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLPlayerDataManager.java @@ -9,7 +9,6 @@ import net.Indyuce.mmocore.api.player.OfflinePlayerData; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.profess.PlayerClass; import net.Indyuce.mmocore.api.player.profess.SavedClassInformation; -import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.guild.provided.Guild; import net.Indyuce.mmocore.manager.data.PlayerDataManager; import net.Indyuce.mmocore.manager.data.mysql.MySQLTableEditor.Table; @@ -35,6 +34,13 @@ public class MySQLPlayerDataManager extends PlayerDataManager { try { MMOCore.sqlDebug("Loading data for: '" + data.getUniqueId() + "'..."); + // Initialize custom resources + if (!data.hasUsedTemporaryData()) { + data.setMana(data.getStats().getStat("MAX_MANA")); + data.setStamina(data.getStats().getStat("MAX_STAMINA")); + data.setStellium(data.getStats().getStat("MAX_STELLIUM")); + } + if (!result.next()) { data.setLevel(getDefaultData().getLevel()); data.setClassPoints(getDefaultData().getClassPoints()); @@ -44,12 +50,6 @@ public class MySQLPlayerDataManager extends PlayerDataManager { data.setExperience(0); data.getQuestData().updateBossBar(); - if (!data.hasUsedTemporaryData()) { - data.setMana(data.getStats().getStat(StatType.MAX_MANA)); - data.setStamina(data.getStats().getStat(StatType.MAX_STAMINA)); - data.setStellium(data.getStats().getStat(StatType.MAX_STELLIUM)); - } - data.setFullyLoaded(); MMOCore.sqlDebug("Loaded DEFAULT data for: '" + data.getUniqueId() + "' as no saved data was found."); return; @@ -69,12 +69,6 @@ public class MySQLPlayerDataManager extends PlayerDataManager { json.entrySet().forEach(entry -> data.getItemClaims().put(entry.getKey(), entry.getValue().getAsInt())); } - if (!data.hasUsedTemporaryData()) { - data.setMana(data.getStats().getStat(StatType.MAX_MANA)); - data.setStamina(data.getStats().getStat(StatType.MAX_STAMINA)); - data.setStellium(data.getStats().getStat(StatType.MAX_STELLIUM)); - } - if (!isEmpty(result.getString("guild"))) { Guild guild = provider.getGuildManager().getGuild(result.getString("guild")); data.setGuild(guild.getMembers().has(data.getUniqueId()) ? guild : null); diff --git a/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLPlayerDataManager.java b/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLPlayerDataManager.java index 7efe48fa..e8eaa739 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLPlayerDataManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLPlayerDataManager.java @@ -6,7 +6,6 @@ import net.Indyuce.mmocore.api.player.OfflinePlayerData; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.profess.PlayerClass; import net.Indyuce.mmocore.api.player.profess.SavedClassInformation; -import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.guild.provided.Guild; import net.Indyuce.mmocore.manager.data.DataProvider; import net.Indyuce.mmocore.manager.data.PlayerDataManager; @@ -41,9 +40,9 @@ public class YAMLPlayerDataManager extends PlayerDataManager { data.setClass(MMOCore.plugin.classManager.get(config.getString("class"))); if (!data.hasUsedTemporaryData()) { - data.setMana(data.getStats().getStat(StatType.MAX_MANA)); - data.setStamina(data.getStats().getStat(StatType.MAX_STAMINA)); - data.setStellium(data.getStats().getStat(StatType.MAX_STELLIUM)); + data.setMana(data.getStats().getStat("MAX_MANA")); + data.setStamina(data.getStats().getStat("MAX_STAMINA")); + data.setStellium(data.getStats().getStat("MAX_STELLIUM")); } if (config.contains("guild")) { diff --git a/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java b/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java index 93a5a73f..e794c9e3 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java @@ -3,7 +3,6 @@ package net.Indyuce.mmocore.manager.profession; import io.lumine.mythic.lib.api.MMOLineConfig; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.loot.chest.condition.Condition; import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance; import net.Indyuce.mmocore.loot.droptable.dropitem.fishing.FishingDropItem; @@ -31,6 +30,11 @@ public class FishingManager extends SpecificProfessionManager { } catch (IllegalArgumentException exception) { MMOCore.log(Level.WARNING, "Could not load fishing drop table " + key + ": " + exception.getMessage()); } + + // Link fishing stats to this profession + MMOCore.plugin.statManager.registerProfession("FISHING_STRENGTH", getLinkedProfession()); + MMOCore.plugin.statManager.registerProfession("CRITICAL_FISHING_CHANCE", getLinkedProfession()); + MMOCore.plugin.statManager.registerProfession("CRITICAL_FISHING_FAILURE_CHANCE", getLinkedProfession()); } public FishingDropTable calculateDropTable(Entity entity) { @@ -46,7 +50,6 @@ public class FishingManager extends SpecificProfessionManager { public static class FishingDropTable { private final Set conditions = new HashSet<>(); private final List items = new ArrayList<>(); - private double maxWeight = 0; public FishingDropTable(ConfigurationSection section) { Validate.notNull(section, "Could not load config"); @@ -72,7 +75,6 @@ public class FishingManager extends SpecificProfessionManager { try { FishingDropItem dropItem = new FishingDropItem(new MMOLineConfig(str)); items.add(dropItem); - maxWeight += dropItem.getItem().getWeight(); } catch (RuntimeException exception) { MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load item '" + str + "' from fishing drop table '" + id + "': " + exception.getMessage()); @@ -93,11 +95,13 @@ public class FishingManager extends SpecificProfessionManager { } /** - * The Fishing Drop Item is calculated randomly bu the chance stat will make - * low weight items more likely to be caught. + * The chance stat will make low weight items more + * likely to be chosen by the algorithm + * + * @return Randomly computed fishing drop item */ public FishingDropItem getRandomItem(PlayerData player) { - double chance = player.getStats().getStat(StatType.CHANCE); + double chance = player.getStats().getStat("CHANCE"); //chance=0 ->the tier.chance remains the same //chance ->+inf -> the tier.chance becomes the same for everyone, uniform law diff --git a/src/main/java/net/Indyuce/mmocore/manager/social/PartyManager.java b/src/main/java/net/Indyuce/mmocore/manager/social/PartyManager.java index be3c8358..b6a1f7f0 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/social/PartyManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/social/PartyManager.java @@ -1,8 +1,8 @@ package net.Indyuce.mmocore.manager.social; +import io.lumine.mythic.lib.UtilityMethods; import io.lumine.mythic.lib.api.stat.modifier.StatModifier; import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.manager.MMOCoreManager; import org.bukkit.configuration.ConfigurationSection; @@ -26,8 +26,7 @@ public class PartyManager implements MMOCoreManager { if (config != null) for (String key : config.getKeys(false)) try { - StatType stat = StatType.valueOf(key.toUpperCase().replace("-", "_").replace(" ", "_")); - buffs.add(new StatModifier("mmocoreParty", stat.name(), config.getString(key))); + buffs.add(new StatModifier("mmocoreParty", UtilityMethods.enumName(key), config.getString(key))); } catch (IllegalArgumentException exception) { MMOCore.log(Level.WARNING, "Could not load party buff '" + key + "': " + exception.getMessage()); } diff --git a/src/main/java/net/Indyuce/mmocore/player/stats/StatInfo.java b/src/main/java/net/Indyuce/mmocore/player/stats/StatInfo.java new file mode 100644 index 00000000..078b4af7 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/player/stats/StatInfo.java @@ -0,0 +1,71 @@ +package net.Indyuce.mmocore.player.stats; + +import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.util.math.formula.LinearValue; +import net.Indyuce.mmocore.experience.Profession; +import org.jetbrains.annotations.NotNull; + +import java.text.DecimalFormat; +import java.util.Objects; + +/** + * @author Jules + * @impl MMOCore used to have a giant enum of all the stat types + * which is now incompatible with MythicLib because the MMO plugins + * now have completely OPEN to edition numeric stat registries + */ +public class StatInfo { + public final String name; + + /** + * Profession linked to that stat. Stats which have a profession linked to + * them do NOT scale on the main player level but rather on that specific + * profession level + */ + public Profession profession; + + /** + * Default formula for the stat + */ + public LinearValue defaultInfo; + + /** + * How that stat displays anywhere in GUIs + */ + public DecimalFormat format; + + private static final DecimalFormat DEFAULT_DECIMAL_FORMAT = new DecimalFormat("0.#"); + + public StatInfo(String name) { + this.name = name; + } + + @NotNull + public String format(double d) { + return (format == null ? DEFAULT_DECIMAL_FORMAT : format).format(d); + } + + @NotNull + public LinearValue getDefaultFormula() { + return defaultInfo == null ? LinearValue.ZERO : defaultInfo; + } + + @NotNull + public static StatInfo valueOf(String str) { + StatInfo found = MMOCore.plugin.statManager.getInfo(str); + return found == null ? new StatInfo(str) : found; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + StatInfo statInfo = (StatInfo) o; + return name.equals(statInfo.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } +} From 73fbb5844d2c85e2de163fd396963a28f2185341 Mon Sep 17 00:00:00 2001 From: Indyuce Date: Wed, 1 Jun 2022 23:00:49 +0200 Subject: [PATCH 33/39] Push or Ill kill your family --- .../Indyuce/mmocore/waypoint/Waypoint.java | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java index 7391f8a5..93bee8ae 100644 --- a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java +++ b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java @@ -30,13 +30,13 @@ public class Waypoint extends PostLoadObject implements Unlockable { *

* If it's empty it can access any waypoint. */ - private final Map destinations = new HashMap<>(); + private final Map destinations = new HashMap<>(); /** * Waypoint options saved here. */ private final Map options = new HashMap<>(); - private final double dynamicCost, setSpawnCost; + private final double dynamicCost, setSpawnCost, normalCost; private final List dynamicUseConditions = new ArrayList<>(); public Waypoint(ConfigurationSection config) { @@ -50,6 +50,7 @@ public class Waypoint extends PostLoadObject implements Unlockable { radiusSquared = Math.pow(config.getDouble("radius"), 2); dynamicCost = config.getDouble("cost.dynamic-use"); + normalCost = config.getDouble("cost.normal-use"); setSpawnCost = config.getDouble("cost.set-spawnpoint"); for (WaypointOption option : WaypointOption.values()) @@ -66,6 +67,7 @@ public class Waypoint extends PostLoadObject implements Unlockable { } } + @Override protected void whenPostLoaded(@NotNull ConfigurationSection config) { @@ -73,7 +75,7 @@ public class Waypoint extends PostLoadObject implements Unlockable { if (config.contains("linked")) { ConfigurationSection section = config.getConfigurationSection("linked"); for (String key : section.getKeys(false)) - destinations.put(MMOCore.plugin.waypointManager.get(key), section.getInt(key)); + destinations.put(MMOCore.plugin.waypointManager.get(key), section.getDouble(key)); } } @@ -93,19 +95,11 @@ public class Waypoint extends PostLoadObject implements Unlockable { return loc; } - /** - * @param other Another waypoint - * @return If any player standing on that waypoint can teleport to given waypoint - */ - @Deprecated - public boolean hasDestination(Waypoint other) { - return destinations.isEmpty() || destinations.containsKey(other); - } - public double getDynamicCost() { return dynamicCost; } + @Deprecated public double getSetSpawnCost() { return setSpawnCost; } @@ -125,8 +119,8 @@ public class Waypoint extends PostLoadObject implements Unlockable { * @return Integer.POSITIVE_INFINITY if the way point is not linked * If it is, cost of the instant travel between the two waypoints. */ - public int getDirectCost(Waypoint waypoint) { - return destinations.getOrDefault(waypoint, Integer.MAX_VALUE); + public double getDirectCost(Waypoint waypoint) { + return destinations.isEmpty() ? normalCost : destinations.getOrDefault(waypoint, Double.POSITIVE_INFINITY); } public List getAllPath() { From 560a2def41ddbef368911747d21af08ed4b7ac6e Mon Sep 17 00:00:00 2001 From: Indyuce Date: Sat, 4 Jun 2022 12:08:50 +0200 Subject: [PATCH 34/39] Fixed an issue with paper having durability, like wth spigot --- src/main/java/net/Indyuce/mmocore/api/util/MMOCoreUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 b15bb60a..64a5744a 100644 --- a/src/main/java/net/Indyuce/mmocore/api/util/MMOCoreUtils.java +++ b/src/main/java/net/Indyuce/mmocore/api/util/MMOCoreUtils.java @@ -196,7 +196,7 @@ public class MMOCoreUtils { */ public static void decreaseDurability(Player player, EquipmentSlot slot, int damage) { ItemStack item = player.getInventory().getItem(slot); - if (!item.hasItemMeta() || !(item.getItemMeta() instanceof Damageable) || item.getItemMeta().isUnbreakable()) + if (item == null || item.getType().getMaxDurability() == 0 || !item.hasItemMeta() || !(item.getItemMeta() instanceof Damageable) || item.getItemMeta().isUnbreakable()) return; PlayerItemDamageEvent event = new PlayerItemDamageEvent(player, item, damage); From 9a08c142fbf7f8fae145dc97b2d630bfe05c096f Mon Sep 17 00:00:00 2001 From: Indyuce Date: Sat, 4 Jun 2022 12:10:01 +0200 Subject: [PATCH 35/39] Cleanup --- .../java/net/Indyuce/mmocore/MMOCore.java | 4 +- .../source/MineBlockExperienceSource.java | 2 +- .../source/MoveExperienceSource.java | 38 ++++++++----------- .../source/PlayExperienceSource.java | 16 ++------ .../source/ProjectileExperienceSource.java | 14 +++---- .../source/ResourceExperienceSource.java | 1 - .../source/TameExperienceSource.java | 3 +- ...ion.java => MMOCoreTargetRestriction.java} | 3 +- .../mmocore/party/PartyModuleType.java | 7 +++- src/main/resources/config.yml | 3 +- 10 files changed, 38 insertions(+), 53 deletions(-) rename src/main/java/net/Indyuce/mmocore/party/{PartyMemberTargetRestriction.java => MMOCoreTargetRestriction.java} (88%) diff --git a/src/main/java/net/Indyuce/mmocore/MMOCore.java b/src/main/java/net/Indyuce/mmocore/MMOCore.java index 04096c71..622b56a8 100644 --- a/src/main/java/net/Indyuce/mmocore/MMOCore.java +++ b/src/main/java/net/Indyuce/mmocore/MMOCore.java @@ -39,7 +39,7 @@ import net.Indyuce.mmocore.manager.profession.*; import net.Indyuce.mmocore.manager.social.BoosterManager; import net.Indyuce.mmocore.manager.social.PartyManager; import net.Indyuce.mmocore.manager.social.RequestManager; -import net.Indyuce.mmocore.party.PartyMemberTargetRestriction; +import net.Indyuce.mmocore.party.MMOCoreTargetRestriction; import net.Indyuce.mmocore.party.PartyModule; import net.Indyuce.mmocore.party.PartyModuleType; import net.Indyuce.mmocore.party.provided.MMOCorePartyModule; @@ -116,7 +116,7 @@ public class MMOCore extends LuminePlugin { } // Register MMOCore-specific objects - MythicLib.plugin.getEntities().registerRestriction(new PartyMemberTargetRestriction()); + MythicLib.plugin.getEntities().registerRestriction(new MMOCoreTargetRestriction()); MythicLib.plugin.getModifiers().registerModifierType("attribute", configObject -> new AttributeModifier(configObject)); // Register extra objective, drop items... diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/MineBlockExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/MineBlockExperienceSource.java index 4eef178f..fcc457a4 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/MineBlockExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/MineBlockExperienceSource.java @@ -15,7 +15,7 @@ import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.inventory.ItemStack; public class MineBlockExperienceSource extends SpecificExperienceSource { - public final Material material; + private final Material material; private final boolean silkTouch; private final boolean crop; diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/MoveExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/MoveExperienceSource.java index 6af6bf03..66ae8959 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/MoveExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/MoveExperienceSource.java @@ -1,18 +1,14 @@ package net.Indyuce.mmocore.experience.source; -import com.mojang.datafixers.types.Func; import io.lumine.mythic.lib.api.MMOLineConfig; -import io.lumine.mythic.lib.damage.DamageType; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; import org.apache.commons.lang.Validate; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerMoveEvent; -import org.xml.sax.SAXParseException; import java.util.Arrays; import java.util.Objects; @@ -20,9 +16,7 @@ import java.util.function.Function; import java.util.stream.Collectors; public class MoveExperienceSource extends SpecificExperienceSource { - MovingType type; - - + private final MovingType type; public MoveExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { super(dispenser, config); @@ -42,18 +36,18 @@ public class MoveExperienceSource extends SpecificExperienceSource { return new ExperienceSourceManager() { @EventHandler public void onMove(PlayerMoveEvent e) { - double deltax=e.getTo().getBlockX()-e.getFrom().getBlockX(); - double deltay=e.getTo().getBlockY()-e.getFrom().getBlockY(); - double deltaz=e.getTo().getBlockZ()-e.getFrom().getBlockZ(); - if(deltax!=0&&deltay!=0&&deltaz!=0) { - double delta=Math.sqrt(deltax*deltax+deltay*deltay+deltaz*deltaz); - if(e.getPlayer().hasMetadata("NPC")) + double deltax = e.getTo().getBlockX() - e.getFrom().getBlockX(); + double deltay = e.getTo().getBlockY() - e.getFrom().getBlockY(); + double deltaz = e.getTo().getBlockZ() - e.getFrom().getBlockZ(); + if (deltax != 0 && deltay != 0 && deltaz != 0) { + double delta = Math.sqrt(deltax * deltax + deltay * deltay + deltaz * deltaz); + if (e.getPlayer().hasMetadata("NPC")) return; - Player player=e.getPlayer(); - PlayerData playerData =PlayerData.get(player); - for(MoveExperienceSource source:getSources()) { - if(source.matchesParameter(playerData,null)) { - giveExperience(playerData,delta,null); + Player player = e.getPlayer(); + PlayerData playerData = PlayerData.get(player); + for (MoveExperienceSource source : getSources()) { + if (source.matchesParameter(playerData, null)) { + giveExperience(playerData, delta, null); } } } @@ -63,13 +57,13 @@ public class MoveExperienceSource extends SpecificExperienceSource { @Override public boolean matchesParameter(PlayerData player, Object obj) { - return type==null||type.matches(player.getPlayer()); + return type == null || type.matches(player.getPlayer()); } public enum MovingType { SNEAK(Player::isSneaking), - FLY((p)->p.isFlying()||p.isGliding()), - SWIM((p)->p.getLocation().getBlock().isLiquid()), + FLY((p) -> p.isFlying() || p.isGliding()), + SWIM((p) -> p.getLocation().getBlock().isLiquid()), SPRINT(Player::isSprinting), WALK((p) -> !p.isSneaking() && !p.isSprinting() && !p.isFlying() && !p.getLocation().getBlock().isLiquid()); @@ -80,7 +74,7 @@ public class MoveExperienceSource extends SpecificExperienceSource { } public boolean matches(Player player) { - return !player.isInsideVehicle()&&matching.apply(player); + return !player.isInsideVehicle() && matching.apply(player); } } diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/PlayExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/PlayExperienceSource.java index d95e6a7b..b2f49d62 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/PlayExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/PlayExperienceSource.java @@ -6,12 +6,13 @@ import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; -import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.scheduler.BukkitRunnable; +import java.util.Objects; + public class PlayExperienceSource extends SpecificExperienceSource { private final World world; @@ -25,18 +26,9 @@ public class PlayExperienceSource extends SpecificExperienceSource { */ public PlayExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { super(dispenser, config); - if (!config.contains("in-combat")) - inCombat = false; - else { - inCombat = config.getBoolean("in-combat"); - } - if (!config.contains("world")) - world = null; - else { - String name = config.getString("world"); - Validate.notNull(world = Bukkit.getWorld(name), "Could not find world " + config.getString("world")); - } + inCombat = config.getBoolean("in-combat", false); + world = config.contains("world") ? Objects.requireNonNull(Bukkit.getWorld(config.getString("world")), "Could not find world " + config.getString("world")) : null; if (!config.contains("x1") || !config.contains("x2")) { x1 = Double.NEGATIVE_INFINITY; x2 = Double.POSITIVE_INFINITY; diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java index 49647b70..c3ac3578 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java @@ -1,18 +1,17 @@ package net.Indyuce.mmocore.experience.source; -import de.schlichtherle.key.passwd.swing.BasicUnknownKeyFeedback; -import io.lumine.mythic.core.skills.mechanics.ShootMechanic; import io.lumine.mythic.lib.api.MMOLineConfig; -import me.glaremasters.guilds.utils.BackupUtils; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; import org.apache.commons.lang.Validate; -import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.entity.*; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.Trident; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.ProjectileHitEvent; @@ -21,13 +20,10 @@ import org.bukkit.scheduler.BukkitRunnable; import java.util.Arrays; import java.util.HashMap; -import java.util.HashSet; -import java.util.Locale; import java.util.function.Function; import java.util.stream.Collectors; public class ProjectileExperienceSource extends SpecificExperienceSource { - private final ProjectileType projectileType; public ProjectileExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { @@ -59,7 +55,7 @@ public class ProjectileExperienceSource extends SpecificExperienceSource { private final PlayerResource resource; - /** * Gives experience when the player uses a specific resoure. If no resource is precised it will trigger for * mana, stamina and stellium. The amount specified si the xp given per resource consummed. diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/TameExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/TameExperienceSource.java index af7a22a4..83a455c6 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/TameExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/TameExperienceSource.java @@ -13,8 +13,6 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.entity.EntityDamageByEntityEvent; public class TameExperienceSource extends SpecificExperienceSource { - - public TameExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { super(dispenser, config); } @@ -22,6 +20,7 @@ public class TameExperienceSource extends SpecificExperienceSource { @Override public ExperienceSourceManager newManager() { return new ExperienceSourceManager() { + @EventHandler public void onWolfHit(EntityDamageByEntityEvent e) { if(e.getDamager() instanceof Wolf) { diff --git a/src/main/java/net/Indyuce/mmocore/party/PartyMemberTargetRestriction.java b/src/main/java/net/Indyuce/mmocore/party/MMOCoreTargetRestriction.java similarity index 88% rename from src/main/java/net/Indyuce/mmocore/party/PartyMemberTargetRestriction.java rename to src/main/java/net/Indyuce/mmocore/party/MMOCoreTargetRestriction.java index d2a6989f..e3603461 100644 --- a/src/main/java/net/Indyuce/mmocore/party/PartyMemberTargetRestriction.java +++ b/src/main/java/net/Indyuce/mmocore/party/MMOCoreTargetRestriction.java @@ -7,7 +7,7 @@ import net.Indyuce.mmocore.api.player.PlayerData; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; -public class PartyMemberTargetRestriction implements TargetRestriction { +public class MMOCoreTargetRestriction implements TargetRestriction { @Override public boolean canTarget(Player player, LivingEntity livingEntity, InteractionType interactionType) { @@ -15,6 +15,7 @@ public class PartyMemberTargetRestriction implements TargetRestriction { return true; AbstractParty party = MMOCore.plugin.partyModule.getParty(PlayerData.get(player)); + // TODO check for guild return party == null || !party.hasMember((Player) livingEntity); } } diff --git a/src/main/java/net/Indyuce/mmocore/party/PartyModuleType.java b/src/main/java/net/Indyuce/mmocore/party/PartyModuleType.java index f6b0370a..8a031652 100644 --- a/src/main/java/net/Indyuce/mmocore/party/PartyModuleType.java +++ b/src/main/java/net/Indyuce/mmocore/party/PartyModuleType.java @@ -1,13 +1,16 @@ package net.Indyuce.mmocore.party; -import net.Indyuce.mmocore.party.compat.*; +import net.Indyuce.mmocore.party.compat.DungeonsXLPartyModule; +import net.Indyuce.mmocore.party.compat.McMMOPartyModule; +import net.Indyuce.mmocore.party.compat.PAFPartyModule; +import net.Indyuce.mmocore.party.compat.PartiesPartyModule; import net.Indyuce.mmocore.party.provided.MMOCorePartyModule; import org.bukkit.Bukkit; import javax.inject.Provider; public enum PartyModuleType { - DUNGEONS("Dungeons", DungeonsPartyModule::new), + // DUNGEONS("Dungeons", DungeonsPartyModule::new), DUNGEONSXL("DungeonsXL", DungeonsXLPartyModule::new), MCMMO("mcMMO", McMMOPartyModule::new), MMOCORE("MMOCore", MMOCorePartyModule::new), diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 0ccdbde5..db45266d 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -55,7 +55,8 @@ protect-custom-mine: false # - mmocore # - dungeonsxl # - parties -# - parties_and_friends +# - party_and_friends +# - mcmmo party-plugin: mmocore ## Edit the plugin handling parties here. From 0ae7c3613d830874a699c8e7d0fe16a96e73f935 Mon Sep 17 00:00:00 2001 From: Indyuce Date: Sat, 4 Jun 2022 12:17:33 +0200 Subject: [PATCH 36/39] Fixed an error when setting exp to 0 --- .../mmocore/command/rpg/admin/ExperienceCommandTreeNode.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ExperienceCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ExperienceCommandTreeNode.java index b556d3d7..5c4b7664 100644 --- a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ExperienceCommandTreeNode.java +++ b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ExperienceCommandTreeNode.java @@ -58,8 +58,8 @@ public class ExperienceCommandTreeNode extends CommandTreeNode { int amount; try { amount = Integer.parseInt(args[5]); - Validate.isTrue(amount > 0); - } catch (NumberFormatException exception) { + Validate.isTrue(amount >= 0); + } catch (RuntimeException exception) { sender.sendMessage(ChatColor.RED + args[5] + " is not a valid number."); return CommandResult.FAILURE; } From a0685334e1df541720fc11d4ba075930399c3854 Mon Sep 17 00:00:00 2001 From: Indyuce Date: Sat, 4 Jun 2022 12:20:08 +0200 Subject: [PATCH 37/39] Fixed an issue with enchant plugins + enchant exp source --- .../manager/profession/EnchantManager.java | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/main/java/net/Indyuce/mmocore/manager/profession/EnchantManager.java b/src/main/java/net/Indyuce/mmocore/manager/profession/EnchantManager.java index 592d69f4..25b3605f 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/profession/EnchantManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/profession/EnchantManager.java @@ -4,17 +4,19 @@ import io.lumine.mythic.lib.MythicLib; import net.Indyuce.mmocore.MMOCore; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.enchantments.Enchantment; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; public class EnchantManager extends SpecificProfessionManager { - private final Map base = new HashMap<>(); + private final Map base = new HashMap<>(); - public EnchantManager() { - super("base-enchant-exp"); - } + public EnchantManager() { + super("base-enchant-exp"); + } @Override public void loadProfessionConfiguration(ConfigurationSection config) { @@ -27,17 +29,20 @@ public class EnchantManager extends SpecificProfessionManager { } } - public void registerBaseExperience(Enchantment enchant, double value) { - base.put(enchant, value); - } + public void registerBaseExperience(Enchantment enchant, double value) { + base.put(enchant, value); + } - public double getBaseExperience(Enchantment enchant) { - return base.get(enchant); - } + @NotNull + public double getBaseExperience(Enchantment enchant) { + // Can be null if argument passed is an enchant with no config attached to it + @Nullable Double found = base.get(enchant); + return found == null ? 0 : found; + } - @Override - public void initialize(boolean clearBefore) { - if (clearBefore) - base.clear(); - } + @Override + public void initialize(boolean clearBefore) { + if (clearBefore) + base.clear(); + } } From 39486771b1ecaf6d5aeea3a4ad464bddb7ace197 Mon Sep 17 00:00:00 2001 From: Indyuce Date: Sat, 4 Jun 2022 12:38:27 +0200 Subject: [PATCH 38/39] Added NONE skill casting mode --- .../mmocore/skill/cast/SkillCastingMode.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingMode.java b/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingMode.java index 49c85ade..ebc82f10 100644 --- a/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingMode.java +++ b/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingMode.java @@ -19,17 +19,27 @@ public enum SkillCastingMode { SKILL_BAR(config -> new SkillBar(config)), /** - * + * When entering casting mode you can use the mouse scroller + * to navigate through the entire castable skill list. Then press + * one key to cast the one selected. */ SKILL_SCROLL(config -> new SkillScroller(config)), /** * Initialize your skill combo by pressing some key. *

- * Then press a certain amount of keys to + * Then press a certain key combo. The config can be used + * to map key combos to skill bind slots, for instance LLR + * would cast the 2nd skill but LRL the 3rd one. */ KEY_COMBOS(config -> new KeyCombos(config)), + /** + * Entirely disables skill casting. + */ + NONE(config -> new Listener() { + }); + /** * Not implemented yet. *

From 617c2a3713ff7937a7b40c564f4d34578fcdbace Mon Sep 17 00:00:00 2001 From: Indyuce Date: Sun, 5 Jun 2022 16:32:08 +0200 Subject: [PATCH 39/39] p.u.s.h --- src/main/java/net/Indyuce/mmocore/MMOCore.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/net/Indyuce/mmocore/MMOCore.java b/src/main/java/net/Indyuce/mmocore/MMOCore.java index 622b56a8..3af53024 100644 --- a/src/main/java/net/Indyuce/mmocore/MMOCore.java +++ b/src/main/java/net/Indyuce/mmocore/MMOCore.java @@ -119,6 +119,7 @@ public class MMOCore extends LuminePlugin { MythicLib.plugin.getEntities().registerRestriction(new MMOCoreTargetRestriction()); MythicLib.plugin.getModifiers().registerModifierType("attribute", configObject -> new AttributeModifier(configObject)); + // Register extra objective, drop items... if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null) loadManager.registerLoader(new WorldGuardMMOLoader());