All source projects

MrUltimateLibrary Source

Standalone source project / 68 files

MrUltimateLibrary is the backbone of all my plugins; it offers features that facilitate plugin creation, maintenance, and updates.

java

MrUltimateLibrary/src/main/java/eu/mrneznamy/mrultimatelibrary/bossbar/MrLibBossBar.java

JAVA · Read-only source

package eu.mrneznamy.mrultimatelibrary.bossbar;

import eu.mrneznamy.mrultimatelibrary.utils.MrLibColors;
import org.bukkit.Bukkit;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;

/**
 * BossBar system with fill/countdown/permanent modes
 */
public class MrLibBossBar {
    
    private final JavaPlugin plugin;
    private final Map<UUID, ActiveBar> activeBars = new HashMap<>();
    
    public MrLibBossBar(JavaPlugin plugin) {
        this.plugin = plugin;
    }
    
    /**
     * Show permanent bossbar
     * 
     * @param player Player
     * @param message Message
     * @param color Bar color
     * @param style Bar style
     */
    public void showPermanent(Player player, String message, BarColor color, BarStyle style) {
        remove(player);
        
        BossBar bar = createBar(message, player, color, style, 1.0);
        bar.addPlayer(player);
        
        ActiveBar activeBar = new ActiveBar(bar, BarMode.PERMANENT);
        activeBars.put(player.getUniqueId(), activeBar);
    }
    
    /**
     * Show filling bossbar (0% -> 100%)
     * 
     * @param player Player
     * @param message Message
     * @param color Bar color
     * @param durationTicks Duration in ticks
     */
    public void showFilling(Player player, String message, BarColor color, BarStyle style, long durationTicks) {
        remove(player);
        
        BossBar bar = createBar(message, player, color, style, 0.0);
        bar.addPlayer(player);
        
        ActiveBar activeBar = new ActiveBar(bar, BarMode.FILLING);
        activeBar.totalTicks = durationTicks;
        activeBar.currentTick = 0;
        activeBars.put(player.getUniqueId(), activeBar);
        
        startTask(player, activeBar);
    }
    
    /**
     * Show countdown bossbar (100% -> 0%)
     * 
     * @param player Player
     * @param message Message (use %time% for remaining seconds)
     * @param color Bar color
     * @param durationTicks Duration in ticks
     */
    public void showCountdown(Player player, String message, BarColor color, BarStyle style, long durationTicks) {
        remove(player);
        
        BossBar bar = createBar(message, player, color, style, 1.0);
        bar.addPlayer(player);
        
        ActiveBar activeBar = new ActiveBar(bar, BarMode.COUNTDOWN);
        activeBar.totalTicks = durationTicks;
        activeBar.currentTick = durationTicks;
        activeBar.baseMessage = message;
        activeBars.put(player.getUniqueId(), activeBar);
        
        startTask(player, activeBar);
    }
    
    /**
     * Show dynamic bossbar (custom progress calculation)
     * 
     * @param player Player
     * @param messageProvider Message provider function
     * @param progressProvider Progress provider function (0.0 - 1.0)
     * @param color Bar color
     */
    public void showDynamic(Player player, Function<Player, String> messageProvider, 
                            Function<Player, Double> progressProvider, 
                            BarColor color, BarStyle style, long durationTicks) {
        remove(player);
        
        BossBar bar = createBar("", player, color, style, 0.0);
        bar.addPlayer(player);
        
        ActiveBar activeBar = new ActiveBar(bar, BarMode.DYNAMIC);
        activeBar.messageProvider = messageProvider;
        activeBar.progressProvider = progressProvider;
        activeBar.totalTicks = durationTicks;
        activeBar.currentTick = 0;
        activeBars.put(player.getUniqueId(), activeBar);
        
        startTask(player, activeBar);
    }
    
    /**
     * Remove bossbar from player
     */
    public void remove(Player player) {
        ActiveBar activeBar = activeBars.remove(player.getUniqueId());
        if (activeBar != null) {
            activeBar.cancel();
            activeBar.bar.removeAll();
        }
    }
    
    /**
     * Remove all bossbars
     */
    public void removeAll() {
        activeBars.values().forEach(bar -> {
            bar.cancel();
            bar.bar.removeAll();
        });
        activeBars.clear();
    }
    
    private void startTask(Player player, ActiveBar activeBar) {
        activeBar.taskId = Bukkit.getScheduler().runTaskTimer(plugin, () -> {
            if (!player.isOnline()) {
                remove(player);
                return;
            }
            
            switch (activeBar.mode) {
                case FILLING:
                    activeBar.currentTick++;
                    double fillProgress = Math.min(1.0, (double) activeBar.currentTick / activeBar.totalTicks);
                    activeBar.bar.setProgress(fillProgress);
                    
                    if (activeBar.currentTick >= activeBar.totalTicks) {
                        remove(player);
                    }
                    break;
                    
                case COUNTDOWN:
                    activeBar.currentTick--;
                    double countProgress = Math.max(0.0, (double) activeBar.currentTick / activeBar.totalTicks);
                    activeBar.bar.setProgress(countProgress);
                    
                    if (activeBar.baseMessage != null && activeBar.baseMessage.contains("%time%")) {
                        int seconds = (int) (activeBar.currentTick / 20);
                        String updated = activeBar.baseMessage.replace("%time%", String.valueOf(seconds));
                        activeBar.bar.setTitle(MrLibColors.colorize(updated, player));
                    }
                    
                    if (activeBar.currentTick <= 0) {
                        remove(player);
                    }
                    break;
                    
                case DYNAMIC:
                    activeBar.currentTick++;
                    if (activeBar.messageProvider != null) {
                        String msg = activeBar.messageProvider.apply(player);
                        activeBar.bar.setTitle(MrLibColors.colorize(msg, player));
                    }
                    if (activeBar.progressProvider != null) {
                        double progress = Math.max(0.0, Math.min(1.0, activeBar.progressProvider.apply(player)));
                        activeBar.bar.setProgress(progress);
                    }
                    
                    if (activeBar.currentTick >= activeBar.totalTicks) {
                        remove(player);
                    }
                    break;
            }
        }, 0L, 1L).getTaskId();
    }
    
    private BossBar createBar(String message, Player player, BarColor color, BarStyle style, double progress) {
        BossBar bar = Bukkit.createBossBar(
            MrLibColors.colorize(message, player),
            color,
            style
        );
        bar.setProgress(progress);
        bar.setVisible(true);
        return bar;
    }
    
    private static class ActiveBar {
        BossBar bar;
        BarMode mode;
        int taskId = -1;
        long totalTicks;
        long currentTick;
        String baseMessage;
        Function<Player, String> messageProvider;
        Function<Player, Double> progressProvider;
        
        ActiveBar(BossBar bar, BarMode mode) {
            this.bar = bar;
            this.mode = mode;
        }
        
        void cancel() {
            if (taskId != -1) {
                Bukkit.getScheduler().cancelTask(taskId);
            }
        }
    }
    
    private enum BarMode {
        PERMANENT,
        FILLING,
        COUNTDOWN,
        DYNAMIC
    }
}

233 linesGNU GENERAL PUBLIC LICENSE · Version 3, 29 June 2007 · UTF-8 · Read only