From 2ce53146dea17ddc93296c7c8668321375d635fb Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Fri, 21 Jun 2024 19:07:21 -0400 Subject: [PATCH 01/24] Create example configurations for balloons Add model engine as a dependency in pom.xml --- pom.xml | 17 ++++++++++ .../resources/balloons/dyeable_example.yml | 12 +++++++ .../resources/balloons/multipart_example.yml | 32 ++++++++++++++++++- 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8ca02d2b..fb26de32 100644 --- a/pom.xml +++ b/pom.xml @@ -84,9 +84,15 @@ sonatype https://oss.sonatype.org/content/groups/public/ + + nexus + Lumine Public + https://mvn.lumine.io/repository/maven-public/ + + kiputyttö-releases Ilari's Project Repository @@ -95,6 +101,7 @@ + io.papermc.paper paper-api @@ -106,6 +113,8 @@ adventure-text-minimessage 4.17.0 + + org.projectlombok lombok @@ -123,5 +132,13 @@ maven-model 3.9.7 + + + + com.ticxo.modelengine + ModelEngine + R4.0.4 + provided + diff --git a/src/main/resources/balloons/dyeable_example.yml b/src/main/resources/balloons/dyeable_example.yml index 078519d8..2061cf23 100644 --- a/src/main/resources/balloons/dyeable_example.yml +++ b/src/main/resources/balloons/dyeable_example.yml @@ -13,3 +13,15 @@ dyeable_example: - '&8Bloons Example Balloon' - '' - '&eᴄʟɪᴄᴋ ᴛᴏ ᴇǫᴜɪᴘ' +single_meg_example: + id: single_meg_example + permission: balloon.single_meg_example + meg-model-id: single_meg_example + icon: + display-material: FLINT + display-custom-model-data: 7 + name: 'Single MEG Balloon' + lore: + - '&8Bloons Default Balloon' + - '' + - '&eᴄʟɪᴄᴋ ᴛᴏ ᴇǫᴜɪᴘ' diff --git a/src/main/resources/balloons/multipart_example.yml b/src/main/resources/balloons/multipart_example.yml index 7f919acb..1f79b13f 100644 --- a/src/main/resources/balloons/multipart_example.yml +++ b/src/main/resources/balloons/multipart_example.yml @@ -32,4 +32,34 @@ multipart_example: tail: # Tail must be supplied for a balloon of this kind material: LEATHER_HORSE_ARMOR # The material of the tail color: '#ffffff' # The color of the tail, this is optional - custom-model-data: 10282 # The custom model data of the tail, this is not required but is recommended for use of models \ No newline at end of file + custom-model-data: 10282 # The custom model data of the tail, this is not required but is recommended for use of models +multipart_meg_example: + type: multipart # The type of balloon, this must be multipart for multipart balloons + id: multipart_meg_example # The id of the balloon, this must be unique + permission: balloon.multipart_meg_example + icon: + material: FLINT # The material of the balloon + custom-model-data: 10283 # The custom model data of the balloon GUI item, this is not required but is recommended for use of models + name: 'Multipart Balloon' + lore: + - '&8Bloons Default Balloon' + - '' + - '&eᴄʟɪᴄᴋ ᴛᴏ ᴇǫᴜɪᴘ' + node-count: 5 # The amount of nodes/models in the balloon including the head and tail + distance-between-nodes: 2.0 # The distance between nodes/models in blocks + leash-height: 1.2 # The height of the leash from the zero relative to the balloon + head-node-offset: 0.0 # The offset of length of head node segments in blocks + body-node-offset: 0.0 # The offset of length of body node segments in blocks + tail-node-offset: 0.0 # The offset of length of tail node segments in blocks + max-joint-angle: 35.0 # The max angle in degrees of freedom for each joint between nodes + y-axis-interpolation: 0.2 # The amount of interpolation between nodes on the Y axis (must be between 0.0 and 1.0) + turning-spline-interpolation: 0.5 # The amount of interpolation for the spline when turning + passive-sine-wave-speed: 0.05 # The speed of the passive sine wave + passive-sine-wave-amplitude: 0.5 # The amplitude of the passive sine wave + passive-nose-sine-wave-amplitude: 0.5 # The amplitude of the passive sine wave for the nose + head: # Head must be supplied for a balloon of this kind + meg-model-id: example_meg_model # The id of the meg model + body: # Body must be supplied for a balloon of this kind + meg-model-id: example_meg_model # The id of the meg model + tail: # Tail must be supplied for a balloon of this kind + meg-model-id: example_meg_model # The id of the meg model From 66c7b06b011ee13addcdddc499823f4b74043e4e Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Fri, 21 Jun 2024 19:23:53 -0400 Subject: [PATCH 02/24] Remove multipart example config --- .../resources/balloons/multipart_example.yml | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/src/main/resources/balloons/multipart_example.yml b/src/main/resources/balloons/multipart_example.yml index 1f79b13f..955f5bb1 100644 --- a/src/main/resources/balloons/multipart_example.yml +++ b/src/main/resources/balloons/multipart_example.yml @@ -33,33 +33,3 @@ multipart_example: material: LEATHER_HORSE_ARMOR # The material of the tail color: '#ffffff' # The color of the tail, this is optional custom-model-data: 10282 # The custom model data of the tail, this is not required but is recommended for use of models -multipart_meg_example: - type: multipart # The type of balloon, this must be multipart for multipart balloons - id: multipart_meg_example # The id of the balloon, this must be unique - permission: balloon.multipart_meg_example - icon: - material: FLINT # The material of the balloon - custom-model-data: 10283 # The custom model data of the balloon GUI item, this is not required but is recommended for use of models - name: 'Multipart Balloon' - lore: - - '&8Bloons Default Balloon' - - '' - - '&eᴄʟɪᴄᴋ ᴛᴏ ᴇǫᴜɪᴘ' - node-count: 5 # The amount of nodes/models in the balloon including the head and tail - distance-between-nodes: 2.0 # The distance between nodes/models in blocks - leash-height: 1.2 # The height of the leash from the zero relative to the balloon - head-node-offset: 0.0 # The offset of length of head node segments in blocks - body-node-offset: 0.0 # The offset of length of body node segments in blocks - tail-node-offset: 0.0 # The offset of length of tail node segments in blocks - max-joint-angle: 35.0 # The max angle in degrees of freedom for each joint between nodes - y-axis-interpolation: 0.2 # The amount of interpolation between nodes on the Y axis (must be between 0.0 and 1.0) - turning-spline-interpolation: 0.5 # The amount of interpolation for the spline when turning - passive-sine-wave-speed: 0.05 # The speed of the passive sine wave - passive-sine-wave-amplitude: 0.5 # The amplitude of the passive sine wave - passive-nose-sine-wave-amplitude: 0.5 # The amplitude of the passive sine wave for the nose - head: # Head must be supplied for a balloon of this kind - meg-model-id: example_meg_model # The id of the meg model - body: # Body must be supplied for a balloon of this kind - meg-model-id: example_meg_model # The id of the meg model - tail: # Tail must be supplied for a balloon of this kind - meg-model-id: example_meg_model # The id of the meg model From 55a53ce0e7f27938cd44aacb6492be53fcd9bd62 Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 09:48:47 -0400 Subject: [PATCH 03/24] Create a basic implementation of MEG --- .../bloons/balloon/single/SingleBalloon.java | 55 ++++++++++++++++--- .../balloon/single/SingleBalloonType.java | 36 +++++++++++- .../configuration/ConfigConfiguration.java | 47 +++++++++++----- .../resources/balloons/dyeable_example.yml | 4 +- 4 files changed, 115 insertions(+), 27 deletions(-) diff --git a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java index aa53cbf3..063a6383 100644 --- a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java +++ b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java @@ -1,5 +1,7 @@ package net.jeqo.bloons.balloon.single; +import com.ticxo.modelengine.api.ModelEngineAPI; +import com.ticxo.modelengine.api.model.ModeledEntity; import lombok.Getter; import lombok.Setter; import net.jeqo.bloons.Bloons; @@ -29,11 +31,14 @@ @Getter @Setter public class SingleBalloon extends BukkitRunnable { + private SingleBalloonType balloonType; private Player player; private ItemStack balloonVisual; private ArmorStand balloonArmorStand; public Chicken balloonChicken; + private ModeledEntity modeledEntity; + private Location playerLocation; private Location moveLocation; @@ -49,9 +54,11 @@ public class SingleBalloon extends BukkitRunnable { */ public SingleBalloon(Player player, String balloonID) { this.setPlayer(player); + this.setBalloonType(Bloons.getBalloonCore().getSingleBalloonByID(balloonID)); - // Configure the balloon visual elements - this.setBalloonVisual(this.getConfiguredBalloonVisual(balloonID)); + if (this.getBalloonType().getMegModelID() == null) { + this.setBalloonVisual(getConfiguredBalloonVisual(balloonID)); + } } /** @@ -88,7 +95,24 @@ public void run() { this.setMoveLocation(this.getMoveLocation().add(vector)); double vectorZ = vector.getZ() * 50.0D * -1.0D; double vectorX = vector.getX() * 50.0D * -1.0D; - this.getBalloonArmorStand().setHeadPose(new EulerAngle(Math.toRadians(vectorZ), Math.toRadians(playerLocation.getYaw()), Math.toRadians(vectorX))); + // Create EulerAngle to tilt parts of the armor body + EulerAngle tiltAngle = new EulerAngle(Math.toRadians(vectorZ), Math.toRadians(playerLocation.getYaw()), Math.toRadians(vectorX)); + + // Set the pose(s) of the armor stand + ArmorStand armorStand = this.getBalloonArmorStand(); + + // Set the pose of only the head regardless of the model type + armorStand.setHeadPose(tiltAngle); + + // Only set the entire pose of the armor stand if it uses MEG, this is to reduce lag across the server + // when having 100's of models/armor stands used simultaneously + if (this.getBalloonType().getMegModelID() != null) { + armorStand.setBodyPose(tiltAngle); + armorStand.setLeftArmPose(tiltAngle); + armorStand.setRightArmPose(tiltAngle); + armorStand.setLeftLegPose(tiltAngle); + armorStand.setRightLegPose(tiltAngle); + } // Teleport the balloon to the move location and set the player location yaw this.teleport(this.getMoveLocation()); @@ -108,6 +132,10 @@ public void run() { * @throws IllegalStateException If the task has already been cancelled */ public synchronized void cancel() throws IllegalStateException { + if (this.getModeledEntity() != null) { + // Remove the MEG model if it exists + this.getModeledEntity().removeModel(this.getBalloonType().getMegModelID()); + } this.getBalloonArmorStand().remove(); this.getBalloonChicken().remove(); super.cancel(); @@ -137,10 +165,12 @@ private void initializeBalloon() { this.setPlayerLocation(this.getPlayer().getLocation()); this.getPlayerLocation().setYaw(0.0F); - // Create and set the balloons visual appearance/model - ItemMeta meta = this.getBalloonVisual().getItemMeta(); - meta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); - this.getBalloonVisual().setItemMeta(meta); + if (this.getBalloonType().getMegModelID() == null) { + // Create and set the balloons visual appearance/model + ItemMeta meta = this.getBalloonVisual().getItemMeta(); + meta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); + this.getBalloonVisual().setItemMeta(meta); + } // Initialize the armor stand and lead to the player this.initializeBalloonArmorStand(); @@ -211,7 +241,16 @@ public void initializeBalloonArmorStand() { this.getBalloonArmorStand().setSmall(false); this.getBalloonArmorStand().setMarker(true); this.getBalloonArmorStand().setCollidable(false); - this.getBalloonArmorStand().getEquipment().setHelmet(this.getBalloonVisual()); + if (this.getBalloonType().getMegModelID() == null) { + this.getBalloonArmorStand().getEquipment().setHelmet(this.getBalloonVisual()); + } else { + try { + this.setModeledEntity(ModelEngineAPI.createModeledEntity(this.getBalloonArmorStand())); + this.getModeledEntity().addModel(ModelEngineAPI.createActiveModel(this.getBalloonType().getMegModelID()), true); + } catch (Exception e) { + Logger.logError("An error occurred while creating the MEG model for the balloon " + this.getBalloonType().getId() + "! This is most likely because the ID of the model doesn't exist in the meg-model-id field."); + } + } this.getBalloonArmorStand().customName(Component.text(BalloonConfiguration.BALLOON_ARMOR_STAND_ID)); } diff --git a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java index 39ea953c..98645bd4 100644 --- a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java +++ b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java @@ -11,14 +11,23 @@ public class SingleBalloonType { private String key; private String id; private String permission; + private String name; + + /** Also called icon.lore for MEG balloons **/ + private String[] lore; + + /** Options for a non-MEG balloon **/ private String material; private String color; private int customModelData; - private String name; - private String[] lore; + + /** MEG only options **/ + private String megModelID; + private String iconMaterial = "#ffffff"; + private int iconCustomModelData; /** - * Creates a new single balloon type configuration + * Creates a new single balloon type configuration for a non-MEG balloon * @param key The key of the balloon type in the configuration, type java.lang.String * @param id The unique identifier for the balloon type, type java.lang.String * @param permission The permission required to use the balloon type, type java.lang.String @@ -38,4 +47,25 @@ public SingleBalloonType(String key, String id, String permission, String materi this.setName(name); this.setLore(lore); } + + /** + * Creates a new single balloon type configuration for a MEG balloon + * @param key The key of the balloon type in the configuration, type java.lang.String + * @param id The unique identifier for the balloon type, type java.lang.String + * @param permission The permission required to use the balloon type, type java.lang.String + * @param material The name of the Bukkit Material used to create the item, type java.lang.String + * @param customModelData The custom model data value stored in the item metadata, type int + * @param name The name of the balloon, type java.lang.String + * @param lore The lore of the balloon, type java.lang.String[] + */ + public SingleBalloonType(String key, String id, String permission, String material, int customModelData, String megModelID, String name, String[] lore) { + this.setKey(key); + this.setId(id); + this.setPermission(permission); + this.setMegModelID(megModelID); + this.setMaterial(material); + this.setCustomModelData(customModelData); + this.setName(name); + this.setLore(lore); + } } diff --git a/src/main/java/net/jeqo/bloons/configuration/ConfigConfiguration.java b/src/main/java/net/jeqo/bloons/configuration/ConfigConfiguration.java index 9377dec8..43f452cf 100644 --- a/src/main/java/net/jeqo/bloons/configuration/ConfigConfiguration.java +++ b/src/main/java/net/jeqo/bloons/configuration/ConfigConfiguration.java @@ -96,20 +96,39 @@ public static ArrayList getSingleBalloons() { if (!type.equals(BalloonConfiguration.SINGLE_BALLOON_TYPE_IDENTIFIER)) continue; - try { - // Add the single balloon type to the array list - singleBalloons.add(new SingleBalloonType( - key, - config.getString(key + ".id"), - config.getString(key + ".permission"), - config.getString(key + ".material"), - config.getString(key + ".color"), - config.getInt(key + ".custom-model-data"), - config.getString(key + ".name"), - config.getStringList(key + ".lore").toArray(new String[0]) - )); - } catch (Exception e) { - Logger.logWarning("Error processing multipart balloon type for section: " + key + " in file: " + fileName + " - " + e.getMessage()); + if (config.getString(key + ".meg-model-id") != null) { + // Process the MEG balloon type + try { + singleBalloons.add(new SingleBalloonType( + key, + config.getString(key + ".id"), + config.getString(key + ".permission"), + config.getString(key + ".icon.material"), + config.getInt(key + ".icon.custom-model-data"), + config.getString(key + ".meg-model-id"), + config.getString(key + ".icon.name"), + config.getStringList(key + ".icon.lore").toArray(new String[0]) + )); + } catch (Exception e) { + Logger.logWarning("Error processing MEG balloon type for section: " + key + " in file: " + fileName + " - " + e.getMessage()); + } + } else { + // Process the non-MEG balloon type + try { + // Add the single balloon type to the array list + singleBalloons.add(new SingleBalloonType( + key, + config.getString(key + ".id"), + config.getString(key + ".permission"), + config.getString(key + ".material"), + config.getString(key + ".color"), + config.getInt(key + ".custom-model-data"), + config.getString(key + ".name"), + config.getStringList(key + ".lore").toArray(new String[0]) + )); + } catch (Exception e) { + Logger.logWarning("Error processing multipart balloon type for section: " + key + " in file: " + fileName + " - " + e.getMessage()); + } } } } diff --git a/src/main/resources/balloons/dyeable_example.yml b/src/main/resources/balloons/dyeable_example.yml index 2061cf23..345f45ca 100644 --- a/src/main/resources/balloons/dyeable_example.yml +++ b/src/main/resources/balloons/dyeable_example.yml @@ -18,8 +18,8 @@ single_meg_example: permission: balloon.single_meg_example meg-model-id: single_meg_example icon: - display-material: FLINT - display-custom-model-data: 7 + material: FLINT + custom-model-data: 7 name: 'Single MEG Balloon' lore: - '&8Bloons Default Balloon' From 199eb363b684d5aea5db5055f2065f02900a0fc5 Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 09:50:20 -0400 Subject: [PATCH 04/24] Remove unused single balloon type vars --- .../net/jeqo/bloons/balloon/single/SingleBalloonType.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java index 98645bd4..f44f8d00 100644 --- a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java +++ b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java @@ -18,13 +18,11 @@ public class SingleBalloonType { /** Options for a non-MEG balloon **/ private String material; - private String color; + private String color = "#ffffff"; private int customModelData; /** MEG only options **/ private String megModelID; - private String iconMaterial = "#ffffff"; - private int iconCustomModelData; /** * Creates a new single balloon type configuration for a non-MEG balloon From 0665d741c7332704313a636cc639c68bd3cc549d Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 09:55:28 -0400 Subject: [PATCH 05/24] Fix log of material not dyeable to only trigger on non-MEG balloons --- .../net/jeqo/bloons/balloon/single/SingleBalloonType.java | 4 +--- .../java/net/jeqo/bloons/commands/manager/CommandCore.java | 4 +++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java index f44f8d00..877e00b8 100644 --- a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java +++ b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java @@ -13,11 +13,9 @@ public class SingleBalloonType { private String permission; private String name; - /** Also called icon.lore for MEG balloons **/ private String[] lore; - - /** Options for a non-MEG balloon **/ private String material; + // Not used by MEG balloons private String color = "#ffffff"; private int customModelData; diff --git a/src/main/java/net/jeqo/bloons/commands/manager/CommandCore.java b/src/main/java/net/jeqo/bloons/commands/manager/CommandCore.java index de28d21f..61473382 100644 --- a/src/main/java/net/jeqo/bloons/commands/manager/CommandCore.java +++ b/src/main/java/net/jeqo/bloons/commands/manager/CommandCore.java @@ -339,7 +339,9 @@ private void setBalloonColor(ItemMeta meta, SingleBalloonType singleBalloonType) if (meta instanceof LeatherArmorMeta) { ((LeatherArmorMeta) meta).setColor(Color.hexToColor(color)); } else { - Logger.logWarning(String.format(Languages.getMessage("material-not-dyeable"), singleBalloonType.getMaterial())); + if (singleBalloonType.getMegModelID() == null) { + Logger.logWarning(String.format(Languages.getMessage("material-not-dyeable"), singleBalloonType.getMaterial())); + } } } } From 4642438516feffe2b6c1889402b701dedbcc487c Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 10:02:44 -0400 Subject: [PATCH 06/24] Fix warning messages of config file already existing --- .../net/jeqo/bloons/balloon/BalloonCore.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java b/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java index 770c6536..b4ee9f11 100644 --- a/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java +++ b/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java @@ -8,6 +8,7 @@ import net.jeqo.bloons.configuration.ConfigConfiguration; import org.bukkit.plugin.java.JavaPlugin; +import java.io.File; import java.util.ArrayList; /** @@ -65,10 +66,20 @@ public void initialize() { * Copies the example balloons folder to the plugin's data folder if it doesn't exist */ public void copyExampleBalloons() { + // List of example balloon files + String[] exampleBalloons = new String[] { + "/color_pack_example.yml", + "/dyeable_example.yml", + "/multipart_example.yml" + }; + // Save all example files in the balloons folder in /resources - Bloons.getInstance().saveResource(ConfigConfiguration.BALLOON_CONFIGURATION_FOLDER + "/color_pack_example.yml", false); - Bloons.getInstance().saveResource(ConfigConfiguration.BALLOON_CONFIGURATION_FOLDER + "/dyeable_example.yml", false); - Bloons.getInstance().saveResource(ConfigConfiguration.BALLOON_CONFIGURATION_FOLDER + "/multipart_example.yml", false); + for (String example : exampleBalloons) { + File file = new File(Bloons.getInstance().getDataFolder() + File.separator + ConfigConfiguration.BALLOON_CONFIGURATION_FOLDER + example); + if (file.exists()) continue; + + Bloons.getInstance().saveResource(ConfigConfiguration.BALLOON_CONFIGURATION_FOLDER + example, false); + } } /** From 8e21026febc7b26a285fe6bc9a60804959e3c922 Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 10:52:45 -0400 Subject: [PATCH 07/24] Implement idle animations --- .../bloons/balloon/single/SingleBalloon.java | 36 ++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java index 063a6383..91d4a4d8 100644 --- a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java +++ b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java @@ -1,6 +1,8 @@ package net.jeqo.bloons.balloon.single; import com.ticxo.modelengine.api.ModelEngineAPI; +import com.ticxo.modelengine.api.animation.handler.AnimationHandler; +import com.ticxo.modelengine.api.model.ActiveModel; import com.ticxo.modelengine.api.model.ModeledEntity; import lombok.Getter; import lombok.Setter; @@ -37,7 +39,11 @@ public class SingleBalloon extends BukkitRunnable { private ArmorStand balloonArmorStand; public Chicken balloonChicken; + /** MEG related variables **/ private ModeledEntity modeledEntity; + private ActiveModel activeModel; + private AnimationHandler animationHandler; + private final String defaultIdleAnimationID = "idle"; private Location playerLocation; private Location moveLocation; @@ -122,6 +128,15 @@ public void run() { this.teleport(playerLocation); } + // If all parts of a MEG balloon exist and the idle animation exists and it isn't playing, play it + if (this.getAnimationHandler() != null) { + if (this.getAnimationHandler().getAnimation(this.getDefaultIdleAnimationID()) != null) { + if (!this.getAnimationHandler().isPlayingAnimation(this.getDefaultIdleAnimationID())) { + this.getAnimationHandler().playAnimation(this.getDefaultIdleAnimationID(), 0.3, 0.3, 1,true); + } + } + } + this.setPlayerLocation(this.getPlayer().getLocation()); this.getPlayerLocation().setYaw(playerLocation.getYaw()); this.setTicks(this.getTicks() + 1); @@ -134,7 +149,8 @@ public void run() { public synchronized void cancel() throws IllegalStateException { if (this.getModeledEntity() != null) { // Remove the MEG model if it exists - this.getModeledEntity().removeModel(this.getBalloonType().getMegModelID()); + ModeledEntity modeledEntity = ModelEngineAPI.getModeledEntity(this.getBalloonArmorStand()); + modeledEntity.removeModel(this.getBalloonType().getMegModelID()); } this.getBalloonArmorStand().remove(); this.getBalloonChicken().remove(); @@ -234,7 +250,7 @@ public ItemStack getConfiguredBalloonVisual(String balloonID) { public void initializeBalloonArmorStand() { this.setBalloonArmorStand(this.getPlayerLocation().getWorld().spawn(this.getPlayerLocation(), ArmorStand.class)); this.getBalloonArmorStand().setBasePlate(false); - this.getBalloonArmorStand().setVisible(false); + this.getBalloonArmorStand().setVisible(true); this.getBalloonArmorStand().setInvulnerable(true); this.getBalloonArmorStand().setCanPickupItems(false); this.getBalloonArmorStand().setGravity(false); @@ -245,10 +261,20 @@ public void initializeBalloonArmorStand() { this.getBalloonArmorStand().getEquipment().setHelmet(this.getBalloonVisual()); } else { try { - this.setModeledEntity(ModelEngineAPI.createModeledEntity(this.getBalloonArmorStand())); - this.getModeledEntity().addModel(ModelEngineAPI.createActiveModel(this.getBalloonType().getMegModelID()), true); + // Create the entity and tag it onto the armor stand + ModeledEntity modeledEntity = ModelEngineAPI.createModeledEntity(this.getBalloonArmorStand()); + ActiveModel activeModel = ModelEngineAPI.createActiveModel(this.getBalloonType().getMegModelID()); + + modeledEntity.addModel(activeModel, true); + + // Set the animation handler to the one of the active model + this.setAnimationHandler(activeModel.getAnimationHandler()); + + // If an idle animation exists, play it initially + this.getAnimationHandler().playAnimation(this.getDefaultIdleAnimationID(), 0.3, 0.3, 1,true); } catch (Exception e) { - Logger.logError("An error occurred while creating the MEG model for the balloon " + this.getBalloonType().getId() + "! This is most likely because the ID of the model doesn't exist in the meg-model-id field."); + Logger.logError("An error occurred while creating the MEG model for the balloon " + this.getBalloonType().getId() + "! This is because a MEG model error occurred."); + e.printStackTrace(); } } this.getBalloonArmorStand().customName(Component.text(BalloonConfiguration.BALLOON_ARMOR_STAND_ID)); From 1d8fde3e2233ced941ab13e4f7a5e191805b8a03 Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 11:34:33 -0400 Subject: [PATCH 08/24] Remove armor stand debug visibility --- src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java index 91d4a4d8..4ea39abd 100644 --- a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java +++ b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java @@ -250,7 +250,7 @@ public ItemStack getConfiguredBalloonVisual(String balloonID) { public void initializeBalloonArmorStand() { this.setBalloonArmorStand(this.getPlayerLocation().getWorld().spawn(this.getPlayerLocation(), ArmorStand.class)); this.getBalloonArmorStand().setBasePlate(false); - this.getBalloonArmorStand().setVisible(true); + this.getBalloonArmorStand().setVisible(false); this.getBalloonArmorStand().setInvulnerable(true); this.getBalloonArmorStand().setCanPickupItems(false); this.getBalloonArmorStand().setGravity(false); From 039f730e8a4c3eede12d5644354a553fc1f29297 Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 11:45:38 -0400 Subject: [PATCH 09/24] Mess around with MEG dummies --- .../java/net/jeqo/bloons/balloon/single/SingleBalloon.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java index 4ea39abd..efcc1e22 100644 --- a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java +++ b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java @@ -2,6 +2,7 @@ import com.ticxo.modelengine.api.ModelEngineAPI; import com.ticxo.modelengine.api.animation.handler.AnimationHandler; +import com.ticxo.modelengine.api.entity.Dummy; import com.ticxo.modelengine.api.model.ActiveModel; import com.ticxo.modelengine.api.model.ModeledEntity; import lombok.Getter; @@ -262,7 +263,10 @@ public void initializeBalloonArmorStand() { } else { try { // Create the entity and tag it onto the armor stand - ModeledEntity modeledEntity = ModelEngineAPI.createModeledEntity(this.getBalloonArmorStand()); + Dummy dummy = new Dummy<>(); + + dummy.setDetectingPlayers(false); + ModeledEntity modeledEntity = ModelEngineAPI.createModeledEntity(dummy); ActiveModel activeModel = ModelEngineAPI.createActiveModel(this.getBalloonType().getMegModelID()); modeledEntity.addModel(activeModel, true); From bc0775c4884449266d54e9077760e03e96894037 Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 11:47:10 -0400 Subject: [PATCH 10/24] Revert changes of using dummies --- .../java/net/jeqo/bloons/balloon/single/SingleBalloon.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java index efcc1e22..4ea39abd 100644 --- a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java +++ b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java @@ -2,7 +2,6 @@ import com.ticxo.modelengine.api.ModelEngineAPI; import com.ticxo.modelengine.api.animation.handler.AnimationHandler; -import com.ticxo.modelengine.api.entity.Dummy; import com.ticxo.modelengine.api.model.ActiveModel; import com.ticxo.modelengine.api.model.ModeledEntity; import lombok.Getter; @@ -263,10 +262,7 @@ public void initializeBalloonArmorStand() { } else { try { // Create the entity and tag it onto the armor stand - Dummy dummy = new Dummy<>(); - - dummy.setDetectingPlayers(false); - ModeledEntity modeledEntity = ModelEngineAPI.createModeledEntity(dummy); + ModeledEntity modeledEntity = ModelEngineAPI.createModeledEntity(this.getBalloonArmorStand()); ActiveModel activeModel = ModelEngineAPI.createActiveModel(this.getBalloonType().getMegModelID()); modeledEntity.addModel(activeModel, true); From 63e9dcc737257e61a0c4c5f64cfbc4a32ca3bd4e Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 12:35:32 -0400 Subject: [PATCH 11/24] Created the configurations and the fetching of them --- .../bloons/balloon/single/SingleBalloon.java | 6 ++-- .../balloon/single/SingleBalloonType.java | 34 +++++++++++++++++++ .../configuration/ConfigConfiguration.java | 2 ++ .../resources/balloons/dyeable_example.yml | 2 ++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java index 4ea39abd..a3cc8228 100644 --- a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java +++ b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java @@ -93,7 +93,7 @@ public void run() { } // Set the move location to the armor stand location minus 2 on the Y axis - this.setMoveLocation(this.getBalloonArmorStand().getLocation().subtract(0.0D, 2.0D, 0.0D).clone()); + this.setMoveLocation(this.getBalloonArmorStand().getLocation().subtract(0.0D, this.getBalloonType().getBalloonHeight(), 0.0D).clone()); // Set the vector to the player location minus the move location Vector vector = playerLocation.toVector().subtract(this.getMoveLocation().toVector()); @@ -169,8 +169,8 @@ public void spawnRemoveParticle() { * @param location The location to teleport the balloon to, type org.bukkit.Location */ private void teleport(Location location) { - this.getBalloonArmorStand().teleport(location.add(0.0D, 2.0D, 0.0D)); - this.getBalloonChicken().teleport(location.add(0.0D, 1.2D, 0.0D)); + this.getBalloonArmorStand().teleport(location.add(0.0D, this.getBalloonType().getBalloonHeight(), 0.0D)); + this.getBalloonChicken().teleport(location.add(0.0D, this.getBalloonType().getLeashHeight(), 0.0D)); } /** diff --git a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java index 877e00b8..2f110bfb 100644 --- a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java +++ b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java @@ -19,6 +19,9 @@ public class SingleBalloonType { private String color = "#ffffff"; private int customModelData; + private double leashHeight = 1.2D; + private double balloonHeight = 1.5D; + /** MEG only options **/ private String megModelID; @@ -44,6 +47,37 @@ public SingleBalloonType(String key, String id, String permission, String materi this.setLore(lore); } + /** + * Creates a new single balloon type configuration for a non-MEG balloon + * @param key The key of the balloon type in the configuration, type java.lang.String + * @param id The unique identifier for the balloon type, type java.lang.String + * @param permission The permission required to use the balloon type, type java.lang.String + * @param leashHeight The height of the leash when the balloon is attached to a player, type double + * @param balloonHeight The height of the balloon when attached to a player, type double + * @param material The name of the Bukkit Material used to create the item, type java.lang.String + * @param color The color of the model as a hex color code value, type java.lang.String + * @param customModelData The custom model data value stored in the item metadata, type int + * @param name The name of the balloon, type java.lang.String + * @param lore The lore of the balloon, type java.lang.String[] + */ + public SingleBalloonType(String key, String id, String permission, double leashHeight, double balloonHeight, String material, String color, int customModelData, String name, String[] lore) { + this.setKey(key); + this.setId(id); + this.setPermission(permission); + if (leashHeight > 0.0D) { + this.setLeashHeight(leashHeight); + } + + if (balloonHeight > 0.0D) { + this.setBalloonHeight(balloonHeight); + } + this.setMaterial(material); + this.setColor(color); + this.setCustomModelData(customModelData); + this.setName(name); + this.setLore(lore); + } + /** * Creates a new single balloon type configuration for a MEG balloon * @param key The key of the balloon type in the configuration, type java.lang.String diff --git a/src/main/java/net/jeqo/bloons/configuration/ConfigConfiguration.java b/src/main/java/net/jeqo/bloons/configuration/ConfigConfiguration.java index 43f452cf..a103b95e 100644 --- a/src/main/java/net/jeqo/bloons/configuration/ConfigConfiguration.java +++ b/src/main/java/net/jeqo/bloons/configuration/ConfigConfiguration.java @@ -120,6 +120,8 @@ public static ArrayList getSingleBalloons() { key, config.getString(key + ".id"), config.getString(key + ".permission"), + config.getDouble(key + ".leash-height"), + config.getDouble(key + ".balloon-height"), config.getString(key + ".material"), config.getString(key + ".color"), config.getInt(key + ".custom-model-data"), diff --git a/src/main/resources/balloons/dyeable_example.yml b/src/main/resources/balloons/dyeable_example.yml index 345f45ca..85be6dba 100644 --- a/src/main/resources/balloons/dyeable_example.yml +++ b/src/main/resources/balloons/dyeable_example.yml @@ -5,6 +5,8 @@ dyeable_example: type: single id: dyeable_example permission: balloon.dyeable + leash-height: 1.2 # The height of the balloon leash from about the players head + balloon-height: 2.0 # The height of the balloon from about the players head material: LEATHER_HORSE_ARMOR color: '#ffffff' custom-model-data: 1 From 5e6b75b2d2f90a36498a0f2e008497d3092a2807 Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 12:37:33 -0400 Subject: [PATCH 12/24] Set default balloon height to be 2.0 --- .../java/net/jeqo/bloons/balloon/single/SingleBalloonType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java index 2f110bfb..c0899fea 100644 --- a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java +++ b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java @@ -20,7 +20,7 @@ public class SingleBalloonType { private int customModelData; private double leashHeight = 1.2D; - private double balloonHeight = 1.5D; + private double balloonHeight = 2.0D; /** MEG only options **/ private String megModelID; From 70be6f4f990983ee633760f8f0efc989916272e0 Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 12:46:43 -0400 Subject: [PATCH 13/24] Fully comment the single balloon type class --- .../balloon/single/SingleBalloonType.java | 52 +++++++++++++++---- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java index c0899fea..2abd315f 100644 --- a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java +++ b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java @@ -8,21 +8,55 @@ */ @Getter @Setter public class SingleBalloonType { + /** + * The key we are retrieving values from + */ private String key; + /** + * The unique identifier for the balloon type + */ private String id; + /** + * The permission required to use the balloon + */ private String permission; - private String name; - - private String[] lore; + /** + * The height of the leash attached to a player relative from the head of the player in blocks + * Default is 1.2 blocks + */ + private double leashHeight = 1.2D; + /** + * The height of the balloon when attached to a player relative from the head of the player in blocks + * Default is 2.0 blocks + */ + private double balloonHeight = 2.0D; + /** + * The name of the material that makes up the balloons model + */ private String material; - // Not used by MEG balloons + /* + * The color of the model as a hex color code value if the balloon is not a MEG balloon and if + * the material above is dyeable + * Default is #ffffff (white) + */ private String color = "#ffffff"; + /** + * The value of the custom model data stored in the item metadata for the model + */ private int customModelData; + /** + * The name of the balloon that is displayed both in chat and in the Bloons menu + */ + private String name; + /** + * The lore of the item that is displayed in the GUI + */ + private String[] lore; - private double leashHeight = 1.2D; - private double balloonHeight = 2.0D; - - /** MEG only options **/ + /** + * The ID of the MEG (ModelEngine) model you wish to use as the balloon model + * This is only used if the balloon is a MEG balloon + */ private String megModelID; /** @@ -67,7 +101,6 @@ public SingleBalloonType(String key, String id, String permission, double leashH if (leashHeight > 0.0D) { this.setLeashHeight(leashHeight); } - if (balloonHeight > 0.0D) { this.setBalloonHeight(balloonHeight); } @@ -85,6 +118,7 @@ public SingleBalloonType(String key, String id, String permission, double leashH * @param permission The permission required to use the balloon type, type java.lang.String * @param material The name of the Bukkit Material used to create the item, type java.lang.String * @param customModelData The custom model data value stored in the item metadata, type int + * @param megModelID The ID of the MEG model to use as the balloon model, type java.lang.String * @param name The name of the balloon, type java.lang.String * @param lore The lore of the balloon, type java.lang.String[] */ From e6e377db6020f1e4fa60d13f5bcd45a8fd4c154c Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 12:48:36 -0400 Subject: [PATCH 14/24] Rearranged the methods in SingleBalloon --- .../bloons/balloon/single/SingleBalloon.java | 144 +++++++++--------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java index a3cc8228..6d58d7e2 100644 --- a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java +++ b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java @@ -67,6 +67,78 @@ public SingleBalloon(Player player, String balloonID) { } } + /** + * Initializes the balloon and its subcomponents. + * Sets the current players location, and initializes the armor stand, and chicken entities + */ + private void initializeBalloon() { + this.setPlayerLocation(this.getPlayer().getLocation()); + this.getPlayerLocation().setYaw(0.0F); + + if (this.getBalloonType().getMegModelID() == null) { + // Create and set the balloons visual appearance/model + ItemMeta meta = this.getBalloonVisual().getItemMeta(); + meta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); + this.getBalloonVisual().setItemMeta(meta); + } + + // Initialize the armor stand and lead to the player + this.initializeBalloonArmorStand(); + this.initializeBalloonLead(); + } + + /** + * Initializes the balloon's armor stand entity with the proper configurations + */ + public void initializeBalloonArmorStand() { + this.setBalloonArmorStand(this.getPlayerLocation().getWorld().spawn(this.getPlayerLocation(), ArmorStand.class)); + this.getBalloonArmorStand().setBasePlate(false); + this.getBalloonArmorStand().setVisible(false); + this.getBalloonArmorStand().setInvulnerable(true); + this.getBalloonArmorStand().setCanPickupItems(false); + this.getBalloonArmorStand().setGravity(false); + this.getBalloonArmorStand().setSmall(false); + this.getBalloonArmorStand().setMarker(true); + this.getBalloonArmorStand().setCollidable(false); + if (this.getBalloonType().getMegModelID() == null) { + this.getBalloonArmorStand().getEquipment().setHelmet(this.getBalloonVisual()); + } else { + try { + // Create the entity and tag it onto the armor stand + ModeledEntity modeledEntity = ModelEngineAPI.createModeledEntity(this.getBalloonArmorStand()); + ActiveModel activeModel = ModelEngineAPI.createActiveModel(this.getBalloonType().getMegModelID()); + + modeledEntity.addModel(activeModel, true); + + // Set the animation handler to the one of the active model + this.setAnimationHandler(activeModel.getAnimationHandler()); + + // If an idle animation exists, play it initially + this.getAnimationHandler().playAnimation(this.getDefaultIdleAnimationID(), 0.3, 0.3, 1,true); + } catch (Exception e) { + Logger.logError("An error occurred while creating the MEG model for the balloon " + this.getBalloonType().getId() + "! This is because a MEG model error occurred."); + e.printStackTrace(); + } + } + this.getBalloonArmorStand().customName(Component.text(BalloonConfiguration.BALLOON_ARMOR_STAND_ID)); + } + + /** + * Initializes the balloon's lead to the player (chicken entity) + */ + public void initializeBalloonLead() { + this.setBalloonChicken(this.getPlayerLocation().getWorld().spawn(this.getPlayerLocation(), Chicken.class)); + this.getBalloonChicken().setInvulnerable(true); + this.getBalloonChicken().setInvisible(true); + this.getBalloonChicken().setSilent(true); + this.getBalloonChicken().setBaby(); + this.getBalloonChicken().setAgeLock(true); + this.getBalloonChicken().setAware(false); + this.getBalloonChicken().setCollidable(false); + this.getBalloonChicken().setLeashHolder(this.getPlayer()); + this.getBalloonChicken().customName(Component.text(BalloonConfiguration.BALLOON_CHICKEN_ID)); + } + /** * What runs inside the extended bukkit runnable, it's * the control center of the core functionality of how the balloon moves @@ -173,26 +245,6 @@ private void teleport(Location location) { this.getBalloonChicken().teleport(location.add(0.0D, this.getBalloonType().getLeashHeight(), 0.0D)); } - /** - * Initializes the balloon and its subcomponents. - * Sets the current players location, and initializes the armor stand, and chicken entities - */ - private void initializeBalloon() { - this.setPlayerLocation(this.getPlayer().getLocation()); - this.getPlayerLocation().setYaw(0.0F); - - if (this.getBalloonType().getMegModelID() == null) { - // Create and set the balloons visual appearance/model - ItemMeta meta = this.getBalloonVisual().getItemMeta(); - meta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); - this.getBalloonVisual().setItemMeta(meta); - } - - // Initialize the armor stand and lead to the player - this.initializeBalloonArmorStand(); - this.initializeBalloonLead(); - } - /** * Retrieves the item stack object of the visual appearance of the balloon * @param balloonID The balloon ID to get the visual appearance of, type java.lang.String @@ -244,58 +296,6 @@ public ItemStack getConfiguredBalloonVisual(String balloonID) { return item; } - /** - * Initializes the balloon's armor stand entity with the proper configurations - */ - public void initializeBalloonArmorStand() { - this.setBalloonArmorStand(this.getPlayerLocation().getWorld().spawn(this.getPlayerLocation(), ArmorStand.class)); - this.getBalloonArmorStand().setBasePlate(false); - this.getBalloonArmorStand().setVisible(false); - this.getBalloonArmorStand().setInvulnerable(true); - this.getBalloonArmorStand().setCanPickupItems(false); - this.getBalloonArmorStand().setGravity(false); - this.getBalloonArmorStand().setSmall(false); - this.getBalloonArmorStand().setMarker(true); - this.getBalloonArmorStand().setCollidable(false); - if (this.getBalloonType().getMegModelID() == null) { - this.getBalloonArmorStand().getEquipment().setHelmet(this.getBalloonVisual()); - } else { - try { - // Create the entity and tag it onto the armor stand - ModeledEntity modeledEntity = ModelEngineAPI.createModeledEntity(this.getBalloonArmorStand()); - ActiveModel activeModel = ModelEngineAPI.createActiveModel(this.getBalloonType().getMegModelID()); - - modeledEntity.addModel(activeModel, true); - - // Set the animation handler to the one of the active model - this.setAnimationHandler(activeModel.getAnimationHandler()); - - // If an idle animation exists, play it initially - this.getAnimationHandler().playAnimation(this.getDefaultIdleAnimationID(), 0.3, 0.3, 1,true); - } catch (Exception e) { - Logger.logError("An error occurred while creating the MEG model for the balloon " + this.getBalloonType().getId() + "! This is because a MEG model error occurred."); - e.printStackTrace(); - } - } - this.getBalloonArmorStand().customName(Component.text(BalloonConfiguration.BALLOON_ARMOR_STAND_ID)); - } - - /** - * Initializes the balloon's lead to the player (chicken entity) - */ - public void initializeBalloonLead() { - this.setBalloonChicken(this.getPlayerLocation().getWorld().spawn(this.getPlayerLocation(), Chicken.class)); - this.getBalloonChicken().setInvulnerable(true); - this.getBalloonChicken().setInvisible(true); - this.getBalloonChicken().setSilent(true); - this.getBalloonChicken().setBaby(); - this.getBalloonChicken().setAgeLock(true); - this.getBalloonChicken().setAware(false); - this.getBalloonChicken().setCollidable(false); - this.getBalloonChicken().setLeashHolder(this.getPlayer()); - this.getBalloonChicken().customName(Component.text(BalloonConfiguration.BALLOON_CHICKEN_ID)); - } - /** * Checks if a balloon needs to be removed or added * @param player The player to check, type org.bukkit.entity.Player From 62f926e3c1a45cfbc39ae51eb58ea99d2921e01e Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 12:51:05 -0400 Subject: [PATCH 15/24] Move example balloons out of the method for copying example balloons --- .../net/jeqo/bloons/balloon/BalloonCore.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java b/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java index b4ee9f11..0b504917 100644 --- a/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java +++ b/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java @@ -25,6 +25,14 @@ public class BalloonCore { * Contains all valid and loaded single balloon types/configurations */ public ArrayList singleBalloonTypes = new ArrayList<>(); + /** + * Contains all example balloon files to copy to the plugin's data folder + */ + private final String[] exampleBalloons = new String[] { + "color_pack_example.yml", + "dyeable_example.yml", + "multipart_example.yml" + }; /** * Creates a new instance of the balloon core manager with preset registered balloons @@ -66,16 +74,9 @@ public void initialize() { * Copies the example balloons folder to the plugin's data folder if it doesn't exist */ public void copyExampleBalloons() { - // List of example balloon files - String[] exampleBalloons = new String[] { - "/color_pack_example.yml", - "/dyeable_example.yml", - "/multipart_example.yml" - }; - // Save all example files in the balloons folder in /resources - for (String example : exampleBalloons) { - File file = new File(Bloons.getInstance().getDataFolder() + File.separator + ConfigConfiguration.BALLOON_CONFIGURATION_FOLDER + example); + for (String example : this.getExampleBalloons()) { + File file = new File(Bloons.getInstance().getDataFolder() + File.separator + ConfigConfiguration.BALLOON_CONFIGURATION_FOLDER + File.separator + example); if (file.exists()) continue; Bloons.getInstance().saveResource(ConfigConfiguration.BALLOON_CONFIGURATION_FOLDER + example, false); From 25356c4e376f047cab4028ffccdc140540088c16 Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 13:06:28 -0400 Subject: [PATCH 16/24] Clean up basic code structure of the balloon directory --- .../net/jeqo/bloons/balloon/BalloonCore.java | 50 ++------------- ...ModelType.java => BalloonSegmentType.java} | 2 +- .../multipart/MultipartBalloonModel.java | 19 +++++- .../multipart/MultipartBalloonType.java | 61 +++++++++++++++++++ .../balloon/multipart/nodes/ModelNode.java | 20 +++++- .../multipart/nodes/ModelNodeVector.java | 10 --- .../bloons/balloon/single/SingleBalloon.java | 13 +++- .../balloon/single/SingleBalloonType.java | 30 +-------- .../configuration/ConfigConfiguration.java | 8 +-- 9 files changed, 116 insertions(+), 97 deletions(-) rename src/main/java/net/jeqo/bloons/balloon/model/{BalloonModelType.java => BalloonSegmentType.java} (92%) diff --git a/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java b/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java index 0b504917..5bd640fe 100644 --- a/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java +++ b/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java @@ -34,18 +34,6 @@ public class BalloonCore { "multipart_example.yml" }; - /** - * Creates a new instance of the balloon core manager with preset registered balloons - * @param plugin The plugin instance, type org.bukkit.plugin.java.JavaPlugin - * @param balloons The balloons to register, type java.util.ArrayList[net.jeqo.bloons.balloon.multipart.MultipartBalloonType] - * @param singleBalloons The single balloons to register, type java.util.ArrayList[net.jeqo.bloons.balloon.single.SingleBalloonType] - */ - public BalloonCore(JavaPlugin plugin, ArrayList balloons, ArrayList singleBalloons) { - this.setPlugin(plugin); - this.setMultipartBalloonTypes(balloons); - this.setSingleBalloonTypes(singleBalloons); - } - /** * Creates a new empty balloon core instance * @param plugin The plugin instance, type org.bukkit.plugin.java.JavaPlugin @@ -83,42 +71,11 @@ public void copyExampleBalloons() { } } - /** - * Adds a balloon to the registered balloons list - * @param balloon The balloon to add, type net.jeqo.bloons.balloon.multipart.MultipartBalloonType - */ - public void addMultipartBalloon(MultipartBalloonType balloon) { - this.getMultipartBalloonTypes().add(balloon); - } - - /** - * Removes a balloon from the registered balloons list - * @param balloon The balloon to remove, type net.jeqo.bloons.balloon.multipart.MultipartBalloonType - */ - public void removeMultipartBalloon(MultipartBalloonType balloon) { - this.getMultipartBalloonTypes().remove(balloon); - } - - /** - * Adds a single balloon to the registered balloons list - * @param balloon The single balloon to add, type net.jeqo.bloons.balloon.single.SingleBalloonType - */ - public void addSingleBalloon(SingleBalloonType balloon) { - this.getSingleBalloonTypes().add(balloon); - } - - /** - * Removes a single balloon from the registered balloons list - * @param balloon The single balloon to remove, type net.jeqo.bloons.balloon.single.SingleBalloonType - */ - public void removeSingleBalloon(SingleBalloonType balloon) { - this.getSingleBalloonTypes().remove(balloon); - } - /** * Retrieves a balloon by its ID from the registered balloons list * @param ID The ID of the balloon, type java.lang.String - * @return The balloon with the specified name, type net.jeqo.bloons.balloon.multipart.MultipartBalloonType/null + * @return The balloon with the specified name, type net.jeqo.bloons.balloon.multipart.MultipartBalloonType + * Returns null if no balloon is found by the specified ID */ public MultipartBalloonType getMultipartBalloonByID(String ID) { // Loop over every balloon in the registered balloons list @@ -136,7 +93,8 @@ public MultipartBalloonType getMultipartBalloonByID(String ID) { /** * Retrieves a single balloon by its ID from the registered balloons list * @param ID The ID of the balloon, type java.lang.String - * @return The single balloon with the specified ID, type net.jeqo.bloons.balloon.single.SingleBalloonType/null + * @return The single balloon with the specified ID, type net.jeqo.bloons.balloon.single.SingleBalloonType + * Returns null if no balloon is found by the specified ID */ public SingleBalloonType getSingleBalloonByID(String ID) { // Loop over every single balloon in the registered balloons list diff --git a/src/main/java/net/jeqo/bloons/balloon/model/BalloonModelType.java b/src/main/java/net/jeqo/bloons/balloon/model/BalloonSegmentType.java similarity index 92% rename from src/main/java/net/jeqo/bloons/balloon/model/BalloonModelType.java rename to src/main/java/net/jeqo/bloons/balloon/model/BalloonSegmentType.java index 25dd9ba7..05ecd3dc 100644 --- a/src/main/java/net/jeqo/bloons/balloon/model/BalloonModelType.java +++ b/src/main/java/net/jeqo/bloons/balloon/model/BalloonSegmentType.java @@ -3,7 +3,7 @@ /** * The type of segment that the model accommodates */ -public enum BalloonModelType { +public enum BalloonSegmentType { /** * This is the head of the balloon, indexed as the last index in the multipart balloon */ diff --git a/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java b/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java index cd663aef..23a0804b 100644 --- a/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java +++ b/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java @@ -3,7 +3,7 @@ import lombok.Getter; import lombok.Setter; import net.jeqo.bloons.balloon.model.BalloonModel; -import net.jeqo.bloons.balloon.model.BalloonModelType; +import net.jeqo.bloons.balloon.model.BalloonSegmentType; import net.jeqo.bloons.logger.Logger; import net.jeqo.bloons.colors.Color; import net.jeqo.bloons.message.Languages; @@ -15,9 +15,22 @@ */ @Getter @Setter public class MultipartBalloonModel { - private BalloonModelType modelType; + /** + * The type of segment that the model accommodates + * This can either be the head, body, or tail of the balloon + */ + private BalloonSegmentType modelType; + /** + * The material used to create the model + */ private String material; + /** + * The color of the model + */ private String color; + /** + * The custom model data value stored in the item metadata + */ private Integer customModelData; /** @@ -27,7 +40,7 @@ public class MultipartBalloonModel { * @param color The color of the model as a hex color code value, type java.lang.String * @param customModelData The custom model data value stored in the item metadata, type int */ - public MultipartBalloonModel(BalloonModelType modelType, String material, String color, int customModelData) { + public MultipartBalloonModel(BalloonSegmentType modelType, String material, String color, int customModelData) { this.setModelType(modelType); this.setMaterial(material); this.setColor(color); diff --git a/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonType.java b/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonType.java index 19af1205..776e0ed2 100644 --- a/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonType.java +++ b/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonType.java @@ -8,24 +8,85 @@ */ @Getter @Setter public class MultipartBalloonType { + /** + * The unique identifier for the balloon type + */ private String id; + /** + * The permission required to use the balloon + */ private String permission; + /** + * The name of the balloon that is displayed both in chat and in the Bloons menu + */ private String name; + /** + * The lore of the item that is displayed in the GUI + */ private String[] lore; + /** + * The number of nodes, or models, in the balloon + */ private int nodeCount; + /** + * The distance between each node in the balloon measured in blocks + */ private double distanceBetweenNodes; + /** + * The height of the leash attached to a player relative from the head of the player in blocks + */ private double leashHeight; + /** + * The offset of the head node from its 0 position measured in blocks + */ private double headNodeOffset = 0.0; + /** + * The offset of the body node from its 0 position measured in blocks + */ private double bodyNodeOffset = 0.0; + /** + * The offset of the tail node from its 0 position measured in blocks + */ private double tailNodeOffset = 0.0; + /** + * The max angle that a segment/node can rotate to in degrees in both directions + * This number *2 is equal to the total range of motion for each segment + */ private double maxNodeJointAngle = 35.0; + /** + * The interpolation of the Y-axis motion of every segment + */ private double yAxisInterpolation = 0.35; + /** + * The interpolation of the turning spline to prevent overturning and + * to enhance smoother turning + */ private double turningSplineInterpolation = 0.35; + /** + * The speed of the passive sine wave animation. This is the amount of blocks it + * will move every tick due to the runnable running every tick. + */ private double passiveSineWaveSpeed = 0.05; + /** + * The amplitude of the passive sine wave animation. This is the maximum amount of + * blocks the balloon will move in the positive and negative direction. + */ private double passiveSineWaveAmplitude = 0.5; + /** + * The amplitude of the passive sine wave animation starting at the nose + */ private double passiveNoseSineWaveAmplitude = 0.5; + /** + * The model used for the head node + */ private MultipartBalloonModel headModel; + /** + * The model used for the body node + */ private MultipartBalloonModel bodyModel; + /** + * The model used for the tail node + */ private MultipartBalloonModel tailModel; /** diff --git a/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/ModelNode.java b/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/ModelNode.java index 17c204dc..6d3e45d5 100644 --- a/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/ModelNode.java +++ b/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/ModelNode.java @@ -18,16 +18,32 @@ */ @Getter @Setter public class ModelNode { + /** + * The front most point of the segment/node + */ public ModelNodeVector pointA; + /** + * The back most point of the segment/node + */ public ModelNodeVector pointB = new ModelNodeVector(); + /** + * The parent node of the current node + */ public ModelNode parent = null; + /** + * The child node of the current node + */ public ModelNode child = null; + /** + * The armor stand that represents the node + */ ArmorStand balloonArmorStand; - float index; - float length; + + private float index; + private float length; private MultipartBalloonType balloonType; private Player balloonOwner; double maxNodeJointAngle; diff --git a/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/ModelNodeVector.java b/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/ModelNodeVector.java index 36b5a583..c4ef63fb 100644 --- a/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/ModelNodeVector.java +++ b/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/ModelNodeVector.java @@ -31,16 +31,6 @@ public ModelNodeVector(float x, float y, float z) { this.z = z; } - /** - * Creates a segment vector holding a 2D space. - * @param x X axis. - * @param z Z axis. - */ - public ModelNodeVector(float x, float z) { - this.x = x; - this.z = z; - } - /** * Sets a 3D's vectors axis. * @param x X axis float. diff --git a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java index 6d58d7e2..4b415149 100644 --- a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java +++ b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java @@ -33,25 +33,32 @@ @Getter @Setter public class SingleBalloon extends BukkitRunnable { + /** Must have variables related to any balloon **/ private SingleBalloonType balloonType; private Player player; - private ItemStack balloonVisual; private ArmorStand balloonArmorStand; public Chicken balloonChicken; + /** + * Only used for non-MEG balloons to configure the visual appearance of the balloon + */ + private ItemStack balloonVisual; + /** MEG related variables **/ private ModeledEntity modeledEntity; private ActiveModel activeModel; private AnimationHandler animationHandler; private final String defaultIdleAnimationID = "idle"; + /** Variables used for the movement of the balloon **/ private Location playerLocation; private Location moveLocation; private int ticks = 0; private float targetYaw = 0.0F; - private static final String leatherMaterialPrefix = "LEATHER_"; // A constant to define a dyeable material + // A prefix that is needed for dyable materials + private static final String LEATHER_MATERIAL_PREFIX = "LEATHER_"; /** * Constructor for the SingleBalloon class @@ -279,7 +286,7 @@ public ItemStack getConfiguredBalloonVisual(String balloonID) { meta.setCustomModelData(singleBalloonType.getCustomModelData()); // If the color of the balloon is not set, log an error and return null - if (singleBalloonType.getColor() != null && singleBalloonType.getMaterial().startsWith(leatherMaterialPrefix)) { + if (singleBalloonType.getColor() != null && singleBalloonType.getMaterial().startsWith(LEATHER_MATERIAL_PREFIX)) { // If the color of the balloon is set to potion, log a warning and return null if (singleBalloonType.getColor().equalsIgnoreCase("potion")) { Logger.logWarning(String.format(Languages.getMessage("material-not-dyeable"), material)); diff --git a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java index 2abd315f..4dd0acbd 100644 --- a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java +++ b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloonType.java @@ -59,28 +59,6 @@ public class SingleBalloonType { */ private String megModelID; - /** - * Creates a new single balloon type configuration for a non-MEG balloon - * @param key The key of the balloon type in the configuration, type java.lang.String - * @param id The unique identifier for the balloon type, type java.lang.String - * @param permission The permission required to use the balloon type, type java.lang.String - * @param material The name of the Bukkit Material used to create the item, type java.lang.String - * @param color The color of the model as a hex color code value, type java.lang.String - * @param customModelData The custom model data value stored in the item metadata, type int - * @param name The name of the balloon, type java.lang.String - * @param lore The lore of the balloon, type java.lang.String[] - */ - public SingleBalloonType(String key, String id, String permission, String material, String color, int customModelData, String name, String[] lore) { - this.setKey(key); - this.setId(id); - this.setPermission(permission); - this.setMaterial(material); - this.setColor(color); - this.setCustomModelData(customModelData); - this.setName(name); - this.setLore(lore); - } - /** * Creates a new single balloon type configuration for a non-MEG balloon * @param key The key of the balloon type in the configuration, type java.lang.String @@ -98,12 +76,8 @@ public SingleBalloonType(String key, String id, String permission, double leashH this.setKey(key); this.setId(id); this.setPermission(permission); - if (leashHeight > 0.0D) { - this.setLeashHeight(leashHeight); - } - if (balloonHeight > 0.0D) { - this.setBalloonHeight(balloonHeight); - } + if (leashHeight > 0.0D) this.setLeashHeight(leashHeight); + if (balloonHeight > 0.0D) this.setBalloonHeight(balloonHeight); this.setMaterial(material); this.setColor(color); this.setCustomModelData(customModelData); diff --git a/src/main/java/net/jeqo/bloons/configuration/ConfigConfiguration.java b/src/main/java/net/jeqo/bloons/configuration/ConfigConfiguration.java index a103b95e..77e2edc9 100644 --- a/src/main/java/net/jeqo/bloons/configuration/ConfigConfiguration.java +++ b/src/main/java/net/jeqo/bloons/configuration/ConfigConfiguration.java @@ -1,7 +1,7 @@ package net.jeqo.bloons.configuration; import net.jeqo.bloons.Bloons; -import net.jeqo.bloons.balloon.model.BalloonModelType; +import net.jeqo.bloons.balloon.model.BalloonSegmentType; import net.jeqo.bloons.balloon.multipart.MultipartBalloonModel; import net.jeqo.bloons.balloon.multipart.MultipartBalloonType; import net.jeqo.bloons.balloon.single.SingleBalloonType; @@ -209,19 +209,19 @@ public static ArrayList getMultipartBalloons() { config.getDouble(key + ".passive-sine-wave-amplitude"), config.getDouble(key + ".passive-nose-sine-wave-amplitude"), new MultipartBalloonModel( - BalloonModelType.HEAD, + BalloonSegmentType.HEAD, config.getString(key + ".head.material"), config.getString(key + ".head.color"), config.getInt(key + ".head.custom-model-data") ), new MultipartBalloonModel( - BalloonModelType.BODY, + BalloonSegmentType.BODY, config.getString(key + ".body.material"), config.getString(key + ".body.color"), config.getInt(key + ".body.custom-model-data") ), new MultipartBalloonModel( - BalloonModelType.TAIL, + BalloonSegmentType.TAIL, config.getString(key + ".tail.material"), config.getString(key + ".tail.color"), config.getInt(key + ".tail.custom-model-data") From f4bb51cc3c97731ca4b00c62e2531e89e0d69695 Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 13:11:26 -0400 Subject: [PATCH 17/24] Remove more unused code and commented more variables --- .../net/jeqo/bloons/balloon/BalloonCore.java | 3 +++ .../bloons/balloon/model/BalloonModel.java | 6 ++--- .../multipart/balloon/MultipartBalloon.java | 21 +++++++++++++--- .../balloon/MultipartBalloonBuilder.java | 9 ++++--- .../balloon/multipart/nodes/ModelNode.java | 24 ++++++++++++++++++- 5 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java b/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java index 5bd640fe..48f5c8d2 100644 --- a/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java +++ b/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java @@ -16,6 +16,9 @@ */ @Setter @Getter public class BalloonCore { + /** + * The plugin instance that runs the balloon core, type org.bukkit.plugin.java.JavaPlugin + */ private JavaPlugin plugin; /** * Contains all valid and loaded multipart balloon types/configurations diff --git a/src/main/java/net/jeqo/bloons/balloon/model/BalloonModel.java b/src/main/java/net/jeqo/bloons/balloon/model/BalloonModel.java index 6cd94a50..1a572073 100644 --- a/src/main/java/net/jeqo/bloons/balloon/model/BalloonModel.java +++ b/src/main/java/net/jeqo/bloons/balloon/model/BalloonModel.java @@ -12,7 +12,7 @@ * A class to handle the creation of balloon models with custom model data and color metadata */ public class BalloonModel { - private static final String leatherMaterialPrefix = "LEATHER_"; // A constant to define a dyeable material + private static final String LEATHER_MATERIAL_PREFIX = "LEATHER_"; // A constant to define a dyeable material /** * Generates a coloured model with the specified colour and custom model data @@ -23,7 +23,7 @@ public class BalloonModel { */ public static ItemStack createColouredModel(Material material, Color colour, int customModelData) { // Check if the material is dyeable and contains leather attributes - if (!material.name().contains(leatherMaterialPrefix)) { + if (!material.name().contains(LEATHER_MATERIAL_PREFIX)) { Logger.logError("Material " + material.name() + " is not a dyeable material."); return new ItemStack(material); } @@ -52,7 +52,7 @@ public static ItemStack createColouredModel(Material material, Color colour, int */ public static ItemStack createColouredModel(Material material, int colourRed, int colourGreen, int colourBlue, int customModelData) { // Check if the material is dyeable and contains leather attributes - if (!material.name().contains(leatherMaterialPrefix)) { + if (!material.name().contains(LEATHER_MATERIAL_PREFIX)) { Logger.logWarning(String.format(Languages.getMessage("material-not-dyeable"), material)); return new ItemStack(material); } diff --git a/src/main/java/net/jeqo/bloons/balloon/multipart/balloon/MultipartBalloon.java b/src/main/java/net/jeqo/bloons/balloon/multipart/balloon/MultipartBalloon.java index 9db77875..49647fdd 100644 --- a/src/main/java/net/jeqo/bloons/balloon/multipart/balloon/MultipartBalloon.java +++ b/src/main/java/net/jeqo/bloons/balloon/multipart/balloon/MultipartBalloon.java @@ -22,19 +22,34 @@ */ @Getter public class MultipartBalloon { + /** + * The type of balloon that the multipart balloon is creating + */ @Setter private MultipartBalloonType balloonType; + /** + * The owner of the balloon + */ @Setter private Player balloonOwner; - + /** + * The chicken that is used to attach the player via a lead to the balloon + */ @Setter private Chicken balloonChicken; - + /** + * The tentacle node that is the front of the balloon + */ @Setter private ModelNode tentacle; + /** + * The runnable that is used to constantly update the balloons' position + */ @Setter private BukkitRunnable runnable; - + /** + * The list of model nodes that are used to create the balloon + */ private final List modelNodes = new ArrayList<>(); /** diff --git a/src/main/java/net/jeqo/bloons/balloon/multipart/balloon/MultipartBalloonBuilder.java b/src/main/java/net/jeqo/bloons/balloon/multipart/balloon/MultipartBalloonBuilder.java index bf49f1f8..e41ab08c 100644 --- a/src/main/java/net/jeqo/bloons/balloon/multipart/balloon/MultipartBalloonBuilder.java +++ b/src/main/java/net/jeqo/bloons/balloon/multipart/balloon/MultipartBalloonBuilder.java @@ -9,10 +9,13 @@ */ @Setter public class MultipartBalloonBuilder { - - // Both of these have attached lombok setters to - // allow for easy setting of the values in the instance + /** + * The type of balloon to create + */ MultipartBalloonType balloonType; + /** + * The owner of the balloon + */ Player balloonOwner; /** diff --git a/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/ModelNode.java b/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/ModelNode.java index 6d3e45d5..2ae702c9 100644 --- a/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/ModelNode.java +++ b/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/ModelNode.java @@ -41,13 +41,35 @@ public class ModelNode { */ ArmorStand balloonArmorStand; - + /** + * The index position of the node in the balloon chain + */ private float index; + /** + * The length of the segment in blocks + */ private float length; + /** + * The type of balloon that the node is a part of that is currently + * registered in the configuration file + */ private MultipartBalloonType balloonType; + /** + * The owner of the balloon + */ private Player balloonOwner; + /** + * The maximum angle that the node can rotate to + */ double maxNodeJointAngle; + /** + * The interpolation factor for the Y-axis + */ double yAxisInterpolation; + /** + * The interpolation factor for the turning spline + * to make the turning of the balloon smoother + */ double turningSplineInterpolation; /** From d66d2785b17475ca5ee149e4f52ee46a227c1e3a Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 13:14:41 -0400 Subject: [PATCH 18/24] Rename variables to make more sense and renamed classes --- .../multipart/MultipartBalloonModel.java | 8 +- .../multipart/balloon/MultipartBalloon.java | 92 +++++++++---------- ...delNode.java => MultipartBalloonNode.java} | 22 ++--- ...r.java => MultipartBalloonNodeVector.java} | 22 ++--- .../bloons/balloon/single/SingleBalloon.java | 92 +++++++++---------- .../MultipartBalloonPlayerJoinListener.java | 2 +- .../MultipartBalloonPlayerListener.java | 4 +- 7 files changed, 121 insertions(+), 121 deletions(-) rename src/main/java/net/jeqo/bloons/balloon/multipart/nodes/{ModelNode.java => MultipartBalloonNode.java} (91%) rename src/main/java/net/jeqo/bloons/balloon/multipart/nodes/{ModelNodeVector.java => MultipartBalloonNodeVector.java} (71%) diff --git a/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java b/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java index 23a0804b..0470cef6 100644 --- a/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java +++ b/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java @@ -19,7 +19,7 @@ public class MultipartBalloonModel { * The type of segment that the model accommodates * This can either be the head, body, or tail of the balloon */ - private BalloonSegmentType modelType; + private BalloonSegmentType segmentType; /** * The material used to create the model */ @@ -35,13 +35,13 @@ public class MultipartBalloonModel { /** * Creates a new model for a multipart balloon - * @param modelType The type of model (head, body, tail), type net.jeqo.bloons.balloon.model.BalloonModelType + * @param segmentType The type of model (head, body, tail), type net.jeqo.bloons.balloon.model.BalloonModelType * @param material The name of the Bukkit Material used to create the item, type java.lang.String * @param color The color of the model as a hex color code value, type java.lang.String * @param customModelData The custom model data value stored in the item metadata, type int */ - public MultipartBalloonModel(BalloonSegmentType modelType, String material, String color, int customModelData) { - this.setModelType(modelType); + public MultipartBalloonModel(BalloonSegmentType segmentType, String material, String color, int customModelData) { + this.setSegmentType(segmentType); this.setMaterial(material); this.setColor(color); this.setCustomModelData(customModelData); diff --git a/src/main/java/net/jeqo/bloons/balloon/multipart/balloon/MultipartBalloon.java b/src/main/java/net/jeqo/bloons/balloon/multipart/balloon/MultipartBalloon.java index 49647fdd..af4077dc 100644 --- a/src/main/java/net/jeqo/bloons/balloon/multipart/balloon/MultipartBalloon.java +++ b/src/main/java/net/jeqo/bloons/balloon/multipart/balloon/MultipartBalloon.java @@ -4,7 +4,7 @@ import lombok.Setter; import net.jeqo.bloons.Bloons; import net.jeqo.bloons.balloon.multipart.MultipartBalloonType; -import net.jeqo.bloons.balloon.multipart.nodes.ModelNode; +import net.jeqo.bloons.balloon.multipart.nodes.MultipartBalloonNode; import net.jeqo.bloons.configuration.BalloonConfiguration; import net.kyori.adventure.text.Component; import org.bukkit.Location; @@ -26,22 +26,22 @@ public class MultipartBalloon { * The type of balloon that the multipart balloon is creating */ @Setter - private MultipartBalloonType balloonType; + private MultipartBalloonType type; /** * The owner of the balloon */ @Setter - private Player balloonOwner; + private Player owner; /** * The chicken that is used to attach the player via a lead to the balloon */ @Setter - private Chicken balloonChicken; + private Chicken chicken; /** * The tentacle node that is the front of the balloon */ @Setter - private ModelNode tentacle; + private MultipartBalloonNode tentacle; /** * The runnable that is used to constantly update the balloons' position */ @@ -50,24 +50,24 @@ public class MultipartBalloon { /** * The list of model nodes that are used to create the balloon */ - private final List modelNodes = new ArrayList<>(); + private final List multipartBalloonNodes = new ArrayList<>(); /** * Initializes the balloons functionality */ public void initialize() { // Things that only need to be set up once and not looped over - ModelNode current = new ModelNode((float) this.getBalloonOwner().getLocation().getX(), (float) this.getBalloonOwner().getLocation().getY(), (float) this.getBalloonOwner().getLocation().getZ(), - (float) ((float) this.getBalloonType().getDistanceBetweenNodes() + this.getBalloonType().getTailNodeOffset()), 0, getBalloonType(), this.getBalloonOwner(), - this.getBalloonType().getMaxNodeJointAngle(), this.getBalloonType().getYAxisInterpolation(), this.getBalloonType().getTurningSplineInterpolation()); + MultipartBalloonNode current = new MultipartBalloonNode((float) this.getOwner().getLocation().getX(), (float) this.getOwner().getLocation().getY(), (float) this.getOwner().getLocation().getZ(), + (float) ((float) this.getType().getDistanceBetweenNodes() + this.getType().getTailNodeOffset()), 0, getType(), this.getOwner(), + this.getType().getMaxNodeJointAngle(), this.getType().getYAxisInterpolation(), this.getType().getTurningSplineInterpolation()); // Add the current node to the list of model nodes - this.getModelNodes().add(current); + this.getMultipartBalloonNodes().add(current); // Create a new node for each node in the balloon type - for (int i = 1; i < this.getBalloonType().getNodeCount(); i++) { - ModelNode next = getModelNode(i, current); - this.getModelNodes().add(next); + for (int i = 1; i < this.getType().getNodeCount(); i++) { + MultipartBalloonNode next = getModelNode(i, current); + this.getMultipartBalloonNodes().add(next); current.child = next; current = next; } @@ -84,18 +84,18 @@ public void initialize() { */ public void initializeBalloonLead() { // Location to spawn the lead holder at - Location location = new Location(this.getBalloonOwner().getWorld(), this.getBalloonOwner().getLocation().getX(), this.getBalloonOwner().getLocation().getY() + 2, this.getBalloonOwner().getLocation().getZ()); + Location location = new Location(this.getOwner().getWorld(), this.getOwner().getLocation().getX(), this.getOwner().getLocation().getY() + 2, this.getOwner().getLocation().getZ()); // Configure the chicken entity properties - this.setBalloonChicken(this.getBalloonOwner().getWorld().spawn(location, Chicken.class)); - this.getBalloonChicken().setInvulnerable(true); - this.getBalloonChicken().setInvisible(true); - this.getBalloonChicken().setBaby(); - this.getBalloonChicken().setSilent(true); - this.getBalloonChicken().setAgeLock(true); - this.getBalloonChicken().setAware(false); - this.getBalloonChicken().setCollidable(false); - this.getBalloonChicken().customName(Component.text(BalloonConfiguration.BALLOON_CHICKEN_ID)); + this.setChicken(this.getOwner().getWorld().spawn(location, Chicken.class)); + this.getChicken().setInvulnerable(true); + this.getChicken().setInvisible(true); + this.getChicken().setBaby(); + this.getChicken().setSilent(true); + this.getChicken().setAgeLock(true); + this.getChicken().setAware(false); + this.getChicken().setCollidable(false); + this.getChicken().customName(Component.text(BalloonConfiguration.BALLOON_CHICKEN_ID)); } /** @@ -104,20 +104,20 @@ public void initializeBalloonLead() { * @param current The current node, type net.jeqo.bloons.balloon.multipart.nodes.ModelNode * @return The next model node, type net.jeqo.bloons.balloon.multipart.nodes.ModelNode */ - private @NotNull ModelNode getModelNode(int index, ModelNode current) { - ModelNode next; + private @NotNull MultipartBalloonNode getModelNode(int index, MultipartBalloonNode current) { + MultipartBalloonNode next; // If the index is the last node, create a head node - if (index == this.getBalloonType().getNodeCount() - 1) { - next = new ModelNode(current, (float) ((float) this.getBalloonType().getDistanceBetweenNodes() + this.getBalloonType().getHeadNodeOffset()), - index, getBalloonType(), this.getBalloonOwner(), this.getBalloonType().getMaxNodeJointAngle(), this.getBalloonType().getYAxisInterpolation(), - this.getBalloonType().getTurningSplineInterpolation()); + if (index == this.getType().getNodeCount() - 1) { + next = new MultipartBalloonNode(current, (float) ((float) this.getType().getDistanceBetweenNodes() + this.getType().getHeadNodeOffset()), + index, getType(), this.getOwner(), this.getType().getMaxNodeJointAngle(), this.getType().getYAxisInterpolation(), + this.getType().getTurningSplineInterpolation()); // Otherwise, create a body node } else { - next = new ModelNode(current, (float) ((float) this.getBalloonType().getDistanceBetweenNodes() + this.getBalloonType().getBodyNodeOffset()), - index, getBalloonType(), this.getBalloonOwner(), this.getBalloonType().getMaxNodeJointAngle(), this.getBalloonType().getYAxisInterpolation(), - this.getBalloonType().getTurningSplineInterpolation()); + next = new MultipartBalloonNode(current, (float) ((float) this.getType().getDistanceBetweenNodes() + this.getType().getBodyNodeOffset()), + index, getType(), this.getOwner(), this.getType().getMaxNodeJointAngle(), this.getType().getYAxisInterpolation(), + this.getType().getTurningSplineInterpolation()); } return next; @@ -132,9 +132,9 @@ public void run() { long timeInTicks = 1; // Internally, this stays at one tick to ensure constant updating of positioning - double speed = this.getBalloonType().getPassiveSineWaveSpeed(); // Adjust the speed of the sine wave - double amplitude = this.getBalloonType().getPassiveSineWaveAmplitude(); // Adjust the amplitude of the sine wave - double noseAmplitude = this.getBalloonType().getPassiveNoseSineWaveAmplitude(); // Adjust how much the nose of the first node goes up and down + double speed = this.getType().getPassiveSineWaveSpeed(); // Adjust the speed of the sine wave + double amplitude = this.getType().getPassiveSineWaveAmplitude(); // Adjust the amplitude of the sine wave + double noseAmplitude = this.getType().getPassiveNoseSineWaveAmplitude(); // Adjust how much the nose of the first node goes up and down final boolean[] isInitialized = {false}; @@ -144,7 +144,7 @@ public void run() { @Override public void run() { // Gets the constantly updated owners location - Location balloonOwnerLocation = getBalloonOwner().getLocation(); + Location balloonOwnerLocation = getOwner().getLocation(); // Calculate the Y offset using a sine function with adjusted amplitude double sinValue = Math.sin(yOffset); @@ -162,7 +162,7 @@ public void run() { getTentacle().display(); // Make the other segments follow - ModelNode next = getTentacle().getParent(); + MultipartBalloonNode next = getTentacle().getParent(); while (next != null) { next.follow(); next.display(); @@ -182,9 +182,9 @@ public void run() { // not break the lead if (isInitialized[0]) { // Teleport the chicken holding the leash constantly - Location leadTeleportPoint = new Location(getBalloonOwner().getWorld(), midpointX, getTentacle().getPointA().y + balloonType.getLeashHeight(), midpointZ); - getBalloonChicken().teleport(leadTeleportPoint); - getBalloonChicken().setLeashHolder(getBalloonOwner()); + Location leadTeleportPoint = new Location(getOwner().getWorld(), midpointX, getTentacle().getPointA().y + type.getLeashHeight(), midpointZ); + getChicken().teleport(leadTeleportPoint); + getChicken().setLeashHolder(getOwner()); } } }); @@ -206,15 +206,15 @@ public void destroy() { } // Remove the chicken first to reduce lead dropping on armor stand clears - this.getBalloonChicken().remove(); + this.getChicken().remove(); // Loop through every node and destroy it (remove the armor stand mainly) - for (ModelNode modelNode : this.getModelNodes()) { - modelNode.destroy(); + for (MultipartBalloonNode multipartBalloonNode : this.getMultipartBalloonNodes()) { + multipartBalloonNode.destroy(); } // Clear the model nodes list to prevent memory leaks - this.getModelNodes().clear(); + this.getMultipartBalloonNodes().clear(); } /** @@ -222,7 +222,7 @@ public void destroy() { * @param builder The builder to retrieve the variables from */ MultipartBalloon(MultipartBalloonBuilder builder) { - this.setBalloonType(builder.balloonType); - this.setBalloonOwner(builder.balloonOwner); + this.setType(builder.balloonType); + this.setOwner(builder.balloonOwner); } } diff --git a/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/ModelNode.java b/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/MultipartBalloonNode.java similarity index 91% rename from src/main/java/net/jeqo/bloons/balloon/multipart/nodes/ModelNode.java rename to src/main/java/net/jeqo/bloons/balloon/multipart/nodes/MultipartBalloonNode.java index 2ae702c9..3c331f7a 100644 --- a/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/ModelNode.java +++ b/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/MultipartBalloonNode.java @@ -17,24 +17,24 @@ * Handles the movement and functionality of a single node, model, or armor stand in a multipart balloon */ @Getter @Setter -public class ModelNode { +public class MultipartBalloonNode { /** * The front most point of the segment/node */ - public ModelNodeVector pointA; + public MultipartBalloonNodeVector pointA; /** * The back most point of the segment/node */ - public ModelNodeVector pointB = new ModelNodeVector(); + public MultipartBalloonNodeVector pointB = new MultipartBalloonNodeVector(); /** * The parent node of the current node */ - public ModelNode parent = null; + public MultipartBalloonNode parent = null; /** * The child node of the current node */ - public ModelNode child = null; + public MultipartBalloonNode child = null; /** * The armor stand that represents the node @@ -82,12 +82,12 @@ public class ModelNode { * @param balloonType Type of balloon, type net.jeqo.bloons.balloon.multipart.MultipartBalloonType * @param balloonOwner Owner of the balloon, type org.bukkit.entity.Player */ - public ModelNode(float x, float y, float z, float length, int index, MultipartBalloonType balloonType, Player balloonOwner, double maxNodeJointAngle, double yAxisInterpolation, double turningSplineInterpolation) { + public MultipartBalloonNode(float x, float y, float z, float length, int index, MultipartBalloonType balloonType, Player balloonOwner, double maxNodeJointAngle, double yAxisInterpolation, double turningSplineInterpolation) { this.setLength(length); this.setIndex(index); this.setBalloonType(balloonType); this.setBalloonOwner(balloonOwner); - this.setPointA(new ModelNodeVector(x, y, z)); + this.setPointA(new MultipartBalloonNodeVector(x, y, z)); this.setMaxNodeJointAngle(maxNodeJointAngle); this.setYAxisInterpolation(yAxisInterpolation); this.setTurningSplineInterpolation(turningSplineInterpolation); @@ -108,7 +108,7 @@ public ModelNode(float x, float y, float z, float length, int index, MultipartBa * @param length Length of segment in blocks, type float * @param index Index number in the balloon, type int */ - public ModelNode(ModelNode parent, float length, int index, MultipartBalloonType balloonType, Player balloonOwner, double maxNodeJointAngle, double yAxisInterpolation, double turningSplineInterpolation) { + public MultipartBalloonNode(MultipartBalloonNode parent, float length, int index, MultipartBalloonType balloonType, Player balloonOwner, double maxNodeJointAngle, double yAxisInterpolation, double turningSplineInterpolation) { this.setParent(parent); this.setPointA(parent.getPointB().copy()); this.setLength(length); @@ -162,8 +162,8 @@ public void follow() { * @param targetZ Target Z axis, type float */ public void follow(float targetX, float targetY, float targetZ) { - ModelNodeVector target = new ModelNodeVector(targetX, targetY, targetZ); - ModelNodeVector dir = ModelNodeVector.subtract(target, this.getPointB()); + MultipartBalloonNodeVector target = new MultipartBalloonNodeVector(targetX, targetY, targetZ); + MultipartBalloonNodeVector dir = MultipartBalloonNodeVector.subtract(target, this.getPointB()); double targetAngle = dir.heading(); @@ -246,7 +246,7 @@ private double lerpVal(double startVal, double endVal, double interpolationFacto * @return The heading of the two node vectors, type float */ public float heading(){ - return ModelNodeVector.subtract(this.getPointA(), this.getPointB()).heading(); + return MultipartBalloonNodeVector.subtract(this.getPointA(), this.getPointB()).heading(); } /** diff --git a/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/ModelNodeVector.java b/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/MultipartBalloonNodeVector.java similarity index 71% rename from src/main/java/net/jeqo/bloons/balloon/multipart/nodes/ModelNodeVector.java rename to src/main/java/net/jeqo/bloons/balloon/multipart/nodes/MultipartBalloonNodeVector.java index c4ef63fb..80f48212 100644 --- a/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/ModelNodeVector.java +++ b/src/main/java/net/jeqo/bloons/balloon/multipart/nodes/MultipartBalloonNodeVector.java @@ -5,7 +5,7 @@ /** * A custom vector to store the axis of a balloon node */ -public class ModelNodeVector implements Serializable { +public class MultipartBalloonNodeVector implements Serializable { /** * Model node vector axis. */ @@ -16,7 +16,7 @@ public class ModelNodeVector implements Serializable { /** * Creates a blank model node vector. */ - public ModelNodeVector() { + public MultipartBalloonNodeVector() { } /** @@ -25,7 +25,7 @@ public ModelNodeVector() { * @param y Y axis. * @param z Z axis. */ - public ModelNodeVector(float x, float y, float z) { + public MultipartBalloonNodeVector(float x, float y, float z) { this.x = x; this.y = y; this.z = z; @@ -57,8 +57,8 @@ public void set(float x, float z) { * Copies a segment vector. * @return The copy of the vector. */ - public ModelNodeVector copy() { - return new ModelNodeVector(x, y, z); + public MultipartBalloonNodeVector copy() { + return new MultipartBalloonNodeVector(x, y, z); } /** @@ -67,7 +67,7 @@ public ModelNodeVector copy() { * @param v2 Segment vector 2. * @return The combined segment vector. */ - static public ModelNodeVector add(ModelNodeVector v1, ModelNodeVector v2) { + static public MultipartBalloonNodeVector add(MultipartBalloonNodeVector v1, MultipartBalloonNodeVector v2) { return add(v1, v2, null); } @@ -78,9 +78,9 @@ static public ModelNodeVector add(ModelNodeVector v1, ModelNodeVector v2) { * @param target Target vector. * @return The combined vectors. */ - static public ModelNodeVector add(ModelNodeVector v1, ModelNodeVector v2, ModelNodeVector target) { + static public MultipartBalloonNodeVector add(MultipartBalloonNodeVector v1, MultipartBalloonNodeVector v2, MultipartBalloonNodeVector target) { if (target == null) { - target = new ModelNodeVector(v1.x + v2.x,v1.y + v2.y, v1.z + v2.z); + target = new MultipartBalloonNodeVector(v1.x + v2.x,v1.y + v2.y, v1.z + v2.z); } else { target.set(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z); } @@ -93,7 +93,7 @@ static public ModelNodeVector add(ModelNodeVector v1, ModelNodeVector v2, ModelN * @param v2 Segment vector 2. * @return The result of the two subtracted vectors. */ - static public ModelNodeVector subtract(ModelNodeVector v1, ModelNodeVector v2) { + static public MultipartBalloonNodeVector subtract(MultipartBalloonNodeVector v1, MultipartBalloonNodeVector v2) { return subtract(v1, v2, null); } @@ -104,9 +104,9 @@ static public ModelNodeVector subtract(ModelNodeVector v1, ModelNodeVector v2) { * @param target Target vector. * @return The result of the subtraction. */ - static public ModelNodeVector subtract(ModelNodeVector v1, ModelNodeVector v2, ModelNodeVector target) { + static public MultipartBalloonNodeVector subtract(MultipartBalloonNodeVector v1, MultipartBalloonNodeVector v2, MultipartBalloonNodeVector target) { if (target == null) { - target = new ModelNodeVector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z); + target = new MultipartBalloonNodeVector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z); } else { target.set(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z); } diff --git a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java index 4b415149..373ba8ce 100644 --- a/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java +++ b/src/main/java/net/jeqo/bloons/balloon/single/SingleBalloon.java @@ -34,15 +34,15 @@ @Getter @Setter public class SingleBalloon extends BukkitRunnable { /** Must have variables related to any balloon **/ - private SingleBalloonType balloonType; + private SingleBalloonType type; private Player player; - private ArmorStand balloonArmorStand; - public Chicken balloonChicken; + private ArmorStand armorStand; + public Chicken chicken; /** * Only used for non-MEG balloons to configure the visual appearance of the balloon */ - private ItemStack balloonVisual; + private ItemStack visual; /** MEG related variables **/ private ModeledEntity modeledEntity; @@ -67,10 +67,10 @@ public class SingleBalloon extends BukkitRunnable { */ public SingleBalloon(Player player, String balloonID) { this.setPlayer(player); - this.setBalloonType(Bloons.getBalloonCore().getSingleBalloonByID(balloonID)); + this.setType(Bloons.getBalloonCore().getSingleBalloonByID(balloonID)); - if (this.getBalloonType().getMegModelID() == null) { - this.setBalloonVisual(getConfiguredBalloonVisual(balloonID)); + if (this.getType().getMegModelID() == null) { + this.setVisual(getConfiguredBalloonVisual(balloonID)); } } @@ -82,11 +82,11 @@ private void initializeBalloon() { this.setPlayerLocation(this.getPlayer().getLocation()); this.getPlayerLocation().setYaw(0.0F); - if (this.getBalloonType().getMegModelID() == null) { + if (this.getType().getMegModelID() == null) { // Create and set the balloons visual appearance/model - ItemMeta meta = this.getBalloonVisual().getItemMeta(); + ItemMeta meta = this.getVisual().getItemMeta(); meta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); - this.getBalloonVisual().setItemMeta(meta); + this.getVisual().setItemMeta(meta); } // Initialize the armor stand and lead to the player @@ -98,22 +98,22 @@ private void initializeBalloon() { * Initializes the balloon's armor stand entity with the proper configurations */ public void initializeBalloonArmorStand() { - this.setBalloonArmorStand(this.getPlayerLocation().getWorld().spawn(this.getPlayerLocation(), ArmorStand.class)); - this.getBalloonArmorStand().setBasePlate(false); - this.getBalloonArmorStand().setVisible(false); - this.getBalloonArmorStand().setInvulnerable(true); - this.getBalloonArmorStand().setCanPickupItems(false); - this.getBalloonArmorStand().setGravity(false); - this.getBalloonArmorStand().setSmall(false); - this.getBalloonArmorStand().setMarker(true); - this.getBalloonArmorStand().setCollidable(false); - if (this.getBalloonType().getMegModelID() == null) { - this.getBalloonArmorStand().getEquipment().setHelmet(this.getBalloonVisual()); + this.setArmorStand(this.getPlayerLocation().getWorld().spawn(this.getPlayerLocation(), ArmorStand.class)); + this.getArmorStand().setBasePlate(false); + this.getArmorStand().setVisible(false); + this.getArmorStand().setInvulnerable(true); + this.getArmorStand().setCanPickupItems(false); + this.getArmorStand().setGravity(false); + this.getArmorStand().setSmall(false); + this.getArmorStand().setMarker(true); + this.getArmorStand().setCollidable(false); + if (this.getType().getMegModelID() == null) { + this.getArmorStand().getEquipment().setHelmet(this.getVisual()); } else { try { // Create the entity and tag it onto the armor stand - ModeledEntity modeledEntity = ModelEngineAPI.createModeledEntity(this.getBalloonArmorStand()); - ActiveModel activeModel = ModelEngineAPI.createActiveModel(this.getBalloonType().getMegModelID()); + ModeledEntity modeledEntity = ModelEngineAPI.createModeledEntity(this.getArmorStand()); + ActiveModel activeModel = ModelEngineAPI.createActiveModel(this.getType().getMegModelID()); modeledEntity.addModel(activeModel, true); @@ -123,27 +123,27 @@ public void initializeBalloonArmorStand() { // If an idle animation exists, play it initially this.getAnimationHandler().playAnimation(this.getDefaultIdleAnimationID(), 0.3, 0.3, 1,true); } catch (Exception e) { - Logger.logError("An error occurred while creating the MEG model for the balloon " + this.getBalloonType().getId() + "! This is because a MEG model error occurred."); + Logger.logError("An error occurred while creating the MEG model for the balloon " + this.getType().getId() + "! This is because a MEG model error occurred."); e.printStackTrace(); } } - this.getBalloonArmorStand().customName(Component.text(BalloonConfiguration.BALLOON_ARMOR_STAND_ID)); + this.getArmorStand().customName(Component.text(BalloonConfiguration.BALLOON_ARMOR_STAND_ID)); } /** * Initializes the balloon's lead to the player (chicken entity) */ public void initializeBalloonLead() { - this.setBalloonChicken(this.getPlayerLocation().getWorld().spawn(this.getPlayerLocation(), Chicken.class)); - this.getBalloonChicken().setInvulnerable(true); - this.getBalloonChicken().setInvisible(true); - this.getBalloonChicken().setSilent(true); - this.getBalloonChicken().setBaby(); - this.getBalloonChicken().setAgeLock(true); - this.getBalloonChicken().setAware(false); - this.getBalloonChicken().setCollidable(false); - this.getBalloonChicken().setLeashHolder(this.getPlayer()); - this.getBalloonChicken().customName(Component.text(BalloonConfiguration.BALLOON_CHICKEN_ID)); + this.setChicken(this.getPlayerLocation().getWorld().spawn(this.getPlayerLocation(), Chicken.class)); + this.getChicken().setInvulnerable(true); + this.getChicken().setInvisible(true); + this.getChicken().setSilent(true); + this.getChicken().setBaby(); + this.getChicken().setAgeLock(true); + this.getChicken().setAware(false); + this.getChicken().setCollidable(false); + this.getChicken().setLeashHolder(this.getPlayer()); + this.getChicken().customName(Component.text(BalloonConfiguration.BALLOON_CHICKEN_ID)); } /** @@ -152,7 +152,7 @@ public void initializeBalloonLead() { */ public void run() { // If the balloon armor stand is null, initialize the balloon - if (this.getBalloonArmorStand() == null) initializeBalloon(); + if (this.getArmorStand() == null) initializeBalloon(); // Every tick, retrieve the updated player location Location playerLocation = this.getPlayerLocation(); @@ -172,7 +172,7 @@ public void run() { } // Set the move location to the armor stand location minus 2 on the Y axis - this.setMoveLocation(this.getBalloonArmorStand().getLocation().subtract(0.0D, this.getBalloonType().getBalloonHeight(), 0.0D).clone()); + this.setMoveLocation(this.getArmorStand().getLocation().subtract(0.0D, this.getType().getBalloonHeight(), 0.0D).clone()); // Set the vector to the player location minus the move location Vector vector = playerLocation.toVector().subtract(this.getMoveLocation().toVector()); @@ -184,14 +184,14 @@ public void run() { EulerAngle tiltAngle = new EulerAngle(Math.toRadians(vectorZ), Math.toRadians(playerLocation.getYaw()), Math.toRadians(vectorX)); // Set the pose(s) of the armor stand - ArmorStand armorStand = this.getBalloonArmorStand(); + ArmorStand armorStand = this.getArmorStand(); // Set the pose of only the head regardless of the model type armorStand.setHeadPose(tiltAngle); // Only set the entire pose of the armor stand if it uses MEG, this is to reduce lag across the server // when having 100's of models/armor stands used simultaneously - if (this.getBalloonType().getMegModelID() != null) { + if (this.getType().getMegModelID() != null) { armorStand.setBodyPose(tiltAngle); armorStand.setLeftArmPose(tiltAngle); armorStand.setRightArmPose(tiltAngle); @@ -203,7 +203,7 @@ public void run() { this.teleport(this.getMoveLocation()); // If the balloon armor stand is more than 5 blocks away, teleport to player location - if (this.getBalloonArmorStand().getLocation().distance(playerLocation) > 5.0D) { + if (this.getArmorStand().getLocation().distance(playerLocation) > 5.0D) { this.teleport(playerLocation); } @@ -228,11 +228,11 @@ public void run() { public synchronized void cancel() throws IllegalStateException { if (this.getModeledEntity() != null) { // Remove the MEG model if it exists - ModeledEntity modeledEntity = ModelEngineAPI.getModeledEntity(this.getBalloonArmorStand()); - modeledEntity.removeModel(this.getBalloonType().getMegModelID()); + ModeledEntity modeledEntity = ModelEngineAPI.getModeledEntity(this.getArmorStand()); + modeledEntity.removeModel(this.getType().getMegModelID()); } - this.getBalloonArmorStand().remove(); - this.getBalloonChicken().remove(); + this.getArmorStand().remove(); + this.getChicken().remove(); super.cancel(); } @@ -248,8 +248,8 @@ public void spawnRemoveParticle() { * @param location The location to teleport the balloon to, type org.bukkit.Location */ private void teleport(Location location) { - this.getBalloonArmorStand().teleport(location.add(0.0D, this.getBalloonType().getBalloonHeight(), 0.0D)); - this.getBalloonChicken().teleport(location.add(0.0D, this.getBalloonType().getLeashHeight(), 0.0D)); + this.getArmorStand().teleport(location.add(0.0D, this.getType().getBalloonHeight(), 0.0D)); + this.getChicken().teleport(location.add(0.0D, this.getType().getLeashHeight(), 0.0D)); } /** diff --git a/src/main/java/net/jeqo/bloons/listeners/multipart/MultipartBalloonPlayerJoinListener.java b/src/main/java/net/jeqo/bloons/listeners/multipart/MultipartBalloonPlayerJoinListener.java index 9861ee0c..311e8f02 100644 --- a/src/main/java/net/jeqo/bloons/listeners/multipart/MultipartBalloonPlayerJoinListener.java +++ b/src/main/java/net/jeqo/bloons/listeners/multipart/MultipartBalloonPlayerJoinListener.java @@ -24,7 +24,7 @@ public void onPlayerJoin(PlayerJoinEvent event) { if (equipEvent.isCancelled()) return; - MultipartBalloonType balloonType = MultipartBalloonManagement.getPlayerBalloon(event.getPlayer().getUniqueId()).getBalloonType(); + MultipartBalloonType balloonType = MultipartBalloonManagement.getPlayerBalloon(event.getPlayer().getUniqueId()).getType(); MultipartBalloonManagement.removePlayerBalloon(event.getPlayer().getUniqueId()); diff --git a/src/main/java/net/jeqo/bloons/listeners/multipart/MultipartBalloonPlayerListener.java b/src/main/java/net/jeqo/bloons/listeners/multipart/MultipartBalloonPlayerListener.java index d193363e..5a69deff 100644 --- a/src/main/java/net/jeqo/bloons/listeners/multipart/MultipartBalloonPlayerListener.java +++ b/src/main/java/net/jeqo/bloons/listeners/multipart/MultipartBalloonPlayerListener.java @@ -42,7 +42,7 @@ public void onDeath(PlayerDeathEvent event) { @EventHandler public void onRespawn(PlayerRespawnEvent event) { MultipartBalloon previousBalloon = Bloons.getPlayerMultipartBalloons().get(event.getPlayer().getPlayer().getUniqueId()); - MultipartBalloonType type = previousBalloon.getBalloonType(); + MultipartBalloonType type = previousBalloon.getType(); if (previousBalloon == null) return; @@ -68,7 +68,7 @@ public void onRespawn(PlayerRespawnEvent event) { public void onWorldChange(PlayerChangedWorldEvent event) { MultipartBalloon balloon = Bloons.getPlayerMultipartBalloons().get(event.getPlayer().getUniqueId()); MultipartBalloon previousBalloon = Bloons.getPlayerMultipartBalloons().get(event.getPlayer().getPlayer().getUniqueId()); - MultipartBalloonType type = previousBalloon.getBalloonType(); + MultipartBalloonType type = previousBalloon.getType(); MultipartBalloonForceUnequipEvent multipartBalloonForceUnequipEvent = new MultipartBalloonForceUnequipEvent(event.getPlayer(), balloon); From 2d77350d214744658e66484b6e7a72c479a5ff57 Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 15:37:46 -0400 Subject: [PATCH 19/24] Made fields optional for a multipart balloon types --- .../multipart/MultipartBalloonType.java | 303 ++---------------- 1 file changed, 31 insertions(+), 272 deletions(-) diff --git a/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonType.java b/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonType.java index 776e0ed2..7daacef3 100644 --- a/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonType.java +++ b/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonType.java @@ -27,55 +27,55 @@ public class MultipartBalloonType { /** * The number of nodes, or models, in the balloon */ - private int nodeCount; + private int nodeCount = 5; // optional /** * The distance between each node in the balloon measured in blocks */ - private double distanceBetweenNodes; + private double distanceBetweenNodes = 2.0; // optional /** * The height of the leash attached to a player relative from the head of the player in blocks */ - private double leashHeight; + private double leashHeight = 1.2; // optional /** * The offset of the head node from its 0 position measured in blocks */ - private double headNodeOffset = 0.0; + private double headNodeOffset = 0.0; // optional /** * The offset of the body node from its 0 position measured in blocks */ - private double bodyNodeOffset = 0.0; + private double bodyNodeOffset = 0.0; // optional /** * The offset of the tail node from its 0 position measured in blocks */ - private double tailNodeOffset = 0.0; + private double tailNodeOffset = 0.0; // optional /** * The max angle that a segment/node can rotate to in degrees in both directions * This number *2 is equal to the total range of motion for each segment */ - private double maxNodeJointAngle = 35.0; + private double maxNodeJointAngle = 35.0; // optional /** * The interpolation of the Y-axis motion of every segment */ - private double yAxisInterpolation = 0.35; + private double yAxisInterpolation = 0.35; // optional /** * The interpolation of the turning spline to prevent overturning and * to enhance smoother turning */ - private double turningSplineInterpolation = 0.35; + private double turningSplineInterpolation = 0.35; // optional /** * The speed of the passive sine wave animation. This is the amount of blocks it * will move every tick due to the runnable running every tick. */ - private double passiveSineWaveSpeed = 0.05; + private double passiveSineWaveSpeed = 0.05; // optional /** * The amplitude of the passive sine wave animation. This is the maximum amount of * blocks the balloon will move in the positive and negative direction. */ - private double passiveSineWaveAmplitude = 0.5; + private double passiveSineWaveAmplitude = 0.5; // optional /** * The amplitude of the passive sine wave animation starting at the nose */ - private double passiveNoseSineWaveAmplitude = 0.5; + private double passiveNoseSineWaveAmplitude = 0.5; // optional /** * The model used for the head node */ @@ -113,265 +113,24 @@ public class MultipartBalloonType { * @param tailModel The model used for the tail node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel */ public MultipartBalloonType(String id, String permission, String name, String[] lore, int nodeCount, double distanceBetweenNodes, double leashHeight, double headNodeOffset, double bodyNodeOffset, double tailNodeOffset, double maxNodeJointAngle, double yAxisInterpolation, double turningSplineInterpolation, double passiveSineWaveSpeed, double passiveSineWaveAmplitude, double passiveNoseSineWaveAmplitude, MultipartBalloonModel headModel, MultipartBalloonModel bodyModel, MultipartBalloonModel tailModel) { - this.setId(id); - this.setPermission(permission); - this.setName(name); - this.setLore(lore); - this.setNodeCount(nodeCount); - this.setDistanceBetweenNodes(distanceBetweenNodes); - this.setLeashHeight(leashHeight); - this.setHeadNodeOffset(headNodeOffset); - this.setBodyNodeOffset(bodyNodeOffset); - this.setTailNodeOffset(tailNodeOffset); - this.setMaxNodeJointAngle(maxNodeJointAngle); - this.setYAxisInterpolation(yAxisInterpolation); - this.setTurningSplineInterpolation(turningSplineInterpolation); - this.setPassiveSineWaveSpeed(passiveSineWaveSpeed); - this.setPassiveSineWaveAmplitude(passiveSineWaveAmplitude); - this.setPassiveNoseSineWaveAmplitude(passiveNoseSineWaveAmplitude); - this.setHeadModel(headModel); - this.setBodyModel(bodyModel); - this.setTailModel(tailModel); - } - - /** - * Creates a new multipart balloon type which contains - * the data in the configuration for the balloon - * @param id The ID of the balloon, type java.lang.String - * @param permission The permission required to use the balloon (i.e. blue.jeqo), type java.lang.String - * @param name The name of the balloon, type java.lang.String - * @param lore The lore lines of the balloon in the balloon GUI, type java.lang.String[] - * @param nodeCount The number of nodes, or models, in the balloon, type int - * @param distanceBetweenNodes The distance between each node in the balloon measured as blocks, type double - * @param headNodeOffset The offset of the head node from its 0 position measured as blocks, type double - * @param bodyNodeOffset The offset of the body node from its 0 position measured as blocks, type double - * @param tailNodeOffset The offset of the tail node from its 0 position measured as blocks, type double - * @param maxNodeJointAngle The maximum angle a node can rotate in degrees, type double - * @param yAxisInterpolation The interpolation of the Y-axis, type double - * @param turningSplineInterpolation The interpolation of the turning spline to prevent overturning, type double - * @param passiveSineWaveSpeed The speed of the passive sine wave animation, type double - * @param passiveSineWaveAmplitude The amplitude of the passive sine wave animation, type double - * @param headModel The model used for the head node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - * @param bodyModel The model used for the body node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - * @param tailModel The model used for the tail node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - */ - public MultipartBalloonType(String id, String permission, String name, String[] lore, int nodeCount, double distanceBetweenNodes, double headNodeOffset, double bodyNodeOffset, double tailNodeOffset, double maxNodeJointAngle, double yAxisInterpolation, double turningSplineInterpolation, double passiveSineWaveSpeed, double passiveSineWaveAmplitude, MultipartBalloonModel headModel, MultipartBalloonModel bodyModel, MultipartBalloonModel tailModel) { - this.setId(id); - this.setPermission(permission); - this.setName(name); - this.setLore(lore); - this.setNodeCount(nodeCount); - this.setDistanceBetweenNodes(distanceBetweenNodes); - this.setHeadNodeOffset(headNodeOffset); - this.setBodyNodeOffset(bodyNodeOffset); - this.setTailNodeOffset(tailNodeOffset); - this.setMaxNodeJointAngle(maxNodeJointAngle); - this.setYAxisInterpolation(yAxisInterpolation); - this.setTurningSplineInterpolation(turningSplineInterpolation); - this.setPassiveSineWaveSpeed(passiveSineWaveSpeed); - this.setPassiveSineWaveAmplitude(passiveSineWaveAmplitude); - this.setHeadModel(headModel); - this.setBodyModel(bodyModel); - this.setTailModel(tailModel); - } - - /** - * Creates a new multipart balloon type which contains - * the data in the configuration for the balloon - * @param id The ID of the balloon, type java.lang.String - * @param permission The permission required to use the balloon (i.e. blue.jeqo), type java.lang.String - * @param name The name of the balloon, type java.lang.String - * @param lore The lore lines of the balloon in the balloon GUI, type java.lang.String[] - * @param nodeCount The number of nodes, or models, in the balloon, type int - * @param distanceBetweenNodes The distance between each node in the balloon measured as blocks, type double - * @param headNodeOffset The offset of the head node from its 0 position measured as blocks, type double - * @param bodyNodeOffset The offset of the body node from its 0 position measured as blocks, type double - * @param tailNodeOffset The offset of the tail node from its 0 position measured as blocks, type double - * @param maxNodeJointAngle The maximum angle a node can rotate in degrees, type double - * @param yAxisInterpolation The interpolation of the Y-axis, type double - * @param turningSplineInterpolation The interpolation of the turning spline to prevent overturning, type double - * @param passiveSineWaveSpeed The speed of the passive sine wave animation, type double - * @param headModel The model used for the head node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - * @param bodyModel The model used for the body node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - * @param tailModel The model used for the tail node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - */ - public MultipartBalloonType(String id, String permission, String name, String[] lore, int nodeCount, double distanceBetweenNodes, double headNodeOffset, double bodyNodeOffset, double tailNodeOffset, double maxNodeJointAngle, double yAxisInterpolation, double turningSplineInterpolation, double passiveSineWaveSpeed, MultipartBalloonModel headModel, MultipartBalloonModel bodyModel, MultipartBalloonModel tailModel) { - this.setId(id); - this.setPermission(permission); - this.setName(name); - this.setLore(lore); - this.setNodeCount(nodeCount); - this.setDistanceBetweenNodes(distanceBetweenNodes); - this.setHeadNodeOffset(headNodeOffset); - this.setBodyNodeOffset(bodyNodeOffset); - this.setTailNodeOffset(tailNodeOffset); - this.setMaxNodeJointAngle(maxNodeJointAngle); - this.setYAxisInterpolation(yAxisInterpolation); - this.setTurningSplineInterpolation(turningSplineInterpolation); - this.setPassiveSineWaveSpeed(passiveSineWaveSpeed); - this.setHeadModel(headModel); - this.setBodyModel(bodyModel); - this.setTailModel(tailModel); - } - - /** - * Creates a new multipart balloon type which contains - * the data in the configuration for the balloon - * @param id The ID of the balloon, type java.lang.String - * @param permission The permission required to use the balloon (i.e. blue.jeqo), type java.lang.String - * @param name The name of the balloon, type java.lang.String - * @param lore The lore lines of the balloon in the balloon GUI, type java.lang.String[] - * @param nodeCount The number of nodes, or models, in the balloon, type int - * @param distanceBetweenNodes The distance between each node in the balloon measured as blocks, type double - * @param headNodeOffset The offset of the head node from its 0 position measured as blocks, type double - * @param bodyNodeOffset The offset of the body node from its 0 position measured as blocks, type double - * @param tailNodeOffset The offset of the tail node from its 0 position measured as blocks, type double - * @param maxNodeJointAngle The maximum angle a node can rotate in degrees, type double - * @param yAxisInterpolation The interpolation of the Y-axis, type double - * @param turningSplineInterpolation The interpolation of the turning spline to prevent overturning, type double - * @param headModel The model used for the head node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - * @param bodyModel The model used for the body node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - * @param tailModel The model used for the tail node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - */ - public MultipartBalloonType(String id, String permission, String name, String[] lore, int nodeCount, double distanceBetweenNodes, double headNodeOffset, double bodyNodeOffset, double tailNodeOffset, double maxNodeJointAngle, double yAxisInterpolation, double turningSplineInterpolation, MultipartBalloonModel headModel, MultipartBalloonModel bodyModel, MultipartBalloonModel tailModel) { - this.setId(id); - this.setPermission(permission); - this.setName(name); - this.setLore(lore); - this.setNodeCount(nodeCount); - this.setDistanceBetweenNodes(distanceBetweenNodes); - this.setHeadNodeOffset(headNodeOffset); - this.setBodyNodeOffset(bodyNodeOffset); - this.setTailNodeOffset(tailNodeOffset); - this.setMaxNodeJointAngle(maxNodeJointAngle); - this.setYAxisInterpolation(yAxisInterpolation); - this.setTurningSplineInterpolation(turningSplineInterpolation); - this.setHeadModel(headModel); - this.setBodyModel(bodyModel); - this.setTailModel(tailModel); - } - - /** - * Creates a new multipart balloon type which contains - * the data in the configuration for the balloon - * @param id The ID of the balloon, type java.lang.String - * @param permission The permission required to use the balloon (i.e. blue.jeqo), type java.lang.String - * @param name The name of the balloon, type java.lang.String - * @param lore The lore lines of the balloon in the balloon GUI, type java.lang.String[] - * @param nodeCount The number of nodes, or models, in the balloon, type int - * @param distanceBetweenNodes The distance between each node in the balloon measured as blocks, type double - * @param headModel The model used for the head node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - * @param bodyModel The model used for the body node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - * @param tailModel The model used for the tail node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - */ - public MultipartBalloonType(String id, String permission, String name, String[] lore, int nodeCount, double distanceBetweenNodes, MultipartBalloonModel headModel, MultipartBalloonModel bodyModel, MultipartBalloonModel tailModel) { - this.setId(id); - this.setPermission(permission); - this.setName(name); - this.setLore(lore); - this.setNodeCount(nodeCount); - this.setDistanceBetweenNodes(distanceBetweenNodes); - this.setHeadModel(headModel); - this.setBodyModel(bodyModel); - this.setTailModel(tailModel); - } - - /** - * Creates a new multipart balloon type which contains - * the data in the configuration for the balloon - * @param id The ID of the balloon, type java.lang.String - * @param permission The permission required to use the balloon (i.e. blue.jeqo), type java.lang.String - * @param name The name of the balloon, type java.lang.String - * @param lore The lore lines of the balloon in the balloon GUI, type java.lang.String[] - * @param nodeCount The number of nodes, or models, in the balloon, type int - * @param distanceBetweenNodes The distance between each node in the balloon measured as blocks, type double - * @param headNodeOffset The offset of the head node from its 0 position measured as blocks, type double - * @param bodyNodeOffset The offset of the body node from its 0 position measured as blocks, type double - * @param tailNodeOffset The offset of the tail node from its 0 position measured as blocks, type double - * @param headModel The model used for the head node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - * @param bodyModel The model used for the body node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - * @param tailModel The model used for the tail node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - */ - public MultipartBalloonType(String id, String permission, String name, String[] lore, int nodeCount, double distanceBetweenNodes, double headNodeOffset, double bodyNodeOffset, double tailNodeOffset, MultipartBalloonModel headModel, MultipartBalloonModel bodyModel, MultipartBalloonModel tailModel) { - this.setId(id); - this.setPermission(permission); - this.setName(name); - this.setLore(lore); - this.setNodeCount(nodeCount); - this.setDistanceBetweenNodes(distanceBetweenNodes); - this.setHeadNodeOffset(headNodeOffset); - this.setBodyNodeOffset(bodyNodeOffset); - this.setTailNodeOffset(tailNodeOffset); - this.setHeadModel(headModel); - this.setBodyModel(bodyModel); - this.setTailModel(tailModel); - } - - /** - * Creates a new multipart balloon type which contains - * the data in the configuration for the balloon - * @param id The ID of the balloon, type java.lang.String - * @param permission The permission required to use the balloon (i.e. blue.jeqo), type java.lang.String - * @param name The name of the balloon, type java.lang.String - * @param lore The lore lines of the balloon in the balloon GUI, type java.lang.String[] - * @param nodeCount The number of nodes, or models, in the balloon, type int - * @param distanceBetweenNodes The distance between each node in the balloon measured as blocks, type double - * @param headNodeOffset The offset of the head node from its 0 position measured as blocks, type double - * @param bodyNodeOffset The offset of the body node from its 0 position measured as blocks, type double - * @param tailNodeOffset The offset of the tail node from its 0 position measured as blocks, type double - * @param maxNodeJointAngle The maximum angle a node can rotate in degrees, type double - * @param headModel The model used for the head node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - * @param bodyModel The model used for the body node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - * @param tailModel The model used for the tail node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - */ - public MultipartBalloonType(String id, String permission, String name, String[] lore, int nodeCount, double distanceBetweenNodes, double headNodeOffset, double bodyNodeOffset, double tailNodeOffset, double maxNodeJointAngle, MultipartBalloonModel headModel, MultipartBalloonModel bodyModel, MultipartBalloonModel tailModel) { - this.setId(id); - this.setPermission(permission); - this.setName(name); - this.setLore(lore); - this.setNodeCount(nodeCount); - this.setDistanceBetweenNodes(distanceBetweenNodes); - this.setHeadNodeOffset(headNodeOffset); - this.setBodyNodeOffset(bodyNodeOffset); - this.setTailNodeOffset(tailNodeOffset); - this.setMaxNodeJointAngle(maxNodeJointAngle); - this.setHeadModel(headModel); - this.setBodyModel(bodyModel); - this.setTailModel(tailModel); - } - - /** - * Creates a new multipart balloon type which contains - * the data in the configuration for the balloon - * @param id The ID of the balloon, type java.lang.String - * @param permission The permission required to use the balloon (i.e. blue.jeqo), type java.lang.String - * @param name The name of the balloon, type java.lang.String - * @param lore The lore lines of the balloon in the balloon GUI, type java.lang.String[] - * @param nodeCount The number of nodes, or models, in the balloon, type int - * @param distanceBetweenNodes The distance between each node in the balloon measured as blocks, type double - * @param headNodeOffset The offset of the head node from its 0 position measured as blocks, type double - * @param bodyNodeOffset The offset of the body node from its 0 position measured as blocks, type double - * @param tailNodeOffset The offset of the tail node from its 0 position measured as blocks, type double - * @param maxNodeJointAngle The maximum angle a node can rotate in degrees, type double - * @param yAxisInterpolation The interpolation of the Y-axis, type double - * @param headModel The model used for the head node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - * @param bodyModel The model used for the body node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - * @param tailModel The model used for the tail node, type net.jeqo.bloons.balloon.multipart.MultipartBalloonModel - */ - public MultipartBalloonType(String id, String permission, String name, String[] lore, int nodeCount, double distanceBetweenNodes, double headNodeOffset, double bodyNodeOffset, double tailNodeOffset, double maxNodeJointAngle, double yAxisInterpolation, MultipartBalloonModel headModel, MultipartBalloonModel bodyModel, MultipartBalloonModel tailModel) { - this.setId(id); - this.setPermission(permission); - this.setName(name); - this.setLore(lore); - this.setNodeCount(nodeCount); - this.setDistanceBetweenNodes(distanceBetweenNodes); - this.setHeadNodeOffset(headNodeOffset); - this.setBodyNodeOffset(bodyNodeOffset); - this.setTailNodeOffset(tailNodeOffset); - this.setMaxNodeJointAngle(maxNodeJointAngle); - this.setYAxisInterpolation(yAxisInterpolation); - this.setHeadModel(headModel); - this.setBodyModel(bodyModel); - this.setTailModel(tailModel); + this.setId(id); // required + this.setPermission(permission); // required + this.setName(name); // required + this.setLore(lore); // required + if (nodeCount > 0) this.setNodeCount(nodeCount); // 5 by default, optional + if (distanceBetweenNodes > 0.0D) this.setDistanceBetweenNodes(distanceBetweenNodes); // 2.0 by default, optional + if (leashHeight > 0.0D) this.setLeashHeight(leashHeight); // 1.2 by default, optional + this.setHeadNodeOffset(headNodeOffset); // 0 by default, optional + this.setBodyNodeOffset(bodyNodeOffset); // 0 by default, optional + this.setTailNodeOffset(tailNodeOffset); // 0 by default, optional + if (maxNodeJointAngle > 0.0D) this.setMaxNodeJointAngle(maxNodeJointAngle); // 35.0 by default, optional + if (yAxisInterpolation > 0.0D) this.setYAxisInterpolation(yAxisInterpolation); // 0.35 by default, optional + if (turningSplineInterpolation > 0.0D) this.setTurningSplineInterpolation(turningSplineInterpolation); // 0.35 by default, optional + if (passiveSineWaveSpeed > 0.0D) this.setPassiveSineWaveSpeed(passiveSineWaveSpeed); // 0.05 by default, optional + if (passiveSineWaveAmplitude > 0.0D) this.setPassiveSineWaveAmplitude(passiveSineWaveAmplitude); // 0.5 by default, optional + if (passiveNoseSineWaveAmplitude > 0.0D) this.setPassiveNoseSineWaveAmplitude(passiveNoseSineWaveAmplitude); // 0.5 by default, optional + this.setHeadModel(headModel); // required + this.setBodyModel(bodyModel); // required + this.setTailModel(tailModel); // required } } From 7589a80acc643e1813aaf47ff26db5d482b9914e Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 15:52:34 -0400 Subject: [PATCH 20/24] Create more optional fields for multipart balloons --- .../multipart/MultipartBalloonModel.java | 6 ++--- .../multipart/MultipartBalloonType.java | 22 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java b/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java index 0470cef6..c77a7db9 100644 --- a/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java +++ b/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java @@ -23,15 +23,15 @@ public class MultipartBalloonModel { /** * The material used to create the model */ - private String material; + private String material; // required /** * The color of the model */ - private String color; + private String color = "#ffffff"; // optional /** * The custom model data value stored in the item metadata */ - private Integer customModelData; + private Integer customModelData; // required /** * Creates a new model for a multipart balloon diff --git a/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonType.java b/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonType.java index 7daacef3..57713fd8 100644 --- a/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonType.java +++ b/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonType.java @@ -31,51 +31,51 @@ public class MultipartBalloonType { /** * The distance between each node in the balloon measured in blocks */ - private double distanceBetweenNodes = 2.0; // optional + private double distanceBetweenNodes = 2.0D; // optional /** * The height of the leash attached to a player relative from the head of the player in blocks */ - private double leashHeight = 1.2; // optional + private double leashHeight = 1.2D; // optional /** * The offset of the head node from its 0 position measured in blocks */ - private double headNodeOffset = 0.0; // optional + private double headNodeOffset = 0.0D; // optional /** * The offset of the body node from its 0 position measured in blocks */ - private double bodyNodeOffset = 0.0; // optional + private double bodyNodeOffset = 0.0D; // optional /** * The offset of the tail node from its 0 position measured in blocks */ - private double tailNodeOffset = 0.0; // optional + private double tailNodeOffset = 0.0D; // optional /** * The max angle that a segment/node can rotate to in degrees in both directions * This number *2 is equal to the total range of motion for each segment */ - private double maxNodeJointAngle = 35.0; // optional + private double maxNodeJointAngle = 35.0D; // optional /** * The interpolation of the Y-axis motion of every segment */ - private double yAxisInterpolation = 0.35; // optional + private double yAxisInterpolation = 0.35D; // optional /** * The interpolation of the turning spline to prevent overturning and * to enhance smoother turning */ - private double turningSplineInterpolation = 0.35; // optional + private double turningSplineInterpolation = 0.35D; // optional /** * The speed of the passive sine wave animation. This is the amount of blocks it * will move every tick due to the runnable running every tick. */ - private double passiveSineWaveSpeed = 0.05; // optional + private double passiveSineWaveSpeed = 0.05D; // optional /** * The amplitude of the passive sine wave animation. This is the maximum amount of * blocks the balloon will move in the positive and negative direction. */ - private double passiveSineWaveAmplitude = 0.5; // optional + private double passiveSineWaveAmplitude = 0.5D; // optional /** * The amplitude of the passive sine wave animation starting at the nose */ - private double passiveNoseSineWaveAmplitude = 0.5; // optional + private double passiveNoseSineWaveAmplitude = 0.5D; // optional /** * The model used for the head node */ From 2ee79021bf8612efba445291628819ac1bf046e1 Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 16:02:17 -0400 Subject: [PATCH 21/24] Update configuration files --- .../net/jeqo/bloons/balloon/BalloonCore.java | 1 + .../resources/balloons/color_pack_example.yml | 2 +- src/main/resources/balloons/dyeable_example.yml | 16 ++-------------- src/main/resources/balloons/meg_example.yml | 13 +++++++++++++ 4 files changed, 17 insertions(+), 15 deletions(-) create mode 100644 src/main/resources/balloons/meg_example.yml diff --git a/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java b/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java index 48f5c8d2..b05389b0 100644 --- a/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java +++ b/src/main/java/net/jeqo/bloons/balloon/BalloonCore.java @@ -34,6 +34,7 @@ public class BalloonCore { private final String[] exampleBalloons = new String[] { "color_pack_example.yml", "dyeable_example.yml", + "meg_example.yml", "multipart_example.yml" }; diff --git a/src/main/resources/balloons/color_pack_example.yml b/src/main/resources/balloons/color_pack_example.yml index faab8f5c..8b4e968e 100644 --- a/src/main/resources/balloons/color_pack_example.yml +++ b/src/main/resources/balloons/color_pack_example.yml @@ -2,7 +2,7 @@ # It can contain all the way from one balloon to technically an infinite # amount of balloons, as long as the server can handle it. blue: - type: single # The type of balloon, this must be single for single balloons + type: single id: blue permission: balloon.blue material: FLINT diff --git a/src/main/resources/balloons/dyeable_example.yml b/src/main/resources/balloons/dyeable_example.yml index 85be6dba..76c27752 100644 --- a/src/main/resources/balloons/dyeable_example.yml +++ b/src/main/resources/balloons/dyeable_example.yml @@ -5,8 +5,8 @@ dyeable_example: type: single id: dyeable_example permission: balloon.dyeable - leash-height: 1.2 # The height of the balloon leash from about the players head - balloon-height: 2.0 # The height of the balloon from about the players head + leash-height: 1.2 + balloon-height: 2.0 material: LEATHER_HORSE_ARMOR color: '#ffffff' custom-model-data: 1 @@ -15,15 +15,3 @@ dyeable_example: - '&8Bloons Example Balloon' - '' - '&eᴄʟɪᴄᴋ ᴛᴏ ᴇǫᴜɪᴘ' -single_meg_example: - id: single_meg_example - permission: balloon.single_meg_example - meg-model-id: single_meg_example - icon: - material: FLINT - custom-model-data: 7 - name: 'Single MEG Balloon' - lore: - - '&8Bloons Default Balloon' - - '' - - '&eᴄʟɪᴄᴋ ᴛᴏ ᴇǫᴜɪᴘ' diff --git a/src/main/resources/balloons/meg_example.yml b/src/main/resources/balloons/meg_example.yml new file mode 100644 index 00000000..e9ccc306 --- /dev/null +++ b/src/main/resources/balloons/meg_example.yml @@ -0,0 +1,13 @@ +# An example of a MEG balloon which utilizes custom models from ModelEngine +meg_example: + id: meg_example + permission: balloon.meg_example + meg-model-id: meg_example + icon: + material: FLINT + custom-model-data: 7 + name: 'MEG Balloon' + lore: + - '&8Bloons Default Balloon' + - '' + - '&eᴄʟɪᴄᴋ ᴛᴏ ᴇǫᴜɪᴘ' \ No newline at end of file From df5bbb2a92ca91579a82902fdec0bc09e08e0176 Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 16:09:45 -0400 Subject: [PATCH 22/24] Fix color field not being optional for multipart balloon models --- .../jeqo/bloons/balloon/multipart/MultipartBalloonModel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java b/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java index c77a7db9..899c08b0 100644 --- a/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java +++ b/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java @@ -43,7 +43,7 @@ public class MultipartBalloonModel { public MultipartBalloonModel(BalloonSegmentType segmentType, String material, String color, int customModelData) { this.setSegmentType(segmentType); this.setMaterial(material); - this.setColor(color); + if (!color.equals(this.getColor())) this.setColor(color); this.setCustomModelData(customModelData); } From 3fa64e896e512a5ad428db211c8ed5b7465eab06 Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 18:09:58 -0400 Subject: [PATCH 23/24] Fix issues in regards to configurations --- .../jeqo/bloons/balloon/multipart/MultipartBalloonModel.java | 2 +- src/main/resources/balloons/meg_example.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java b/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java index 899c08b0..4717dc45 100644 --- a/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java +++ b/src/main/java/net/jeqo/bloons/balloon/multipart/MultipartBalloonModel.java @@ -43,7 +43,7 @@ public class MultipartBalloonModel { public MultipartBalloonModel(BalloonSegmentType segmentType, String material, String color, int customModelData) { this.setSegmentType(segmentType); this.setMaterial(material); - if (!color.equals(this.getColor())) this.setColor(color); + if (!color.equals(this.getColor()) && color != null && !color.isEmpty()) this.setColor(color); this.setCustomModelData(customModelData); } diff --git a/src/main/resources/balloons/meg_example.yml b/src/main/resources/balloons/meg_example.yml index e9ccc306..4bef83d5 100644 --- a/src/main/resources/balloons/meg_example.yml +++ b/src/main/resources/balloons/meg_example.yml @@ -1,5 +1,6 @@ # An example of a MEG balloon which utilizes custom models from ModelEngine meg_example: + type: single id: meg_example permission: balloon.meg_example meg-model-id: meg_example From f8738c9bf57f841c8133b4a7e3c7263990579b45 Mon Sep 17 00:00:00 2001 From: IanTapply22 Date: Sun, 23 Jun 2024 21:24:57 -0400 Subject: [PATCH 24/24] Fix wiki link being invalid in config.yml --- src/main/resources/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 91ab77a6..f2b04852 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -3,7 +3,7 @@ # Bloons 2.0.0 # Made by Jeqo # -# Wiki: https://jeqo.net/wiki/bloons +# Wiki: https://jeqo.net/wiki # Discord: https://jeqo.net/discord # # Default Assets Made by TwistedDreams