You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

131 lines
4.9 KiB
Java

package com.zivilon.itemeffects;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import java.util.Map;
import java.util.HashMap;
import java.util.UUID;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
import java.util.stream.Collectors;
import com.zivilon.itemeffects.ItemEffects;
public class AuraManager {
private final ItemEffects plugin;
private final Map<UUID, PlayerAuraTask> runningAuras = new HashMap<>();
private Map<UUID, List<PotionEffect>> originalEffects = new HashMap<>();
public AuraManager(ItemEffects plugin) {
this.plugin = plugin;
}
// Please don't break, this thing was a hell to set up and I don't want to ever look at it again
public void startAuraTask(Aura aura) {
// Cancel the old task if it exists
BukkitTask oldTask = null;
if (runningAuras.containsKey(aura.getOwner().getUniqueId())) {
oldTask = runningAuras.get(aura.getOwner().getUniqueId()).getTask();
}
if (oldTask != null) {
oldTask.cancel();
}
// Start a new repeating task
BukkitTask newTask = Bukkit.getScheduler().runTaskTimer(plugin, () -> {
World world = aura.getOwner().getWorld();
for (Aura.AuraEffectSet effectSet : aura.getEffectSets()) {
for (Player nearbyPlayer : world.getPlayers()) {
if (nearbyPlayer.equals(aura.getOwner())) continue; // Skip the aura owner
double distance = nearbyPlayer.getLocation().distance(aura.getOwner().getLocation());
// Check player distance within the task
if (distance <= effectSet.getRadius()) {
// 1. If player already has an effect of the same type and it's not ambient
if (nearbyPlayer.hasPotionEffect(effectSet.getEffect().getType()) && !getPotionEffectOfType(nearbyPlayer, effectSet.getEffect().getType()).isAmbient()) {
originalEffects.put(nearbyPlayer.getUniqueId(), new ArrayList<>(Collections.singletonList(getPotionEffectOfType(nearbyPlayer, effectSet.getEffect().getType()))));
}
// 2. Remove any existing conflicting effects
nearbyPlayer.removePotionEffect(effectSet.getEffect().getType());
// 3. Apply the aura effect
nearbyPlayer.addPotionEffect(effectSet.getEffect());
}
}
}
}, 0L, 40L); // Run every 2 seconds (40 ticks)
// Store the new task in our map
runningAuras.put(aura.getOwner().getUniqueId(), new PlayerAuraTask(aura, newTask));
}
private PotionEffect getPotionEffectOfType(Player player, PotionEffectType type) {
for (PotionEffect effect : player.getActivePotionEffects()) {
if (effect.getType().equals(type)) {
return effect;
}
}
return null;
}
public void stopAuraTask(Player player) {
PlayerAuraTask auraTask = runningAuras.remove(player.getUniqueId());
if (auraTask == null) {
return;
}
BukkitTask task = auraTask.getTask();
if (task != null) {
task.cancel();
}
// Immediately restore original effects to the aura owner
if (originalEffects.containsKey(player.getUniqueId())) {
List<PotionEffect> storedEffects = originalEffects.remove(player.getUniqueId());
for (PotionEffect effect : storedEffects) {
player.addPotionEffect(effect, true);
}
}
// Restore effects to all players affected by this aura
restoreEffectsOnAuraEnd(auraTask.getAura());
}
public void restoreEffectsOnAuraEnd(Aura aura) {
// Iterate over all players in the aura's world
for (Player player : aura.getOwner().getWorld().getPlayers()) {
// Check if we stored any original effects for the player
if (originalEffects.containsKey(player.getUniqueId())) {
List<PotionEffect> storedEffects = originalEffects.get(player.getUniqueId()); // Just get the effects without removing them
if(storedEffects != null) {
// Iterate over each of the effect sets in the aura
for (Aura.AuraEffectSet effectSet : aura.getEffectSets()) {
for (PotionEffect effect : storedEffects) {
player.removePotionEffect(effect.getType()); // Remove the current effect
player.addPotionEffect(effect, true); // Apply the stored effect
}
}
originalEffects.remove(player.getUniqueId()); // Now remove it after processing all effect sets
}
}
}
}
}