diff --git a/Plugin/build.gradle b/Plugin/build.gradle index 39c86ca..0870522 100644 --- a/Plugin/build.gradle +++ b/Plugin/build.gradle @@ -13,8 +13,6 @@ dependencies { implementation 'org.bstats:bstats-bukkit:1.7' compileOnly 'org.spigotmc:spigot-api:1.16.3-R0.1-SNAPSHOT' compileOnly 'commons-io:commons-io:2.8.0' - compileOnly 'me.clip:placeholderapi:2.10.9' - compileOnly 'com.willfp:EcoEnchants:5.3.1' } shadowJar { diff --git a/Plugin/src/main/java/com/willfp/illusioner/illusioner/listeners/AttackListeners.java b/Plugin/src/main/java/com/willfp/illusioner/illusioner/listeners/AttackListeners.java index 88ed8e4..31b983c 100644 --- a/Plugin/src/main/java/com/willfp/illusioner/illusioner/listeners/AttackListeners.java +++ b/Plugin/src/main/java/com/willfp/illusioner/illusioner/listeners/AttackListeners.java @@ -2,6 +2,7 @@ package com.willfp.illusioner.illusioner.listeners; import com.willfp.illusioner.illusioner.IllusionerManager; import com.willfp.illusioner.util.NumberUtils; +import com.willfp.illusioner.util.internal.OptionedSound; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Sound; @@ -29,6 +30,13 @@ public class AttackListeners implements Listener { Player player = (Player) event.getEntity(); + OptionedSound hitSound = IllusionerManager.OPTIONS.getGameplayOptions().getHitSound(); + if(hitSound.isBroadcast()) { + player.getWorld().playSound(event.getEntity().getLocation(), hitSound.getSound(), hitSound.getVolume(), hitSound.getPitch()); + } else { + player.playSound(event.getEntity().getLocation(), hitSound.getSound(), hitSound.getVolume(), hitSound.getPitch()); + } + IllusionerManager.OPTIONS.getGameplayOptions().getEffectOptions().forEach(effectOption -> { if(NumberUtils.randFloat(0, 100) > effectOption.getChance()) return; @@ -61,6 +69,13 @@ public class AttackListeners implements Listener { loc.add(0, 1, 0); } player.getWorld().spawnEntity(loc, summonerOption.getType()); + + OptionedSound summonSound = IllusionerManager.OPTIONS.getGameplayOptions().getSummonSound(); + if(summonSound.isBroadcast()) { + player.getWorld().playSound(event.getEntity().getLocation(), summonSound.getSound(), summonSound.getVolume(), summonSound.getPitch()); + } else { + player.playSound(event.getEntity().getLocation(), summonSound.getSound(), summonSound.getVolume(), summonSound.getPitch()); + } }); } diff --git a/Plugin/src/main/java/com/willfp/illusioner/illusioner/options/GameplayOptions.java b/Plugin/src/main/java/com/willfp/illusioner/illusioner/options/GameplayOptions.java index 40d4128..e0b0130 100644 --- a/Plugin/src/main/java/com/willfp/illusioner/illusioner/options/GameplayOptions.java +++ b/Plugin/src/main/java/com/willfp/illusioner/illusioner/options/GameplayOptions.java @@ -1,6 +1,8 @@ package com.willfp.illusioner.illusioner.options; +import com.willfp.illusioner.config.ConfigManager; import com.willfp.illusioner.util.internal.OptionedSound; +import org.bukkit.Sound; import org.bukkit.entity.EntityType; import org.bukkit.potion.PotionEffectType; @@ -9,6 +11,7 @@ import java.util.Set; public class GameplayOptions { private OptionedSound hitSound; + private OptionedSound summonSound; private final Set effectOptions = new HashSet<>(); private final Set summonerOptions = new HashSet<>(); @@ -19,13 +22,49 @@ public class GameplayOptions { private boolean ignoreExplosionDamage; public void reload() { + hitSound = new OptionedSound( + Sound.valueOf(ConfigManager.getConfig().getString("sounds.hit.sound")), + (float) ConfigManager.getConfig().getDouble("sounds.hit.volume"), + (float) ConfigManager.getConfig().getDouble("sounds.hit.pitch"), + ConfigManager.getConfig().getBool("sounds.hit.broadcast") + ); + summonSound = new OptionedSound( + Sound.valueOf(ConfigManager.getConfig().getString("sounds.summon.sound")), + (float) ConfigManager.getConfig().getDouble("sounds.summon.volume"), + (float) ConfigManager.getConfig().getDouble("sounds.summon.pitch"), + ConfigManager.getConfig().getBool("sounds.summon.broadcast") + ); + + shuffle = ConfigManager.getConfig().getBool("attacks.shuffle.enabled"); + shuffleChance = ConfigManager.getConfig().getDouble("attacks.shuffle.chance"); + ignoreExplosionDamage = ConfigManager.getConfig().getBool("ignore-explosion-damage"); + + effectOptions.clear(); + ConfigManager.getConfig().config.getConfigurationSection("attacks.effects").getKeys(false).forEach(key -> { + PotionEffectType type = PotionEffectType.getByName(ConfigManager.getConfig().getString("attacks.effects." + key + ".type")); + int level = ConfigManager.getConfig().getInt("attacks.effects." + key + ".level"); + int duration = ConfigManager.getConfig().getInt("attacks.effects." + key + ".duration"); + double chance = ConfigManager.getConfig().getDouble("attacks.effects." + key + ".chance"); + effectOptions.add(new EffectOption(chance, level, duration, type)); + }); + + summonerOptions.clear(); + ConfigManager.getConfig().config.getConfigurationSection("attacks.summons").getKeys(false).forEach(key -> { + EntityType type = EntityType.valueOf(ConfigManager.getConfig().getString("attacks.summons." + key + ".type")); + double chance = ConfigManager.getConfig().getDouble("attacks.summons." + key + ".chance"); + summonerOptions.add(new SummonerOption(chance, type)); + }); } public OptionedSound getHitSound() { return hitSound; } + public OptionedSound getSummonSound() { + return summonSound; + } + public Set getEffectOptions() { return effectOptions; } diff --git a/Plugin/src/main/java/com/willfp/illusioner/illusioner/options/IllusionerOptions.java b/Plugin/src/main/java/com/willfp/illusioner/illusioner/options/IllusionerOptions.java index 71a0f2c..3c4fe44 100644 --- a/Plugin/src/main/java/com/willfp/illusioner/illusioner/options/IllusionerOptions.java +++ b/Plugin/src/main/java/com/willfp/illusioner/illusioner/options/IllusionerOptions.java @@ -1,13 +1,17 @@ package com.willfp.illusioner.illusioner.options; +import com.willfp.illusioner.config.ConfigManager; import com.willfp.illusioner.illusioner.BlockStructure; import com.willfp.illusioner.util.NumberUtils; import com.willfp.illusioner.util.internal.OptionedSound; import com.willfp.illusioner.util.tuplets.Pair; +import org.bukkit.Material; +import org.bukkit.Sound; import org.bukkit.boss.BarColor; import org.bukkit.boss.BarStyle; import org.bukkit.inventory.ItemStack; +import java.util.HashSet; import java.util.Set; public class IllusionerOptions { @@ -21,16 +25,47 @@ public class IllusionerOptions { private double maxHealth; private double attackDamage; private Set drops; - private GameplayOptions gameplayOptions; + private final GameplayOptions gameplayOptions = new GameplayOptions(); public IllusionerOptions() { reload(); } public void reload() { + color = BarColor.valueOf(ConfigManager.getConfig().getString("bossbar.color")); + style = BarStyle.valueOf(ConfigManager.getConfig().getString("bossbar.style")); + name = ConfigManager.getConfig().getString("name"); + xpBounds = new Pair<>(ConfigManager.getConfig().getInt("xp.minimum"), ConfigManager.getConfig().getInt("xp.maximum")); + maxHealth = ConfigManager.getConfig().getDouble("max-health"); + attackDamage = ConfigManager.getConfig().getDouble("attack-damage"); + spawnSounds = new HashSet<>(); + ConfigManager.getConfig().config.getConfigurationSection("sounds.spawn").getKeys(false).forEach(key -> { + Sound sound = Sound.valueOf(ConfigManager.getConfig().getString("sounds.spawn." + key + ".sound")); + boolean broadcast = ConfigManager.getConfig().getBool("sounds.spawn." + key + ".broadcast"); + float volume = (float) ConfigManager.getConfig().getDouble("sounds.spawn." + key + ".volume"); + float pitch = (float) ConfigManager.getConfig().getDouble("sounds.spawn." + key + ".pitch"); + spawnSounds.add(new OptionedSound(sound, volume, pitch, broadcast)); + }); + + deathSounds = new HashSet<>(); + ConfigManager.getConfig().config.getConfigurationSection("sounds.death").getKeys(false).forEach(key -> { + Sound sound = Sound.valueOf(ConfigManager.getConfig().getString("sounds.death." + key + ".sound")); + boolean broadcast = ConfigManager.getConfig().getBool("sounds.death." + key + ".broadcast"); + float volume = (float) ConfigManager.getConfig().getDouble("sounds.death." + key + ".volume"); + float pitch = (float) ConfigManager.getConfig().getDouble("sounds.death." + key + ".pitch"); + deathSounds.add(new OptionedSound(sound, volume, pitch, broadcast)); + }); + + spawnStructure = new BlockStructure( + Material.valueOf(ConfigManager.getConfig().getString("spawn.bottom-block")), + Material.valueOf(ConfigManager.getConfig().getString("spawn.middle-block")), + Material.valueOf(ConfigManager.getConfig().getString("spawn.top-block")) + ); gameplayOptions.reload(); + + drops = new HashSet<>(); } public BarColor getColor() { diff --git a/Plugin/src/main/java/com/willfp/illusioner/integrations/Integration.java b/Plugin/src/main/java/com/willfp/illusioner/integrations/Integration.java deleted file mode 100644 index 00ff40e..0000000 --- a/Plugin/src/main/java/com/willfp/illusioner/integrations/Integration.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.willfp.illusioner.integrations; - -/** - * Interface for all integrations with optional dependencies - */ -public interface Integration { - /** - * Get the name of integration - * @return The name - */ - String getPluginName(); -} diff --git a/Plugin/src/main/java/com/willfp/illusioner/integrations/drops/Drops.java b/Plugin/src/main/java/com/willfp/illusioner/integrations/drops/Drops.java deleted file mode 100644 index 0a32649..0000000 --- a/Plugin/src/main/java/com/willfp/illusioner/integrations/drops/Drops.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.willfp.illusioner.integrations.drops; - -import org.bukkit.Bukkit; -import org.bukkit.inventory.ItemStack; - -public class Drops { - public static boolean drop(ItemStack itemStack) { - if(Bukkit.getPluginManager().isPluginEnabled("EcoEnchants")) { - - } - } -} diff --git a/Plugin/src/main/java/com/willfp/illusioner/integrations/placeholder/PlaceholderEntry.java b/Plugin/src/main/java/com/willfp/illusioner/integrations/placeholder/PlaceholderEntry.java deleted file mode 100644 index 8ff9b9b..0000000 --- a/Plugin/src/main/java/com/willfp/illusioner/integrations/placeholder/PlaceholderEntry.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.willfp.illusioner.integrations.placeholder; - -import com.willfp.illusioner.util.interfaces.ObjectBiCallable; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.Nullable; - -/** - * A placeholder entry consists of an identifier and an {@link ObjectBiCallable} to fetch the result - */ -public class PlaceholderEntry { - private final String identifier; - private final ObjectBiCallable function; - private final boolean requiresPlayer; - - /** - * Create a placeholder entry that doesn't require a player - * - * @param identifier The identifier of the placeholder - * @param function A lambda to get the result of the placeholder - */ - public PlaceholderEntry(String identifier, ObjectBiCallable function) { - this(identifier, function, false); - } - - /** - * Create a placeholder entry that may require a player - * - * @param identifier The identifier of the placeholder - * @param function A lambda to get the result of the placeholder - * @param requiresPlayer If the placeholder requires a player - */ - public PlaceholderEntry(String identifier, ObjectBiCallable function, boolean requiresPlayer) { - this.identifier = identifier; - this.function = function; - this.requiresPlayer = requiresPlayer; - } - - /** - * Get the identifier of the placeholder - * - * @return The identifier - */ - public String getIdentifier() { - return this.identifier; - } - - /** - * Get the result of the placeholder with respect to a player - * - * @param player The player to translate with respect to - * @return The result of the placeholder - */ - public String getResult(@Nullable Player player) { - return this.function.call(player); - } - - /** - * Get if the placeholder requires a player to get a result - * - * @return If the placeholder requires a player - */ - public boolean requiresPlayer() { - return requiresPlayer; - } -} diff --git a/Plugin/src/main/java/com/willfp/illusioner/integrations/placeholder/PlaceholderIntegration.java b/Plugin/src/main/java/com/willfp/illusioner/integrations/placeholder/PlaceholderIntegration.java deleted file mode 100644 index 6ec6fe7..0000000 --- a/Plugin/src/main/java/com/willfp/illusioner/integrations/placeholder/PlaceholderIntegration.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.willfp.illusioner.integrations.placeholder; - -import com.willfp.illusioner.integrations.Integration; -import org.bukkit.entity.Player; - -/** - * Interface for Placeholder integrations - */ -public interface PlaceholderIntegration extends Integration { - /** - * Register the integration with the specified plugin - * Not to be confused with internal registration in {@link PlaceholderManager#addIntegration(PlaceholderIntegration)} - */ - void registerIntegration(); - - /** - * Translate all the placeholders in a string with respect to a player - * - * @param text The text to translate - * @param player The player to translate with respect to - * @return The string, translated - */ - String translate(String text, Player player); -} diff --git a/Plugin/src/main/java/com/willfp/illusioner/integrations/placeholder/PlaceholderManager.java b/Plugin/src/main/java/com/willfp/illusioner/integrations/placeholder/PlaceholderManager.java deleted file mode 100644 index 19ab829..0000000 --- a/Plugin/src/main/java/com/willfp/illusioner/integrations/placeholder/PlaceholderManager.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.willfp.illusioner.integrations.placeholder; - -import org.bukkit.entity.Player; -import org.jetbrains.annotations.Nullable; - -import java.util.HashSet; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; - -/** - * Utility class for placeholders - */ -public class PlaceholderManager { - private static final Set placeholders = new HashSet<>(); - private static final Set integrations = new HashSet<>(); - - /** - * Register a new placeholder integration - * - * @param integration The {@link PlaceholderIntegration} to register - */ - public static void addIntegration(PlaceholderIntegration integration) { - integration.registerIntegration(); - integrations.add(integration); - } - - /** - * Register a placeholder - * - * @param expansion The {@link PlaceholderEntry} to register - */ - public static void registerPlaceholder(PlaceholderEntry expansion) { - placeholders.removeIf(placeholderEntry -> placeholderEntry.getIdentifier().equalsIgnoreCase(expansion.getIdentifier())); - placeholders.add(expansion); - } - - /** - * Get the result of a placeholder with respect to a player - * - * @param player The player to get the result from - * @param identifier The placeholder identifier - * @return The value of the placeholder - */ - public static String getResult(@Nullable Player player, String identifier) { - Optional matching = placeholders.stream().filter(expansion -> expansion.getIdentifier().equalsIgnoreCase(identifier)).findFirst(); - if (!matching.isPresent()) - return null; - PlaceholderEntry entry = matching.get(); - if (player == null && entry.requiresPlayer()) - return ""; - return entry.getResult(player); - } - - /** - * Translate all placeholders with respect to a player - * - * @param text The text that may contain placeholders to translate - * @param player The player to translate the placeholders with respect to - * @return The text, translated - */ - public static String translatePlaceholders(String text, @Nullable Player player) { - AtomicReference translatedReference = new AtomicReference<>(text); - integrations.forEach(placeholderIntegration -> translatedReference.set(placeholderIntegration.translate(translatedReference.get(), player))); - return translatedReference.get(); - } -} diff --git a/Plugin/src/main/java/com/willfp/illusioner/integrations/placeholder/plugins/PlaceholderIntegrationPAPI.java b/Plugin/src/main/java/com/willfp/illusioner/integrations/placeholder/plugins/PlaceholderIntegrationPAPI.java deleted file mode 100644 index ad234ac..0000000 --- a/Plugin/src/main/java/com/willfp/illusioner/integrations/placeholder/plugins/PlaceholderIntegrationPAPI.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.willfp.illusioner.integrations.placeholder.plugins; - -import com.willfp.illusioner.IllusionerPlugin; -import com.willfp.illusioner.integrations.placeholder.PlaceholderIntegration; -import com.willfp.illusioner.integrations.placeholder.PlaceholderManager; -import me.clip.placeholderapi.PlaceholderAPI; -import me.clip.placeholderapi.expansion.PlaceholderExpansion; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; - -/** - * PlaceholderAPI integration - */ -public class PlaceholderIntegrationPAPI extends PlaceholderExpansion implements PlaceholderIntegration { - @Override - public boolean persist() { - return true; - } - - @Override - public boolean canRegister() { - return true; - } - - @Override - public @NotNull String getAuthor() { - return "Auxilor"; - } - - @Override - public @NotNull String getIdentifier() { - return "illusioner"; - } - - @Override - public @NotNull String getVersion() { - return IllusionerPlugin.getInstance().getDescription().getVersion(); - } - - @Override - public String onPlaceholderRequest(Player player, @NotNull String identifier) { - return PlaceholderManager.getResult(player, identifier); - } - - @Override - public void registerIntegration() { - this.register(); - } - - @Override - public String getPluginName() { - return "PlaceholderAPI"; - } - - @Override - public String translate(String text, Player player) { - return PlaceholderAPI.setPlaceholders(player, text); - } -} diff --git a/Plugin/src/main/resources/config.yml b/Plugin/src/main/resources/config.yml index a6dbb8a..1f5a56c 100644 --- a/Plugin/src/main/resources/config.yml +++ b/Plugin/src/main/resources/config.yml @@ -1,4 +1,111 @@ # # Illusioner # by Auxilor -# \ No newline at end of file +# + +name: "Illusioner" # What should the display name of the Illusioner be? + +bossbar: + color: BLUE # Choose from: BLUE, GREEN, PINK, PURPLE, RED, WHITE, YELLOW + style: SOLID # Choose from: SOLID, SEGMENTED_6, SEGMENTED_10, SEGMENTED_12, SEGMENTED_20 + +xp: + # Chosen at random between a minimum and maximum + minimum: 20000 # Xp points, not levels + maximum: 25000 + +max-health: 600 # Hearts is this number divided by 2, eg 600 is 300 hearts +attack-damage: 50 # This isn't an easy boss. Recommend to keep this high +ignore-explosion-damage: true + +attacks: + # All chances are percentages and can include decimals + + shuffle: # Shuffles the items around in your hotbar + enabled: true + chance: 5 + + effects: + # Types can be found here: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/potion/PotionEffectType.html + # Duration is in ticks, there are 20 ticks in a second + 1: + type: BLINDNESS + level: 1 + duration: 40 + chance: 20 + 2: + type: CONFUSION + level: 10 + duration: 200 + chance: 10 + 3: + type: SLOW + level: 3 + duration: 60 + chance: 10 + + summons: + # Entity Types can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/entity/EntityType.html + # Entities are summoned close to the player + 1: + type: VINDICATOR + chance: 10 + 2: + type: EVOKER + chance: 10 + +spawn: + # Configure a 3x1 tall column of blocks to summon an illusioner + # Plan to add support for other shapes in the future + top-block: CARVED_PUMPKIN + middle-block: BEACON + bottom-block: DIAMOND_BLOCK + +sounds: + # A sound is defined as follows: + # broadcast - Should the whole server hear this or just the player? + # volume - How far away should people be able to hear this? + # pitch - Range is 0.5 to 2, 0.5 is lower pitch and half speed, 2 is higher pitch and double speed + # Add as many sounds as you want + + hit: + # When the player attacks the illusioner + broadcast: false + sound: ENTITY_ILLUSIONER_CAST_SPELL + volume: 1 + pitch: 2 + + summon: + # When an entity is summoned by the illusioner + broadcast: false + sound: ENTITY_EVOKER_PREPARE_ATTACK + volume: 1 + pitch: 2 + + spawn: + 1: + broadcast: true + sound: ENTITY_ILLUSIONER_MIRROR_MOVE + volume: 1000 + pitch: 0.5 + 2: + broadcast: true + sound: ENTITY_WITHER_SPAWN + volume: 1000 + pitch: 2 + death: + 1: + broadcast: true + sound: ENTITY_EVOKER_PREPARE_WOLOLO + volume: 50 + pitch: 0.8 + 2: + broadcast: true + sound: ENTITY_ILLUSIONER_PREPARE_BLINDNESS + volume: 50 + pitch: 1 + 3: + broadcast: true + sound: ENTITY_WITHER_DEATH + volume: 50 + pitch: 2 \ No newline at end of file diff --git a/build.gradle b/build.gradle index 1c96d77..ac83e5b 100644 --- a/build.gradle +++ b/build.gradle @@ -15,85 +15,21 @@ allprojects { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' } - maven { - url 'https://repo.codemc.org/repository/maven-public' - } - - maven { - url 'https://oss.sonatype.org/content/groups/public/' - } - - maven { - url 'https://maven.enginehub.org/repo/' - } - maven { url 'https://jitpack.io' } - maven { - url 'https://ci.ender.zone/plugin/repository/project/' - } - - maven { - url 'https://ci.ender.zone/plugin/repository/everything/' - } - maven { url 'https://repo.md-5.net/content/repositories/snapshots/' } - maven { - url 'https://repo.janmm14.de/repository/public/' - } - - maven { - url 'https://repo.dmulloy2.net/nexus/repository/public/' - } - maven { url 'https://papermc.io/repo/repository/maven-public/' } - maven { - url 'https://repo.maven.apache.org/maven2/' - } - - maven { - url 'https://repo.dustplanet.de/artifactory/ext-release-local/' - } - - maven { - url 'https://maven.seyfahni.de/repository/snapshots/' - } - maven { url 'https://libraries.minecraft.net/' } - - maven { - url 'https://repo.spongepowered.org/maven/' - } - - maven { - url 'https://org.kitteh.pastegg' - } - - maven { - url 'https://repo.mikeprimm.com/' - } - - maven { - url 'https://maven.sk89q.com/repo/' - } - - maven { - url 'https://github.com/factions-site/repo/raw/public/' - } - - maven { - url 'https://repo.extendedclip.com/content/repositories/placeholderapi/' - } } tasks.withType(JavaCompile) {