Skip to content

Commit

Permalink
Add backwards compatibility, fix bugs, and clean up code
Browse files Browse the repository at this point in the history
  • Loading branch information
IdreesInc committed Dec 28, 2021
1 parent 0caf9e6 commit cea6778
Show file tree
Hide file tree
Showing 13 changed files with 343 additions and 189 deletions.
49 changes: 45 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ Inspired by the star fragments from The Legend of Zelda: Breath of the Wild, the
Shooting stars and falling stars spawn on a per-world basis. This means that the number of players in a world does not affect the spawning rate. When either type of star is given a chance to spawn, the plugin will find a random player within that world and center the spawn in a large radius around said player, in order to avoid sending stars to unloaded chunks where they would never be found.
Additionally, the worlds that shooting and falling stars can spawn in must meet the following conditions:
- Must have players in the world currently
- Must be nighttime (between 13000 and 23000 in game time)
- Must be nighttime (between 13000 and 23000 in game time by default, but this can be configured)
- Must be clear weather (no rain or snow)
- Will not spawn in the nether or end
- Will not spawn in the nether or end by default

## Configuration
Installation is as simple as copying the newest build jar to your plugins folder. A configuration file is created by default, but if the file was created previously it may not include default values that were added in later updates. These values can be added easily by just copying and pasting the particular lines from the defaults below.
Expand All @@ -41,6 +41,10 @@ check-for-updates: true
shooting-stars-enabled: true
# Whether to spawn falling stars or not
falling-stars-enabled: true
# When to begin spawning shooting and falling stars
begin-spawning-stars-time: 13000
# When to stop spawning shooting and falling stars
end-spawning-stars-time: 23000
# The average number of shooting stars to create per minute for each world
shooting-stars-per-minute: 6
# The minimum y level where a shooting star can spawn
Expand Down Expand Up @@ -82,9 +86,13 @@ debug: false
### Falling Star Loot
Falling stars drop loot wherever they fall, and spark for 10 seconds (200 ticks) by default to show their location. The loot they drop is randomly selected from the loot table in the config, with each material being given a weight. For instance, in the default config, there is a 60% chance for a diamond, 20% of an emerald, and 20% chance of a fire_charge. Experience also drops from falling stars, 100 points (not levels) by default.
To define your own loot tables, add the `falling-stars-loot` attribute to your config (remember, you will have to create the plugin config if you haven't already done so) and list each item you want as well as the probability for it to appear. **The names of the items must be from the list provided [here](https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html)**. Remember to only add materials available in your server version.
**You have the option of defining a simple list of items in the config or using Minecraft's built-in [loot table](https://minecraft.fandom.com/wiki/Loot_table) system.** The config-based loot system is simpler as it doesn't require messing with data packs, but it is limited to only one item at a time and is unable to produce items with NBT data attached. For more advanced loot, you'll probably want to use loot tables. Note that both kinds of loot configurations can be used at the same time if you wish to do so for whatever reason.
Here is an example of a custom loot configuration:
#### Simple Config-Based Loot
To define a simple list of potential loot that can appear, add the `falling-stars-loot` attribute to your config (remember, you will have to create the plugin config if it doesn't already exist) and list each item you want as well as the probability for it to appear. **The names of the items must be from the list provided [here](https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html)**. Remember to only add materials available in your server version. Using this method, only one item will spawn at a time. If you want to spawn more items at once or add NBT data to the items spawned, you'll need to use loot tables (more on that below).

Here is an example of a custom config-based loot configuration:

``` yaml
falling-stars-loot:
Expand All @@ -94,6 +102,39 @@ falling-stars-loot:
blue_orchid: 33
```

#### Loot Tables

Using Minecraft's built-in loot table feature, you can fully customize the type of items dropped, the number of items, and add whatever metadata you want. The catch is that loot tables are much more complex and require messing with external data files. [This](https://minecraft.tools/en/loots.php) tool can make it easier to work with loot tables, and a special thanks to [@Trico-Everfire](https://github.com/Trico-Everfire) for this feature's inclusion.

Here is an example of how to use a built-in loot table for the falling star drops:

``` yaml
falling-stars-loot-table: "minecraft:chests/simple_dungeon"
```

### Custom World Settings

If you would like to use different settings for particular worlds, you can use the `world-overrides` attribute in your config. World overrides give you the ability to easily change the plugin's functionality on a per-world basis. The following is an example of a config that has different settings for certain worlds:

``` yaml
falling-stars-spark-time: 200
falling-stars-experience: 100
falling-stars-loot:
diamond: 60
emerald: 20
fire_charge: 20
# These settings override the above global settings for the specified worlds
world-overrides:
some_world:
falling-stars-enabled: false
another_world:
falling-stars-loot-table: "minecraft:chests/simple_dungeon"
falling-stars-experience: 300
```

In the above example, the worlds "some_world" and "another_world" have properties that override the global settings. For instance, falling stars are disabled in "some_world" and a loot table is used in place of the simple loot config for "another_world". Any worlds not mentioned in the `world-overrides` section will continue to follow the global configs or use built in defaults if the attribute is unchanged.

## Commands
**/shootingstar [player]** summons a shooting star in the sky directly above the player. If no player is given, spawns one above the summoner.
*Permission: celeste.shootingstar*
Expand Down
Binary file added dist/Celeste-2.0-BETA.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.idreesinc</groupId>
<artifactId>Celeste</artifactId>
<version>1.6</version>
<version>2.0-BETA</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
Expand Down
43 changes: 19 additions & 24 deletions src/main/java/com/idreesinc/celeste/Astronomer.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package com.idreesinc.celeste;

import com.idreesinc.celeste.config.CelesteConfig;
import org.bukkit.World;
import org.bukkit.scheduler.BukkitRunnable;

import com.idreesinc.celeste.utilities.WorldLootGenerator;

import java.util.List;
import java.util.Random;

Expand All @@ -20,46 +19,42 @@ public void run() {
if (celeste.getServer().getOnlinePlayers().size() == 0) {
return;
}

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);

List<World> worlds = celeste.getServer().getWorlds();
for (World world : worlds) {
CelesteConfig config = celeste.configManager.getConfigForWorld(world.getName());
if (!celeste.configManager.doesWorldHaveOverrides(world.getName())
&& !world.getEnvironment().equals(World.Environment.NORMAL)) {
// Ensure that Celeste only runs on normal worlds unless override is specified in config
continue;
}
if (world.getPlayers().size() == 0) {
continue;
}
if (!(world.getTime() >= config.starStartSpawnTime && world.getTime() <= config.starStopSpawnTime)) {
if (!(world.getTime() >= config.beginSpawningStarsTime && world.getTime() <= config.endSpawningStarsTime)) {
continue;
}
if (world.hasStorm()) {
continue;
}

double shootingStarChance;
double fallingStarChance;
if (config.newMoonMeteorShower && (world.getFullTime() / 24000) % 8 == 4) {
shootingStarChance =
config.shootingStarsPerMinuteMeteorShower / 120d;
fallingStarChance =
config.fallingStarsPerMinuteMeteorShower / 120d;
shootingStarChance = config.shootingStarsPerMinuteMeteorShower / 120d;
fallingStarChance = config.fallingStarsPerMinuteMeteorShower / 120d;
} else {
shootingStarChance = config.shootingStarsPerMinute / 120d;
fallingStarChance = config.fallingStarsPerMinute / 120d;
}

if (config.hasShootingStars && new Random().nextDouble() <= shootingStarChance) {
CelestialSphere.createShootingStar(celeste, world.getPlayers().get(new Random().nextInt(world.getPlayers().size())));
if (config.shootingStarsEnabled && new Random().nextDouble() <= shootingStarChance) {
CelestialSphere.createShootingStar(celeste,
world.getPlayers().get(new Random().nextInt(world.getPlayers().size())));
}
if (config.hasFallingingStars && new Random().nextDouble() <= fallingStarChance) {
CelestialSphere.createFallingStar(celeste, world.getPlayers().get(new Random().nextInt(world.getPlayers().size())));
if (config.fallingStarsEnabled && new Random().nextDouble() <= fallingStarChance) {
CelestialSphere.createFallingStar(celeste,
world.getPlayers().get(new Random().nextInt(world.getPlayers().size())));
}

}


}
}
13 changes: 8 additions & 5 deletions src/main/java/com/idreesinc/celeste/Celeste.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@
import com.idreesinc.celeste.commands.CommandShootingStar;
import com.idreesinc.celeste.utilities.Metrics;
import com.idreesinc.celeste.utilities.UpdateChecker;
import com.idreesinc.celeste.utilities.WorldLootGenerator;
import com.idreesinc.celeste.config.CelesteConfigManager;

public class Celeste extends JavaPlugin {

//public WeightedRandomBag<String> fallingStarDrops = new WeightedRandomBag<>();
public WorldLootGenerator worldLoot = new WorldLootGenerator(this);
public CelesteConfigManager configManager = new CelesteConfigManager(this);

@Override
public void onEnable() {
this.saveDefaultConfig();
// bStats metrics
Metrics metrics = new Metrics(this, 8292);

this.getCommand("celeste").setExecutor(new CommandCeleste(this));
this.getCommand("shootingstar").setExecutor(new CommandShootingStar(this));
this.getCommand("fallingstar").setExecutor(new CommandFallingStar(this));
worldLoot.runWorldLootGenerator();
configManager.processConfigs();

BukkitRunnable stargazingTask = new Astronomer(this);
stargazingTask.runTaskTimer(this, 0, 10);
Expand All @@ -33,7 +33,7 @@ public void onEnable() {

public void reload() {
reloadConfig();
worldLoot.runWorldLootGenerator();
configManager.processConfigs();
checkForUpdates();
}

Expand All @@ -47,6 +47,9 @@ public void checkForUpdates() {
this.getLogger().info("There is an update available for Celeste (" + current + " -> " + api + ")");
}
} catch (NumberFormatException e) {
if (this.getConfig().getBoolean("debug")) {
this.getLogger().severe("Unable to process remote plugin version number '" + version + "'");
}
}
});
}
Expand Down
9 changes: 4 additions & 5 deletions src/main/java/com/idreesinc/celeste/CelestialSphere.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package com.idreesinc.celeste;

import com.idreesinc.celeste.config.CelesteConfig;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.entity.Player;
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;
Expand All @@ -28,7 +27,7 @@ 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());
CelesteConfig config = celeste.configManager.getConfigForWorld(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);
Expand Down Expand Up @@ -68,9 +67,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());
CelesteConfig config = celeste.configManager.getConfigForWorld(location.getWorld().getName());
if (approximate) {
double fallingStarRadius = config.fallingStarRadius;
double fallingStarRadius = config.fallingStarsRadius;
double w = fallingStarRadius * Math.sqrt(new Random().nextDouble());
double t = 2d * Math.PI * new Random().nextDouble();
double x = w * Math.cos(t);
Expand Down
58 changes: 39 additions & 19 deletions src/main/java/com/idreesinc/celeste/FallingStar.java
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
package com.idreesinc.celeste;

import java.util.Random;

import com.idreesinc.celeste.config.CelesteConfig;
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 com.idreesinc.celeste.utilities.WorldLootGenerator;
import java.util.Random;

public class FallingStar extends BukkitRunnable {

private final Celeste celeste;
private final Location location;
private final Location dropLoc;
private final CelesteConfig config;
private double y = 256;
private boolean soundPlayed = false;
private boolean lootDropped = false;
private int sparkTimer;

public FallingStar(Celeste celeste, Location location) {
this.celeste = celeste;
sparkTimer = celeste.worldLoot.worldLootConfigs.get(location.getWorld().getName()).fallingStarSparkTime;//getConfig().getInt("falling-stars-spark-time");
this.location = location;
config = celeste.configManager.getConfigForWorld(location.getWorld().getName());
sparkTimer = config.fallingStarsSparkTime;
dropLoc = new Location(location.getWorld(), location.getX(),
location.getWorld().getHighestBlockAt(location).getY() + 1, location.getZ());
}
Expand All @@ -47,24 +49,42 @@ public void run() {
0, 0, new Random().nextDouble(), 0,
0.2, null, true);
}
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);
if (config.fallingStarsSoundEnabled && !soundPlayed && y <= dropLoc.getY() + 75) {
location.getWorld().playSound(dropLoc, Sound.BLOCK_BELL_RESONATE, (float) config.fallingStarsVolume, 0.5f);
soundPlayed = true;
}
if (y <= dropLoc.getY()) {
if (!lootDropped) {
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);
}
}
// Note that both simple loot and loot tables will drop if both are configured because why not
if (config.fallingStarSimpleLoot != null && config.fallingStarSimpleLoot.entries.size() > 0) {
ItemStack drop = new ItemStack(Material.valueOf(config.fallingStarSimpleLoot.getRandom()), 1);
location.getWorld().dropItem(dropLoc, drop);
if (celeste.getConfig().getBoolean("debug")) {
celeste.getLogger().info("Spawned simple falling star loot");
}
}
if (config.fallingStarLootTable != null) {
// Armor stands are used as markers are not compatible with 1.14
Entity marker = dropLoc.getWorld().spawnEntity(location, EntityType.ARMOR_STAND);
String command = String.format("execute at %s run loot spawn %s %s %s loot %s",
marker.getUniqueId(),
dropLoc.getX(),
dropLoc.getY(),
dropLoc.getZ(),
config.fallingStarLootTable);
celeste.getServer().dispatchCommand(celeste.getServer().getConsoleSender(), command);
marker.remove();
if (celeste.getConfig().getBoolean("debug")) {
celeste.getLogger().info("Spawned falling star loot from loot table '" + config.fallingStarLootTable + "'");
}
}
if (config.fallingStarsExperience > 0) {
ExperienceOrb orb = (ExperienceOrb) dropLoc.getWorld().spawnEntity(dropLoc, EntityType.EXPERIENCE_ORB);
orb.setExperience(config.fallingStarsExperience);
if (celeste.getConfig().getBoolean("debug")) {
celeste.getLogger().info("Dropping experience orbs with value " + config.fallingStarsExperience);
}
}
lootDropped = true;
}
if (y % (step * 5) == 0) {
Expand Down
Loading

0 comments on commit cea6778

Please sign in to comment.