Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added new property Viewer for hologram. #99 #100

Merged
merged 9 commits into from
May 25, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ protected boolean shouldHologramBeShown(@NotNull final Player player) {
return false;
}

if (!getData().getDisplayData().isVisibleByDefault() && !player.hasPermission("fancyholograms.viewhologram." + data.getName())) {
if (!this.getData().getDisplayData().getVisibility().canSee(player, this)) {
return false;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.oliver.fancyholograms.api.data;

import de.oliver.fancyholograms.api.FancyHologramsPlugin;
import de.oliver.fancyholograms.api.data.property.visibility.Visibility;
import de.oliver.fancylib.FancyLib;
import org.bukkit.Bukkit;
import org.bukkit.Location;
Expand All @@ -11,6 +12,7 @@
import org.joml.Vector3f;

import java.util.Locale;
import java.util.Optional;

public class DisplayHologramData implements Data {

Expand All @@ -21,6 +23,7 @@ public class DisplayHologramData implements Data {
public static final float DEFAULT_SHADOW_STRENGTH = 1.0f;
public static final int DEFAULT_VISIBILITY_DISTANCE = -1;
public static final boolean DEFAULT_IS_VISIBLE = true;
public static final Visibility DEFAULT_VISIBILITY = Visibility.ALL;

private Location location;
private Display.Billboard billboard = DEFAULT_BILLBOARD;
Expand All @@ -30,12 +33,12 @@ public class DisplayHologramData implements Data {
private float shadowRadius = DEFAULT_SHADOW_RADIUS;
private float shadowStrength = DEFAULT_SHADOW_STRENGTH;
private int visibilityDistance = DEFAULT_VISIBILITY_DISTANCE;
private boolean visibleByDefault = DEFAULT_IS_VISIBLE;
private Visibility visibility = DEFAULT_VISIBILITY;
private String linkedNpcName;

public DisplayHologramData(Location location, Display.Billboard billboard, Vector3f scale, Vector3f translation,
Display.Brightness brightness, float shadowRadius, float shadowStrength,
int visibilityDistance, String linkedNpcName, boolean visibleByDefault) {
int visibilityDistance, String linkedNpcName, Visibility visibility) {
this.location = location;
this.billboard = billboard;
this.scale = scale;
Expand All @@ -45,7 +48,7 @@ public DisplayHologramData(Location location, Display.Billboard billboard, Vecto
this.shadowStrength = shadowStrength;
this.visibilityDistance = visibilityDistance;
this.linkedNpcName = linkedNpcName;
this.visibleByDefault = visibleByDefault;
this.visibility = visibility;
}

public DisplayHologramData() {
Expand All @@ -62,7 +65,7 @@ public static DisplayHologramData getDefault(Location location) {
DEFAULT_SHADOW_STRENGTH,
DEFAULT_VISIBILITY_DISTANCE,
null,
DEFAULT_IS_VISIBLE
DEFAULT_VISIBILITY
);
}

Expand All @@ -81,7 +84,7 @@ public void write(ConfigurationSection section, String name) {
section.set("shadow_radius", shadowRadius);
section.set("shadow_strength", shadowStrength);
section.set("visibility_distance", visibilityDistance);
section.set("visible_by_default", visibleByDefault);
section.set("visibility", visibility.toString());


if (billboard == Display.Billboard.CENTER) {
Expand Down Expand Up @@ -126,7 +129,24 @@ public void read(ConfigurationSection section, String name) {
shadowStrength = (float) section.getDouble("shadow_strength", DEFAULT_SHADOW_STRENGTH);
visibilityDistance = section.getInt("visibility_distance", DEFAULT_VISIBILITY_DISTANCE);
linkedNpcName = section.getString("linkedNpc");
visibleByDefault = section.getBoolean("visible_by_default", DEFAULT_IS_VISIBLE);

visibility = Optional.ofNullable(section.getString("visibility"))
.flatMap(Visibility::byString)
.orElseGet(() -> {
final var visibleByDefault = section.getBoolean("visible_by_default", DEFAULT_IS_VISIBLE);
if (section.contains("visible_by_default")) {
section.set("visible_by_default", null);
}
if (visibleByDefault) {
return Visibility.ALL;
} else {
return Visibility.PERMISSION_REQUIRED;
}
});

if (section.contains("visible_by_default")) {
section.set("visible_by_default", null);
}

String billboardStr = section.getString("billboard", DisplayHologramData.DEFAULT_BILLBOARD.name());
billboard = switch (billboardStr.toLowerCase()) {
Expand Down Expand Up @@ -213,12 +233,40 @@ public DisplayHologramData setVisibilityDistance(int visibilityDistance) {
return this;
}

/**
* Returns to the default state of visibility.
* This method is deprecated, to control the visibility of the hologram, use {@link #getVisibility()}.
*
* @return {@code true} if hologram can see all players, else {@code false}.
*/
@Deprecated(forRemoval = true)
public boolean isVisibleByDefault() {
return visibleByDefault;
return this.getVisibility() == Visibility.ALL;
}

/**
* Set the default state of visibility.
* This method is deprecated, to control the visibility of the hologram, use {@link #setVisibility(Visibility)}.
*/
@Deprecated(forRemoval = true)
public void setVisibleByDefault(boolean visibleByDefault) {
this.visibleByDefault = visibleByDefault;
this.setVisibility(visibleByDefault ? Visibility.ALL : Visibility.PERMISSION_REQUIRED);
}

/**
* Get the type of visibility for the hologram.
*
* @return type of visibility.
*/
public Visibility getVisibility() {
return this.visibility;
}

/**
* Set the type of visibility for the hologram.
*/
public void setVisibility(Visibility visibility) {
this.visibility = visibility;
}

public String getLinkedNpcName() {
Expand All @@ -242,7 +290,7 @@ public Data copy() {
shadowStrength,
visibilityDistance,
linkedNpcName,
visibleByDefault
visibility
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package de.oliver.fancyholograms.api.data.property.visibility;

import de.oliver.fancyholograms.api.Hologram;
import org.bukkit.entity.Player;

import java.util.Arrays;
import java.util.Optional;

public enum Visibility {
/**
* Everybody can see a hologram.
*/
ALL((player, hologram) -> true),
/**
* Manual control.
*/
MANUAL((player, hologram) -> hologram.isShown(player)),
/**
* The player needs permission to see a specific hologram.
*/
PERMISSION_REQUIRED(
(player, hologram) -> player.hasPermission("fancyholograms.viewhologram." + hologram.getData().getName())
);


private final VisibilityPredicate predicate;


Visibility(VisibilityPredicate predicate) {
this.predicate = predicate;
}


public boolean canSee(Player player, Hologram hologram) {
return this.predicate.canSee(player, hologram);
}


public static Optional<Visibility> byString(String value) {
return Arrays.stream(Visibility.values())
.filter(visibility -> visibility.toString().equalsIgnoreCase(value))
.findFirst();
}

public interface VisibilityPredicate {

boolean canSee(Player player, Hologram hologram);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public boolean execute(@NotNull CommandSender sender, @NotNull String label, @No

final var usingNpcs = FancyHolograms.isUsingFancyNpcs();

List<String> suggestions = new ArrayList<>(Arrays.asList("position", "moveHere", "moveTo", "rotate", "rotatepitch", "billboard", "scale", "visibilityDistance", "visibleByDefault", "shadowRadius", "shadowStrength", usingNpcs ? "linkWithNpc" : "", usingNpcs ? "unlinkWithNpc" : ""));
List<String> suggestions = new ArrayList<>(Arrays.asList("position", "moveHere", "moveTo", "rotate", "rotatepitch", "billboard", "scale", "visibilityDistance", "visibility", "shadowRadius", "shadowStrength", usingNpcs ? "linkWithNpc" : "", usingNpcs ? "unlinkWithNpc" : ""));
suggestions.addAll(type.getCommands());

return suggestions.stream().filter(input -> input.toLowerCase().startsWith(args[2].toLowerCase(Locale.ROOT))).toList();
Expand Down Expand Up @@ -209,7 +209,8 @@ public boolean execute(@NotNull CommandSender sender, @NotNull String label, @No
yield FancyNpcsPlugin.get().getNpcManager().getAllNpcs().stream().map(npc -> npc.getData().getName());
}
case "block" -> Arrays.stream(Material.values()).filter(Material::isBlock).map(Enum::name);
case "seethrough", "visiblebydefault" -> Stream.of("true", "false");
case "seethrough" -> Stream.of("true", "false");
case "visibility" -> new VisibilityCMD().tabcompletion(sender, hologram, args).stream();

default -> null;
};
Expand Down Expand Up @@ -297,7 +298,7 @@ private boolean edit(@NotNull final CommandSender player, @NotNull final Hologra
case "scale" -> new ScaleCMD().run(player, hologram, args);
case "updatetextinterval" -> new UpdateTextIntervalCMD().run(player, hologram, args);
case "visibilitydistance" -> new VisibilityDistanceCMD().run(player, hologram, args);
case "visiblebydefault" -> new VisibleByDefaultCMD().run(player, hologram, args);
case "visibility" -> new VisibilityCMD().run(player, hologram, args);
case "linkwithnpc" -> new LinkWithNpcCMD().run(player, hologram, args);
case "shadowradius" -> new ShadowRadiusCMD().run(player, hologram, args);
case "shadowstrength" -> new ShadowStrengthCMD().run(player, hologram, args);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,50 @@

import de.oliver.fancyholograms.FancyHolograms;
import de.oliver.fancyholograms.api.Hologram;
import de.oliver.fancyholograms.api.data.property.visibility.Visibility;
import de.oliver.fancyholograms.commands.Subcommand;
import de.oliver.fancylib.MessageHelper;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

public class VisibleByDefaultCMD implements Subcommand {
public class VisibilityCMD implements Subcommand {

@Override
public List<String> tabcompletion(@NotNull CommandSender player, @Nullable Hologram hologram, @NotNull String[] args) {
return null;
return Arrays.stream(
Visibility.values()
).map(Objects::toString).toList();
}

@Override
public boolean run(@NotNull CommandSender player, @Nullable Hologram hologram, @NotNull String[] args) {
var visibleByDefault = Boolean.parseBoolean(args[3]);
if (hologram == null) {
final var optionalVisibility = Visibility.byString(args[3]);
if (hologram == null || optionalVisibility.isEmpty()) {
return false;
}
final var visibility = optionalVisibility.get();

final var copied = hologram.getData().copy();
copied.getDisplayData().setVisibleByDefault(visibleByDefault);
copied.getDisplayData().setVisibility(visibility);


if (hologram.getData().getDisplayData().isVisibleByDefault() == copied.getDisplayData().isVisibleByDefault()) {
MessageHelper.warning(player, "This hologram already has visibility by default set to " + visibleByDefault);
if (hologram.getData().getDisplayData().getVisibility() == copied.getDisplayData().getVisibility()) {
MessageHelper.warning(player, "This hologram already has visibility set to " + visibility);
return false;
}

hologram.getData().getDisplayData().setVisibleByDefault(copied.getDisplayData().isVisibleByDefault());
hologram.getData().getDisplayData().setVisibility(copied.getDisplayData().getVisibility());

if (FancyHolograms.get().getHologramConfiguration().isSaveOnChangedEnabled()) {
FancyHolograms.get().getHologramStorage().save(hologram);
}

MessageHelper.success(player, "Changed visibility by default to " + visibleByDefault);
MessageHelper.success(player, "Changed visibility to " + visibility);
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import de.oliver.fancyholograms.api.HologramStorage;
import de.oliver.fancyholograms.api.HologramType;
import de.oliver.fancyholograms.api.data.*;
import de.oliver.fancyholograms.api.data.property.visibility.Visibility;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
import org.bukkit.Bukkit;
Expand All @@ -22,6 +23,7 @@
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;


public class FlatFileHologramStorage implements HologramStorage {

private static final ReadWriteLock lock = new ReentrantReadWriteLock();
Expand Down Expand Up @@ -232,7 +234,21 @@ public static HologramData readHologram(String name, ConfigurationSection config
final var billboardName = config.getString("billboard", DisplayHologramData.DEFAULT_BILLBOARD.name());
final var textAlignmentName = config.getString("text_alignment", TextHologramData.DEFAULT_TEXT_ALIGNMENT.name());
final var linkedNpc = config.getString("linkedNpc");
final var visibleByDefault = config.getBoolean("visible_by_default", DisplayHologramData.DEFAULT_IS_VISIBLE);


final var visibility = Optional.ofNullable(config.getString("visibility"))
.flatMap(Visibility::byString)
.orElseGet(() -> {
final var visibleByDefault = config.getBoolean("visible_by_default", DisplayHologramData.DEFAULT_IS_VISIBLE);
if (config.contains("visible_by_default")) {
config.set("visible_by_default", null);
}
if (visibleByDefault) {
return Visibility.ALL;
} else {
return Visibility.PERMISSION_REQUIRED;
}
});

final var billboard = switch (billboardName.toLowerCase(Locale.ROOT)) {
case "fixed" -> Display.Billboard.FIXED;
Expand All @@ -259,7 +275,7 @@ public static HologramData readHologram(String name, ConfigurationSection config
}


DisplayHologramData displayData = new DisplayHologramData(location, billboard, new Vector3f((float) scaleX, (float) scaleY, (float) scaleZ), DisplayHologramData.DEFAULT_TRANSLATION, null, (float) shadowRadius, (float) shadowStrength, visibilityDistance, linkedNpc, visibleByDefault);
DisplayHologramData displayData = new DisplayHologramData(location, billboard, new Vector3f((float) scaleX, (float) scaleY, (float) scaleZ), DisplayHologramData.DEFAULT_TRANSLATION, null, (float) shadowRadius, (float) shadowStrength, visibilityDistance, linkedNpc, visibility);

TextHologramData textData = new TextHologramData(text, background, textAlignment, textHasShadow, isSeeThrough, textUpdateInterval);

Expand Down