8 Commits

Author SHA1 Message Date
ea50032a89 Alpha 1.0 RELEASE - Patch 0003 2022-04-10 19:10:24 -05:00
057450c585 Alpha 1.0 RELEASE 2022-04-10 18:48:09 -05:00
d08b240ff9 RC04 - Patch 0002
Changelog:
 - Renamed LuckContainer#baseValue() to getValue()
 - Changed the way files save by using the Map#values() call instead of iterating the kvp's.
 - Made the actual percentage rng value round to the closest whole number before being checked.
 - Changed Luck#defaultValue() to getDefaultValue().
2022-04-09 08:38:42 -05:00
cbc57d5971 Alpha 1.0.0 RC04
Switched PlayerHandler access modifiers in favor of Dependency Injection.
2022-04-02 21:16:08 -05:00
247a2fafc0 Bug Fix 0001
**Changelog**:
 - Fixed a bug where the PlayerListener was not being initialized
 - Included the registration for the listener inside the constructor
 - Dropped static import in favor of class parent access
 - Added to the Luck method "setValue(double)" to automatically update the configuration file when called.
 - Adjusted Luck to utilize all 1024 units when calculating the boolean for rng percentage.
2022-04-02 09:00:40 -05:00
ffdafda69c Changed Project Settings 2022-04-01 07:51:58 -05:00
0383bfeaf3 Alpha 1.0 RC02 PATCH 01
Fixed an issue where initializing a new PlayerConfig would attempt to read a non existent value from the Luck Container list.
2022-03-31 19:42:18 -05:00
93ee1e2c43 Alpha 1.0 RC02
Changelog:
  - Some visibility changes (Developers)
  - Added the Luck command.
  - Added some extra backend shortcuts
2022-03-31 19:30:10 -05:00
30 changed files with 647 additions and 265 deletions

Binary file not shown.

1
.idea/.name generated Normal file
View File

@ -0,0 +1 @@
FeelingLucky

View File

@ -3,7 +3,7 @@ plugins {
} }
group = 'io.github.simplex' group = 'io.github.simplex'
version = '1.0-SNAPSHOT' version = 'Alpha-1.0-RC03'
repositories { repositories {
mavenCentral() mavenCentral()
@ -29,6 +29,9 @@ java {
if (JavaVersion.current() < javaVersion) { if (JavaVersion.current() < javaVersion) {
toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion) toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion)
} }
withSourcesJar();
withJavadocJar();
} }
tasks.withType(JavaCompile).configureEach { tasks.withType(JavaCompile).configureEach {

View File

@ -1,4 +1,5 @@
name: Crumb name: FeelingLucky
version: '1.0-SNAPSHOT' version: 'Alpha-1.0-RC03'
main: io.github.simplex.crumb.Crumb author: SimplexDevelopment
main: io.github.simplex.luck.FeelingLucky
api-version: 1.18 api-version: 1.18

View File

@ -1 +1 @@
rootProject.name = 'Crumb' rootProject.name = 'FeelingLucky'

View File

@ -6,6 +6,7 @@ import org.bukkit.entity.Player;
import java.io.Serializable; import java.io.Serializable;
public interface LuckContainer extends Serializable { public interface LuckContainer extends Serializable {
Attribute asAttribute(); Attribute asAttribute();
double getNumber(); double getNumber();
@ -18,5 +19,5 @@ public interface LuckContainer extends Serializable {
Player associatedPlayer(); Player associatedPlayer();
double baseValue(); double getValue();
} }

View File

@ -0,0 +1,35 @@
package io.github.simplex.lib;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public enum Messages {
NOT_FROM_CONSOLE(builder("This command may only be used in game.", null, null)),
NO_PERMISSION(builder("You do not have permission to use this command.", TextColor.color(255, 0, 0), TextDecoration.ITALIC));
private final Component message;
Messages(Component message) {
this.message = message;
}
public Component get() {
return message;
}
private static Component builder(@NotNull String message, @Nullable TextColor color, @Nullable TextDecoration decoration) {
if (color == null) {
if (decoration == null) return Component.empty().content(message);
return Component.empty().content(message).decoration(decoration, TextDecoration.State.TRUE);
}
if (decoration == null) return Component.empty().content(message).color(color);
return Component.empty().content(message).color(color).decoration(decoration, TextDecoration.State.TRUE);
}
}

View File

@ -1,5 +1,6 @@
package io.github.simplex.luck; package io.github.simplex.luck;
import io.github.simplex.luck.listener.*;
import io.github.simplex.luck.player.PlayerConfig; import io.github.simplex.luck.player.PlayerConfig;
import io.github.simplex.luck.player.PlayerHandler; import io.github.simplex.luck.player.PlayerHandler;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -12,26 +13,33 @@ import java.util.Map;
import java.util.UUID; import java.util.UUID;
public final class FeelingLucky extends JavaPlugin { public final class FeelingLucky extends JavaPlugin {
private static final Map<UUID, PlayerConfig> configMap = new HashMap<>(); private final Map<UUID, PlayerConfig> configMap = new HashMap<>();
public LuckCMD cmd;
public PlayerHandler handler; public PlayerHandler handler;
public static Map<UUID, PlayerConfig> getConfigMap() { public Map<UUID, PlayerConfig> getConfigMap() {
return configMap; return configMap;
} }
@Override @Override
public void onEnable() { public void onEnable() {
Bukkit.getLogger().info("Initializing the PlayerHandler..."); getLogger().info("Initializing the PlayerHandler...");
handler = new PlayerHandler(this); handler = new PlayerHandler(this);
Bukkit.getLogger().info("Initialization complete! Attempting to register the handler..."); getLogger().info("Initialization complete! Attempting to register the Listeners...");
this.getServer().getPluginManager().registerEvents(handler, this); new PlayerListener(this);
Bukkit.getLogger().info("Registration complete! Attempting to load all player configuration files..."); new BlockDrops(this);
new ItemDrops(this);
new TakeDamage(this);
new RestoreHunger(this);
new EnchantmentBoost(this);
getLogger().info("Registration complete! Attempting to load all player configuration files...");
File[] files = getDataFolder().listFiles(); File[] files = getDataFolder().listFiles();
if (files != null) { if (files != null) {
Arrays.stream(files).forEach(file -> { Arrays.stream(files).forEach(file -> {
UUID uuid = UUID.fromString(file.getName().split("\\.")[0]); UUID uuid = UUID.fromString(file.getName().split("\\.")[0]);
configMap.put(uuid, PlayerConfig.loadFrom(file)); configMap.put(uuid, PlayerConfig.loadFrom(this, file));
}); });
configMap.forEach((u, pc) -> pc.load()); configMap.forEach((u, pc) -> pc.load());
getLogger().info("Successfully loaded all configurations!"); getLogger().info("Successfully loaded all configurations!");
@ -39,12 +47,16 @@ public final class FeelingLucky extends JavaPlugin {
getLogger().info("There are no player configurations to load."); getLogger().info("There are no player configurations to load.");
} }
Bukkit.getLogger().info("Attempting to load the Luck command...");
cmd = new LuckCMD(this);
Bukkit.getLogger().info("Successfully loaded the Luck command!");
Bukkit.getLogger().info("Successfully initialized!"); Bukkit.getLogger().info("Successfully initialized!");
} }
@Override @Override
public void onDisable() { public void onDisable() {
Bukkit.getLogger().info("Saving all player configurations..."); Bukkit.getLogger().info("Saving all player configurations...");
configMap.forEach((u, pc) -> pc.save()); configMap.values().forEach(PlayerConfig::save);
} }
} }

View File

@ -0,0 +1,172 @@
package io.github.simplex.luck;
import io.github.simplex.lib.Messages;
import io.github.simplex.luck.player.Luck;
import io.github.simplex.luck.player.PlayerConfig;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.TextColor;
import org.bukkit.Bukkit;
import org.bukkit.command.*;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class LuckCMD extends Command implements TabCompleter {
private final FeelingLucky plugin;
public LuckCMD(FeelingLucky plugin) {
super("luck", "FeelingLucky main command.", "/<command> <info | set | reset | give | take> [player] [amount]", List.of());
this.plugin = plugin;
setPermission("luck.default");
plugin.getServer().getCommandMap().register("luck", "FeelingLucky", this);
}
@Override
public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
if (args.length < 1 || args.length > 3) return false;
if (args.length == 3) {
if ((sender instanceof ConsoleCommandSender) || sender.hasPermission("luck.admin")) {
Player player = Bukkit.getPlayer(args[1]);
double amount = Double.parseDouble(args[2]);
if (player == null) {
sender.sendMessage(Component.empty().content("That player cannot be found."));
return true;
}
if (amount > 1024.0 || amount < -1024.0) {
sender.sendMessage(Component.empty().content("Number must be between -1024.0 and 1024.0"));
return true;
}
Luck luck = plugin.handler.getLuckContainer(player);
PlayerConfig config = plugin.getConfigMap().get(player.getUniqueId());
switch (args[0]) {
case "set" -> {
luck.setValue(amount);
plugin.handler.updatePlayer(player, luck);
config.setLuck(luck.getValue());
sender.sendMessage(Component.empty().content("Successfully reset " + args[1] + "'s Luck stat."));
return true;
}
case "give" -> {
luck.addTo(amount);
plugin.handler.updatePlayer(player, luck);
config.setLuck(luck.getValue());
sender.sendMessage(Component.empty().content("Successfully reset " + args[1] + "'s Luck stat."));
return true;
}
case "take" -> {
luck.takeFrom(amount);
plugin.handler.updatePlayer(player, luck);
config.setLuck(luck.getValue());
sender.sendMessage(Component.empty().content("Successfully reset " + args[1] + "'s Luck stat."));
return true;
}
}
} else {
sender.sendMessage(Messages.NO_PERMISSION.get());
return true;
}
}
if (args.length == 2) {
if ((sender instanceof ConsoleCommandSender) || sender.hasPermission("luck.admin")) {
if (args[0].equalsIgnoreCase("info")) {
Player player = Bukkit.getPlayer(args[1]);
if (player == null) {
sender.sendMessage("That player cannot be found.");
return true;
}
Luck luck = plugin.handler.getLuckContainer(player);
sender.sendMessage(Component.empty().content("Luck stat for " + args[1] + ": " + luck.getValue()));
return true;
}
if (args[0].equalsIgnoreCase("reset")) {
Player player = Bukkit.getPlayer(args[1]);
if (player == null) {
sender.sendMessage(Component.empty().content("That player cannot be found."));
return true;
}
Luck luck = plugin.handler.getLuckContainer(player);
PlayerConfig config = plugin.getConfigMap().get(player.getUniqueId());
luck.reset();
plugin.handler.updatePlayer(player, luck);
config.setLuck(luck.getValue());
sender.sendMessage(Component.empty().content("Successfully reset " + args[1] + "'s Luck stat."));
return true;
}
} else {
sender.sendMessage(Messages.NO_PERMISSION.get());
return true;
}
}
if (args.length == 1) {
if (args[0].equalsIgnoreCase("reload") && sender.hasPermission("luck.admin")) {
plugin.getConfigMap().values().forEach(PlayerConfig::reload);
return true;
}
if ((sender instanceof Player player) && player.hasPermission("luck.default")) {
if (args[0].equalsIgnoreCase("info")) {
Luck luck = plugin.handler.getLuckContainer(player);
TextComponent c = Component.text("Your Luck: " + luck.getPercentage());
player.sendMessage(c.color(TextColor.color(0, 255, 0)));
return true;
}
} else if (sender instanceof ConsoleCommandSender) {
sender.sendMessage(Messages.NOT_FROM_CONSOLE.get());
return true;
}
}
return false;
}
@Override
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
List<String> completions = new ArrayList<>() {{
add("info");
}};
List<String> playerNames = new ArrayList<>() {{
Bukkit.getOnlinePlayers().forEach(p -> add(p.getName()));
}};
List<String> adminCommands = List.of("set", "reset", "give", "take");
if ((sender instanceof ConsoleCommandSender) || sender.hasPermission("luck.admin")) {
completions.addAll(adminCommands);
return completions;
}
if (args[0].equalsIgnoreCase("info") && sender.hasPermission("luck.admin")) {
return playerNames;
}
if (completions.contains(args[1]) && sender.hasPermission("luck.admin")) {
switch (args[0]) {
case "info":
case "reset":
case "reload":
return new ArrayList<>();
case "give":
case "take":
case "set":
return List.of("amount");
}
}
return completions;
}
}

View File

@ -0,0 +1,29 @@
package io.github.simplex.luck.listener;
import io.github.simplex.luck.FeelingLucky;
import io.github.simplex.luck.SneakyWorker;
import io.github.simplex.luck.player.Luck;
import org.bukkit.Bukkit;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockDropItemEvent;
import java.util.List;
public record BlockDrops(FeelingLucky plugin) implements Listener {
public BlockDrops {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void extraBlockDrops(BlockDropItemEvent event) {
Player player = event.getPlayer();
Luck luck = plugin.handler.getLuckContainer(player);
List<Item> items = event.getItems();
if (luck.quickRNG(luck.getPercentage())) {
items.forEach(SneakyWorker::move);
}
}
}

View File

@ -0,0 +1,37 @@
package io.github.simplex.luck.listener;
import io.github.simplex.luck.FeelingLucky;
import io.github.simplex.luck.player.Luck;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.enchantment.EnchantItemEvent;
import java.util.List;
import java.util.Map;
public record EnchantmentBoost(FeelingLucky plugin) implements Listener {
public EnchantmentBoost(FeelingLucky plugin) {
this.plugin = plugin;
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void enchantItem(EnchantItemEvent event) {
Map<Enchantment, Integer> enchMap = event.getEnchantsToAdd();
List<Enchantment> enchList = enchMap.keySet().stream().toList();
Player player = event.getEnchanter();
Luck luck = plugin.handler.getLuckContainer(player);
if (luck.quickRNG(luck.getPercentage())) {
Enchantment particular = enchList.get(Luck.RNG().nextInt(enchList.size()));
int rng = Luck.RNG().nextInt(1, 5);
if ((enchMap.get(particular) + rng) > particular.getMaxLevel()) {
enchMap.replace(particular, particular.getMaxLevel());
}
enchMap.replace(particular, enchMap.get(particular) + rng);
}
}
}

View File

@ -0,0 +1,73 @@
package io.github.simplex.luck.listener;
import io.github.simplex.luck.FeelingLucky;
import io.github.simplex.luck.player.Luck;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDropItemEvent;
import org.bukkit.inventory.ItemStack;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class ItemDrops implements Listener {
private final Map<UUID, Player> entityPlayerMap = new HashMap<>();
private final FeelingLucky plugin;
public ItemDrops(FeelingLucky plugin) {
this.plugin = plugin;
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void checkForPreItemDrop(EntityDamageByEntityEvent event) {
if (!(event.getEntity() instanceof LivingEntity entity)) {
return;
}
if (!(event.getDamager() instanceof Player player)) {
return;
}
if (!(entity.getHealth() <= 0.0)) {
return;
}
if (entity instanceof Witch witch) {
if (Luck.quickRNGnoMultiplier(33.0)) {
Location location = witch.getLocation();
World world = location.getWorld();
Item item = world.dropItemNaturally(location, new ItemStack(Material.RABBIT_FOOT, 1));
new EntityDropItemEvent(witch, item).callEvent();
}
}
entityPlayerMap.put(entity.getUniqueId(), player);
}
@EventHandler
public void itemDrops(EntityDropItemEvent event) {
Entity entity = event.getEntity();
if (entityPlayerMap.get(entity.getUniqueId()) == null) return;
Player player = entityPlayerMap.get(entity.getUniqueId());
Luck luck = plugin.handler.getLuckContainer(player);
Item item = event.getItemDrop();
ItemStack stack = item.getItemStack();
int amount = stack.getAmount();
if (luck.quickRNG(luck.getPercentage())) {
int rng = Luck.RNG().nextInt(2, 5);
amount += rng;
stack.setAmount(amount);
event.getItemDrop().setItemStack(stack);
}
}
}

View File

@ -1,171 +1,25 @@
package io.github.simplex.luck.listener; package io.github.simplex.luck.listener;
import io.github.simplex.lib.PotionEffectBuilder;
import io.github.simplex.luck.FeelingLucky; import io.github.simplex.luck.FeelingLucky;
import io.github.simplex.luck.ListBox;
import io.github.simplex.luck.SneakyWorker;
import io.github.simplex.luck.player.Luck; import io.github.simplex.luck.player.Luck;
import io.github.simplex.luck.player.PlayerHandler;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.Location; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.entity.Entity;
import org.bukkit.entity.*; import org.bukkit.entity.Player;
import org.bukkit.entity.Witch;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.block.Action; import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockDropItemEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityDropItemEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerItemConsumeEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public record PlayerListener(FeelingLucky plugin) implements Listener { public record PlayerListener(FeelingLucky plugin) implements Listener {
public PlayerListener(FeelingLucky plugin) {
private static final Map<UUID, Player> entityPlayerMap = new HashMap<>(); this.plugin = plugin;
Bukkit.getServer().getPluginManager().registerEvents(this, plugin);
@EventHandler
public void takeDamage(EntityDamageEvent event) {
Entity entity = event.getEntity();
if (!(entity instanceof Player)) {
return;
}
Player player = (Player) event.getEntity();
Luck luck = PlayerHandler.getLuckContainer(player);
if (ListBox.acceptedCauses.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.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);
player.sendMessage(Component.empty().content("You got lucky and took less damage."));
}
}
}
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()));
player.setFireTicks(0);
player.sendMessage(Component.empty().content("You got lucky and your afflictions were cured."));
}
}
}
}
@EventHandler
public void extraBlockDrops(BlockDropItemEvent event) {
Player player = event.getPlayer();
Luck luck = PlayerHandler.getLuckContainer(player);
List<Item> items = event.getItems();
if (luck.quickRNG(luck.getPercentage())) {
items.forEach(SneakyWorker::move);
}
}
@EventHandler
public void checkForPreItemDrop(EntityDamageByEntityEvent event) {
if (!(event.getEntity() instanceof LivingEntity entity)) {
return;
}
if (!(event.getDamager() instanceof Player player)) {
return;
}
if (!(entity.getHealth() <= 0.0)) {
return;
}
if (entity instanceof Witch witch) {
if (Luck.quickRNG2(33.0)) {
Location location = witch.getLocation();
World world = location.getWorld();
Item item = world.dropItemNaturally(location, new ItemStack(Material.RABBIT_FOOT, 1));
new EntityDropItemEvent(witch, item).callEvent();
}
}
entityPlayerMap.put(entity.getUniqueId(), player);
}
@EventHandler
public void itemDrops(EntityDropItemEvent event) {
Entity entity = event.getEntity();
if (entityPlayerMap.get(entity.getUniqueId()) == null) return;
Player player = entityPlayerMap.get(entity.getUniqueId());
Luck luck = PlayerHandler.getLuckContainer(player);
Item item = event.getItemDrop();
ItemStack stack = item.getItemStack();
int amount = stack.getAmount();
if (luck.quickRNG(luck.getPercentage())) {
int rng = Luck.RNG().nextInt(2, 5);
amount += rng;
stack.setAmount(amount);
event.getItemDrop().setItemStack(stack);
}
}
@EventHandler
public void restoreHunger(PlayerItemConsumeEvent event) {
ItemStack item = event.getItem();
Luck luck = PlayerHandler.getLuckContainer(event.getPlayer());
PotionEffect effect = PotionEffectBuilder.newEffect().type(PotionEffectType.SATURATION).amplifier(2).duration(10).particles(false).create();
if (luck.notDefault()) {
double percentage = luck.getPercentage();
ListBox.foods.forEach(food -> {
if (item.isSimilar(food)) {
if (luck.quickRNG(percentage)) {
event.getPlayer().setExhaustion(event.getPlayer().getExhaustion() + 2);
event.getPlayer().addPotionEffect(effect);
}
}
});
}
} }
@EventHandler @EventHandler
@ -173,12 +27,12 @@ public record PlayerListener(FeelingLucky plugin) implements Listener {
Action action = event.getAction(); Action action = event.getAction();
ItemStack foot = new ItemStack(Material.RABBIT_FOOT); ItemStack foot = new ItemStack(Material.RABBIT_FOOT);
Player player = event.getPlayer(); Player player = event.getPlayer();
Luck luck = PlayerHandler.getLuckContainer(player); Luck luck = plugin.handler.getLuckContainer(player);
if (action.isRightClick() && player.getInventory().getItemInMainHand().isSimilar(foot)) { 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()); player.getInventory().remove(player.getInventory().getItemInMainHand());
luck.addTo(rng); luck.addTo(rng);
plugin.handler.updatePlayer(player, luck);
player.sendMessage(Component.empty().content("Your luck has been increased by " + rng + " points.")); player.sendMessage(Component.empty().content("Your luck has been increased by " + rng + " points."));
} }
} }
@ -187,7 +41,7 @@ public record PlayerListener(FeelingLucky plugin) implements Listener {
public void witchesBrew(EntityDamageByEntityEvent event) { public void witchesBrew(EntityDamageByEntityEvent event) {
Entity eTEMP = event.getDamager(); Entity eTEMP = event.getDamager();
Entity pTEMP = event.getEntity(); Entity pTEMP = event.getEntity();
DamageCause cause = event.getCause(); EntityDamageEvent.DamageCause cause = event.getCause();
if (!(pTEMP instanceof Player player)) { if (!(pTEMP instanceof Player player)) {
return; return;
@ -197,8 +51,8 @@ public record PlayerListener(FeelingLucky plugin) implements Listener {
return; return;
} }
Luck luck = PlayerHandler.getLuckContainer(player); Luck luck = plugin.handler.getLuckContainer(player);
if (cause.equals(DamageCause.MAGIC) || cause.equals(DamageCause.POISON)) { if (cause.equals(EntityDamageEvent.DamageCause.MAGIC) || cause.equals(EntityDamageEvent.DamageCause.POISON)) {
if (luck.quickRNG(33.0)) { if (luck.quickRNG(33.0)) {
luck.takeFrom(5.0); luck.takeFrom(5.0);
plugin.handler.updatePlayer(player, luck); plugin.handler.updatePlayer(player, luck);

View File

@ -0,0 +1,37 @@
package io.github.simplex.luck.listener;
import io.github.simplex.lib.PotionEffectBuilder;
import io.github.simplex.luck.FeelingLucky;
import io.github.simplex.luck.ListBox;
import io.github.simplex.luck.player.Luck;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerItemConsumeEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
public record RestoreHunger(FeelingLucky plugin) implements Listener {
public RestoreHunger {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void restoreHunger(PlayerItemConsumeEvent event) {
ItemStack item = event.getItem();
Luck luck = plugin.handler.getLuckContainer(event.getPlayer());
PotionEffect effect = PotionEffectBuilder.newEffect().type(PotionEffectType.SATURATION).amplifier(2).duration(10).particles(false).create();
if (luck.notDefault()) {
double percentage = luck.getPercentage();
ListBox.foods.forEach(food -> {
if (item.isSimilar(food)) {
if (luck.quickRNG(percentage)) {
event.getPlayer().setExhaustion(event.getPlayer().getExhaustion() + 2);
event.getPlayer().addPotionEffect(effect);
}
}
});
}
}
}

View File

@ -0,0 +1,80 @@
package io.github.simplex.luck.listener;
import io.github.simplex.lib.PotionEffectBuilder;
import io.github.simplex.luck.FeelingLucky;
import io.github.simplex.luck.ListBox;
import io.github.simplex.luck.player.Luck;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent;
public record TakeDamage(FeelingLucky plugin) implements Listener {
public TakeDamage {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void takeDamage(EntityDamageEvent event) {
Entity entity = event.getEntity();
if (!(entity instanceof Player)) {
return;
}
Player player = (Player) event.getEntity();
Luck luck = plugin.handler.getLuckContainer(player);
if (ListBox.acceptedCauses.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 || luck.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);
player.sendMessage(Component.empty().content("You got lucky and took less damage."));
}
}
}
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 || luck.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()));
player.setFireTicks(0);
player.sendMessage(Component.empty().content("You got lucky and your afflictions were cured."));
}
}
}
}
}

View File

@ -1,30 +1,37 @@
package io.github.simplex.luck.player; package io.github.simplex.luck.player;
import io.github.simplex.api.LuckContainer; import io.github.simplex.api.LuckContainer;
import io.github.simplex.luck.FeelingLucky;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.attribute.Attribute; import org.bukkit.attribute.Attribute;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.SplittableRandom; import java.util.SplittableRandom;
@SuppressWarnings("all") @SuppressWarnings("all")
public class Luck implements LuckContainer { public class Luck implements LuckContainer {
private final Player player; private final Player player;
private final double multiplier; private final double multiplier;
private final double BASE_VALUE;
private final PlayerLuckChangeEvent event; private final PlayerLuckChangeEvent event;
private final FeelingLucky plugin;
private final List<Player> markedPlayers = new ArrayList<>();
private double BASE_VALUE;
public Luck(Player player) { public Luck(FeelingLucky plugin, Player player) {
this(player, 1.0); this(plugin, player, 1.0);
} }
public Luck(Player player, double multiplier) { public Luck(FeelingLucky plugin, Player player, double multiplier) {
this.player = player; this.player = player;
this.multiplier = multiplier; this.multiplier = multiplier;
BASE_VALUE = player.getAttribute(Attribute.GENERIC_LUCK).getDefaultValue(); this.plugin = plugin;
event = new PlayerLuckChangeEvent(player); BASE_VALUE = plugin.getConfigMap().get(player.getUniqueId()).getConfig().getDouble("luck");
event = new PlayerLuckChangeEvent(this);
} }
@Contract(pure = true, @Contract(pure = true,
@ -33,15 +40,33 @@ public class Luck implements LuckContainer {
return new SplittableRandom(); return new SplittableRandom();
} }
public static boolean quickRNG2(double percentage) { public static boolean quickRNGnoMultiplier(double percentage) {
double rng; double rng;
if (percentage >= 100.0) { if (percentage >= 100.0) {
rng = 100.0; // 100% chance to trigger, obviously; rng = 1024.0; // 100% chance to trigger, obviously;
} else { } else {
rng = RNG().nextDouble(0.0, 99.0); rng = RNG().nextDouble(0.0, 1024.0);
} }
return (percentage >= rng); double actual = Math.round((rng / 1024.0) * 100);
return (percentage >= actual);
}
public FeelingLucky getPlugin() {
return plugin;
}
public void markPlayer(Player player) {
markedPlayers.add(player);
}
public void unmarkPlayer(Player player) {
markedPlayers.remove(player);
}
public boolean isMarked(Player player) {
return markedPlayers.contains(player);
} }
@Override @Override
@ -77,60 +102,74 @@ public class Luck implements LuckContainer {
public boolean quickRNG(double percentage) { public boolean quickRNG(double percentage) {
double rng; double rng;
if (percentage >= 100.0) { if (percentage >= 100.0) {
rng = 100.0; // 100% chance to trigger, obviously; rng = 1024.0; // 100% chance to trigger, obviously;
} else { } else {
rng = RNG().nextDouble(0.0, 99.0); rng = RNG().nextDouble(0.0, 1024.0);
} }
double actual = Math.round((rng / 1024) * 100);
if (multiplier() > 1.0) { if (multiplier() > 1.0) {
return ((percentage * multiplier()) >= rng); return ((percentage * multiplier()) >= actual);
} }
return (percentage >= rng); return (percentage >= actual);
}
public void reset() {
setValue(getDefaultValue());
} }
@Override @Override
public double baseValue() { public double getValue() {
return BASE_VALUE; return BASE_VALUE;
} }
public double defaultValue() { public void setValue(double value) {
BASE_VALUE = value;
player.getAttribute(Attribute.GENERIC_LUCK).setBaseValue(value);
plugin.getConfigMap().get(associatedPlayer().getUniqueId()).setLuck(value);
Bukkit.getPluginManager().callEvent(event);
}
public double getDefaultValue() {
return player.getAttribute(Attribute.GENERIC_LUCK).getDefaultValue(); return player.getAttribute(Attribute.GENERIC_LUCK).getDefaultValue();
} }
protected void setValue(double value) {
player.getAttribute(Attribute.GENERIC_LUCK).setBaseValue(value);
Bukkit.getPluginManager().callEvent(event);
}
public void addTo(double value) { public void addTo(double value) {
setValue(baseValue() + value); if (value >= 1024.0 || (getValue() + value) >= 1024.0) {
Bukkit.getPluginManager().callEvent(event); setValue(1024.0);
return;
}
setValue(getValue() + value);
} }
public void takeFrom(double value) { public void takeFrom(double value) {
setValue(baseValue() - value); if (value <= -1024.0 || (getValue() - value) <= -1024.0) {
Bukkit.getPluginManager().callEvent(event); setValue(-1024.0);
return;
}
setValue(getValue() + value);
} }
public double getPercentage() { public double getPercentage() {
return baseValue() - defaultValue(); return getValue() - getDefaultValue();
} }
public boolean notDefault() { public boolean notDefault() {
return baseValue() != defaultValue(); return getValue() != getDefaultValue();
} }
public boolean lessThan(double value) { public boolean lessThan(double value) {
return baseValue() < value; return getValue() < value;
} }
public boolean greaterThan(double value) { public boolean greaterThan(double value) {
return baseValue() > value; return getValue() > value;
} }
@Override @Override
public String toString() { public String toString() {
return "" + baseValue(); return "" + getValue();
} }
} }

View File

@ -2,6 +2,7 @@ package io.github.simplex.luck.player;
import io.github.simplex.luck.FeelingLucky; import io.github.simplex.luck.FeelingLucky;
import io.github.simplex.luck.SneakyWorker; import io.github.simplex.luck.SneakyWorker;
import org.bukkit.attribute.Attribute;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
@ -11,18 +12,20 @@ import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
public class PlayerConfig extends YamlConfiguration { public class PlayerConfig {
private final File configFile; private final File configFile;
private final FeelingLucky plugin;
private volatile YamlConfiguration config; private volatile YamlConfiguration config;
@SuppressWarnings("ResultOfMethodCallIgnored") @SuppressWarnings("ResultOfMethodCallIgnored")
public PlayerConfig(FeelingLucky plugin, Player player) { public PlayerConfig(FeelingLucky plugin, Player player) {
this.plugin = plugin;
File dataFolder = plugin.getDataFolder(); File dataFolder = plugin.getDataFolder();
if (!dataFolder.exists()) dataFolder.mkdirs(); if (!dataFolder.exists()) dataFolder.mkdirs();
File file = new File(dataFolder, player.getUniqueId() + ".yml"); File file = new File(dataFolder, player.getUniqueId() + ".yml");
if (!file.exists()) { if (!file.exists()) {
String name = "username: " + player.getName(); String name = "username: " + player.getName();
String luck = "luck: " + PlayerHandler.getLuckContainer(player).defaultValue(); String luck = "luck: " + player.getAttribute(Attribute.GENERIC_LUCK).getDefaultValue();
String multiplier = "multiplier: " + 1.0; String multiplier = "multiplier: " + 1.0;
SneakyWorker.sneakyTry(() -> { SneakyWorker.sneakyTry(() -> {
@ -38,26 +41,30 @@ public class PlayerConfig extends YamlConfiguration {
}); });
} }
configFile = file; configFile = file;
config = loadConfiguration(configFile); config = YamlConfiguration.loadConfiguration(configFile);
String tempUsername = config.getString("username"); String tempUsername = config.getString("username");
if (tempUsername != null && tempUsername.equalsIgnoreCase("replace")) { if (tempUsername == null) {
config.set("username", player.getName()); config.set("username", player.getName());
config.set("luck", PlayerHandler.getLuckContainer(player).defaultValue()); config.set("luck", plugin.handler.getLuckContainer(player).getDefaultValue());
config.set("multiplier", "1.0"); config.set("multiplier", "1.0");
save(); save();
} else if (!tempUsername.equalsIgnoreCase(player.getName())) {
config.set("username", player.getName());
save();
} }
} }
protected PlayerConfig(File file) { protected PlayerConfig(FeelingLucky plugin, File file) {
this.plugin = plugin;
this.configFile = file; this.configFile = file;
config = loadConfiguration(configFile); config = YamlConfiguration.loadConfiguration(configFile);
} }
@Contract("_ -> new") @Contract("_, _ -> new")
public static PlayerConfig loadFrom(File file) { public static PlayerConfig loadFrom(FeelingLucky plugin, File file) {
return new PlayerConfig(file); return new PlayerConfig(plugin, file);
} }
public void save() { public void save() {
@ -65,7 +72,17 @@ public class PlayerConfig extends YamlConfiguration {
} }
public void load() { public void load() {
SneakyWorker.sneakyTry(() -> config = loadConfiguration(configFile)); SneakyWorker.sneakyTry(() -> config = YamlConfiguration.loadConfiguration(configFile));
}
public void reload() {
save();
load();
}
public void setLuck(double luck) {
config.set("luck", luck);
save();
} }
public YamlConfiguration getConfig() { public YamlConfiguration getConfig() {

View File

@ -1,63 +1,55 @@
package io.github.simplex.luck.player; package io.github.simplex.luck.player;
import io.github.simplex.luck.FeelingLucky; import io.github.simplex.luck.FeelingLucky;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerLoginEvent;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
public record PlayerHandler(FeelingLucky plugin) implements Listener { public class PlayerHandler implements Listener {
private static final Map<Player, Luck> playerLuckMap = new HashMap<>(); public final FeelingLucky plugin;
private static final List<Player> markedPlayers = new ArrayList<>(); private final Map<Player, Luck> playerLuckMap = new HashMap<>();
public static Luck getLuckContainer(Player player) { public PlayerHandler(FeelingLucky plugin) {
this.plugin = plugin;
Bukkit.getServer().getPluginManager().registerEvents(this, plugin);
}
public Luck getLuckContainer(Player player) {
return playerLuckMap.get(player); 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();
PlayerConfig config = FeelingLucky.getConfigMap().get(player.getUniqueId());
if (config == null) {
config = new PlayerConfig(plugin, player);
FeelingLucky.getConfigMap().put(player.getUniqueId(), config);
}
String username = config.getString("username");
double luck = config.getDouble("luck");
double multiplier = config.getDouble("multiplier");
if (!player.getName().equalsIgnoreCase(username)) {
config.set("username", player.getName());
config.save();
config.load();
}
Luck container = new Luck(player, multiplier);
container.setValue(luck);
playerLuckMap.put(player, container);
}
public void updatePlayer(Player player, Luck luck) { public void updatePlayer(Player player, Luck luck) {
playerLuckMap.replace(player, luck); playerLuckMap.replace(player, luck);
} }
@EventHandler
public void initializePlayer(PlayerLoginEvent event) {
Player player = event.getPlayer();
PlayerConfig playerConfig = plugin.getConfigMap().get(player.getUniqueId());
if (playerConfig == null) {
playerConfig = new PlayerConfig(plugin, player);
plugin.getConfigMap().put(player.getUniqueId(), playerConfig);
}
String username = playerConfig.getConfig().getString("username");
double luck = playerConfig.getConfig().getDouble("luck");
double multiplier = playerConfig.getConfig().getDouble("multiplier");
if (!player.getName().equalsIgnoreCase(username)) {
playerConfig.getConfig().set("username", player.getName());
playerConfig.save();
playerConfig.load();
}
Luck container = new Luck(plugin, player, multiplier);
container.setValue(luck);
playerLuckMap.put(player, container);
}
} }

View File

@ -1,6 +1,5 @@
package io.github.simplex.luck.player; package io.github.simplex.luck.player;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent; import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -8,16 +7,16 @@ import org.jetbrains.annotations.NotNull;
public class PlayerLuckChangeEvent extends PlayerEvent { public class PlayerLuckChangeEvent extends PlayerEvent {
public final HandlerList handlerList = new HandlerList(); public final HandlerList handlerList = new HandlerList();
public PlayerLuckChangeEvent(@NotNull Player who) { public PlayerLuckChangeEvent(@NotNull Luck luck) {
super(who); super(luck.associatedPlayer());
Luck luck = PlayerHandler.getLuckContainer(who);
if (luck.lessThan(0.0) && !PlayerHandler.isMarked(who)) { if (luck.lessThan(0.0) && !luck.isMarked(luck.associatedPlayer())) {
PlayerHandler.markPlayer(who); luck.markPlayer(luck.associatedPlayer());
return; return;
} }
if (luck.greaterThan(0.0) && PlayerHandler.isMarked(who)) { if (luck.greaterThan(0.0) && luck.isMarked(luck.associatedPlayer())) {
PlayerHandler.unmarkPlayer(who); luck.unmarkPlayer(luck.associatedPlayer());
} }
} }