Advertisement
JackOUT

Untitled

Oct 9th, 2023
854
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 8.86 KB | None | 0 0
  1. package games.coob.laserturrets.util;
  2.  
  3. import games.coob.laserturrets.model.TurretData;
  4. import lombok.Getter;
  5. import lombok.Setter;
  6. import org.bukkit.Location;
  7. import org.bukkit.entity.ArmorStand;
  8. import org.bukkit.entity.Entity;
  9. import org.bukkit.scheduler.BukkitTask;
  10. import org.bukkit.util.Consumer;
  11. import org.mineacademy.fo.Common;
  12. import org.mineacademy.fo.MinecraftVersion;
  13. import org.mineacademy.fo.Valid;
  14. import org.mineacademy.fo.collection.SerializedMap;
  15. import org.mineacademy.fo.model.ConfigSerializable;
  16. import org.mineacademy.fo.remain.CompProperty;
  17. import org.mineacademy.fo.remain.Remain;
  18.  
  19. import java.util.*;
  20.  
  21. public class Hologram implements ConfigSerializable {
  22.  
  23.     /**
  24.      * The distance between each line of lore for this item
  25.      */
  26.     @Getter
  27.     @Setter
  28.     private static double loreLineHeight = 0.26D;
  29.  
  30.     /**
  31.      * A turretData of created animated items
  32.      */
  33.     @Getter
  34.     private static final Set<Hologram> registeredItems = new HashSet<>();
  35.  
  36.     /**
  37.      * The ticking task responsible for calling {@link #onTick()}
  38.      */
  39.     private static volatile BukkitTask tickingTask = null;
  40.  
  41.     /**
  42.      * The armor stand names, each line spawns another invisible stand
  43.      */
  44.     @Getter
  45.     private final List<ArmorStand> loreEntities = new ArrayList<>();
  46.  
  47.     /**
  48.      * The spawning location
  49.      */
  50.     private final Location lastTeleportLocation;
  51.  
  52.     /**
  53.      * The lore over the item
  54.      */
  55.     @Getter
  56.     private final List<String> loreLines = new ArrayList<>();
  57.  
  58.  
  59.     /**
  60.      * The displayed entity
  61.      */
  62.     @Getter
  63.     private Entity entity;
  64.  
  65.     /*
  66.      * A private flag to help with teleporting of this entity
  67.      */
  68.     private Location pendingTeleport = null;
  69.  
  70.     /*
  71.      * Constructs a new item and registers it
  72.      */
  73.     public Hologram(final Location spawnLocation) {
  74.         this.lastTeleportLocation = spawnLocation;
  75.  
  76.         registeredItems.add(this);
  77.  
  78.         onReload();
  79.     }
  80.  
  81.     /**
  82.      * Restart ticking task on reload
  83.      *
  84.      * @deprecated internal use only, do not call
  85.      */
  86.     @Deprecated
  87.     public static void onReload() {
  88.         if (tickingTask != null)
  89.             tickingTask.cancel();
  90.  
  91.         tickingTask = scheduleTickingTask();
  92.     }
  93.  
  94.     /*
  95.      * Helper method to start main anim ticking task
  96.      */
  97.     private static BukkitTask scheduleTickingTask() {
  98.         return Common.runTimer(1, () -> {
  99.  
  100.             for (final Iterator<Hologram> it = registeredItems.iterator(); it.hasNext(); ) {
  101.                 final Hologram model = it.next();
  102.  
  103.                 if (model.isSpawned())
  104.                     if (!model.getEntity().isValid() || model.getEntity().isDead()) {
  105.                         model.removeLore();
  106.                         model.getEntity().remove();
  107.  
  108.                         it.remove();
  109.                     } else
  110.                         model.tick();
  111.             }
  112.         });
  113.     }
  114.  
  115.     /**
  116.      * Spawns this hologram entity
  117.      *
  118.      * @return
  119.      */
  120.     public Hologram spawn() {
  121.         Valid.checkBoolean(!this.isSpawned(), this + " is already spawned!");
  122.  
  123.         this.entity = this.createEntity();
  124.         Valid.checkNotNull(this.entity, "Failed to spawn entity from " + this);
  125.  
  126.         this.drawLore(this.getLastTeleportLocation());
  127.  
  128.         return this;
  129.     }
  130.  
  131.     /**
  132.      * Core implementation method to spawn your entity
  133.      *
  134.      * @return
  135.      */
  136.     private ArmorStand createEntity() {
  137.         final Location location = this.getLastTeleportLocation();
  138.         final ArmorStand armorStand;
  139.  
  140.         if (MinecraftVersion.atLeast(MinecraftVersion.V.v1_11)) {
  141.             final Consumer<ArmorStand> consumer = stand -> {
  142.                 stand.setMarker(true);
  143.                 CompProperty.GRAVITY.apply(stand, false);
  144.                 stand.setSmall(true);
  145.                 stand.setVisible(false);
  146.             };
  147.  
  148.             armorStand = location.getWorld().spawn(location, ArmorStand.class, consumer);
  149.         } else {
  150.             final ArmorStand stand = location.getWorld().spawn(location, ArmorStand.class);
  151.  
  152.             CompProperty.GRAVITY.apply(stand, false);
  153.             stand.setVisible(false);
  154.             stand.setMarker(true);
  155.             stand.setSmall(true);
  156.  
  157.             armorStand = stand;
  158.         }
  159.  
  160.         return armorStand;
  161.     }
  162.  
  163.     private ArmorStand createLoreEntity(final Location location) {
  164.         final ArmorStand armorStand;
  165.  
  166.         if (MinecraftVersion.atLeast(MinecraftVersion.V.v1_11)) {
  167.             final Consumer<ArmorStand> consumer = stand -> {
  168.                 stand.setMarker(true);
  169.                 CompProperty.GRAVITY.apply(stand, false);
  170.                 stand.setSmall(true);
  171.                 stand.setVisible(false);
  172.             };
  173.  
  174.             armorStand = location.getWorld().spawn(location, ArmorStand.class, consumer);
  175.         } else {
  176.             armorStand = location.getWorld().spawn(location, ArmorStand.class);
  177.  
  178.             armorStand.setMarker(true);
  179.             CompProperty.GRAVITY.apply(armorStand, false);
  180.             armorStand.setSmall(true);
  181.             armorStand.setVisible(false);
  182.         }
  183.  
  184.         this.loreEntities.add(armorStand);
  185.         return armorStand;
  186.     }
  187.  
  188.     /*
  189.      * Set a lore for this armor stand
  190.      */
  191.     public void drawLore(Location location) {
  192.         if (this.loreLines.isEmpty())
  193.             return;
  194.  
  195.         if (this.entity instanceof ArmorStand && ((ArmorStand) this.entity).isSmall())
  196.             location = location.clone().add(0, -0.5, 0);
  197.  
  198.         for (final String loreLine : this.loreLines) {
  199.             final ArmorStand armorStand = createLoreEntity(location);
  200.  
  201.             Remain.setCustomName(armorStand, loreLine);
  202.             location = location.subtract(0, loreLineHeight, 0);
  203.         }
  204.     }
  205.  
  206.     /*
  207.      * Iterate the ticking mechanism of this entity
  208.      */
  209.     private void tick() {
  210.  
  211.         if (this.pendingTeleport != null) {
  212.             this.entity.teleport(this.pendingTeleport);
  213.  
  214.             for (final ArmorStand loreEntity : this.loreEntities)
  215.                 loreEntity.teleport(this.pendingTeleport);
  216.  
  217.             this.pendingTeleport = null;
  218.             return;
  219.         }
  220.  
  221.         this.onTick();
  222.     }
  223.  
  224.     /**
  225.      * Called automatically where you can animate this armor stand
  226.      */
  227.     protected void onTick() {
  228.     }
  229.  
  230.     /**
  231.      * Return true if this armor stand is spawned
  232.      *
  233.      * @return
  234.      */
  235.     public final boolean isSpawned() {
  236.         return this.entity != null && this.entity.isValid();
  237.     }
  238.  
  239.     /**
  240.      * Deletes all text that the armor stand has
  241.      */
  242.     public final void removeLore() {
  243.         this.loreEntities.forEach(ArmorStand::remove);
  244.     }
  245.  
  246.     /**
  247.      * @param lore
  248.      */
  249.     public final void setLore(final String... lore) {
  250.         this.loreLines.clear();
  251.         this.loreLines.addAll(Arrays.asList(lore));
  252.     }
  253.  
  254.     /**
  255.      * Return the current armor stand location
  256.      *
  257.      * @return
  258.      */
  259.     public final Location getLocation() {
  260.         this.checkSpawned("getLocation");
  261.  
  262.         return this.entity.getLocation();
  263.     }
  264.  
  265.     /**
  266.      * Return the last known teleport location
  267.      *
  268.      * @return
  269.      */
  270.     public final Location getLastTeleportLocation() {
  271.         return this.lastTeleportLocation.clone();
  272.     }
  273.  
  274.     /**
  275.      * Teleport this hologram with its lores to the given location
  276.      *
  277.      * @param location
  278.      */
  279.     public final void teleport(final Location location) {
  280.         Valid.checkBoolean(this.pendingTeleport == null, this + " is already pending teleport to " + this.pendingTeleport);
  281.         this.checkSpawned("teleport");
  282.  
  283.         this.lastTeleportLocation.setX(location.getY());
  284.         this.lastTeleportLocation.setY(location.getY());
  285.         this.lastTeleportLocation.setZ(location.getZ());
  286.  
  287.         this.pendingTeleport = location;
  288.     }
  289.  
  290.     /**
  291.      * Deletes this armor stand
  292.      */
  293.     public final void remove() {
  294.         for (final Entity entity : this.loreEntities)
  295.             entity.remove();
  296.  
  297.         this.loreEntities.clear();
  298.  
  299.         if (this.entity != null)
  300.             this.entity.remove();
  301.  
  302.         registeredItems.remove(this);
  303.     }
  304.  
  305.     public final void updateLore(final String... loreLines) {
  306.         final List<String> list = new ArrayList<>(Arrays.asList(loreLines));
  307.  
  308.         for (int i = 0; i < list.size(); i++) {
  309.             if (this.getLoreEntities().get(i) == null)
  310.                 this.getLoreEntities().add(this.createLoreEntity(this.getLoreEntities().get(i - 1).getLocation()));
  311.  
  312.             Remain.setCustomName(this.getLoreEntities().get(i), list.get(i));
  313.         }
  314.  
  315.         this.setLore(loreLines);
  316.     }
  317.  
  318.     /*
  319.      * A helper method to check if this entity is spawned
  320.      */
  321.     private void checkSpawned(final String method) {
  322.         Valid.checkBoolean(this.isSpawned(), this + " is not spawned, cannot call " + method + "!");
  323.     }
  324.  
  325.     /**
  326.      * @see java.lang.Object#toString()
  327.      */
  328.     @Override
  329.     public String toString() {
  330.         return "ArmorStandItem{spawnLocation=" + Common.shortLocation(this.lastTeleportLocation) + ", spawned=" + this.isSpawned() + "}";
  331.     }
  332.  
  333.     /**
  334.      * Deletes all floating items on the server
  335.      */
  336.     public static void deleteAll() {
  337.         final Set<Hologram> holograms = new HashSet<>();
  338.  
  339.         for (final TurretData turretData : TurretData.getTurrets())
  340.             holograms.add(turretData.getHologram());
  341.  
  342.         for (final Iterator<Hologram> it = holograms.iterator(); it.hasNext(); ) {
  343.             final Hologram item = it.next();
  344.  
  345.             item.remove();
  346.             it.remove();
  347.         }
  348.     }
  349.  
  350.     public static Hologram deserialize(final SerializedMap map) {
  351.         final Location location = map.getLocation("Location");
  352.         final String[] lines = map.getStringList("Lore").toArray(new String[0]);
  353.  
  354.         final Hologram hologram = new Hologram(location.clone().add(0.5, 0.5, 0.5));
  355.  
  356.         hologram.setLore(lines);
  357.  
  358.         return hologram;
  359.     }
  360.  
  361.     @Override
  362.     public SerializedMap serialize() {
  363.         final SerializedMap map = new SerializedMap();
  364.  
  365.         map.put("Location", this.lastTeleportLocation);
  366.         map.put("Lore", this.loreLines);
  367.  
  368.         return map;
  369.     }
  370. }
  371.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement