Created
October 19, 2015 02:44
-
-
Save aikar/9d2827799e3772b8ab62 to your computer and use it in GitHub Desktop.
Empire Minecraft Hologram System
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2015. Starlis LLC / dba Empire Minecraft | |
* | |
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval | |
* | |
*/ | |
package com.empireminecraft.systems.holograms; | |
import com.empireminecraft.config.meta.PersistentMetaKey; | |
import com.empireminecraft.entityai.EntityAIApi; | |
import com.empireminecraft.metaapi.MetaApi; | |
import com.empireminecraft.util.ItemUtil; | |
import com.empireminecraft.util.Util; | |
import lombok.Data; | |
import org.bukkit.Location; | |
import org.bukkit.Material; | |
import org.bukkit.entity.ArmorStand; | |
import org.bukkit.entity.Entity; | |
import org.bukkit.entity.EntityType; | |
import org.bukkit.inventory.ItemStack; | |
import org.bukkit.inventory.meta.BookMeta; | |
import java.util.ArrayList; | |
import java.util.Collection; | |
import java.util.List; | |
import java.util.UUID; | |
import static org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.FORCE; | |
@Data | |
public class Hologram { | |
private static final double DIST_BETWEEN_LINES = 0.225; | |
public final String id; | |
Location loc; | |
List<String> lines = new ArrayList<>(); | |
final ItemStack book; | |
public Hologram(Location loc) { | |
id = UUID.randomUUID().toString(); | |
this.loc = loc; | |
lines.add(""); | |
this.book = makeBook(); | |
} | |
public Hologram(Entity entity) { | |
id = getId(entity); | |
loc = Util.stringToLocation((String) MetaApi.getEntityMeta(entity, PersistentMetaKey.HOLOGRAM_LOC), entity.getWorld()); | |
final MetaApi.MetaList<String> pages = MetaApi.getEntityMeta(entity, PersistentMetaKey.HOLOGRAM_PAGES); | |
lines.addAll(pages); | |
this.book = makeBook(); | |
} | |
public Hologram(ItemStack book) { | |
if (book == null || book.getType() != Material.BOOK_AND_QUILL) { | |
throw new IllegalStateException("Not a Hologram"); | |
} | |
id = ItemUtil.getMeta(book, PersistentMetaKey.HOLOGRAM_ID); | |
if (id == null) { | |
throw new IllegalStateException("Invalid ID"); | |
} | |
loc = Util.stringToLocation(ItemUtil.getMeta(book, PersistentMetaKey.HOLOGRAM_LOC)); | |
if (loc == null) { | |
throw new IllegalStateException("Invalid Location"); | |
} | |
lines = ((BookMeta) book.getItemMeta()).getPages(); | |
ItemUtil.setMeta(book, PersistentMetaKey.HOLOGRAM_ID, id); | |
this.book = book; | |
} | |
public static boolean isHologram(ItemStack item) { | |
return item != null && item.getType() == Material.BOOK_AND_QUILL | |
&& ItemUtil.getMeta(item, PersistentMetaKey.HOLOGRAM_ID) != null; | |
} | |
public static boolean isHologram(Entity entity) { | |
return entity != null && getId(entity) != null; | |
} | |
public ItemStack makeBook() { | |
ItemStack book = new ItemStack(Material.BOOK_AND_QUILL); | |
final ItemUtil.LoreBuilder lore = ItemUtil.buildLore(book) | |
.setName("&5Hologram Editor") | |
.add(Util.blockLocationToString(loc)) | |
.empty(); | |
for (int i = 0; i < lines.size() && i < 2; i++) { | |
lore.add(lines.get(i)); | |
} | |
lore.setMeta(PersistentMetaKey.HOLOGRAM_ID, id) | |
.setMeta(PersistentMetaKey.HOLOGRAM_LOC, Util.fullLocationToString(loc)) | |
.makeSoulbound() | |
.save(); | |
// Set a page or it breaks on rename | |
BookMeta meta = (BookMeta) book.getItemMeta(); | |
meta.setPages(lines); | |
book.setItemMeta(meta); | |
return book; | |
} | |
public static void setId(Entity entity, String id) { | |
MetaApi.setEntityMeta(entity, PersistentMetaKey.HOLOGRAM_ID, id); | |
} | |
public static String getId(Entity entity) { | |
return MetaApi.getEntityMeta(entity, PersistentMetaKey.HOLOGRAM_ID); | |
} | |
private static Entity addLine(Location loc, final String line, final String id) { | |
return loc.getWorld().spawnEntity(loc, EntityType.ARMOR_STAND, FORCE, input -> { | |
ArmorStand entity = (ArmorStand) input; | |
entity.setVisible(false); | |
entity.setGravity(false); | |
entity.setSmall(true); | |
entity.setCustomName(Util.color(line)); | |
entity.setCustomNameVisible(true); | |
entity.setMarker(true); | |
EntityAIApi.setEntitySize(entity, 0, 0); | |
EntityAIApi.setDisabledSlots(entity, 2039583); | |
EntityAIApi.setDisabledEntity(entity, true); | |
setId(input, id); | |
return false; | |
}); | |
} | |
public void update(BookMeta meta) { | |
lines = meta.getPages(); | |
refresh(); | |
} | |
public void refresh() { | |
removeEntities(); | |
final String locStr = Util.fullLocationToString(loc); | |
Location first = loc.clone().add(0, ((lines.size() / 2) * DIST_BETWEEN_LINES) - 0.75, 0); | |
boolean stored = false; | |
for (String line : lines) { | |
final Entity entity = addLine(first.clone(), line, id); | |
if (!stored) { | |
final MetaApi.MetaList<String> pages = new MetaApi.MetaList<>(); | |
pages.addAll(lines); | |
MetaApi.setEntityMeta(entity, PersistentMetaKey.HOLOGRAM_PAGES, pages); | |
MetaApi.setEntityMeta(entity, PersistentMetaKey.HOLOGRAM_LOC, locStr); | |
stored = true; | |
} | |
first.subtract(0, DIST_BETWEEN_LINES, 0); | |
} | |
} | |
public void removeEntities() { | |
final Collection<Entity> nearby = loc.getWorld().getNearbyEntities(loc, 3, 256, 3); | |
for (Entity entity : nearby) { | |
if (isHologram(entity)) { | |
if (getId(entity).equals(id)) { | |
deinitialize(entity); | |
entity.remove(); | |
} | |
} | |
} | |
} | |
public static void deinitialize(Entity entity) { | |
// Leave this in to clean up old horse holograms incase any are missed. | |
EntityAIApi.setDisabledEntity(entity, false); | |
final Entity vehicle = entity.getVehicle(); | |
if (vehicle != null) { | |
EntityAIApi.setDisabledEntity(vehicle, false); | |
vehicle.eject(); | |
vehicle.remove(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2015. Starlis LLC / dba Empire Minecraft | |
* | |
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval | |
* | |
*/ | |
package com.empireminecraft.systems.holograms; | |
import com.empireminecraft.commands.features.HologramCommand; | |
import com.empireminecraft.config.meta.PersistentMetaKey; | |
import com.empireminecraft.customevents.EntityEvents; | |
import com.empireminecraft.metaapi.MetaApi; | |
import com.empireminecraft.util.BukkitUtil; | |
import com.empireminecraft.util.UserUtil; | |
import com.empireminecraft.util.Util; | |
import org.bukkit.Chunk; | |
import org.bukkit.Location; | |
import org.bukkit.entity.ArmorStand; | |
import org.bukkit.entity.Entity; | |
import org.bukkit.entity.Player; | |
import org.bukkit.event.EventHandler; | |
import org.bukkit.event.player.PlayerEditBookEvent; | |
import org.bukkit.inventory.ItemStack; | |
import org.bukkit.inventory.meta.BookMeta; | |
import org.bukkit.inventory.meta.ItemMeta; | |
public class HologramManager { | |
public static void initialize() { | |
new HologramCommand(); | |
new BukkitUtil.Listener() { | |
@EventHandler | |
public void onEntitySpawn(EntityEvents.EntitySpawnEvent event) { | |
final Entity entity = event.getEntity(); | |
if (Hologram.isHologram(entity)) { | |
if (MetaApi.getEntityMeta(entity, PersistentMetaKey.HOLOGRAM_PAGES) != null) { | |
// Rebuild it with latest code. | |
final Hologram hologram = new Hologram(entity); | |
final Chunk chunk = entity.getLocation().getChunk(); | |
BukkitUtil.runTaskNextTick(() -> { | |
if (chunk.isLoaded()) { | |
hologram.refresh(); | |
} | |
}); | |
} | |
} | |
} | |
@EventHandler | |
public void onBookChange(PlayerEditBookEvent event) { | |
final Player player = event.getPlayer(); | |
if (!UserUtil.isSrStaff(player)) { | |
return; | |
} | |
final ItemStack item = player.getInventory().getItem(event.getSlot()); | |
if (Hologram.isHologram(item)) { | |
final BookMeta newBookMeta = event.getNewBookMeta(); | |
if (newBookMeta.getPageCount() == 0) { | |
newBookMeta.setPages(""); | |
} | |
final Hologram hologram = getHologram(item); | |
if (hologram != null) { | |
hologram.update(newBookMeta); | |
Util.log(player.getName() + " updated hologram at " + Util.blockLocationToString(hologram.loc) + " to " + Util.join( | |
hologram.lines.toArray(new String[hologram.lines.size()]), ",")); | |
final ItemMeta itemMeta = hologram.makeBook().getItemMeta(); | |
itemMeta.setDisplayName(newBookMeta.getDisplayName()); | |
event.setNewBookMeta((BookMeta) itemMeta); | |
} | |
} | |
} | |
}; | |
} | |
public static Hologram getHologram(ItemStack item) { | |
if (!Hologram.isHologram(item)) { | |
return null; | |
} | |
return new Hologram(item); | |
} | |
public static void createHologram(Player player, Location loc) { | |
Hologram holo = new Hologram(loc); | |
UserUtil.givePlayerItem(player, holo.getBook()); | |
Util.sendMsg(player, "&aEdit the book you received to manage this hologram."); | |
} | |
public static void getEditBooks(Player player) { | |
Location loc = player.getLocation(); | |
for (ArmorStand armorStand : loc.getWorld().getNearbyEntitiesByType(ArmorStand.class, loc, 3, 5, 3)) { | |
if (Hologram.isHologram(armorStand)) { | |
try { | |
if (MetaApi.getEntityMeta(armorStand, PersistentMetaKey.HOLOGRAM_PAGES) != null) { | |
final Hologram hologram = new Hologram(armorStand); | |
UserUtil.givePlayerItem(player, hologram.getBook()); | |
} | |
} catch (IllegalStateException ignored) { | |
Util.sendMsg(player, "&cFound a weird hologram"); | |
Util.printException(ignored); | |
} | |
} | |
} | |
} | |
public static void deleteHologram(Player player) { | |
final ItemStack itemInHand = player.getItemInHand(); | |
if (Hologram.isHologram(itemInHand)) { | |
try { | |
new Hologram(itemInHand).removeEntities(); | |
} catch (IllegalStateException ignored) { | |
Util.printException(ignored); | |
Util.sendMsg(player, "&cHologram book is broken."); | |
} | |
} else { | |
Util.sendMsg(player, "&cMust be holding a hologram book"); | |
} | |
} | |
public static void moveHologram(Player player, Location loc) { | |
final Hologram hologram = getHologram(player.getItemInHand()); | |
if (hologram == null) { | |
Util.sendMsg(player, "&cMust be holding a hologram book"); | |
return; | |
} | |
hologram.removeEntities(); | |
hologram.setLoc(loc); | |
hologram.refresh(); | |
player.setItemInHand(hologram.makeBook()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment