diff --git a/src/main/java/io/github/simplex/api/LuckContainer.java b/src/main/java/io/github/simplex/api/LuckContainer.java index 1466d69..62e847e 100644 --- a/src/main/java/io/github/simplex/api/LuckContainer.java +++ b/src/main/java/io/github/simplex/api/LuckContainer.java @@ -3,7 +3,9 @@ package io.github.simplex.api; import org.bukkit.attribute.Attribute; import org.bukkit.entity.Player; -public interface LuckContainer { +import java.io.Serializable; + +public interface LuckContainer extends Serializable { Attribute asAttribute(); double getNumber(); diff --git a/src/main/java/io/github/simplex/lib/PotionEffectBuilder.java b/src/main/java/io/github/simplex/lib/PotionEffectBuilder.java new file mode 100644 index 0000000..13c28ff --- /dev/null +++ b/src/main/java/io/github/simplex/lib/PotionEffectBuilder.java @@ -0,0 +1,68 @@ +package io.github.simplex.lib; + +import io.github.simplex.luck.player.Luck; +import org.bukkit.NamespacedKey; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.jetbrains.annotations.Contract; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public final class PotionEffectBuilder { + + @Contract("-> new") + public static Worker newEffect() { + return new Worker(); + } + + @Contract("-> new") + public static PotionEffectType randomType() { + List namesList = new ArrayList<>(); + PotionEffectType[] types = PotionEffectType.values(); + Arrays.stream(types).forEach(type -> namesList.add(type.getKey())); + int size = namesList.size(); + int next = Luck.RNG().nextInt(size - 1); + NamespacedKey name = namesList.get(next); + return PotionEffectType.getByKey(name); + } + + public static class Worker { + public PotionEffect potionEffect; + + public Worker() { + potionEffect = new PotionEffect(PotionEffectType.ABSORPTION, 0, 0); + } + + public Worker duration(int duration) { + potionEffect = potionEffect.withDuration(duration); + return this; + } + + public Worker amplifier(int amplifier) { + potionEffect = potionEffect.withAmplifier(amplifier); + return this; + } + + public Worker particles(boolean show) { + potionEffect = potionEffect.withParticles(show); + return this; + } + + public Worker ambience(boolean ambient) { + potionEffect = potionEffect.withAmbient(ambient); + return this; + } + + public Worker type(PotionEffectType type) { + potionEffect = potionEffect.withType(type); + return this; + } + + public PotionEffect create() { + return potionEffect; + } + } + +} diff --git a/src/main/java/io/github/simplex/luck/FeelingLucky.java b/src/main/java/io/github/simplex/luck/FeelingLucky.java index ec6b5fe..0048836 100644 --- a/src/main/java/io/github/simplex/luck/FeelingLucky.java +++ b/src/main/java/io/github/simplex/luck/FeelingLucky.java @@ -2,28 +2,43 @@ package io.github.simplex.luck; import io.github.simplex.luck.player.PlayerConfig; import io.github.simplex.luck.player.PlayerHandler; +import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; public final class FeelingLucky extends JavaPlugin { - public PlayerHandler handler; private static final List configList = new ArrayList<>(); - - @Override - public void onEnable() { - handler = new PlayerHandler(this); - configList.forEach(PlayerConfig::load); - this.getServer().getPluginManager().registerEvents(handler, this); - } - - @Override - public void onDisable() { - configList.forEach(PlayerConfig::save); - } + public PlayerHandler handler; public static List getConfigList() { return configList; } + + @Override + public void onEnable() { + Bukkit.getLogger().info("Initializing the PlayerHandler..."); + handler = new PlayerHandler(this); + Bukkit.getLogger().info("Initialization complete! Attempting to register the handler..."); + this.getServer().getPluginManager().registerEvents(handler, this); + Bukkit.getLogger().info("Registration complete! Attempting to load all player configuration files..."); + if (getDataFolder().listFiles() != null) { + Arrays.stream(getDataFolder().listFiles()).forEach(file -> { + configList.add(PlayerConfig.loadFrom(file)); + }); + configList.forEach(PlayerConfig::load); + getLogger().info("Successfully loaded all configurations!"); + } else { + getLogger().info("There are no player configurations to load."); + } + Bukkit.getLogger().info("Successfully initialized!"); + } + + @Override + public void onDisable() { + Bukkit.getLogger().info("Saving all player configurations..."); + configList.forEach(PlayerConfig::save); + } } diff --git a/src/main/java/io/github/simplex/luck/listener/PlayerListener.java b/src/main/java/io/github/simplex/luck/listener/PlayerListener.java index 820eea2..3461902 100644 --- a/src/main/java/io/github/simplex/luck/listener/PlayerListener.java +++ b/src/main/java/io/github/simplex/luck/listener/PlayerListener.java @@ -1,5 +1,6 @@ package io.github.simplex.luck.listener; +import io.github.simplex.lib.PotionEffectBuilder; import io.github.simplex.luck.FeelingLucky; import io.github.simplex.luck.player.Luck; import io.github.simplex.luck.player.PlayerHandler; @@ -22,12 +23,7 @@ import org.bukkit.potion.PotionEffectType; import java.util.ArrayList; import java.util.List; -public class PlayerListener implements Listener { - private final FeelingLucky plugin; - - public PlayerListener(FeelingLucky plugin) { - this.plugin = plugin; - } +public record PlayerListener(FeelingLucky plugin) implements Listener { @EventHandler public void takeDamage(EntityDamageEvent event) { @@ -40,6 +36,17 @@ public class PlayerListener implements Listener { if (ListBox.acceptedCauses.contains(event.getCause())) { if (luck.notDefault()) { double percentage = luck.getPercentage(); + + if (percentage < 0 || PlayerHandler.isMarked(player)) { + percentage = Math.abs(percentage); + if (luck.quickRNG(percentage)) { + event.setCancelled(true); + player.damage(event.getDamage() * 2); + player.sendMessage(Component.empty().content("You were unlucky and took double damage.")); + } + return; + } + if (luck.quickRNG(percentage)) { event.setCancelled(true); player.damage(event.getDamage() / 2); @@ -51,6 +58,24 @@ public class PlayerListener implements Listener { if (ListBox.sideCauses.contains(event.getCause())) { if (luck.notDefault()) { double percentage = luck.getPercentage(); + + /* + * If a player's luck stat is a negative number, or they are "marked", + * this will trigger instead of the regular luck spin. + */ + if (percentage < 0 || PlayerHandler.isMarked(player)) { + percentage = Math.abs(percentage); + if (luck.quickRNG(percentage)) { + event.setCancelled(true); + player.addPotionEffect(PotionEffectBuilder.newEffect() + .type(ListBox.potionEffects.get(Luck.RNG().nextInt(ListBox.potionEffects.size() - 1))) + .amplifier(Luck.RNG().nextInt(1, 5)) + .duration(Luck.RNG().nextInt(1, 120)) + .create()); + } + return; + } + if (luck.quickRNG(percentage)) { event.setCancelled(true); player.getActivePotionEffects().removeIf(p -> ListBox.potionEffects.contains(p.getType())); @@ -84,7 +109,7 @@ public class PlayerListener implements Listener { Player player = event.getPlayer(); Luck luck = PlayerHandler.getLuckContainer(player); if (action.isRightClick() && player.getInventory().getItemInMainHand().isSimilar(foot)) { - double rng = luck.RNG().nextDouble(2.0, 5.0); + double rng = Luck.RNG().nextDouble(2.0, 5.0); player.getInventory().remove(player.getInventory().getItemInMainHand()); luck.addTo(rng); diff --git a/src/main/java/io/github/simplex/luck/player/Luck.java b/src/main/java/io/github/simplex/luck/player/Luck.java index 66b4c2a..6d89513 100644 --- a/src/main/java/io/github/simplex/luck/player/Luck.java +++ b/src/main/java/io/github/simplex/luck/player/Luck.java @@ -4,9 +4,12 @@ import io.github.simplex.api.LuckContainer; import org.bukkit.Bukkit; import org.bukkit.attribute.Attribute; import org.bukkit.entity.Player; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; import java.util.SplittableRandom; +@SuppressWarnings("all") public class Luck implements LuckContainer { private final Player player; private final double multiplier; @@ -24,6 +27,12 @@ public class Luck implements LuckContainer { event = new PlayerLuckChangeEvent(player); } + @Contract(pure = true, + value = "-> new") + public static @NotNull SplittableRandom RNG() { + return new SplittableRandom(); + } + @Override public Attribute asAttribute() { return Attribute.GENERIC_LUCK; @@ -54,10 +63,6 @@ public class Luck implements LuckContainer { return player; } - public SplittableRandom RNG() { - return new SplittableRandom(); - } - public boolean quickRNG(double percentage) { double rng; if (percentage > 99.0) { @@ -109,7 +114,7 @@ public class Luck implements LuckContainer { return baseValue() < value; } - public boolean greaterThan (double value) { + public boolean greaterThan(double value) { return baseValue() > value; } diff --git a/src/main/java/io/github/simplex/luck/player/PlayerConfig.java b/src/main/java/io/github/simplex/luck/player/PlayerConfig.java index 37db03d..18c2def 100644 --- a/src/main/java/io/github/simplex/luck/player/PlayerConfig.java +++ b/src/main/java/io/github/simplex/luck/player/PlayerConfig.java @@ -2,13 +2,12 @@ package io.github.simplex.luck.player; import io.github.simplex.luck.FeelingLucky; import io.github.simplex.luck.SneakyWorker; -import org.bukkit.attribute.Attribute; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; +import org.jetbrains.annotations.Contract; -import java.io.File; -import java.io.InputStream; -import java.io.InputStreamReader; +import java.io.*; +import java.nio.charset.StandardCharsets; public class PlayerConfig extends YamlConfiguration { private final File configFile; @@ -16,14 +15,24 @@ public class PlayerConfig extends YamlConfiguration { @SuppressWarnings("ResultOfMethodCallIgnored") public PlayerConfig(FeelingLucky plugin, Player player) { - File dataFolder = new File(plugin.getDataFolder(), "players"); + File dataFolder = plugin.getDataFolder(); if (!dataFolder.exists()) dataFolder.mkdirs(); File file = new File(dataFolder, player.getUniqueId() + ".yml"); if (!file.exists()) { + String name = "username: " + player.getName(); + String luck = "luck: " + PlayerHandler.getLuckContainer(player).defaultValue(); + String multiplier = "multiplier: " + 1.0; + SneakyWorker.sneakyTry(() -> { file.createNewFile(); - InputStreamReader reader = new InputStreamReader(plugin.getResource("default_player.yml")); - loadConfiguration(reader).save(file); + + BufferedWriter writer = new BufferedWriter(new FileWriter(file, StandardCharsets.UTF_8)); + writer.write(name); + writer.newLine(); + writer.write(luck); + writer.newLine(); + writer.write(multiplier); + writer.close(); }); } configFile = file; @@ -31,12 +40,22 @@ public class PlayerConfig extends YamlConfiguration { if (config.getString("username").equalsIgnoreCase("replace")) { config.set("username", player.getName()); - config.set("luck", new Luck(player).defaultValue()); + config.set("luck", PlayerHandler.getLuckContainer(player).defaultValue()); config.set("multiplier", "1.0"); save(); } } + protected PlayerConfig(File file) { + this.configFile = file; + config = loadConfiguration(configFile); + } + + @Contract("_ -> new") + public static PlayerConfig loadFrom(File file) { + return new PlayerConfig(file); + } + public void save() { SneakyWorker.sneakyTry(() -> config.save(configFile)); } diff --git a/src/main/java/io/github/simplex/luck/player/PlayerHandler.java b/src/main/java/io/github/simplex/luck/player/PlayerHandler.java index 40d10dc..9763c46 100644 --- a/src/main/java/io/github/simplex/luck/player/PlayerHandler.java +++ b/src/main/java/io/github/simplex/luck/player/PlayerHandler.java @@ -19,6 +19,18 @@ public record PlayerHandler(FeelingLucky plugin) implements Listener { return playerLuckMap.get(player); } + public static void markPlayer(Player player) { + markedPlayers.add(player); + } + + public static void unmarkPlayer(Player player) { + markedPlayers.remove(player); + } + + public static boolean isMarked(Player player) { + return markedPlayers.contains(player); + } + @EventHandler public void initializePlayer(PlayerLoginEvent event) { Player player = event.getPlayer(); @@ -44,16 +56,4 @@ public record PlayerHandler(FeelingLucky plugin) implements Listener { public void updatePlayer(Player player, Luck luck) { playerLuckMap.replace(player, luck); } - - public static void markPlayer(Player player) { - markedPlayers.add(player); - } - - public static void unmarkPlayer(Player player) { - markedPlayers.remove(player); - } - - public static boolean isMarked(Player player) { - return markedPlayers.contains(player); - } }