From 2708dd2072d42e6c1275fff91868b6e7c3e2613e Mon Sep 17 00:00:00 2001 From: Jules Date: Mon, 26 Jun 2023 22:54:03 +0200 Subject: [PATCH] Fixed killmob not giving exp with flame & fire aspect --- .../source/KillMobExperienceSource.java | 44 ++++++++++++++----- .../mmocore/manager/ExperienceManager.java | 11 ++--- .../profession/ExperienceSourceManager.java | 19 +++++++- 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/source/KillMobExperienceSource.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/source/KillMobExperienceSource.java index 70b29076..7a72c5b8 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/source/KillMobExperienceSource.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/source/KillMobExperienceSource.java @@ -2,7 +2,8 @@ package net.Indyuce.mmocore.experience.source; import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.api.MMOLineConfig; -import io.lumine.mythic.lib.api.event.PlayerKillEntityEvent; +import io.lumine.mythic.lib.api.event.PlayerAttackEvent; +import io.lumine.mythic.lib.util.FlushableRegistry; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.util.MMOCoreUtils; @@ -15,9 +16,11 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.persistence.PersistentDataType; import javax.annotation.Nullable; +import java.util.UUID; public class KillMobExperienceSource extends SpecificExperienceSource { private final EntityType type; @@ -37,17 +40,36 @@ public class KillMobExperienceSource extends SpecificExperienceSource { public ExperienceSourceManager newManager() { return new ExperienceSourceManager() { - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void a(PlayerKillEntityEvent event) { - Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> { - if (event.getTarget().isDead() && !event.getTarget().getPersistentDataContainer().has(new NamespacedKey(MMOCore.plugin, "spawner_spawned"), PersistentDataType.STRING)) { - PlayerData data = PlayerData.get(event.getPlayer()); + /** + * This map is used to keep track of the last player who + * hit some entity. It is flushed on entity death. + */ + private final FlushableRegistry registry = new FlushableRegistry<>((entity, attacker) -> Bukkit.getEntity(entity) == null, 20 * 60); - for (KillMobExperienceSource source : getSources()) - if (source.matches(data, event.getTarget())) - source.giveExperience(data, 1, MMOCoreUtils.getCenterLocation(event.getTarget())); - } - }, 2); + @Override + public void whenClosed() { + registry.close(); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void registerLastAttacker(PlayerAttackEvent event) { + registry.getRegistry().put(event.getEntity().getUniqueId(), event.getAttacker().getData().getUniqueId()); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void giveExp(EntityDeathEvent event) { + + // Always remove entry from map + final @Nullable UUID lastAttacker = this.registry.getRegistry().remove(event.getEntity().getUniqueId()); + if (lastAttacker == null) return; + + if (event.getEntity().getPersistentDataContainer().has(new NamespacedKey(MMOCore.plugin, "spawner_spawned"), PersistentDataType.STRING)) + return; + + final PlayerData data = PlayerData.get(lastAttacker); + for (KillMobExperienceSource source : getSources()) + if (source.matches(data, event.getEntity())) + source.giveExperience(data, 1, MMOCoreUtils.getCenterLocation(event.getEntity())); } }; } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/ExperienceManager.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/ExperienceManager.java index 6714cb23..a1d70b4d 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/ExperienceManager.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/ExperienceManager.java @@ -9,7 +9,7 @@ import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; import org.apache.commons.lang.Validate; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import java.io.File; @@ -25,10 +25,8 @@ public class ExperienceManager implements MMOCoreManager { * Experience sources from the exp-sources.yml config file where you can * input any exp source which can later be used along with the 'from' * exp source anywhere in the plugin. - *

- * TODO First needs to edit the exp-source current structure. This is going to break a lot of things * - * @deprecated See TODO + * @deprecated TODO First needs to edit the exp-source current structure. This is going to break a lot of things */ @Deprecated private final Map>> publicExpSources = new HashMap<>(); @@ -55,6 +53,7 @@ public class ExperienceManager implements MMOCoreManager { return expCurves.containsKey(id); } + @NotNull public ExpCurve getCurveOrThrow(String id) { Validate.isTrue(hasCurve(id), "Could not find exp curve with ID '" + id + "'"); return expCurves.get(id); @@ -70,10 +69,12 @@ public class ExperienceManager implements MMOCoreManager { return expTables.containsKey(id); } + @NotNull public ExperienceTable getTableOrThrow(String id) { return Objects.requireNonNull(expTables.get(id), "Could not find exp table with ID '" + id + "'"); } + @NotNull public ExperienceTable loadExperienceTable(Object obj) { if (obj instanceof ConfigurationSection) @@ -99,7 +100,7 @@ public class ExperienceManager implements MMOCoreManager { expCurves.clear(); expTables.clear(); - managers.values().forEach(HandlerList::unregisterAll); + managers.forEach((c, manager) -> manager.close()); managers.clear(); } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/profession/ExperienceSourceManager.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/profession/ExperienceSourceManager.java index 98ab98d8..f08b02f3 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/profession/ExperienceSourceManager.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/profession/ExperienceSourceManager.java @@ -1,19 +1,23 @@ package net.Indyuce.mmocore.manager.profession; +import io.lumine.mythic.lib.util.Closeable; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.experience.source.type.ExperienceSource; +import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; +import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import java.util.HashSet; import java.util.Set; -public abstract class ExperienceSourceManager implements Listener { +public abstract class ExperienceSourceManager implements Listener, Closeable { /** * List of all active experience sources */ private final Set sources = new HashSet<>(); + private boolean open = true; public ExperienceSourceManager() { Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin); @@ -23,6 +27,19 @@ public abstract class ExperienceSourceManager implem sources.add(source); } + public void whenClosed() { + // Nothing by default + } + + @Override + public void close() { + Validate.isTrue(open, "Manager is already closed"); + open = false; + + HandlerList.unregisterAll(this); + whenClosed(); + } + public Set getSources() { return sources; }