Update for 1.20.3

- Added verbose entry to the Player configuration files. Player configuration files will need to be regenerated. Please make sure to make backups of all configurations before regenerating configuration files.
- Fixed a bug with the hide feature; now, any entity within a 25 block radius will automatically lose target of the player when their luck activates while sneaking.
- Removed the vein-mining feature as it is unstable and non-functional. A fix and/or replacement will be implemented in a future update.
- Updated supported version to 1.20.3
- Adjusted Logging methods.
This commit is contained in:
Paul Reilly 2023-12-07 20:38:47 -06:00
parent 32a9435e30
commit c4e29ff728
30 changed files with 610 additions and 270 deletions

View File

@ -3,7 +3,7 @@ plugins {
}
group = 'io.github.simplex'
version = '1.2.1'
version = '1.3.0'
repositories {
mavenCentral()
@ -12,7 +12,7 @@ repositories {
}
dependencies {
compileOnly("io.papermc.paper:paper-api:1.19-R0.1-SNAPSHOT")
compileOnly("io.papermc.paper:paper-api:1.20.3-R0.1-SNAPSHOT")
}
def targetJavaVersion = 17

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@ -1,10 +1,14 @@
package io.github.simplex.api;
import java.io.Serializable;
import org.bukkit.entity.Player;
import java.io.Serializable;
public interface LuckContainer extends Serializable
{
public interface LuckContainer extends Serializable {
boolean isVerbose();
void setVerbose(boolean verbose);
boolean isMatch(double number);

View File

@ -1,21 +1,24 @@
package io.github.simplex.lib;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentLike;
public enum Messages {
public enum Messages
{
NOT_FROM_CONSOLE(MiniComponent.err("This command may only be used in game.")),
NO_PERMISSION(MiniComponent.err("You do not have permission to use this command.")),
NO_PLAYER(MiniComponent.warn("That player cannot be found.")),
OUT_OF_BOUNDS(MiniComponent.err("Number must be between -1024.0 and 1024.0"));
private final Component message;
private final ComponentLike message;
Messages(Component message) {
Messages(ComponentLike message)
{
this.message = message;
}
public Component get() {
public ComponentLike get()
{
return message;
}
}

View File

@ -1,10 +1,12 @@
package io.github.simplex.lib;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentLike;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.ChatColor;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;
public class MiniComponent {
private final String content;
@ -21,17 +23,17 @@ public class MiniComponent {
}
@Contract("_ -> new")
public static Component info(String content) {
public static ComponentLike info(String content) {
return new MiniComponent(content).color(ChatColor.GREEN).send();
}
@Contract("_ -> new")
public static Component warn(String content) {
public static ComponentLike warn(String content) {
return new MiniComponent(content).color(ChatColor.YELLOW).decorate(TextDecoration.ITALIC).send();
}
@Contract("_ -> new")
public static Component err(String content) {
public static ComponentLike err(String content) {
return new MiniComponent(content).color(ChatColor.RED).decorate(TextDecoration.BOLD).send();
}
@ -45,7 +47,7 @@ public class MiniComponent {
return this;
}
public Component send() {
public @Nullable Component send() {
if (color == null) {
if (decoration == null) return Component.empty().content(content);

View File

@ -1,17 +1,19 @@
package io.github.simplex.luck;
import io.github.simplex.luck.listener.AbstractListener;
import io.github.simplex.luck.util.Logs;
import io.github.simplex.luck.util.SneakyWorker;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("ResultOfMethodCallIgnored")
public class Config extends YamlConfiguration {
private final Map<String, Object> configEntries = new HashMap<>() {{
public class Config extends YamlConfiguration
{
private final Map<String, Object> configEntries = new HashMap<>()
{{
put("high_rarity_chance", 512.0);
put("medium_rarity_chance", 128.0);
put("low_rarity_chance", 64.0);
@ -32,26 +34,32 @@ public class Config extends YamlConfiguration {
}};
private File configFile;
public Config(FeelingLucky plugin) {
public Config(FeelingLucky plugin)
{
File dataFolder = plugin.getDataFolder();
if (dataFolder.mkdirs()) {
if (dataFolder.mkdirs())
{
plugin.getLogger().info("Created new data folder. Writing new configuration file...");
plugin.saveResource("config.yml", true);
}
File configFile = new File(dataFolder, "config.yml");
if (!configFile.exists()) {
if (!configFile.exists())
{
plugin.getLogger().info("No configuration file exists. Creating a new one...");
plugin.saveResource("config.yml", true);
}
this.configFile = configFile;
if (validateIntegrity(this.configFile)) {
if (validateIntegrity(this.configFile))
{
load();
} else {
}
else
{
configEntries.forEach(super::set);
plugin.getLogger().warning("Your configuration file is missing keys. " +
Logs.warn("Your configuration file is missing keys. " +
"\nPlease use /rgc in the console to regenerate the config file. " +
"\nAlternatively, delete the config.yml and restart your server. " +
"\nIt is safe to ignore this, as default values will be used." +
@ -59,40 +67,50 @@ public class Config extends YamlConfiguration {
}
}
public void save() {
public void save()
{
SneakyWorker.sneakyTry(() -> save(configFile));
}
public void load() {
public void load()
{
SneakyWorker.sneakyTry(() -> load(configFile));
}
public void reload() {
public void reload()
{
save();
load();
}
public boolean validateIntegrity(@NotNull File fromDisk) {
public boolean validateIntegrity(@NotNull File fromDisk)
{
YamlConfiguration disk = YamlConfiguration.loadConfiguration(fromDisk);
if (disk.getKeys(true).size() <= 0) {
if (disk.getKeys(true).isEmpty())
{
return false;
}
boolean result = true;
for (String key : configEntries.keySet()) {
if (!disk.getKeys(false).contains(key)) {
if (result) result = false;
for (String key : configEntries.keySet())
{
if (!disk.getKeys(false).contains(key))
{
if (result)
result = false;
}
}
return result;
}
public AbstractListener.Rarity getRarity(String name) {
public AbstractListener.Rarity getRarity(String name)
{
return AbstractListener.Rarity.valueOf(getString(name));
}
public double getChance(String path) {
public double getChance(String path)
{
return getDouble(path);
}
}

View File

@ -7,30 +7,34 @@ import io.github.simplex.luck.util.LuckCMD;
import io.github.simplex.luck.util.RegenerateConfigCMD;
import io.github.simplex.luck.util.SpecialFootItem;
import io.github.simplex.metrics.Metrics;
import org.bukkit.command.CommandMap;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import net.kyori.adventure.chat.ChatType;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandMap;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
public final class FeelingLucky extends JavaPlugin {
public final class FeelingLucky extends JavaPlugin
{
private final Map<UUID, PlayerConfig> configMap = new HashMap<>();
private final File playerDirectory = new File(getDataFolder(), "players");
private final SpecialFootItem specialFootItem = new SpecialFootItem();
private final ChatType.Bound bind = ChatType.CHAT.bind(Component.text(getName()));
private PlayerHandler handler;
private Config config;
public Map<UUID, PlayerConfig> getConfigMap() {
public Map<UUID, PlayerConfig> getConfigMap()
{
return configMap;
}
@Override
public void onEnable() {
public void onEnable()
{
getLogger().info("Initializing metrics...");
new Metrics(this, 15054);
getLogger().info("Metrics loaded. Initializing the PlayerHandler...");
@ -50,7 +54,8 @@ public final class FeelingLucky extends JavaPlugin {
}
@Override
public void onDisable() {
public void onDisable()
{
getLogger().info("Saving all player configurations...");
configMap.values().forEach(PlayerConfig::save);
getLogger().info("Complete! Saving the main config...");
@ -58,8 +63,10 @@ public final class FeelingLucky extends JavaPlugin {
getLogger().info("Complete! Goodbye! :)");
}
private void loadPlayerConfigurations() {
if (!playerDirectory.exists()) {
private void loadPlayerConfigurations()
{
if (!playerDirectory.exists())
{
getLogger().info("No directory exists. Creating...");
playerDirectory.mkdirs();
getLogger().info("Created new directory \"FeelingLucky/players\".");
@ -67,19 +74,24 @@ public final class FeelingLucky extends JavaPlugin {
}
File[] files = playerDirectory.listFiles();
if (files != null) {
Arrays.stream(files).forEach(file -> {
if (files != null)
{
Arrays.stream(files).forEach(file ->
{
UUID uuid = UUID.fromString(file.getName().split("\\.")[0]);
configMap.put(uuid, PlayerConfig.initFrom(this, file));
});
configMap.forEach((u, pc) -> pc.load());
getLogger().info("Successfully loaded all configurations!");
} else {
}
else
{
getLogger().info("There are no player configurations to load.");
}
}
private void registerListeners() {
private void registerListeners()
{
new BlockDrops(this);
new BonemealFullCrop(this);
new CheatDeath(this);
@ -90,7 +102,7 @@ public final class FeelingLucky extends JavaPlugin {
new IllOmen(this);
new ItemDrops(this);
new JumpBoost(this);
new OreVein(this);
// new OreVein(this); (Currently unstable & unsafe).
new PlayerListener(this);
new RandomEffect(this);
new RestoreHunger(this);
@ -99,21 +111,30 @@ public final class FeelingLucky extends JavaPlugin {
new VillagerInventory(this);
}
public PlayerHandler getHandler() {
public PlayerHandler getHandler()
{
return handler;
}
@Override
@NotNull
public Config getConfig() {
public Config getConfig()
{
return config;
}
public SpecialFootItem getFoot() {
public SpecialFootItem getFoot()
{
return specialFootItem;
}
public CommandMap getCommandMap() {
public CommandMap getCommandMap()
{
return getServer().getCommandMap();
}
public ChatType.Bound bind()
{
return bind;
}
}

View File

@ -1,8 +1,9 @@
package io.github.simplex.luck.listener;
import io.github.simplex.luck.Config;
import io.github.simplex.luck.FeelingLucky;
import io.github.simplex.luck.player.PlayerHandler;
import net.kyori.adventure.audience.Audience;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
public abstract class AbstractListener implements Listener {
@ -35,4 +36,8 @@ public abstract class AbstractListener implements Listener {
LOW,
NONE
}
public Audience asAudience(final Player player) {
return player;
}
}

View File

@ -1,28 +1,35 @@
package io.github.simplex.luck.listener;
import io.github.simplex.lib.MiniComponent;
import io.github.simplex.luck.FeelingLucky;
import io.github.simplex.luck.player.Luck;
import io.github.simplex.luck.util.SneakyWorker;
import java.util.List;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockDropItemEvent;
import java.util.List;
public final class BlockDrops extends AbstractListener {
public BlockDrops(FeelingLucky plugin) {
public final class BlockDrops extends AbstractListener
{
public BlockDrops(FeelingLucky plugin)
{
super(plugin);
register(this);
}
@EventHandler
public void extraBlockDrops(BlockDropItemEvent event) {
public void extraBlockDrops(BlockDropItemEvent event)
{
Player player = event.getPlayer();
Luck luck = getHandler().getLuckContainer(player);
List<Item> items = event.getItems();
if (luck.quickRNG(luck.getValue()) && doesQualify("block_drops", luck.getValue())) {
if (luck.quickRNG(luck.getValue()) && doesQualify("block_drops", luck.getValue()))
{
event.getItems().addAll(items.stream().map(SneakyWorker::move).toList());
}
if (luck.isVerbose())
asAudience(player).sendMessage(MiniComponent.info("You got lucky and received extra drops!"));
}
}

View File

@ -4,6 +4,7 @@ import io.github.simplex.lib.ItemBuilder;
import io.github.simplex.lib.MiniComponent;
import io.github.simplex.luck.FeelingLucky;
import io.github.simplex.luck.player.Luck;
import net.kyori.adventure.audience.Audience;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.data.Ageable;
@ -23,6 +24,7 @@ public final class BonemealFullCrop extends AbstractListener {
@EventHandler
public void bonemealFullCrop(PlayerInteractEvent event) {
Player player = event.getPlayer();
Audience pAud = player;
Action action = event.getAction();
ItemStack bonemeal = ItemBuilder.of(Material.BONE_MEAL).build();
Luck luck = getHandler().getLuckContainer(player);
@ -43,6 +45,12 @@ public final class BonemealFullCrop extends AbstractListener {
crop.setAge(crop.getMaximumAge());
data.merge(crop);
block.setBlockData(data);
if (luck.isVerbose()) {
asAudience(player).sendMessage(MiniComponent.info("Your luck has caused your crop to become ready for" +
" " +
"harvest!"));
}
}
}
}

View File

@ -3,26 +3,35 @@ package io.github.simplex.luck.listener;
import io.github.simplex.lib.MiniComponent;
import io.github.simplex.luck.FeelingLucky;
import io.github.simplex.luck.player.Luck;
import net.kyori.adventure.audience.Audience;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.PlayerDeathEvent;
public final class CheatDeath extends AbstractListener {
public CheatDeath(FeelingLucky plugin) {
public final class CheatDeath extends AbstractListener
{
public CheatDeath(FeelingLucky plugin)
{
super(plugin);
register(this);
}
@EventHandler
public void cheatDeath(PlayerDeathEvent event) {
public void cheatDeath(PlayerDeathEvent event)
{
Player player = event.getPlayer();
Luck luck = getHandler().getLuckContainer(player);
double absorption = Math.round(Luck.RNG().nextDouble(5.0, 10.0));
if (luck.quickRNG(luck.getValue()) && doesQualify("cheat_death", luck.getValue())) {
if (luck.quickRNG(luck.getValue()) && doesQualify("cheat_death", luck.getValue()))
{
event.setCancelled(true);
player.setHealth(1.0);
player.setAbsorptionAmount(absorption);
player.sendMessage(MiniComponent.of("You got lucky and cheated death!").send());
if (luck.isVerbose())
{
asAudience(player).sendMessage(MiniComponent.info("You got lucky and cheated death!"));
}
}
}
}

View File

@ -1,40 +1,52 @@
package io.github.simplex.luck.listener;
import io.github.simplex.lib.MiniComponent;
import io.github.simplex.luck.FeelingLucky;
import io.github.simplex.luck.player.Luck;
import java.util.List;
import java.util.Map;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.enchantment.EnchantItemEvent;
import java.util.List;
import java.util.Map;
public final class EnchantmentBoost extends AbstractListener {
public EnchantmentBoost(FeelingLucky plugin) {
public final class EnchantmentBoost extends AbstractListener
{
public EnchantmentBoost(FeelingLucky plugin)
{
super(plugin);
register(this);
}
@EventHandler
public void enchantItem(EnchantItemEvent event) {
public void enchantItem(EnchantItemEvent event)
{
Map<Enchantment, Integer> enchMap = event.getEnchantsToAdd();
List<Enchantment> enchList = enchMap.keySet().stream().toList();
Player player = event.getEnchanter();
Luck luck = getHandler().getLuckContainer(player);
if (luck.quickRNG(luck.getValue()) && doesQualify("enchanting", luck.getValue())) {
if (luck.quickRNG(luck.getValue()) && doesQualify("enchanting", luck.getValue()))
{
Enchantment particular = enchList.get(Luck.RNG().nextInt(enchList.size()));
int rng = Luck.RNG().nextInt(1, 5);
if ((enchMap.get(particular) + rng) > particular.getMaxLevel()) {
if ((enchMap.get(particular) + rng) > particular.getMaxLevel())
{
enchMap.replace(particular, particular.getMaxLevel());
}
enchMap.replace(particular, enchMap.get(particular) + rng);
if (luck.isVerbose())
{
asAudience(player).sendMessage(
MiniComponent.info("Your luck has given you an extra random enchantment."));
}
}
}
public FeelingLucky plugin() {
public FeelingLucky plugin()
{
return plugin;
}
}

View File

@ -1,28 +1,38 @@
package io.github.simplex.luck.listener;
import com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent;
import io.github.simplex.lib.MiniComponent;
import io.github.simplex.luck.FeelingLucky;
import io.github.simplex.luck.player.Luck;
import org.bukkit.entity.ExperienceOrb;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
public final class ExpBoost extends AbstractListener {
public ExpBoost(FeelingLucky plugin) {
public final class ExpBoost extends AbstractListener
{
public ExpBoost(FeelingLucky plugin)
{
super(plugin);
register(this);
}
@EventHandler
public void boostExperienceGain(PlayerPickupExperienceEvent event) {
public void boostExperienceGain(PlayerPickupExperienceEvent event)
{
ExperienceOrb orb = event.getExperienceOrb();
int n = orb.getExperience();
int math = (5 * n ^ 2) / (2 * n + 4);
int rounded = Math.round(math);
Player player = event.getPlayer();
Luck luck = plugin.getHandler().getLuckContainer(player);
if (luck.quickRNG(luck.getValue()) && doesQualify("experience", luck.getValue())) {
if (luck.quickRNG(luck.getValue()) && doesQualify("experience", luck.getValue()))
{
orb.setExperience(rounded);
if (luck.isVerbose())
{
asAudience(player).sendMessage(
MiniComponent.info("Your luck has given you extra experience!"));
}
}
}
}

View File

@ -8,20 +8,30 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
public class GiveDamage extends AbstractListener {
public GiveDamage(FeelingLucky plugin) {
public class GiveDamage extends AbstractListener
{
public GiveDamage(FeelingLucky plugin)
{
super(plugin);
register(this);
}
@EventHandler
public void playerAttack(EntityDamageByEntityEvent e) {
public void playerAttack(EntityDamageByEntityEvent e)
{
if ((e.getDamager() instanceof Player player)
&& (e.getEntity() instanceof LivingEntity)) {
&& (e.getEntity() instanceof LivingEntity))
{
double nextDmg = e.getDamage() + Luck.RNG().nextDouble(1.0, 5.0);
Luck luck = plugin.getHandler().getLuckContainer(player);
if (luck.quickRNG(luck.getValue()) && doesQualify("give_damage", luck.getValue())) {
if (luck.quickRNG(luck.getValue()) && doesQualify("give_damage", luck.getValue()))
{
e.setDamage(nextDmg);
if (luck.isVerbose())
{
asAudience(player).sendMessage(
MiniComponent.info("Your luck gave you a critical hit!"));
}
}
}
}

View File

@ -3,58 +3,47 @@ package io.github.simplex.luck.listener;
import io.github.simplex.lib.MiniComponent;
import io.github.simplex.luck.FeelingLucky;
import io.github.simplex.luck.player.Luck;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Monster;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import java.util.*;
public class HideCheck extends AbstractListener {
public Map<Player, List<Entity>> entityMapList = new HashMap<>();
public HideCheck(FeelingLucky plugin) {
public class HideCheck extends AbstractListener
{
public HideCheck(FeelingLucky plugin)
{
super(plugin);
register(this);
}
@EventHandler
public void initPlayerMaps(PlayerJoinEvent event) {
entityMapList.put(event.getPlayer(), List.of());
}
@EventHandler
public void checkTargeting(EntityTargetLivingEntityEvent event) {
if (event.getTarget() instanceof Player player) {
if (event.getEntity() instanceof LivingEntity entity) {
List<Entity> buffer = entityMapList.get(player).isEmpty() ?
new ArrayList<>() : entityMapList.get(player);
buffer.add(entity);
entityMapList.replace(player, buffer);
}
}
}
@EventHandler
public void checkForSneak(PlayerToggleSneakEvent event) {
public void checkForSneak(PlayerToggleSneakEvent event)
{
Player player = event.getPlayer();
if (player.isSneaking()) return;
if (player.isSneaking())
return;
Luck luck = plugin.getHandler().getLuckContainer(player);
if (luck.quickRNG(luck.getValue()) && doesQualify("hide_check", luck.getValue())) {
entityMapList.get(player).forEach(e -> {
e.getTrackedPlayers().remove(player);
if (luck.quickRNG(luck.getValue()) && doesQualify("hide_check", luck.getValue()))
{
player.getNearbyEntities(25, 25, 25)
.stream()
.filter(e -> e instanceof Monster)
.map(e -> (Monster) e)
.forEach(m ->
{
final LivingEntity target = m.getTarget();
if (target != null && target.getUniqueId().equals(player.getUniqueId()))
{
m.setTarget(null);
}
});
player.sendMessage(MiniComponent.info("Your luck has hidden you from sight."));
}
}
@EventHandler
public void removePlayerOnLeave(PlayerQuitEvent event) {
entityMapList.remove(event.getPlayer());
if (luck.isVerbose())
{
asAudience(player).sendMessage(MiniComponent.info("Your luck has hidden you from sight."));
}
}
}
}

View File

@ -11,70 +11,92 @@ import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
public class IllOmen extends AbstractListener {
public IllOmen(FeelingLucky plugin) {
public class IllOmen extends AbstractListener
{
public IllOmen(FeelingLucky plugin)
{
super(plugin);
register(this);
}
@EventHandler
public void reconnectCheck(PlayerJoinEvent event) {
public void reconnectCheck(PlayerJoinEvent event)
{
Player player = event.getPlayer();
PotionEffectType type = PotionEffectType.BAD_OMEN;
Luck luck = getHandler().getLuckContainer(player);
if (player.hasPotionEffect(type)) {
if (player.hasPotionEffect(type))
{
luck.cache();
double maths = luck.getValue() - (luck.getValue() * 0.25);
luck.setValue(maths);
player.sendMessage(MiniComponent.info("A -25% debuff has been applied to your luck from the Bad Omen status effect."));
} else if (luck.cached(player) && !player.hasPotionEffect(type)) {
asAudience(player).sendMessage(MiniComponent.info("A -25% debuff has been applied to your luck from the " +
"Bad Omen " +
"status effect."));
}
else if (luck.cached(player) && !player.hasPotionEffect(type))
{
luck.restore();
player.sendMessage("The -25% debuff to your luck has been removed.");
asAudience(player).sendMessage(MiniComponent.info("The -25% debuff to your luck has been removed."));
}
}
@EventHandler
public void effectApplyCheck(EntityPotionEffectEvent event) {
public void effectApplyCheck(EntityPotionEffectEvent event)
{
EntityPotionEffectEvent.Cause cause = EntityPotionEffectEvent.Cause.PATROL_CAPTAIN;
EntityPotionEffectEvent.Action added = EntityPotionEffectEvent.Action.ADDED;
EntityPotionEffectEvent.Action changed = EntityPotionEffectEvent.Action.CHANGED;
if (event.getCause().equals(cause) && (event.getAction().equals(added) || event.getAction().equals(changed))) {
if (event.getEntity() instanceof Player player) {
if (event.getCause().equals(cause) && (event.getAction().equals(added) || event.getAction().equals(changed)))
{
if (event.getEntity() instanceof Player player)
{
Luck luck = plugin.getHandler().getLuckContainer(player);
luck.cache();
double maths = luck.getValue() - (luck.getValue() * 0.25);
luck.setValue(maths);
player.sendMessage(MiniComponent.warn("A -25% debuff has been applied to your luck from the Bad Omen status effect."));
asAudience(player).sendMessage(
MiniComponent.warn("A -25% debuff has been applied to your luck from the Bad Omen status effect."));
}
}
}
@EventHandler
public void effectRemoveCheck(EntityPotionEffectEvent event) {
public void effectRemoveCheck(EntityPotionEffectEvent event)
{
PotionEffect old = event.getOldEffect();
EntityPotionEffectEvent.Action cleared = EntityPotionEffectEvent.Action.CLEARED;
EntityPotionEffectEvent.Action removed = EntityPotionEffectEvent.Action.REMOVED;
if (old == null) return;
if (old == null)
return;
if (old.getType().equals(PotionEffectType.BAD_OMEN) && (event.getAction().equals(cleared) || event.getAction().equals(removed))) {
if ((event.getEntity() instanceof Player player)) {
if (old.getType().equals(PotionEffectType.BAD_OMEN) && (event.getAction().equals(cleared) || event.getAction()
.equals(
removed)))
{
if ((event.getEntity() instanceof Player player))
{
Luck luck = plugin.getHandler().getLuckContainer(player);
if (luck.cached(player)) {
if (luck.cached(player))
{
luck.restore();
player.sendMessage("The -25% debuff to your luck has been removed.");
asAudience(player).sendMessage(MiniComponent.info("The -25% debuff to your luck has been removed."));
}
}
}
}
@EventHandler
public void disconnectCheck(PlayerQuitEvent event) {
if (event.getPlayer().hasPotionEffect(PotionEffectType.BAD_OMEN)) {
public void disconnectCheck(PlayerQuitEvent event)
{
if (event.getPlayer().hasPotionEffect(PotionEffectType.BAD_OMEN))
{
Luck luck = plugin.getHandler().getLuckContainer(event.getPlayer());
if (luck.cached(event.getPlayer())) {
if (luck.cached(event.getPlayer()))
{
luck.restore();
}
}

View File

@ -1,7 +1,11 @@
package io.github.simplex.luck.listener;
import io.github.simplex.lib.MiniComponent;
import io.github.simplex.luck.FeelingLucky;
import io.github.simplex.luck.player.Luck;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
@ -12,30 +16,32 @@ import org.bukkit.event.entity.EntityDeathEvent;
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 extends AbstractListener {
public class ItemDrops extends AbstractListener
{
private final Map<UUID, Player> entityPlayerMap = new HashMap<>();
private boolean canAffect = false;
public ItemDrops(FeelingLucky plugin) {
public ItemDrops(FeelingLucky plugin)
{
super(plugin);
register(this);
}
@EventHandler
public void checkForPreItemDrop(EntityDamageByEntityEvent event) {
if (!(event.getEntity() instanceof LivingEntity entity)) {
public void checkForPreItemDrop(EntityDamageByEntityEvent event)
{
if (!(event.getEntity() instanceof LivingEntity entity))
{
return;
}
if (!(event.getDamager() instanceof Player player)) {
if (!(event.getDamager() instanceof Player player))
{
return;
}
if (!(entity.getHealth() <= 0.0)) {
if (entity.getHealth() > 0.0)
{
return;
}
@ -43,8 +49,10 @@ public class ItemDrops extends AbstractListener {
}
@EventHandler
public void checkForDroppedItems(EntityDeathEvent event) {
if (event.getEntity() instanceof Player) {
public void checkForDroppedItems(EntityDeathEvent event)
{
if (event.getEntity() instanceof Player)
{
canAffect = false;
return;
}
@ -53,23 +61,32 @@ public class ItemDrops extends AbstractListener {
}
@EventHandler
public void itemDrops(EntityDropItemEvent event) {
public void itemDrops(EntityDropItemEvent event)
{
Entity entity = event.getEntity();
if (entityPlayerMap.get(entity.getUniqueId()) == null) return;
if (entityPlayerMap.get(entity.getUniqueId()) == null)
return;
if (!canAffect) return;
if (!canAffect)
return;
Player player = entityPlayerMap.get(entity.getUniqueId());
Luck luck = getHandler().getLuckContainer(player);
Item item = event.getItemDrop();
ItemStack stack = item.getItemStack();
int amount = stack.getAmount();
if (luck.quickRNG(luck.getValue()) && doesQualify("item_drops", luck.getValue())) {
if (luck.quickRNG(luck.getValue()) && doesQualify("item_drops", luck.getValue()))
{
int rng = Luck.RNG().nextInt(2, 5);
amount += rng;
stack.setAmount(amount);
event.getItemDrop().setItemStack(stack);
if (luck.isVerbose())
{
asAudience(player).sendMessage(MiniComponent.info("Your luck earned you some extra loot!"));
}
}
}
}

View File

@ -21,7 +21,11 @@ public class JumpBoost extends AbstractListener {
Vector velocity = player.getVelocity().clone();
if (luck.quickRNG(luck.getValue()) && doesQualify("jump_boost", luck.getValue())) {
player.setVelocity(new Vector(velocity.getX(), velocity.getY() + 3, velocity.getZ()));
player.setVelocity(velocity.multiply(2.5));
if (luck.isVerbose()) {
asAudience(player).sendMessage(MiniComponent.info("Your luck gave you an extra boost to your jump!"));
}
}
}
}

View File

@ -15,7 +15,13 @@ import org.bukkit.event.block.BlockBreakEvent;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.jetbrains.annotations.ApiStatus;
/**
* This class is currently unstable.
*/
@Deprecated
@ApiStatus.Experimental
public class OreVein extends AbstractListener {
public OreVein(FeelingLucky plugin) {

View File

@ -37,15 +37,16 @@ public final class PlayerListener extends AbstractListener {
Luck luck = getHandler().getLuckContainer(player);
if (timer.onCooldown(player)) {
player.sendMessage(MiniComponent.err("That feature can only be used once every 30 seconds."));
player.sendMessage(MiniComponent.info("You have " + timer.remaining(player) + " seconds remaining."));
asAudience(player).sendMessage(MiniComponent.err("That feature can only be used once every 30 seconds."));
asAudience(player).sendMessage(MiniComponent.info("You have " + timer.remaining(player) + " seconds " +
"remaining."));
return;
}
if (action.isRightClick() && player.getInventory().getItemInMainHand().getType().equals(foot.getType())) {
if (foot.getItemMeta().equals(special.meta()) || foot.equals(special.get())) {
luck.setMultiplier(luck.multiplier() + 0.1);
player.sendMessage(MiniComponent.info("Your luck multiplier has increased by 0.1!"));
asAudience(player).sendMessage(MiniComponent.info("Your luck multiplier has increased by 0.1!"));
}
double rng = Luck.RNG().nextDouble(2.0, 5.0);
rng = Math.round(rng);
@ -53,7 +54,7 @@ public final class PlayerListener extends AbstractListener {
luck.addTo(rng);
plugin.getHandler().updatePlayer(player, luck);
timer.setCooldown(player.getUniqueId(), System.currentTimeMillis());
player.sendMessage(MiniComponent.info("Your luck has been increased by " + rng + " points."));
asAudience(player).sendMessage(MiniComponent.info("Your luck has been increased by " + rng + " points."));
}
}
@ -76,7 +77,7 @@ public final class PlayerListener extends AbstractListener {
if (luck.quickRNG(33.0)) {
luck.takeFrom(5.0);
plugin.getHandler().updatePlayer(player, luck);
player.sendMessage(MiniComponent.warn("Your luck has been decreased by 5 points!"));
asAudience(player).sendMessage(MiniComponent.warn("Your luck has been decreased by 5 points!"));
}
}
}

View File

@ -4,22 +4,24 @@ import io.github.simplex.lib.MiniComponent;
import io.github.simplex.luck.FeelingLucky;
import io.github.simplex.luck.player.Luck;
import io.github.simplex.luck.util.ListBox;
import java.util.List;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.potion.PotionEffect;
import java.util.List;
public class RandomEffect extends AbstractListener {
public RandomEffect(FeelingLucky plugin) {
public class RandomEffect extends AbstractListener
{
public RandomEffect(FeelingLucky plugin)
{
super(plugin);
register(this);
}
@EventHandler
public void giveRandomEffect(PlayerRespawnEvent respawn) {
public void giveRandomEffect(PlayerRespawnEvent respawn)
{
Player player = respawn.getPlayer();
Luck luck = plugin.getHandler().getLuckContainer(player);
@ -27,14 +29,21 @@ public class RandomEffect extends AbstractListener {
int size = effectList.size();
PotionEffect random = effectList.get(Luck.RNG().nextInt(size - 1));
if (luck.quickRNG(luck.getValue()) && doesQualify("random_effect", luck.getValue())) {
if (luck.quickRNG(luck.getValue()) && doesQualify("random_effect", luck.getValue()))
{
player.addPotionEffect(random);
player.sendMessage(MiniComponent.info("Thanks to luck, a random positive potion effect has been applied to you."));
if (luck.isVerbose())
{
asAudience(player).sendMessage(
MiniComponent.info("Thanks to luck, a random positive potion effect has " +
"been applied to you."));
}
}
}
@EventHandler
public void giveRandomEffect(PlayerTeleportEvent tp) {
public void giveRandomEffect(PlayerTeleportEvent tp)
{
Player player = tp.getPlayer();
Luck luck = plugin.getHandler().getLuckContainer(player);
@ -42,9 +51,14 @@ public class RandomEffect extends AbstractListener {
int size = effectList.size();
PotionEffect random = effectList.get(Luck.RNG().nextInt(size - 1));
if (luck.quickRNG(luck.getValue()) && doesQualify("random_effect", luck.getValue())) {
if (luck.quickRNG(luck.getValue()) && doesQualify("random_effect", luck.getValue()))
{
player.addPotionEffect(random);
player.sendMessage(MiniComponent.info("Thanks to luck, a random positive potion effect has been applied to you."));
if (luck.isVerbose())
{
asAudience(player).sendMessage(
MiniComponent.info("Thanks to luck, a random positive potion effect has been applied to you."));
}
}
}
}

View File

@ -1,5 +1,6 @@
package io.github.simplex.luck.listener;
import io.github.simplex.lib.MiniComponent;
import io.github.simplex.lib.PotionEffectBuilder;
import io.github.simplex.luck.FeelingLucky;
import io.github.simplex.luck.player.Luck;
@ -10,27 +11,44 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
public class RestoreHunger extends AbstractListener {
public RestoreHunger(FeelingLucky plugin) {
public class RestoreHunger extends AbstractListener
{
public RestoreHunger(FeelingLucky plugin)
{
super(plugin);
register(this);
}
@EventHandler
public void restoreHunger(PlayerItemConsumeEvent event) {
public void restoreHunger(PlayerItemConsumeEvent event)
{
ItemStack item = event.getItem();
Luck luck = getHandler().getLuckContainer(event.getPlayer());
PotionEffect effect = PotionEffectBuilder.newEffect().type(PotionEffectType.SATURATION).amplifier(2).duration(10).particles(false).create();
if (luck.notDefault()) {
PotionEffect effect = PotionEffectBuilder.newEffect()
.type(PotionEffectType.SATURATION)
.amplifier(2)
.duration(10)
.particles(false)
.create();
if (luck.notDefault())
{
double percentage = luck.getValue();
ListBox.foods.forEach(food -> {
if (item.isSimilar(food)) {
if (luck.quickRNG(percentage) && doesQualify("restore_hunger", percentage)) {
ListBox.foods.forEach(food ->
{
if (item.isSimilar(food) && (luck.quickRNG(percentage) && doesQualify(
"restore_hunger", percentage)))
{
event.getPlayer().setExhaustion(event.getPlayer().getExhaustion() + 2);
event.getPlayer().addPotionEffect(effect);
}
}
});
if (luck.isVerbose())
{
asAudience(event.getPlayer())
.sendMessage(MiniComponent.info("Your luck has restored your hunger a little more."));
}
}
}
}

View File

@ -25,8 +25,7 @@ public class TakeDamage extends AbstractListener {
}
Player player = (Player) event.getEntity();
Luck luck = getHandler().getLuckContainer(player);
if (ListBox.acceptedCauses.contains(event.getCause())) {
if (luck.notDefault()) {
if (ListBox.acceptedCauses.contains(event.getCause()) && (luck.notDefault())) {
double percentage = luck.getValue();
/*
@ -38,7 +37,7 @@ public class TakeDamage extends AbstractListener {
if (luck.quickRNG(percentage)) {
event.setCancelled(true);
player.damage(event.getDamage() * 2);
player.sendMessage(MiniComponent.warn("You were unlucky and took double damage!"));
asAudience(player).sendMessage(MiniComponent.warn("You were unlucky and took double damage!"));
}
return;
}
@ -47,11 +46,10 @@ public class TakeDamage extends AbstractListener {
event.setCancelled(true);
player.damage(event.getDamage() / 2);
}
}
}
if (ListBox.sideCauses.contains(event.getCause())) {
if (luck.notDefault()) {
if (ListBox.sideCauses.contains(event.getCause()) && (luck.notDefault())) {
double percentage = luck.getValue();
/*
@ -71,9 +69,10 @@ public class TakeDamage extends AbstractListener {
event.setCancelled(true);
player.getActivePotionEffects().removeIf(p -> ListBox.potionEffects.contains(p.getType()));
player.setFireTicks(0);
player.sendMessage(MiniComponent.info("You got lucky and your afflictions were cured."));
}
}
asAudience(player).sendMessage(MiniComponent.info("You got lucky and your afflictions were cured" +
"."));
}
}
}
}

View File

@ -11,30 +11,41 @@ import org.bukkit.inventory.CraftingInventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
public class UnbreakableTool extends AbstractListener {
public UnbreakableTool(FeelingLucky plugin) {
public class UnbreakableTool extends AbstractListener
{
public UnbreakableTool(FeelingLucky plugin)
{
super(plugin);
register(this);
}
@EventHandler
public void unbreakableTool(CraftItemEvent event) {
public void unbreakableTool(CraftItemEvent event)
{
CraftingInventory inventory = event.getInventory();
ItemStack stack = inventory.getResult();
if (stack == null) return;
if (stack == null)
return;
ItemMeta meta = stack.getItemMeta();
if (ItemBuilder.isTool(stack.getType())) {
if (event.getWhoClicked() instanceof Player player) {
if (ItemBuilder.isTool(stack.getType()) && (event.getWhoClicked() instanceof Player player))
{
Luck luck = getHandler().getLuckContainer(player);
if (luck.quickRNG(luck.getValue()) && doesQualify("unbreakable", luck.getValue())) {
if (luck.quickRNG(luck.getValue()) && doesQualify("unbreakable", luck.getValue()))
{
meta.setUnbreakable(true);
stack.setItemMeta(meta);
inventory.setResult(stack);
player.sendMessage(MiniComponent.info("By the grace of Luck you have crafted an unbreakable tool!"));
}
}
if (luck.isVerbose())
{
asAudience(player)
.sendMessage(
MiniComponent.info("By the grace of Luck you have crafted an unbreakable tool!"));
}
}
}
}
}

View File

@ -25,6 +25,7 @@ public class Luck implements LuckContainer {
private double BASE_VALUE;
private double multiplier;
private double tempSave;
private boolean verbose;
public Luck(FeelingLucky plugin, Player player) {
this(plugin, player, 1.0);
@ -85,6 +86,16 @@ public class Luck implements LuckContainer {
return markedPlayers.contains(player);
}
@Override
public void setVerbose(final boolean verbose) {
this.verbose = verbose;
}
@Override
public boolean isVerbose() {
return verbose;
}
@Override
public boolean isMatch(double number) {
return getValue() == number;

View File

@ -1,55 +1,38 @@
package io.github.simplex.luck.player;
import io.github.simplex.luck.FeelingLucky;
import io.github.simplex.luck.util.SneakyWorker;
import io.github.simplex.luck.util.Logs;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.attribute.Attribute;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
public class PlayerConfig {
public class PlayerConfig
{
private final File configFile;
private final OfflinePlayer player;
private volatile YamlConfiguration config;
private final FeelingLucky plugin;
private YamlConfiguration config;
@SuppressWarnings("ResultOfMethodCallIgnored")
public PlayerConfig(FeelingLucky plugin, Player player) {
public PlayerConfig(FeelingLucky plugin, Player player)
{
this.plugin = plugin;
this.player = player;
if (!plugin.getDataFolder().exists()) plugin.getDataFolder().mkdirs();
File dataFolder = new File(plugin.getDataFolder(), "players");
if (!dataFolder.exists()) dataFolder.mkdirs();
File file = new File(dataFolder, player.getUniqueId() + ".yml");
if (!file.exists()) {
String name = "username: " + player.getName();
String luck = "luck: " + 0;
String multiplier = "multiplier: " + 1.0;
SneakyWorker.sneakyTry(() -> {
file.createNewFile();
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();
});
}
final File file = configFile(plugin, player);
configFile = file;
config = YamlConfiguration.loadConfiguration(configFile);
String tempUsername = config.getString("username");
if (tempUsername == null) {
if (tempUsername == null)
{
config.set("username", player.getName());
config.set("luck", plugin.getHandler().getLuckContainer(player).getDefaultValue());
config.set("multiplier", "1.0");
@ -57,50 +40,141 @@ public class PlayerConfig {
}
}
protected PlayerConfig(FeelingLucky plugin, File file) {
protected PlayerConfig(FeelingLucky plugin, File file)
{
this.plugin = plugin;
this.configFile = file;
this.player = Bukkit.getOfflinePlayer(UUID.fromString(file.getName().split("\\.")[0]));
config = YamlConfiguration.loadConfiguration(configFile);
}
@Contract("_, _ -> new")
public static PlayerConfig initFrom(FeelingLucky plugin, File file) {
public static PlayerConfig initFrom(FeelingLucky plugin, File file)
{
return new PlayerConfig(plugin, file);
}
public void save() {
SneakyWorker.sneakyTry(() -> config.save(configFile));
@NotNull
private File configFile(FeelingLucky plugin, Player player)
{
if (!plugin.getDataFolder().exists())
plugin.getDataFolder().mkdirs();
File dataFolder = new File(plugin.getDataFolder(), "players");
if (!dataFolder.exists())
dataFolder.mkdirs();
File file = new File(dataFolder, player.getUniqueId() + ".yml");
if (!file.exists())
{
try
{
file.createNewFile();
final YamlConfiguration v0 = new YamlConfiguration();
v0.set("username", player.getName());
v0.set("luck", 0);
v0.set("multiplier", 1.0);
v0.set("verbose", true);
v0.save(file);
}
catch (IOException ex)
{
Logs.error(ex);
}
}
return file;
}
public void load() {
SneakyWorker.sneakyTry(() -> config = YamlConfiguration.loadConfiguration(configFile));
public void save()
{
try
{
config.save(configFile);
}
catch (IOException ex)
{
Logs.error(ex);
}
}
public void reload() {
public void load()
{
try
{
config.load(configFile);
}
catch (IOException | InvalidConfigurationException ex)
{
Logs.error(ex);
Logs.warn("Attempting to reinitialize variable... this is dangerous!");
try
{
config = YamlConfiguration.loadConfiguration(configFile);
}
catch (IllegalArgumentException th)
{
Logs.error(th);
}
}
}
public void reload()
{
save();
load();
}
public OfflinePlayer getPlayer() {
public OfflinePlayer getPlayer()
{
return player;
}
public void setUsername(String name) {
config.set("username", name);
save();
public String getUsername() {
return config.getString("username");
}
public void setLuck(double luck) {
public double getLuck()
{
return config.getDouble("luck");
}
public void setLuck(double luck)
{
config.set("luck", luck);
save();
reload();
}
public void setMultiplier(double multiplier) {
public double getMultiplier()
{
return config.getDouble("multiplier");
}
public void setMultiplier(double multiplier)
{
config.set("multiplier", multiplier);
save();
reload();
}
public YamlConfiguration getConfig() {
public boolean isVerbose()
{
return config.getBoolean("verbose");
}
public void setVerbose(final boolean verbose)
{
config.set("verbose", verbose);
reload();
}
public void setUsername(String name)
{
config.set("username", name);
reload();
}
public YamlConfiguration getConfig()
{
return config;
}
}

View File

@ -38,9 +38,10 @@ public class PlayerHandler implements Listener {
plugin.getConfigMap().put(player.getUniqueId(), playerConfig);
}
String username = playerConfig.getConfig().getString("username");
double luck = playerConfig.getConfig().getDouble("luck");
double multiplier = playerConfig.getConfig().getDouble("multiplier");
String username = playerConfig.getUsername();
double luck = playerConfig.getLuck();
double multiplier = playerConfig.getMultiplier();
boolean verbose = playerConfig.isVerbose();
if (!player.getName().equalsIgnoreCase(username)) {
playerConfig.getConfig().set("username", player.getName());
@ -49,6 +50,7 @@ public class PlayerHandler implements Listener {
}
Luck container = new Luck(plugin, player, multiplier);
container.setVerbose(verbose);
container.setValue(luck);
playerLuckMap.put(player, container);

View File

@ -0,0 +1,52 @@
package io.github.simplex.luck.util;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Logs
{
private static final Logger logger = LoggerFactory.getLogger("FeelingLucky");
private Logs()
{
throw new AssertionError();
}
public static void info(String message)
{
logger.info(message);
}
public static void warn(String message)
{
logger.warn(message);
}
public static void warn(String message, Throwable th)
{
logger.warn(message, th);
}
public static void warn(Throwable th)
{
final String msg = ExceptionUtils.getRootCauseMessage(th);
logger.warn(msg);
}
public static void error(String message)
{
logger.error(message);
}
public static void error(String message, Throwable th)
{
logger.error(message, th);
}
public static void error(Throwable th)
{
final String msg = ExceptionUtils.getRootCauseMessage(th);
logger.error(msg, th);
}
}

View File

@ -114,6 +114,17 @@ public class LuckCMD extends Command implements TabCompleter, PluginIdentifiable
return true;
}
if (args[0].equalsIgnoreCase("verbose") && sender instanceof Player player) {
final boolean a1 = Boolean.parseBoolean(args[1]);
Luck luck = plugin.getHandler().getLuckContainer(player);
PlayerConfig config = plugin.getConfigMap().get(player.getUniqueId());
luck.setVerbose(a1);
plugin.getHandler().updatePlayer(player, luck);
config.setVerbose(a1);
sender.sendMessage(MiniComponent.info("Verbose mode set to " + a1 + "."));
return true;
}
if (args[0].equalsIgnoreCase("reset")) {
Player player = Bukkit.getPlayer(args[1]);

View File

@ -21,7 +21,7 @@ public class SneakyWorker {
+ ex.getClass().getSimpleName()
+ " has occurred. A cause will be printed. \n\n"
+ ex.getCause();
Bukkit.getLogger().severe(sb);
Logs.error(sb);
}
}