Skip to content

Commit

Permalink
feat: 1.1.5 NPC and Hologram fixes and documents
Browse files Browse the repository at this point in the history
* added jitpack support since we need jdk 17 to compile FancyNpcs

* added full javadoc documentary to DecentHologramDisplay

* added more null check for getLocation().getWorld().getName()

* fix npc hologram to clone location when update
  • Loading branch information
tintinkung committed Apr 23, 2024
1 parent b5cacfe commit 40a3465
Show file tree
Hide file tree
Showing 15 changed files with 199 additions and 69 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Fancy NPC plugin manager class with Decent Hologram as npc name-tag.
<dependency>
<groupId>com.aseanbte.aseanlib</groupId>
<artifactId>aseanlib-npc</artifactId>
<version>1.1.4</version>
<version>1.1.5</version>
</dependency>
<!-- FancyNpcs Plugin -->
<dependency>
Expand Down
2 changes: 1 addition & 1 deletion hologram/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>aseanlib</artifactId>
<groupId>com.aseanbte.aseanlib</groupId>
<version>1.1.4</version>
<version>1.1.5</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,48 @@
import java.util.List;
import java.util.UUID;

/**
* Display contents the hologram will be using.<br/>
* [1] ItemStack - Display item at the top of hologram.<br/>
* [2] Title - Header message atop the hologram.<br/>
* [3] Content - the main content to display.<br/>
* [4] Footer - footer line, this is default as a separator line.
*/
public interface DecentHologramContent {
/**
* Display entity as minecraft item.
* This will be display at the top of hologram
* @return Minecraft ItemStack
*/
ItemStack getItem();

String getTitle(UUID var1);
/**
* Title message as String.
* @param playerUUID Focused player.
* @return The message.
*/
String getTitle(UUID playerUUID);

List<DecentHologramDisplay.DataLine<?>> getHeader(UUID var1);
/**
* Header message as DataLine.
* By default, this is using the value from getTitle as a header with a separator line
* @param playerUUID Focused player.
* @return The DataLine.
*/
List<DecentHologramDisplay.DataLine<?>> getHeader(UUID playerUUID);

List<DecentHologramDisplay.DataLine<?>> getContent(UUID var1);
/**
* Main content to be written in the hologram
* @param playerUUID Focused player.
* @return The DataLine.
*/
List<DecentHologramDisplay.DataLine<?>> getContent(UUID playerUUID);

List<DecentHologramDisplay.DataLine<?>> getFooter(UUID var1);
/**
* The footer line at the bottom of the hologram.
* By default, this is a separator line.
* @param playerUUID Focused player.
* @return The DataLine.
*/
List<DecentHologramDisplay.DataLine<?>> getFooter(UUID playerUUID);
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,9 @@
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;

import eu.decentsoftware.holograms.api.DHAPI;
import eu.decentsoftware.holograms.api.DecentHolograms;
import eu.decentsoftware.holograms.api.holograms.Hologram;
import eu.decentsoftware.holograms.api.DecentHologramsAPI;
import eu.decentsoftware.holograms.api.holograms.HologramLine;
import eu.decentsoftware.holograms.api.holograms.HologramPage;
import eu.decentsoftware.holograms.event.HologramClickEvent;
Expand All @@ -48,57 +45,83 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* Wrapper class to use DecentHologram API, this creates and manage hologram per player.
* Meaning that individual player can see the hologram personally in multiplayer world.
*/
public abstract class DecentHologramDisplay implements DecentHologramContent {
public static List<DecentHologramDisplay> activeDisplays = new ArrayList<>();
public static DecentHolograms decentHolograms;
public static String contentSeparator = "§7---------------";
public static final String EMPTY_TAG = "&f";
private final String id;
private Location position;
private boolean isEnabled;
protected final HashMap<UUID, Hologram> holograms = new HashMap<>();
private ClickAction clickListener;
public static final String contentSeparator = "§7---------------";
private final String id;
private Location location;
private boolean isEnabled;

/**
* This action is executed when the player clicks on the 'mark as read' text on the hologram.
* Click action which is executed when the player clicks on the hologram on the hologram.
*/
@FunctionalInterface
public interface ClickAction {
void onClick(@NotNull HologramClickEvent clickEvent);
}

/**
* Register hologram listener as DecentHologramListener Class.
* {@code DecentHologramDisplay.registerPlugin(this);}
* @param plugin Plugin in use of this library.
*/
public static void registerPlugin(Plugin plugin) {
decentHolograms = DecentHologramsAPI.get();
plugin.getServer().getPluginManager().registerEvents(new DecentHologramListener(), plugin);
}

public DecentHologramDisplay(@NotNull String id, Location position, boolean isEnabled) {
/**
* @param id Hologram identifier for creating DecentHologram name, this will later be concatenated as "${player.uuid}-${id}"
* @param location The location in a world to create hologram.
* @param isEnabled Force enable or disable this hologram on create, this will not register new hologram in the hashmap.
*/
public DecentHologramDisplay(@NotNull String id, Location location, boolean isEnabled) {
this.id = id;
this.position = position;
this.location = location;
this.isEnabled = isEnabled;
activeDisplays.add(this);
}

/**
* Create hologram for player to see.
* If the player has correct ViewPermission and hologram is configured enabled,
* the hologram will be created
* @param player The player that will be able to view this hologram
*/
public void create(Player player) {
if(!isEnabled) return;
if (this.hasViewPermission(player.getUniqueId())) {
if (this.holograms.containsKey(player.getUniqueId())) {
this.reload(player.getUniqueId());
} else {
Bukkit.getLogger().log(Level.INFO, "[DHAPI] Created display ID: " + id + " For player: " + player.getUniqueId());
Hologram hologram = DHAPI.createHologram(player.getUniqueId() + "-" + id, position);
// Allow only player to see
hologram.setDefaultVisibleState(false);
hologram.setShowPlayer(player);

this.holograms.put(player.getUniqueId(), hologram);
this.reload(player.getUniqueId());
}
if(!isEnabled | !this.hasViewPermission(player.getUniqueId())) return;
if (this.holograms.containsKey(player.getUniqueId())) {
this.reload(player.getUniqueId());
} else {
Bukkit.getConsoleSender().sendMessage("[DHAPI] Created display ID: " + id + " For player: " + player.getUniqueId());
Hologram hologram = DHAPI.createHologram(player.getUniqueId() + "-" + id, location);

// Exclude all player to view this then allow only player to see
hologram.setDefaultVisibleState(false);
hologram.setShowPlayer(player);

this.holograms.put(player.getUniqueId(), hologram);
this.reload(player.getUniqueId());
}
}

public abstract boolean hasViewPermission(UUID var1);
/**
* Abstract method to add functionality to whether a player creating this hologram can view it or not.
* @param playerUUID Focused player.
* @return If true, the hologram will be created for player. Else not.
*/
public abstract boolean hasViewPermission(UUID playerUUID);

/**
* Check if a player can view this hologram.
* @param playerUUID Focused player.
* @return True if hologram is visible to player.
*/
public boolean isVisible(UUID playerUUID) {
return this.holograms.containsKey(playerUUID);
}
Expand All @@ -111,6 +134,10 @@ public List<DataLine<?>> getFooter(UUID playerUUID) {
return Collections.singletonList(new TextLine(contentSeparator));
}

/**
* Re-Write hologram dataLines received by getHeader(), getContent() and getFooter() in order.
* @param playerUUID Focused player.
*/
public void reload(UUID playerUUID) {
if (!holograms.containsKey(playerUUID)) return;
List<DataLine<?>> dataLines = new ArrayList<>();
Expand All @@ -127,10 +154,17 @@ public void reload(UUID playerUUID) {
updateDataLines(holograms.get(playerUUID).getPage(0), 0, dataLines);
}

/**
* Call the reload method on all holograms.
*/
public void reloadAll() {
for (UUID playerUUID : holograms.keySet()) reload(playerUUID);
}

/**
* Remove a hologram assigned to this display from player access.
* @param playerUUID Focused player.
*/
public void remove(UUID playerUUID) {
if (this.holograms.containsKey(playerUUID)) {
DHAPI.removeHologram(playerUUID + "-" + id);
Expand All @@ -140,40 +174,72 @@ public void remove(UUID playerUUID) {
this.holograms.remove(playerUUID);
}

/**
* Remove all assigned hologram this display has,
* this still does not remove the display itself
*/
public void removeAll() {
List<UUID> playerUUIDs = new ArrayList<>(holograms.keySet());
for (UUID playerUUID : playerUUIDs) remove(playerUUID);
}

/**
* Delete this display entirely
*/
public void delete() {
this.removeAll();
this.holograms.clear();
activeDisplays.remove(this);
}

/**
* Get the identifier from when this hologram is first constructed.
* @return ID as String.
*/
public String getId() {
return this.id;
}

/**
* Get the hologram location.
* @return hologram location.
*/
public Location getLocation() {
return this.position;
return this.location;
}

public void setLocation(Location newPosition) {
this.position = newPosition;
this.location = newPosition;
for (UUID playerUUID : holograms.keySet()) holograms.get(playerUUID).setLocation(newPosition);

}

/**
* Is this hologram enabled.
* @return Is enabled.
*/
public boolean isEnabled() {
return this.isEnabled;
}

/**
* Force set the hologram enabled or disabled.
* @param isEnabled If false, the hologram will not be created in any way.
*/
public void setEnabled(boolean isEnabled) { this.isEnabled = isEnabled; }

/**
* Get hologram instance mapped in this display.
* @param playerUUID Focused player.
* @return Hologram object from DecentHologram plugin.
*/
public Hologram getHologram(UUID playerUUID) {
return this.holograms.get(playerUUID);
}

/**
* Get all the mapped hologram in this display.
* @return HashMap of Hologram by a player UUID.
*/
public HashMap<UUID, Hologram> getHolograms() {
return this.holograms;
}
Expand Down Expand Up @@ -248,25 +314,42 @@ protected static void replaceLine(HologramPage page, int line, String text) {

}

/**
* Assign a click listener to this hologram, a ClickAction will be call when anyone clicks the hologram.
* This should be called right when reloading the hologram
* <pre>{@code
* @Override
* public void reload(UUID playerUUID) {
* super.reload(playerUUID);
* super.setClickListener((clickEvent) -> {});
* }</pre>
* @param clickListener Action callback.
*/
public void setClickListener(@Nullable ClickAction clickListener) {
this.clickListener = clickListener;
}

public @Nullable ClickAction getClickListener() {
return this.clickListener;
}


/**
* Get activeDisplays in DecentHologramDisplay by ID
* @param id The id first used to construct a new DecentHologramDisplay
* @return The hologram assigned to id.
*/
public static DecentHologramDisplay getById(String id) {
return (DecentHologramDisplay) activeDisplays.stream().filter((holo) -> {
return holo.getId().equals(id);
}).findFirst().orElse((DecentHologramDisplay)null);
return activeDisplays.stream().filter(holo -> holo.getId().equals(id)).findFirst().orElse(null);
}

public interface DataLine<T> {
T getLine();
}
/**
* DataLine of any type, acts as a text lines per hologram page.
* @param <T> DataLine type, this can only be ItemStack as ItemLine or String as TextLine
*/
public interface DataLine<T> { T getLine(); }

/**
* Minecraft ItemStack as DataLine
*/
public static class ItemLine implements DataLine<ItemStack> {
private final ItemStack line;

Expand All @@ -279,6 +362,9 @@ public ItemStack getLine() {
}
}

/**
* String as DataLine
*/
public static class TextLine implements DataLine<String> {
private final String line;

Expand All @@ -290,4 +376,4 @@ public String getLine() {
return this.line;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,18 @@
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;

import java.util.Objects;


public class DecentHologramListener implements Listener {
public DecentHologramListener() {
}

@EventHandler
public void onPlayerJoinEvent(PlayerJoinEvent event) {
// Create player's hologram each time they join
for (DecentHologramDisplay display : DecentHologramDisplay.activeDisplays) {
if (display.getLocation() == null) return;
if (display.getLocation().getWorld().getName().equals(event.getPlayer().getWorld().getName()))
if (Objects.requireNonNull(display.getLocation().getWorld()).getName().equals(event.getPlayer().getWorld().getName()))
display.create(event.getPlayer());
}

Expand All @@ -58,7 +59,7 @@ public void onPlayerQuitEvent(PlayerQuitEvent event) {
public void onPlayerChangedWorldEvent(PlayerChangedWorldEvent event) {
for (DecentHologramDisplay display : DecentHologramDisplay.activeDisplays) {
if (display.getLocation() == null) return;
if (display.getLocation().getWorld().getName().equals(event.getFrom().getName())) display.remove(event.getPlayer().getUniqueId());
if (Objects.requireNonNull(display.getLocation().getWorld()).getName().equals(event.getFrom().getName())) display.remove(event.getPlayer().getUniqueId());
else if (display.getLocation().getWorld().getName().equals(event.getPlayer().getWorld().getName())) display.create(event.getPlayer());
}

Expand Down
Loading

0 comments on commit 40a3465

Please sign in to comment.