Advertisement
JackOUT

Untitled

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