diff --git a/build.gradle.kts b/build.gradle.kts index 5df82304..183c9dab 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -53,7 +53,7 @@ dependencies { compileOnly("org.jetbrains:annotations:23.0.0") compileOnly("com.comphenix.protocol:ProtocolLib:5.0.0-SNAPSHOT") compileOnly("me.clip:placeholderapi:2.11.1") - compileOnly("com.ticxo.modelengine:api:R3.0.0") + compileOnly("com.ticxo.modelengine:api:R3.0.1") implementation("net.kyori:adventure-api:4.11.0") implementation ("net.kyori:adventure-text-minimessage:4.11.0") implementation("net.kyori:adventure-platform-bukkit:4.1.2") diff --git a/src/main/java/com/hibiscusmc/hmccosmetics/HMCCosmeticsPlugin.java b/src/main/java/com/hibiscusmc/hmccosmetics/HMCCosmeticsPlugin.java index 08136f1d..677e040c 100644 --- a/src/main/java/com/hibiscusmc/hmccosmetics/HMCCosmeticsPlugin.java +++ b/src/main/java/com/hibiscusmc/hmccosmetics/HMCCosmeticsPlugin.java @@ -31,8 +31,8 @@ public final class HMCCosmeticsPlugin extends JavaPlugin { instance = this; // File setup - saveDefaultConfig(); if (!getDataFolder().exists()) { + saveDefaultConfig(); saveResource("translations.yml", false); saveResource("messages.yml", false); saveResource("cosmetics/examplecosmetics.yml", false); @@ -77,7 +77,7 @@ public final class HMCCosmeticsPlugin extends JavaPlugin { })) .build(); try { - Settings.load(loader.load().node("")); + Settings.load(loader.load()); WardrobeSettings.load(loader.load().node("wardrobe")); DatabaseSettings.load(loader.load().node("database-settings")); } catch (ConfigurateException e) { diff --git a/src/main/java/com/hibiscusmc/hmccosmetics/config/Settings.java b/src/main/java/com/hibiscusmc/hmccosmetics/config/Settings.java index c8a682fb..52a59c6e 100644 --- a/src/main/java/com/hibiscusmc/hmccosmetics/config/Settings.java +++ b/src/main/java/com/hibiscusmc/hmccosmetics/config/Settings.java @@ -45,7 +45,6 @@ public class Settings { plugin.getLogger().severe("Problems will happen with the plugin! Delete and regenerate a new one!"); plugin.getLogger().severe(""); plugin.getLogger().severe(""); - return; } ConfigurationNode cosmeticSettings = source.node(COSMETIC_SETTINGS_PATH); @@ -61,9 +60,7 @@ public class Settings { final var balloonSection = cosmeticSettings.node(BALLOON_OFFSET); - if (balloonSection != null) { - balloonOffset = loadVector(balloonSection); - } + balloonOffset = loadVector(balloonSection); } private static Vector loadVector(final ConfigurationNode config) { @@ -92,6 +89,7 @@ public class Settings { } public static Vector getBalloonOffset() { + if (balloonOffset == null) HMCCosmeticsPlugin.getInstance().getLogger().info("Shits null"); return balloonOffset; } diff --git a/src/main/java/com/hibiscusmc/hmccosmetics/cosmetic/types/CosmeticBalloonType.java b/src/main/java/com/hibiscusmc/hmccosmetics/cosmetic/types/CosmeticBalloonType.java index 2a0bc668..df7ace5f 100644 --- a/src/main/java/com/hibiscusmc/hmccosmetics/cosmetic/types/CosmeticBalloonType.java +++ b/src/main/java/com/hibiscusmc/hmccosmetics/cosmetic/types/CosmeticBalloonType.java @@ -3,44 +3,42 @@ package com.hibiscusmc.hmccosmetics.cosmetic.types; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.config.Settings; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; +import com.hibiscusmc.hmccosmetics.entities.MEGEntity; import com.hibiscusmc.hmccosmetics.user.CosmeticUser; +import com.hibiscusmc.hmccosmetics.util.PlayerUtils; +import com.hibiscusmc.hmccosmetics.util.packets.PacketManager; import com.ticxo.modelengine.api.ModelEngineAPI; import com.ticxo.modelengine.api.generator.model.ModelBlueprint; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; +import org.bukkit.util.Vector; import org.spongepowered.configurate.ConfigurationNode; public class CosmeticBalloonType extends Cosmetic { - private ModelBlueprint model; + private String modelName; public CosmeticBalloonType(String id, ConfigurationNode config) { super(id, config); String modelId = config.node("model").getString(); - HMCCosmeticsPlugin.getInstance().getLogger().info("Attempting Spawning"); - if (ModelEngineAPI.api.getModelRegistry().getBlueprint(modelId) == null) { - HMCCosmeticsPlugin.getInstance().getLogger().warning("Invalid Model Engine Blueprint " + id); - HMCCosmeticsPlugin.getInstance().getLogger().warning("Possible Blueprints" + ModelEngineAPI.api.getModelRegistry().getAllBlueprintId()); - return; - } - this.model = ModelEngineAPI.api.getModelRegistry().getBlueprint(modelId); + this.modelName = modelId; } @Override public void update(CosmeticUser user) { Player player = Bukkit.getPlayer(user.getUniqueId()); - Location loc = player.getLocation().clone(); - loc.add(Settings.getBalloonOffset()); - user.getBalloonEntity().setLocation(loc); + user.getBalloonEntity().setLocation(player.getLocation().clone()); - //user.getBackpackEntity().getBukkitLivingEntity().setRotation(loc.getYaw(), loc.getPitch()); + user.getBalloonEntity().updateModel(); + //PacketManager.sendTeleportPacket(user.getBalloonEntity().getBalloonID(), actual, false, PlayerUtils.getNearbyPlayers(player)); + //PacketManager.sendLeashPacket(user.getBalloonEntity().getBalloonID(), player.getEntityId(), PlayerUtils.getNearbyPlayers(player)); } - public ModelBlueprint getModel() { - return this.model; + public String getModelName() { + return this.modelName; } } diff --git a/src/main/java/com/hibiscusmc/hmccosmetics/entities/BalloonEntity.java b/src/main/java/com/hibiscusmc/hmccosmetics/entities/BalloonEntity.java new file mode 100644 index 00000000..e17f8f14 --- /dev/null +++ b/src/main/java/com/hibiscusmc/hmccosmetics/entities/BalloonEntity.java @@ -0,0 +1,107 @@ +package com.hibiscusmc.hmccosmetics.entities; + +import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; +import com.hibiscusmc.hmccosmetics.config.Settings; +import com.ticxo.modelengine.api.ModelEngineAPI; +import com.ticxo.modelengine.api.model.ActiveModel; +import com.ticxo.modelengine.api.model.ModeledEntity; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.UUID; + +public class BalloonEntity { + + private final int balloonID; + private final MEGEntity megEntity; + + public BalloonEntity(int balloonID, Location location) { + this.balloonID = balloonID; + this.megEntity = new MEGEntity(UUID.randomUUID(), balloonID, new Vector(0, 0, 0), location.add(Settings.getBalloonOffset()), false); + } + + public void updateModel() { + final ModeledEntity model = ModelEngineAPI.api.getModeledEntity(megEntity.getUniqueId()); + + if (model == null) return; + + if (model.getBase() instanceof final MEGEntity e) { + HMCCosmeticsPlugin.getInstance().getLogger().info("Updated Model"); + e.update(this); + } + } + + public void spawnModel(final String id) { + HMCCosmeticsPlugin.getInstance().getLogger().info("Attempting Spawning for " + id); + if (ModelEngineAPI.api.getModelRegistry().getBlueprint(id) == null) { + HMCCosmeticsPlugin.getInstance().getLogger().warning("Invalid Model Engine Blueprint " + id); + return; + } + HMCCosmeticsPlugin.getInstance().getLogger().warning("Possible Blueprints" + ModelEngineAPI.api.getModelRegistry().getAllBlueprintId()); + ActiveModel model = ModelEngineAPI.api.createActiveModelImpl(ModelEngineAPI.api.getModelRegistry().getBlueprint(id)); + ModeledEntity modeledEntity = ModelEngineAPI.api.createModeledEntityImpl(megEntity); + modeledEntity.setRenderRadius(32); + modeledEntity.addModel(model, false); + } + + public void remove() { + final ModeledEntity entity = ModelEngineAPI.api.getModeledEntity(megEntity.getUniqueId()); + + if (entity == null) return; + + for (final Player player : entity.getRangeManager().getPlayerInRange()) { + entity.hideFromPlayer(player); + } + + ModelEngineAPI.removeModeledEntity(megEntity.getUniqueId()); + entity.destroy(); + } + + public void addPlayerToModel(final Player player, final String id) { + final ModeledEntity model = ModelEngineAPI.api.getModeledEntity(megEntity.getUniqueId()); + if (model == null) { + this.spawnModel(id); + return; + } + //if (megEntity.getRangeManager().getPlayerInRange().contains(player)) return; + model.showToPlayer(player); + } + + public void removePlayerFromModel(final Player player) { + final ModeledEntity model = ModelEngineAPI.api.getModeledEntity(megEntity.getUniqueId()); + + if (model == null) return; + + model.hideFromPlayer(player); + } + + + public int getBalloonID() { + return balloonID; + } + + public UUID getUniqueID() { + return megEntity.getUniqueId(); + } + + public Location getLocation() { + return this.megEntity.getLocation(); + } + + public boolean isAlive() { + return this.megEntity.isAlive(); + } + + public void setLocation(Location location) { + this.megEntity.setLocation(location); + } + + public void setVelocity(Vector vector) { + this.megEntity.setVelocity(vector); + } + + public void setAlive(boolean alive) { + this.megEntity.setAlive(alive); + } +} diff --git a/src/main/java/com/hibiscusmc/hmccosmetics/entities/MEGEntity.java b/src/main/java/com/hibiscusmc/hmccosmetics/entities/MEGEntity.java index 6938393d..5d2ad67b 100644 --- a/src/main/java/com/hibiscusmc/hmccosmetics/entities/MEGEntity.java +++ b/src/main/java/com/hibiscusmc/hmccosmetics/entities/MEGEntity.java @@ -37,7 +37,7 @@ public class MEGEntity implements BaseEntity { private List passengers; private RangeManager rangeManager; - protected MEGEntity(final UUID uuid, final int entityId, final Vector velocity, final Location location, final boolean alive) { + public MEGEntity(final UUID uuid, final int entityId, final Vector velocity, final Location location, final boolean alive) { this.uuid = uuid; this.entityId = entityId; this.velocity = velocity; @@ -45,29 +45,20 @@ public class MEGEntity implements BaseEntity { this.alive = alive; this.rotationController = new DefaultBodyRotationController(this); this.passengers = new ArrayList<>(); - this.rangeManager = new EmptyRangeManager(); - this.rangeManager.setRenderDistance(16); + //this.rangeManager = new EmptyRangeManager(); + //this.rangeManager.setRenderDistance(32); } - protected MEGEntity(final UUID uuid, final int entityId) { + public MEGEntity(final UUID uuid, final int entityId) { this.uuid = uuid; this.entityId = entityId; this.alive = false; } - public void update() { - this.velocity = getLocation().toVector(); - this.location = getLocation(); - this.alive = isAlive(); - } - - - public void updateModel() { - final ModeledEntity model = ModelEngineAPI.api.getModeledEntity(getUniqueId()); - - if (model == null) return; - - if (model.getBase() instanceof final MEGEntity e) e.update(); + public void update(BalloonEntity entity) { + this.velocity = entity.getLocation().toVector(); + this.location = entity.getLocation(); + this.alive = entity.isAlive(); } public void spawnModel(final String id) { diff --git a/src/main/java/com/hibiscusmc/hmccosmetics/user/CosmeticUser.java b/src/main/java/com/hibiscusmc/hmccosmetics/user/CosmeticUser.java index 49456338..5936c4b4 100644 --- a/src/main/java/com/hibiscusmc/hmccosmetics/user/CosmeticUser.java +++ b/src/main/java/com/hibiscusmc/hmccosmetics/user/CosmeticUser.java @@ -5,15 +5,22 @@ import com.hibiscusmc.hmccosmetics.config.WardrobeSettings; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot; import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBackpackType; +import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBalloonType; +import com.hibiscusmc.hmccosmetics.entities.BalloonEntity; import com.hibiscusmc.hmccosmetics.entities.InvisibleArmorstand; import com.hibiscusmc.hmccosmetics.entities.MEGEntity; import com.hibiscusmc.hmccosmetics.util.PlayerUtils; +import com.ticxo.modelengine.api.ModelEngineAPI; +import com.ticxo.modelengine.api.model.ActiveModel; +import com.ticxo.modelengine.api.model.ModeledEntity; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EquipmentSlot; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v1_19_R1.CraftWorld; import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack; import org.bukkit.entity.Player; import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.util.Vector; import java.util.Collection; import java.util.HashMap; @@ -26,7 +33,7 @@ public class CosmeticUser { private HashMap playerCosmetics = new HashMap<>(); private Wardrobe wardrobe; private InvisibleArmorstand invisibleArmorstand; - private MEGEntity balloonEntity; + private BalloonEntity balloonEntity; public CosmeticUser(UUID uuid) { @@ -52,7 +59,7 @@ public class CosmeticUser { public InvisibleArmorstand getBackpackEntity() { return this.invisibleArmorstand; } - public MEGEntity getBalloonEntity() { + public BalloonEntity getBalloonEntity() { return this.balloonEntity; } @@ -62,12 +69,19 @@ public class CosmeticUser { CosmeticBackpackType backpackType = (CosmeticBackpackType) cosmetic; spawnBackpack(backpackType); } + if (cosmetic.getSlot() == CosmeticSlot.BALLOON) { + CosmeticBalloonType balloonType = (CosmeticBalloonType) cosmetic; + spawnBalloon(balloonType); + } } public void removeCosmeticSlot(CosmeticSlot slot) { if (slot == CosmeticSlot.BACKPACK) { despawnBackpack(); } + if (slot == CosmeticSlot.BALLOON) { + despawnBalloon(); + } playerCosmetics.remove(slot); } @@ -149,6 +163,26 @@ public class CosmeticUser { } + public void spawnBalloon(CosmeticBalloonType cosmeticBalloonType) { + Player player = Bukkit.getPlayer(getUniqueId()); + List sentTo = PlayerUtils.getNearbyPlayers(player.getLocation()); + + if (this.balloonEntity != null) return; + BalloonEntity balloonEntity1 = new BalloonEntity(Entity.nextEntityId(), player.getLocation()); + + balloonEntity1.spawnModel(cosmeticBalloonType.getModelName()); + balloonEntity1.addPlayerToModel(player, cosmeticBalloonType.getModelName()); + + this.balloonEntity = balloonEntity1; + } + + public void despawnBalloon() { + if (this.balloonEntity == null) return; + + this.balloonEntity.remove(); + this.balloonEntity = null; + } + public void despawnBackpack() { Player player = Bukkit.getPlayer(getUniqueId()); if (invisibleArmorstand == null) return; diff --git a/src/main/java/com/hibiscusmc/hmccosmetics/util/packets/PacketManager.java b/src/main/java/com/hibiscusmc/hmccosmetics/util/packets/PacketManager.java index 46b7e7cb..cd3ef422 100644 --- a/src/main/java/com/hibiscusmc/hmccosmetics/util/packets/PacketManager.java +++ b/src/main/java/com/hibiscusmc/hmccosmetics/util/packets/PacketManager.java @@ -24,6 +24,7 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.UUID; @@ -319,4 +320,49 @@ public class PacketManager extends BasePacket { info.setData(List.of(new PlayerInfoData(new WrappedGameProfile(uuid, player.getName()), 0, EnumWrappers.NativeGameMode.CREATIVE, WrappedChatComponent.fromText(name)))); for (final Player p : sendTo) sendPacket(p, info.getHandle()); } + + /** + * Sends a leash packet, useful for balloons! + * @param leashedEntity Entity being leashed (ex. a horse) + * @param entityId Entity this is affecting (ex. a player) + * @param sendTo Whom to send the packet to + */ + public static void sendLeashPacket( + final int leashedEntity, + final int entityId, + final List sendTo + ) { + for (final Player p : sendTo) { + PacketContainer packet = new PacketContainer(PacketType.Play.Server.ATTACH_ENTITY); + packet.getIntegers().write(0, leashedEntity); + packet.getIntegers().write(1, entityId); + sendPacket(p, packet); + } + } + + /** + * Used when a player is sent 8+ blocks. + * @param entityId Entity this affects + * @param location Location a player is being teleported to + * @param onGround If the packet is on the ground + * @param sendTo Whom to send the packet to + */ + public static void sendTeleportPacket( + final int entityId, + final Location location, + boolean onGround, + final List sendTo + ) { + PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT); + packet.getIntegers().write(0, entityId); + packet.getDoubles().write(0, location.getX()); + packet.getDoubles().write(1, location.getY()); + packet.getDoubles().write(2, location.getZ()); + packet.getBytes().write(0, (byte) (location.getYaw() * 256.0F / 360.0F)); + packet.getBytes().write(1, (byte) (location.getPitch() * 256.0F / 360.0F)); + packet.getBooleans().write(0, onGround); + for (final Player p : sendTo) { + sendPacket(p, packet); + } + } } diff --git a/src/main/resources/cosmetics/examplecosmetics.yml b/src/main/resources/cosmetics/examplecosmetics.yml index c5de8c6e..72f23a05 100644 --- a/src/main/resources/cosmetics/examplecosmetics.yml +++ b/src/main/resources/cosmetics/examplecosmetics.yml @@ -27,4 +27,4 @@ colorfulbackpack: model-data: 4 colorfulballoon: slot: BALLOON - model: green_balloon + model: beach_ball_balloon