diff --git a/pom.xml b/pom.xml
index ba0d6f3..36fb50e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,8 +23,8 @@
maven-compiler-plugin
3.8.1
- ${java.version}
- ${java.version}
+ 11
+ 11
diff --git a/src/main/java/org/aleabodo/fireworksmc/Commands/Fireworkshow.java b/src/main/java/org/aleabodo/fireworksmc/Commands/Fireworkshow.java
index 397a71e..ea621d4 100644
--- a/src/main/java/org/aleabodo/fireworksmc/Commands/Fireworkshow.java
+++ b/src/main/java/org/aleabodo/fireworksmc/Commands/Fireworkshow.java
@@ -3,6 +3,7 @@ package org.aleabodo.fireworksmc.Commands;
import org.aleabodo.fireworksmc.Direction;
import org.aleabodo.fireworksmc.Fireworks_Mc;
import org.aleabodo.fireworksmc.Message;
+import org.aleabodo.fireworksmc.Tempo;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@@ -28,33 +29,68 @@ public class Fireworkshow implements CommandExecutor, TabCompleter {
switch (args[0]) {
case "setlocation":
//Set location
- Fireworks_Mc.show.setLocation(player.getLocation());
+ Fireworks_Mc.config.location = player.getLocation();
+ Fireworks_Mc.config.save();
Message.sendInfo(player, "Location successfully set to your position.");
- break;
+ return true;
case "setdirection":
- //Set direction
- switch (args[1]) {
- case "north":
- Fireworks_Mc.show.setDirection(Direction.NORTH);
- break;
- case "east":
- Fireworks_Mc.show.setDirection(Direction.EAST);
- break;
- case "south":
- Fireworks_Mc.show.setDirection(Direction.SOUTH);
- break;
- case "west":
- Fireworks_Mc.show.setDirection(Direction.WEST);
- break;
- default:
- Message.sendWarning(player, "Please enter either 'north', 'east', 'south', or 'west'!");
+ //Compute direction based on player yaw
+ if (args.length < 2) {
+ float yaw = player.getLocation().getYaw();
+ if (yaw < 0) {
+ yaw += 360;
+ }
+ yaw = (yaw % 360 + 360) % 360; // true modulo, as javas modulo is weird for negative values
+ Direction direction;
+ if (yaw >= 315 || yaw < 45) {
+ direction = Direction.SOUTH;
+ } else if (yaw < 135) {
+ direction = Direction.WEST;
+ } else if (yaw < 225) {
+ direction = Direction.NORTH;
+ } else if (yaw < 315) {
+ direction = Direction.EAST;
+ } else {
+ direction = Direction.NORTH;
+ }
+ Fireworks_Mc.config.direction = direction;
+ Message.sendInfo(player, "Direction successfully set to " + direction);
+ Fireworks_Mc.config.save();
+ return true;
+ }
+
+ //Set direction manually
+ switch (args[1]) {
+ case "NORTH":
+ Fireworks_Mc.config.direction = Direction.NORTH;
+ Message.sendInfo(player, "Direction successfully set to " + Direction.NORTH);
+ Fireworks_Mc.config.save();
+ return true;
+ case "EAST":
+ Fireworks_Mc.config.direction = Direction.EAST;
+ Message.sendInfo(player, "Direction successfully set to " + Direction.EAST);
+ Fireworks_Mc.config.save();
+ return true;
+ case "SOUTH":
+ Fireworks_Mc.config.direction = Direction.SOUTH;
+ Message.sendInfo(player, "Direction successfully set to " + Direction.SOUTH);
+ Fireworks_Mc.config.save();
+ return true;
+ case "WEST":
+ Fireworks_Mc.config.direction = Direction.WEST;
+ Message.sendInfo(player, "Direction successfully set to " + Direction.WEST);
+ Fireworks_Mc.config.save();
+ return true;
+ default:
+ Message.sendWarning(player, "Please enter either 'NORTH', 'EAST', 'SOUTH', 'WEST', or leave empty!");
+ return false;
}
- break;
case "setduration":
//Set duration
try {
int duration = Integer.parseInt(args[1]);
- Fireworks_Mc.show.setDuration(duration);
+ Fireworks_Mc.config.duration = duration;
+ Fireworks_Mc.config.save();
Message.sendInfo(player, "Duration successfully set to " + duration);
return true;
} catch (NumberFormatException e) {
@@ -66,11 +102,118 @@ public class Fireworkshow implements CommandExecutor, TabCompleter {
for (int i = 1; i highlights;
+ public SortedMap tempo;
+
+ public Config() {
+ reload();
+ }
+
+ private void load() {
+ Fireworks_Mc.getPlugin().reloadConfig();
+ FileConfiguration config = Fireworks_Mc.getPlugin().getConfig();
+ this.bpm = config.getInt("bpm", 80);
+ this.duration = config.getInt("duration", 60);
+ this.seed = config.getString("seed", "Survival-Pi");
+ this.highlights = new TreeSet<>(config.getIntegerList("highlights"));
+
+ // Parse and set location
+ this.location = new Location(
+ Fireworks_Mc.getWorld(config.getString("location.world","world")),
+ config.getInt("location.x",0),
+ config.getInt("location.y",80),
+ config.getInt("location.z",0)
+ );
+
+ // Parse and set direction
+ String direction = config.getString("direction", "WEST");
+ if(direction != null) {
+ switch (direction) {
+ case "NORTH":
+ this.direction = Direction.NORTH;
+ case "EAST":
+ this.direction = Direction.EAST;
+ case "SOUTH":
+ this.direction = Direction.SOUTH;
+ default:
+ this.direction = Direction.WEST;
+ }
+ }
+
+ // Parse and set tempo
+ SortedMap tempo = new TreeMap<>();
+ List tempoArray = config.getStringList("tempo");
+ tempo.put(0, Tempo.NORMAL); //Have at least one tempo configuration in the map
+ for (String tempoString : tempoArray) {
+ String[] args = tempoString.split(",");
+ if (args.length == 2) {
+ try {
+ Tempo t;
+ switch (args[1]) {
+ case "QUIET":
+ t = Tempo.QUIET;
+ case "SLOW":
+ t = Tempo.SLOW;
+ case "FAST":
+ t = Tempo.FAST;
+ case "FASTEST":
+ t = Tempo.FASTEST;
+ default:
+ t = Tempo.NORMAL;
+ }
+ tempo.put(Integer.parseInt(args[0]), t);
+ } catch (NumberFormatException e) {
+ Fireworks_Mc.getPlugin().getLogger().log(Level.SEVERE, "Config in section 'tempo' is expecting an integer!");
+ return;
+ }
+ }
+ }
+ this.tempo = tempo;
+ }
+
+ public void save() {
+ FileConfiguration config = Fireworks_Mc.getPlugin().getConfig();
+
+ config.set("bpm", this.bpm);
+ config.set("seed", this.seed);
+ config.set("duration", this.duration);
+ config.set("direction", this.direction.toString());
+ config.set("highlights", new ArrayList<>(this.highlights));
+
+ //Convert tempo map to ArrayList and set tempo in config to this list
+ ArrayList tempoStringList = new ArrayList<>();
+ for (Integer key : this.tempo.keySet()) {
+ Tempo value = this.tempo.get(key);
+ tempoStringList.add(key + "," + value.toString());
+ }
+ config.set("tempo", tempoStringList);
+
+ ConfigurationSection locationSection = config.createSection("location");
+ locationSection.set("world", this.location.getWorld().getName());
+ locationSection.set("x", this.location.getX());
+ locationSection.set("y", this.location.getY());
+ locationSection.set("z", this.location.getZ());
+
+ Fireworks_Mc.getPlugin().saveConfig();
+ }
+
+ public void print() {
+ //Compute string of all highlights. Use this string to append to the text component
+ StringBuilder highlight = new StringBuilder();
+ for (Integer h : this.highlights) {
+ highlight.append("\n")
+ .append(" - ")
+ .append(".".repeat(Message.getNumberOfDotsToAlign(" - " + h)))
+ .append(h);
+ }
+
+ //Compute string of all tempos
+ StringBuilder tempos = new StringBuilder();
+ for (Integer key : this.tempo.keySet()) {
+ Tempo value = this.tempo.get(key);
+ tempos.append("\n")
+ .append(" - ")
+ .append(".".repeat(Message.getNumberOfDotsToAlign(" - " + key + "," + value.toString())))
+ .append(key).append(",").append(value.toString());
+ }
+
+ Message.sendDebug(
+ Component.text("Config:\n").color(NamedTextColor.GOLD),
+ Component.text(
+ "direction: "
+ + ".".repeat(Message.getNumberOfDotsToAlign("direction: " + this.direction.toString()))
+ + this.direction.toString()
+ + "\n"
+
+ + "bpm: "
+ + ".".repeat(Message.getNumberOfDotsToAlign("bpm: " + this.bpm))
+ + this.bpm
+ + "\n"
+
+ + "duration: "
+ + ".".repeat(Message.getNumberOfDotsToAlign("duration: " + this.duration))
+ + this.duration
+ + "\n"
+
+ + "seed: "
+ + ".".repeat(Message.getNumberOfDotsToAlign("seed: " + this.seed))
+ + this.seed
+ + "\n"
+
+ + "location:"
+ + "\n"
+ + " - world: "
+ + ".".repeat(Message.getNumberOfDotsToAlign(" - world: " + this.location.getWorld().getName()))
+ + this.location.getWorld().getName()
+ + "\n"
+ + " - x: "
+ + ".".repeat(Message.getNumberOfDotsToAlign(" - x: " + this.location.getX()))
+ + this.location.getX()
+ + "\n"
+ + " - y: "
+ + ".".repeat(Message.getNumberOfDotsToAlign(" - y: " + this.location.getY()))
+ + this.location.getY()
+ + "\n"
+ + " - z: "
+ + ".".repeat(Message.getNumberOfDotsToAlign(" - z: " + this.location.getZ()))
+ + this.location.getZ()
+ + "\n"
+
+ + "highlights:"
+ + highlight
+ + "\n"
+
+ + "tempo:"
+ + tempos
+ )
+ );
+ }
+
+ public void reload() {
+ load();
+ }
+}
diff --git a/src/main/java/org/aleabodo/fireworksmc/Direction.java b/src/main/java/org/aleabodo/fireworksmc/Direction.java
index 3a806ae..41c9f57 100644
--- a/src/main/java/org/aleabodo/fireworksmc/Direction.java
+++ b/src/main/java/org/aleabodo/fireworksmc/Direction.java
@@ -4,5 +4,20 @@ public enum Direction {
NORTH,
EAST,
SOUTH,
- WEST
+ WEST;
+
+ @Override
+ public String toString() {
+ switch (this) {
+ case NORTH:
+ return "NORTH";
+ case EAST:
+ return "EAST";
+ case SOUTH:
+ return "SOUTH";
+ case WEST:
+ return "WEST";
+ }
+ return null;
+ }
}
diff --git a/src/main/java/org/aleabodo/fireworksmc/Fireworks_Mc.java b/src/main/java/org/aleabodo/fireworksmc/Fireworks_Mc.java
index 2008f37..6893c18 100644
--- a/src/main/java/org/aleabodo/fireworksmc/Fireworks_Mc.java
+++ b/src/main/java/org/aleabodo/fireworksmc/Fireworks_Mc.java
@@ -22,6 +22,7 @@ public final class Fireworks_Mc extends JavaPlugin {
private static Fireworks_Mc plugin;
public static Show show;
+ public static Config config;
@Override
public void onEnable() {
@@ -40,16 +41,22 @@ public final class Fireworks_Mc extends JavaPlugin {
}
particlesAPI = ParticleNativePlugin.getAPI();
+ /*
+ * Initilize config
+ */
+ Fireworks_Mc.config = new Config();
+
//Initialize show with default values
- Fireworks_Mc.show = new Show("Survival-Pi",
+ /*Fireworks_Mc.show = new Show("Survival-Pi",
new Location(Fireworks_Mc.getWorld("world"), 0, 80, 0),
Direction.NORTH,
- 60);
-
+ 60,76);
+*/
/*
* Initialize command executors
*/
Objects.requireNonNull(getCommand("fireworkshow")).setExecutor(new Fireworkshow());
+ Objects.requireNonNull(getCommand("fs")).setExecutor(new Fireworkshow()); //Command alias for fireworkshow
}
@Override
diff --git a/src/main/java/org/aleabodo/fireworksmc/Message.java b/src/main/java/org/aleabodo/fireworksmc/Message.java
index 0535dbe..f7ad340 100644
--- a/src/main/java/org/aleabodo/fireworksmc/Message.java
+++ b/src/main/java/org/aleabodo/fireworksmc/Message.java
@@ -6,6 +6,7 @@ import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
+import org.bukkit.map.MinecraftFont;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
@@ -13,7 +14,7 @@ import java.util.Collection;
public class Message {
public static void sendInfo(@NotNull Player player, Component ... content) {
- Component textComponent = Component.text().color(NamedTextColor.GRAY).build()
+ Component textComponent = Component.text().color(NamedTextColor.WHITE).build()
.append(Component.text("[Fireworks] ")
.color(TextColor.color(0,213,255))
.decoration(TextDecoration.BOLD, true));
@@ -46,7 +47,7 @@ public class Message {
*/
public static void sendWarning(@NotNull Player player, Component ... content) {
- Component textComponent = Component.text().color(NamedTextColor.GRAY).build()
+ Component textComponent = Component.text().color(NamedTextColor.WHITE).build()
.append(Component.text("[Fireworks] ")
.color(TextColor.color(255, 3, 4))
.decoration(TextDecoration.BOLD, true));
@@ -80,7 +81,7 @@ public class Message {
*/
public static void sendBroadcast(Component ... content) {
- Component textComponent = Component.text().color(NamedTextColor.GRAY).build()
+ Component textComponent = Component.text().color(NamedTextColor.WHITE).build()
.append(Component.text("[Fireworks] ")
.color(TextColor.color(255, 153, 0))
.decoration(TextDecoration.BOLD, true));
@@ -104,7 +105,7 @@ public class Message {
*/
public static void sendDebug(Component ... content) {
- Component textComponent = Component.text().color(NamedTextColor.GRAY).build()
+ Component textComponent = Component.text().color(NamedTextColor.WHITE).build()
.append(Component.text("[Fireworks] ")
.color(TextColor.color(255, 0, 245))
.decoration(TextDecoration.BOLD, true));
@@ -114,7 +115,7 @@ public class Message {
}
for (Player p : Bukkit.getOnlinePlayers()) {
- if (p.hasPermission("beacon.debug"))
+ if (p.hasPermission("fireworksmc.debug"))
p.sendMessage(textComponent);
}
}
@@ -122,4 +123,13 @@ public class Message {
public static void sendDebug(String content) {
sendDebug(Component.text(content));
}
+
+ /*
+ * #############################################################################
+ * Utils
+ */
+
+ public static int getNumberOfDotsToAlign(String displayText) {
+ return (int) Math.round((130.0 - MinecraftFont.Font.getWidth(displayText))/2);
+ }
}
\ No newline at end of file
diff --git a/src/main/java/org/aleabodo/fireworksmc/Patterns/Pattern.java b/src/main/java/org/aleabodo/fireworksmc/Patterns/Pattern.java
new file mode 100644
index 0000000..39d784f
--- /dev/null
+++ b/src/main/java/org/aleabodo/fireworksmc/Patterns/Pattern.java
@@ -0,0 +1,17 @@
+package org.aleabodo.fireworksmc.Patterns;
+
+public class Pattern {
+ private int duration = 10;
+
+ public Pattern(int duration) {
+
+ }
+
+ /*
+ * ################### GETTER ###################
+ */
+
+ public int getDuration() {
+ return duration;
+ }
+}
diff --git a/src/main/java/org/aleabodo/fireworksmc/Show.java b/src/main/java/org/aleabodo/fireworksmc/Show.java
index 2469bcd..3246d08 100644
--- a/src/main/java/org/aleabodo/fireworksmc/Show.java
+++ b/src/main/java/org/aleabodo/fireworksmc/Show.java
@@ -1,13 +1,11 @@
package org.aleabodo.fireworksmc;
-import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.FireworkEffect;
import org.bukkit.Location;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Firework;
import org.bukkit.inventory.meta.FireworkMeta;
-import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import java.security.MessageDigest;
@@ -15,16 +13,25 @@ import java.security.NoSuchAlgorithmException;
import java.util.Random;
public class Show {
- private String seed;
+ private long seed;
private Location location;
private Direction direction;
private int duration; //in seconds
+ private int bpm;
- public Show(String seed, Location location, Direction direction, int duration) {
+ public Show(long seed, Location location, Direction direction, int duration, int bpm) {
this.seed = seed;
this.location = location;
this.direction = direction;
this.duration = duration;
+ this.bpm = bpm;
+ }
+
+ /*
+ * Generate the firework show according to the random seed and the timings/highlights configured
+ */
+ public void generate() {
+
}
/**
@@ -60,34 +67,11 @@ public class Show {
}.runTaskLater(Fireworks_Mc.getPlugin(), 20); // 20 ticks = 1 second
}
- /**
- *
- * @param seedString Random seed as string
- * @return Random number between 0 and based on the seed
- */
- private double generateRandomValueFromSeed(String seedString) {
- try {
- MessageDigest md = MessageDigest.getInstance("SHA-256");
- byte[] hashBytes = md.digest(seedString.getBytes());
-
- // Convert the first 8 bytes of the hash to a long value
- long hashValue = 0;
- for (int i = 0; i < 8; i++) {
- hashValue = (hashValue << 8) | (hashBytes[i]);
- }
-
- //Convert long (hastValue) into random number between 0 and 1.
- return new Random(hashValue).nextDouble();
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException("Hashing algorithm not available. (Have to check or Intellij complains.", e);
- }
- }
-
/*
* ################### GETTER ###################
*/
- public String getSeed() {
+ public long getSeed() {
return seed;
}
@@ -103,13 +87,15 @@ public class Show {
return duration;
}
-
+ public int getBpm() {
+ return bpm;
+ }
/*
* ################### SETTER ###################
*/
- public void setSeed(String seed) {
+ public void setSeed(long seed) {
this.seed = seed;
}
@@ -124,4 +110,8 @@ public class Show {
public void setDuration(int duration) {
this.duration = duration;
}
+
+ public void setBpm(int bpm) {
+ this.bpm = bpm;
+ }
}
diff --git a/src/main/java/org/aleabodo/fireworksmc/Tempo.java b/src/main/java/org/aleabodo/fireworksmc/Tempo.java
new file mode 100644
index 0000000..21a5056
--- /dev/null
+++ b/src/main/java/org/aleabodo/fireworksmc/Tempo.java
@@ -0,0 +1,26 @@
+package org.aleabodo.fireworksmc;
+
+public enum Tempo {
+ QUIET,
+ SLOW,
+ NORMAL,
+ FAST,
+ FASTEST;
+
+ @Override
+ public String toString() {
+ switch (this) {
+ case QUIET:
+ return "QUIET";
+ case SLOW:
+ return "SLOW";
+ case NORMAL:
+ return "NORMAL";
+ case FAST:
+ return "FAST";
+ case FASTEST:
+ return "FASTEST";
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/org/aleabodo/fireworksmc/Utils.java b/src/main/java/org/aleabodo/fireworksmc/Utils.java
new file mode 100644
index 0000000..d8258bb
--- /dev/null
+++ b/src/main/java/org/aleabodo/fireworksmc/Utils.java
@@ -0,0 +1,38 @@
+package org.aleabodo.fireworksmc;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Random;
+
+public class Utils {
+ /**
+ *
+ * @param seed as long
+ * @return Random number between 0 and based on the seed
+ */
+ public static double generateRandomValueFromSeed(long seed) {
+ return new Random(seed).nextDouble();
+ }
+
+ /**
+ *
+ * @param seedString Random seed as string
+ * @return Seed converted as long
+ */
+ public static long generateLongFromSeed(String seedString) {
+ try {
+ MessageDigest md = MessageDigest.getInstance("SHA-256");
+ byte[] hashBytes = md.digest(seedString.getBytes());
+
+ // Convert the first 8 bytes of the hash to a long value
+ long hashValue = 0;
+ for (int i = 0; i < 8; i++) {
+ hashValue = (hashValue << 8) | (hashBytes[i]);
+ }
+
+ return hashValue;
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException("Hashing algorithm not available. (Have to check or Intellij complains.", e);
+ }
+ }
+}
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 050cd68..89766a6 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -5,6 +5,7 @@ api-version: '1.20'
commands:
fireworkshow:
description: All fireworks show related commands
+ aliases: [fs]
depend: [ParticleNativeAPI]
permissions:
fireworksmc.setseed: