diff --git a/.gitignore b/.gitignore index 549d5eb..815d563 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,10 @@ out gen *.lnk target/ +.classpath +.project +.settings/ +.gitignore pom.xml.tag pom.xml.releaseBackup pom.xml.versionsBackup diff --git a/src/main/java/com/idreesinc/celeste/Astronomer.java b/src/main/java/com/idreesinc/celeste/Astronomer.java index b8239de..9c1c1c5 100644 --- a/src/main/java/com/idreesinc/celeste/Astronomer.java +++ b/src/main/java/com/idreesinc/celeste/Astronomer.java @@ -3,6 +3,8 @@ import org.bukkit.World; import org.bukkit.scheduler.BukkitRunnable; +import com.idreesinc.celeste.utilities.WorldLootGenerator; + import java.util.List; import java.util.Random; @@ -18,40 +20,46 @@ public void run() { if (celeste.getServer().getOnlinePlayers().size() == 0) { return; } - - List worlds = celeste.getServer().getWorlds(); - for (World world : worlds) { - if (!world.getEnvironment().equals(World.Environment.NORMAL)) { - continue; - } + + for(String worldKey : celeste.worldLoot.worldLootConfigs.keySet()) { + World world = celeste.getServer().getWorld(worldKey); + if(world == null) { + celeste.getLogger().warning("Invalid world: "+worldKey+" please double check config"); + continue; + } + WorldLootGenerator.WLConfiguration config = celeste.worldLoot.worldLootConfigs.get(worldKey); + if (world.getPlayers().size() == 0) { continue; } - if (!(world.getTime() >= 13000 && world.getTime() <= 23000)) { + if (!(world.getTime() >= config.starStartSpawnTime && world.getTime() <= config.starStopSpawnTime)) { continue; } if (world.hasStorm()) { continue; } - + double shootingStarChance; double fallingStarChance; - if (celeste.getConfig().getBoolean("new-moon-meteor-shower") && (world.getFullTime() / 24000) % 8 == 4) { + if (config.newMoonMeteorShower && (world.getFullTime() / 24000) % 8 == 4) { shootingStarChance = - celeste.getConfig().getDouble("shooting-stars-per-minute-during-meteor-showers") / 120d; + config.shootingStarsPerMinuteMeteorShower / 120d; fallingStarChance = - celeste.getConfig().getDouble("falling-stars-per-minute-during-meteor-showers") / 120d; + config.fallingStarsPerMinuteMeteorShower / 120d; } else { - shootingStarChance = celeste.getConfig().getDouble("shooting-stars-per-minute") / 120d; - fallingStarChance = celeste.getConfig().getDouble("falling-stars-per-minute") / 120d; + shootingStarChance = config.shootingStarsPerMinute / 120d; + fallingStarChance = config.fallingStarsPerMinute / 120d; } - if (celeste.getConfig().getBoolean("shooting-stars-enabled") && new Random().nextDouble() <= shootingStarChance) { + if (config.hasShootingStars && new Random().nextDouble() <= shootingStarChance) { CelestialSphere.createShootingStar(celeste, world.getPlayers().get(new Random().nextInt(world.getPlayers().size()))); } - if (celeste.getConfig().getBoolean("falling-stars-enabled") && new Random().nextDouble() <= fallingStarChance) { + if (config.hasFallingingStars && new Random().nextDouble() <= fallingStarChance) { CelestialSphere.createFallingStar(celeste, world.getPlayers().get(new Random().nextInt(world.getPlayers().size()))); } + } + + } } \ No newline at end of file diff --git a/src/main/java/com/idreesinc/celeste/Celeste.java b/src/main/java/com/idreesinc/celeste/Celeste.java index 5041010..e2f3622 100644 --- a/src/main/java/com/idreesinc/celeste/Celeste.java +++ b/src/main/java/com/idreesinc/celeste/Celeste.java @@ -1,19 +1,19 @@ package com.idreesinc.celeste; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitRunnable; + import com.idreesinc.celeste.commands.CommandCeleste; import com.idreesinc.celeste.commands.CommandFallingStar; import com.idreesinc.celeste.commands.CommandShootingStar; import com.idreesinc.celeste.utilities.Metrics; import com.idreesinc.celeste.utilities.UpdateChecker; -import com.idreesinc.celeste.utilities.WeightedRandomBag; -import org.bukkit.Material; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.scheduler.BukkitRunnable; +import com.idreesinc.celeste.utilities.WorldLootGenerator; public class Celeste extends JavaPlugin { - public WeightedRandomBag fallingStarDrops = new WeightedRandomBag<>(); + //public WeightedRandomBag fallingStarDrops = new WeightedRandomBag<>(); + public WorldLootGenerator worldLoot = new WorldLootGenerator(this); @Override public void onEnable() { @@ -23,8 +23,7 @@ public void onEnable() { this.getCommand("celeste").setExecutor(new CommandCeleste(this)); this.getCommand("shootingstar").setExecutor(new CommandShootingStar(this)); this.getCommand("fallingstar").setExecutor(new CommandFallingStar(this)); - - calculateFallingStarDrops(); + worldLoot.runWorldLootGenerator(); BukkitRunnable stargazingTask = new Astronomer(this); stargazingTask.runTaskTimer(this, 0, 10); @@ -34,7 +33,7 @@ public void onEnable() { public void reload() { reloadConfig(); - calculateFallingStarDrops(); + worldLoot.runWorldLootGenerator(); checkForUpdates(); } @@ -52,29 +51,4 @@ public void checkForUpdates() { }); } } - - public void calculateFallingStarDrops() { - ConfigurationSection loot; - fallingStarDrops = new WeightedRandomBag<>(); - if (this.getConfig().isSet("falling-stars-loot")) { - // User has added their own loot table, do not combine with defaults - loot = this.getConfig().getConfigurationSection("falling-stars-loot"); - } else { - // Use default loot table - loot = this.getConfig().getDefaults().getConfigurationSection("falling-stars-loot"); - } - if (loot != null) { - for (String key : loot.getKeys(false)) { - try { - Material.valueOf(key.toUpperCase()); - fallingStarDrops.addEntry(key.toUpperCase(), loot.getDouble(key)); - // System.out.println(key.toUpperCase() + " " + loot.getDouble(key)); - } catch (IllegalArgumentException e) { - System.err.println("Error: Item with name " + key.toUpperCase() + " does not exist, skipping"); - } - } - } else { - System.err.println("Error: Loot table for falling stars can't be found"); - } - } } diff --git a/src/main/java/com/idreesinc/celeste/CelestialSphere.java b/src/main/java/com/idreesinc/celeste/CelestialSphere.java index c802111..9a2b86a 100644 --- a/src/main/java/com/idreesinc/celeste/CelestialSphere.java +++ b/src/main/java/com/idreesinc/celeste/CelestialSphere.java @@ -6,6 +6,8 @@ import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; +import com.idreesinc.celeste.utilities.WorldLootGenerator; + import java.math.RoundingMode; import java.text.DecimalFormat; import java.util.Random; @@ -26,11 +28,12 @@ public static void createShootingStar(Celeste celeste, Location location) { public static void createShootingStar(Celeste celeste, Location location, boolean approximate) { Location starLocation; + WorldLootGenerator.WLConfiguration config = celeste.worldLoot.worldLootConfigs.get(location.getWorld().getName()); double w = 100 * Math.sqrt(new Random().nextDouble()); double t = 2d * Math.PI * new Random().nextDouble(); double x = w * Math.cos(t); - double range = Math.max(0, celeste.getConfig().getInt("shooting-stars-max-height") - celeste.getConfig().getInt("shooting-stars-min-height")); - double y = Math.max(new Random().nextDouble() * range + celeste.getConfig().getInt("shooting-stars-min-height"), location.getY() + 50); + double range = Math.max(0, config.shootingStarsMaxHeight - config.shootingStarsMinHeight); + double y = Math.max(new Random().nextDouble() * range + config.shootingStarsMinHeight, location.getY() + 50); double z = w * Math.sin(t); if (approximate) { starLocation = new Location(location.getWorld(), location.getX() + x, y, location.getZ() + z); @@ -47,7 +50,7 @@ public static void createShootingStar(Celeste celeste, Location location, boolea direction.getY(), direction.getZ(), speed, null, true); } if (celeste.getConfig().getBoolean("debug")) { - celeste.getLogger().info("Shooting star at " + stringifyLocation(starLocation)); + celeste.getLogger().info("Shooting star at " + stringifyLocation(starLocation) + " in world " + starLocation.getWorld().getName()); } } @@ -65,8 +68,9 @@ public static void createFallingStar(Celeste celeste, final Location location) { public static void createFallingStar(Celeste celeste, final Location location, boolean approximate) { Location target = location; + WorldLootGenerator.WLConfiguration config = celeste.worldLoot.worldLootConfigs.get(location.getWorld().getName()); if (approximate) { - double fallingStarRadius = celeste.getConfig().getDouble("falling-stars-radius"); + double fallingStarRadius = config.fallingStarRadius; double w = fallingStarRadius * Math.sqrt(new Random().nextDouble()); double t = 2d * Math.PI * new Random().nextDouble(); double x = w * Math.cos(t); @@ -76,7 +80,7 @@ public static void createFallingStar(Celeste celeste, final Location location, b BukkitRunnable fallingStarTask = new FallingStar(celeste, target); fallingStarTask.runTaskTimer(celeste, 0, 1); if (celeste.getConfig().getBoolean("debug")) { - celeste.getLogger().info("Falling star at " + stringifyLocation(target)); + celeste.getLogger().info("Falling star at " + stringifyLocation(target) + " in world " + target.getWorld().getName()); } } diff --git a/src/main/java/com/idreesinc/celeste/FallingStar.java b/src/main/java/com/idreesinc/celeste/FallingStar.java index b7190e7..90a08c6 100644 --- a/src/main/java/com/idreesinc/celeste/FallingStar.java +++ b/src/main/java/com/idreesinc/celeste/FallingStar.java @@ -1,15 +1,17 @@ package com.idreesinc.celeste; +import java.util.Random; + import org.bukkit.Location; -import org.bukkit.Material; import org.bukkit.Particle; import org.bukkit.Sound; +import org.bukkit.entity.AbstractSkeleton; +import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.ExperienceOrb; -import org.bukkit.inventory.ItemStack; import org.bukkit.scheduler.BukkitRunnable; -import java.util.Random; +import com.idreesinc.celeste.utilities.WorldLootGenerator; public class FallingStar extends BukkitRunnable { @@ -23,7 +25,7 @@ public class FallingStar extends BukkitRunnable { public FallingStar(Celeste celeste, Location location) { this.celeste = celeste; - sparkTimer = celeste.getConfig().getInt("falling-stars-spark-time"); + sparkTimer = celeste.worldLoot.worldLootConfigs.get(location.getWorld().getName()).fallingStarSparkTime;//getConfig().getInt("falling-stars-spark-time"); this.location = location; dropLoc = new Location(location.getWorld(), location.getX(), location.getWorld().getHighestBlockAt(location).getY() + 1, location.getZ()); @@ -45,18 +47,24 @@ public void run() { 0, 0, new Random().nextDouble(), 0, 0.2, null, true); } - if (celeste.getConfig().getBoolean("falling-stars-sound-enabled") && !soundPlayed && y <= dropLoc.getY() + 75) { - location.getWorld().playSound(dropLoc, Sound.BLOCK_BELL_RESONATE, (float) celeste.getConfig().getDouble("falling-stars-volume"), 0.5f); + if (celeste.worldLoot.worldLootConfigs.get(location.getWorld().getName()).fallingStarSoundEnabled && !soundPlayed && y <= dropLoc.getY() + 75) { + location.getWorld().playSound(dropLoc, Sound.BLOCK_BELL_RESONATE, (float) celeste.worldLoot.worldLootConfigs.get(location.getWorld().getName()).fallingStarVolume, 0.5f); soundPlayed = true; } if (y <= dropLoc.getY()) { if (!lootDropped) { - if (celeste.fallingStarDrops.entries.size() > 0) { - ItemStack drop = new ItemStack(Material.valueOf(celeste.fallingStarDrops.getRandom()), 1); - location.getWorld().dropItem(dropLoc, drop); - } - ExperienceOrb orb = (ExperienceOrb) dropLoc.getWorld().spawnEntity(dropLoc, EntityType.EXPERIENCE_ORB); - orb.setExperience(celeste.getConfig().getInt("falling-stars-experience")); + WorldLootGenerator.WLConfiguration config = celeste.worldLoot.worldLootConfigs.get(dropLoc.getWorld().getName().toLowerCase()); + if(config != null) { + for(String lootTableName : config.fallingStarLoot) { + Entity marker = (Entity) dropLoc.getWorld().spawnEntity(location, EntityType.MARKER); + celeste.getServer().dispatchCommand(celeste.getServer().getConsoleSender(),"execute at "+ marker.getUniqueId().toString() +" run loot spawn "+dropLoc.getX() +" "+dropLoc.getY()+" "+dropLoc.getZ()+" loot "+lootTableName); + marker.remove(); + } + if(config.fallingStarExperience > 0) { + ExperienceOrb orb = (ExperienceOrb) dropLoc.getWorld().spawnEntity(dropLoc, EntityType.EXPERIENCE_ORB); + orb.setExperience(config.fallingStarExperience); + } + } lootDropped = true; } if (y % (step * 5) == 0) { diff --git a/src/main/java/com/idreesinc/celeste/utilities/WeightedRandomBag.java b/src/main/java/com/idreesinc/celeste/utilities/WeightedRandomBag.java deleted file mode 100644 index 42be734..0000000 --- a/src/main/java/com/idreesinc/celeste/utilities/WeightedRandomBag.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.idreesinc.celeste.utilities; -//From https://gamedev.stackexchange.com/a/162987 - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -public class WeightedRandomBag { - - private class Entry { - double accumulatedWeight; - T object; - } - - public List entries = new ArrayList(); - private double accumulatedWeight; - private Random rand = new Random(); - - public void addEntry(T object, double weight) { - accumulatedWeight += weight; - Entry e = new Entry(); - e.object = object; - e.accumulatedWeight = accumulatedWeight; - entries.add(e); - } - - public T getRandom() { - double r = rand.nextDouble() * accumulatedWeight; - for (Entry entry: entries) { - if (entry.accumulatedWeight >= r) { - return entry.object; - } - } - // Should only happen when there are no entries - return null; - } -} \ No newline at end of file diff --git a/src/main/java/com/idreesinc/celeste/utilities/WorldLootGenerator.java b/src/main/java/com/idreesinc/celeste/utilities/WorldLootGenerator.java new file mode 100644 index 0000000..d77d56e --- /dev/null +++ b/src/main/java/com/idreesinc/celeste/utilities/WorldLootGenerator.java @@ -0,0 +1,110 @@ +package com.idreesinc.celeste.utilities; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import org.bukkit.NamespacedKey; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.loot.LootContext; +import org.bukkit.loot.LootTable; + +import com.idreesinc.celeste.Celeste; + +/* + * This class is made to handle a few things: + * What worlds are able to have shooting/falling stars in them. + * the amount of shooting/falling stars in a specific world. + * and set loot tables for the loot that can spawn from shooting stars. + * have that loot also be world specific. + * + * This class handles issues #1 and #3 of the Celeste github repo. + * + * @author Trico Everfire. + */ + + +public class WorldLootGenerator { + + private Celeste celeste; + public Map worldLootConfigs = new HashMap<>(); //Saves the world config data in a hashmap. + + public class WLConfiguration { //config to handle each world's data, this way each world can get it's own data. + public boolean newMoonMeteorShower; + public int starStartSpawnTime = 13000; + public int starStopSpawnTime = 23000; + public boolean hasShootingStars = true; + public double shootingStarsPerMinute = 6; + public double shootingStarsPerMinuteMeteorShower = 15; + public int shootingStarsMinHeight = 130; + public int shootingStarsMaxHeight = 160; + public boolean hasFallingingStars = true; + public double fallingStarsPerMinute = 0.2f; + public double fallingStarsPerMinuteMeteorShower = 0.3f; + public int fallingStarRadius = 75; + public boolean fallingStarSoundEnabled = true; + public double fallingStarVolume = 6; + public int fallingStarSparkTime = 200; + public int fallingStarExperience = 100; + public List fallingStarLoot; + + } + + public WorldLootGenerator(Celeste celeste){ + this.celeste = celeste; + } + + public void runWorldLootGenerator() { + this.worldLootConfigs.clear(); //clear map for config updating. + FileConfiguration config = this.celeste.getConfig(); + ConfigurationSection worlds = config.getConfigurationSection("shooting-star-worlds"); + for(String world : worlds.getKeys(false)) { + ConfigurationSection worldSettings = worlds.getConfigurationSection(world); + WLConfiguration worldConfig = new WLConfiguration(); + worldConfig.newMoonMeteorShower = worldSettings.getBoolean("new-moon-meteor-shower",true); + worldConfig.starStartSpawnTime = worldSettings.getInt("star-start-spawn-time", 13000); + worldConfig.starStopSpawnTime = worldSettings.getInt("star-stop-spawn-time", 23000); + + worldConfig.hasShootingStars = worldSettings.getBoolean("shooting-stars-enabled",true); + worldConfig.shootingStarsPerMinute = worldSettings.getDouble("shooting-stars-per-minute", 6); + worldConfig.shootingStarsPerMinuteMeteorShower = worldSettings.getDouble("shooting-stars-per-minute-during-meteor-showers",15); + worldConfig.shootingStarsMinHeight = worldSettings.getInt("shooting-stars-min-height",130); + worldConfig.shootingStarsMaxHeight = worldSettings.getInt("shooting-stars-max-height",160); + + worldConfig.hasFallingingStars = worldSettings.getBoolean("falling-stars-enabled",true); + worldConfig.fallingStarsPerMinute = worldSettings.getDouble("falling-stars-per-minute", 0.2); + worldConfig.fallingStarsPerMinute = worldSettings.getDouble("falling-stars-per-minute", 0.3); + worldConfig.fallingStarRadius = worldSettings.getInt("falling-stars-radius", 75); + worldConfig.fallingStarSoundEnabled = worldSettings.getBoolean("falling-stars-sound-enabled",true); + worldConfig.fallingStarVolume = worldSettings.getDouble("falling-stars-volume", 6); + worldConfig.fallingStarSparkTime = worldSettings.getInt("falling-stars-spark-time",200); + worldConfig.fallingStarExperience = worldSettings.getInt("falling-stars-experience", 100); + worldConfig.fallingStarLoot = worldSettings.getStringList("falling-stars-loot"); + worldLootConfigs.put(world, worldConfig); + } + } + + /* + shooting-stars-enabled: true + falling-stars-enabled: true + shooting-stars-per-minute: 6 + shooting-stars-min-height: 130 + shooting-stars-max-height: 160 + falling-stars-per-minute: 0.2 + falling-stars-radius: 75 + falling-stars-sound-enabled: true + falling-stars-volume: 6 + falling-stars-spark-time: 200 + falling-stars-experience: 100 + falling-stars-loot: + "minecraft:chests/simple_dungeon" + shooting-stars-per-minute-during-meteor-showers: 15 + falling-stars-per-minute-during-meteor-showers: 0.3 + */ + +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index fdb7fcb..016a418 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,22 +1,24 @@ check-for-updates: true -shooting-stars-enabled: true -falling-stars-enabled: true -shooting-stars-per-minute: 6 -shooting-stars-min-height: 130 -shooting-stars-max-height: 160 -falling-stars-per-minute: 0.2 -falling-stars-radius: 75 -falling-stars-sound-enabled: true -falling-stars-volume: 6 -falling-stars-spark-time: 200 -falling-stars-experience: 100 -falling-stars-loot: - diamond: 60 - emerald: 20 - fire_charge: 20 -new-moon-meteor-shower: true -shooting-stars-per-minute-during-meteor-showers: 15 -falling-stars-per-minute-during-meteor-showers: 0.3 +shooting-star-worlds: + world: + new-moon-meteor-shower: true + star-start-spawn-time: 13000 + star-stop-spawn-time: 23000 + shooting-stars-enabled: true + falling-stars-enabled: true + shooting-stars-per-minute: 6 + shooting-stars-min-height: 130 + shooting-stars-max-height: 160 + falling-stars-per-minute: 0.2 + falling-stars-radius: 75 + falling-stars-sound-enabled: true + falling-stars-volume: 6 + falling-stars-spark-time: 200 + falling-stars-experience: 100 + falling-stars-loot: + - "minecraft:chests/simple_dungeon" + shooting-stars-per-minute-during-meteor-showers: 15 + falling-stars-per-minute-during-meteor-showers: 0.3 shooting-stars-summon-text: "Make a wish!" falling-stars-summon-text: "Make a wish!" debug: false