Introduce HologramPosition API and refactor implementation

This commit is contained in:
filoghost 2021-08-05 23:32:44 +02:00
parent 1be79f05b0
commit 14c7ebce69
27 changed files with 413 additions and 272 deletions

View File

@ -104,63 +104,71 @@ public interface Hologram {
double getHeight();
/**
* Teleports a hologram to the given location.
* Returns the hologram position.
*
* @param location the new location
* @return the hologram position
* @since 1
*/
void teleport(@NotNull Location location);
@NotNull HologramPosition getPosition();
/**
* Teleports a hologram to the given location.
* Returns the world of the hologram position.
*
* @param world the world where the hologram should be teleported, use {@link #getWorld()} to teleport it in the same world.
* @return the world of the hologram position
* @since 1
*/
@NotNull World getPositionWorld();
/**
* Returns the X coordinate of the hologram position.
*
* @return the X coordinate of the hologram position
* @since 1
*/
double getPositionX();
/**
* Returns the Y coordinate of the hologram position.
*
* @return the Y coordinate of the hologram position
* @since 1
*/
double getPositionY();
/**
* Returns the Z coordinate of the hologram position.
*
* @return the Z coordinate of the hologram position
* @since 1
*/
double getPositionZ();
/**
* Moves the hologram to the given position.
*
* @param position the new position
* @since 1
*/
void setPosition(@NotNull HologramPosition position);
/**
* Moves the hologram to the given position.
*
* @param world the world where the hologram should be moved
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
* @since 1
*/
void teleport(@NotNull World world, double x, double y, double z);
void setPosition(@NotNull World world, double x, double y, double z);
/**
* Returns the position of the hologram.
* Moves the hologram to the given position.
*
* @return the Location of the hologram
* @param location the new position
* @since 1
*/
@NotNull Location getLocation();
/**
* Returns the world.
*
* @return the world of the hologram
* @since 1
*/
@NotNull World getWorld();
/**
* Returns the X coordinate.
*
* @return the X coordinate of the hologram
* @since 1
*/
double getX();
/**
* Returns the Y coordinate.
*
* @return the Y coordinate of the hologram
* @since 1
*/
double getY();
/**
* Returns the Z coordinate.
*
* @return the Z coordinate of the hologram
* @since 1
*/
double getZ();
void setPosition(@NotNull Location location);
/**
* Returns the {@link VisibilitySettings} of this hologram.

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.api.hologram;
import me.filoghost.holographicdisplays.api.internal.HolographicDisplaysAPIProvider;
import org.bukkit.Location;
import org.bukkit.World;
import org.jetbrains.annotations.NotNull;
public interface HologramPosition {
static @NotNull HologramPosition create(@NotNull World world, double x, double y, double z) {
return HolographicDisplaysAPIProvider.getImplementation().createHologramPosition(world, x, y, z);
}
static @NotNull HologramPosition fromLocation(@NotNull Location location) {
return HolographicDisplaysAPIProvider.getImplementation().createHologramPosition(location);
}
@NotNull World getWorld();
void setWorld(@NotNull World world);
double getX();
void setX(double x);
double getY();
void setY(double y);
double getZ();
void setZ(double z);
void add(double x, double y, double z);
int getBlockX();
int getBlockY();
int getBlockZ();
double distance(@NotNull Location location);
double distanceSquared(@NotNull Location location);
@NotNull Location toLocation();
}

View File

@ -6,6 +6,9 @@
package me.filoghost.holographicdisplays.api.internal;
import me.filoghost.holographicdisplays.api.HolographicDisplaysAPI;
import me.filoghost.holographicdisplays.api.hologram.HologramPosition;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.ApiStatus.Internal;
@ -30,4 +33,8 @@ public abstract class HolographicDisplaysAPIProvider {
public abstract HolographicDisplaysAPI getHolographicDisplaysAPI(Plugin plugin);
public abstract HologramPosition createHologramPosition(World world, double x, double y, double z);
public abstract HologramPosition createHologramPosition(Location location);
}

View File

@ -54,7 +54,7 @@ public class PowerUps extends JavaPlugin implements Listener {
icon.setPickupListener((Player player) -> {
// Play an effect
player.playEffect(hologram.getLocation(), Effect.MOBSPAWNER_FLAMES, null);
player.playEffect(hologram.getPosition().toLocation(), Effect.MOBSPAWNER_FLAMES, null);
// 30 seconds of speed II
player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 30 * 20, 1), true);

View File

@ -10,6 +10,7 @@ import me.filoghost.holographicdisplays.api.HolographicDisplaysAPI;
import me.filoghost.holographicdisplays.api.hologram.Hologram;
import me.filoghost.holographicdisplays.api.placeholder.PlaceholderReplacer;
import me.filoghost.holographicdisplays.plugin.hologram.api.APIHologramManager;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPosition;
import me.filoghost.holographicdisplays.plugin.placeholder.registry.PlaceholderRegistry;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -36,7 +37,7 @@ class DefaultHolographicDisplaysAPI implements HolographicDisplaysAPI {
Preconditions.notNull(source.getWorld(), "source's world");
Preconditions.checkState(Bukkit.isPrimaryThread(), "Async hologram creation");
return apiHologramManager.createHologram(source, plugin);
return apiHologramManager.createHologram(new BaseHologramPosition(source), plugin);
}
@Override

View File

@ -7,10 +7,14 @@ package me.filoghost.holographicdisplays.plugin.api.current;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.holographicdisplays.api.HolographicDisplaysAPI;
import me.filoghost.holographicdisplays.api.hologram.HologramPosition;
import me.filoghost.holographicdisplays.api.internal.HolographicDisplaysAPIProvider;
import me.filoghost.holographicdisplays.common.nms.NMSManager;
import me.filoghost.holographicdisplays.plugin.hologram.api.APIHologramManager;
import me.filoghost.holographicdisplays.plugin.hologram.api.APIHologramPosition;
import me.filoghost.holographicdisplays.plugin.placeholder.registry.PlaceholderRegistry;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.plugin.Plugin;
import java.util.Map;
@ -43,4 +47,14 @@ public class DefaultHolographicDisplaysAPIProvider extends HolographicDisplaysAP
new DefaultHolographicDisplaysAPI(pluginKey, apiHologramManager, placeholderRegistry));
}
@Override
public HologramPosition createHologramPosition(World world, double x, double y, double z) {
return new APIHologramPosition(world, x, y, z);
}
@Override
public HologramPosition createHologramPosition(Location location) {
return new APIHologramPosition(location);
}
}

View File

@ -71,37 +71,37 @@ public class V2HologramAdapter implements Hologram {
@Override
public void teleport(Location location) {
v3Hologram.teleport(location);
v3Hologram.setPosition(location);
}
@Override
public void teleport(World world, double x, double y, double z) {
v3Hologram.teleport(world, x, y, z);
v3Hologram.setPosition(world, x, y, z);
}
@Override
public Location getLocation() {
return v3Hologram.getHologramLocation().toBukkitLocation();
return new Location(v3Hologram.getPositionWorld(), v3Hologram.getPositionX(), v3Hologram.getPositionY(), v3Hologram.getPositionZ());
}
@Override
public double getX() {
return v3Hologram.getHologramLocation().getX();
return v3Hologram.getPositionX();
}
@Override
public double getY() {
return v3Hologram.getHologramLocation().getY();
return v3Hologram.getPositionY();
}
@Override
public double getZ() {
return v3Hologram.getHologramLocation().getZ();
return v3Hologram.getPositionZ();
}
@Override
public World getWorld() {
return v3Hologram.getHologramLocation().getWorld();
return v3Hologram.getPositionWorld();
}
@Override

View File

@ -11,6 +11,7 @@ import com.gmail.filoghost.holographicdisplays.api.placeholder.PlaceholderReplac
import me.filoghost.fcommons.Preconditions;
import me.filoghost.holographicdisplays.plugin.hologram.api.APIHologram;
import me.filoghost.holographicdisplays.plugin.hologram.api.APIHologramManager;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPosition;
import me.filoghost.holographicdisplays.plugin.placeholder.registry.PlaceholderRegistry;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -40,7 +41,7 @@ public class V2HologramsAPIProvider extends HologramsAPIProvider {
Preconditions.notNull(source.getWorld(), "source's world");
Preconditions.checkState(Bukkit.isPrimaryThread(), "async hologram creation");
return apiHologramManager.createHologram(source, plugin).getV2Adapter();
return apiHologramManager.createHologram(new BaseHologramPosition(source), plugin).getV2Adapter();
}
@Override

View File

@ -13,6 +13,7 @@ import me.filoghost.holographicdisplays.plugin.config.HologramLineParser;
import me.filoghost.holographicdisplays.plugin.config.HologramLoadException;
import me.filoghost.holographicdisplays.plugin.event.InternalHologramChangeEvent;
import me.filoghost.holographicdisplays.plugin.event.InternalHologramChangeEvent.ChangeType;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPosition;
import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologram;
import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologramLine;
import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologramManager;
@ -67,8 +68,8 @@ public class InternalHologramEditor {
return internalHologramManager.getHolograms();
}
public InternalHologram create(Location spawnLocation, String hologramName) {
return internalHologramManager.createHologram(spawnLocation, hologramName);
public InternalHologram create(BaseHologramPosition spawnPosition, String hologramName) {
return internalHologramManager.createHologram(spawnPosition, hologramName);
}
public void delete(InternalHologram hologram) {

View File

@ -12,9 +12,8 @@ import me.filoghost.holographicdisplays.plugin.commands.HologramSubCommand;
import me.filoghost.holographicdisplays.plugin.commands.InternalHologramEditor;
import me.filoghost.holographicdisplays.plugin.event.InternalHologramChangeEvent.ChangeType;
import me.filoghost.holographicdisplays.plugin.format.ColorScheme;
import me.filoghost.holographicdisplays.plugin.hologram.base.HologramLocation;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPosition;
import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologram;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
public class AlignCommand extends HologramSubCommand {
@ -37,24 +36,24 @@ public class AlignCommand extends HologramSubCommand {
CommandValidate.check(hologram != referenceHologram, "The holograms must not be the same.");
HologramLocation referenceLocation = referenceHologram.getHologramLocation();
Location newLocation = hologram.getHologramLocation().toBukkitLocation();
BaseHologramPosition referencePosition = referenceHologram.getBasePosition();
BaseHologramPosition newPosition = hologram.getBasePosition();
String axis = args[0];
if (axis.equalsIgnoreCase("x")) {
newLocation.setX(referenceLocation.getX());
newPosition.setX(referencePosition.getX());
} else if (axis.equalsIgnoreCase("y")) {
newLocation.setY(referenceLocation.getY());
newPosition.setY(referencePosition.getY());
} else if (axis.equalsIgnoreCase("z")) {
newLocation.setZ(referenceLocation.getZ());
newPosition.setZ(referencePosition.getZ());
} else if (axis.equalsIgnoreCase("xz")) {
newLocation.setX(referenceLocation.getX());
newLocation.setZ(referenceLocation.getZ());
newPosition.setX(referencePosition.getX());
newPosition.setZ(referencePosition.getZ());
} else {
throw new CommandException("You must specify either X, Y, Z or XZ, " + axis + " is not a valid axis.");
}
hologram.teleport(newLocation);
hologram.setPosition(newPosition);
hologramEditor.saveChanges(hologram, ChangeType.EDIT_LOCATION);
sender.sendMessage(ColorScheme.PRIMARY + "Hologram \"" + hologram.getName() + "\""

View File

@ -13,10 +13,10 @@ import me.filoghost.holographicdisplays.plugin.commands.HologramSubCommand;
import me.filoghost.holographicdisplays.plugin.commands.InternalHologramEditor;
import me.filoghost.holographicdisplays.plugin.event.InternalHologramChangeEvent.ChangeType;
import me.filoghost.holographicdisplays.plugin.format.ColorScheme;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPosition;
import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologram;
import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologramLine;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -47,14 +47,14 @@ public class CreateCommand extends HologramSubCommand {
CommandValidate.check(hologramEditor.getHologram(hologramName) == null,
"A hologram with that name already exists.");
Location spawnLocation = player.getLocation();
BaseHologramPosition spawnPosition = new BaseHologramPosition(player.getLocation());
boolean moveUp = player.isOnGround();
if (moveUp) {
spawnLocation.add(0.0, 1.2, 0.0);
spawnPosition.add(0, 1.2, 0);
}
InternalHologram hologram = hologramEditor.create(spawnLocation, hologramName);
InternalHologram hologram = hologramEditor.create(spawnPosition, hologramName);
InternalHologramLine line;
if (args.length > 1) {

View File

@ -12,7 +12,7 @@ import me.filoghost.holographicdisplays.plugin.commands.HologramSubCommand;
import me.filoghost.holographicdisplays.plugin.commands.InternalHologramEditor;
import me.filoghost.holographicdisplays.plugin.format.ColorScheme;
import me.filoghost.holographicdisplays.plugin.format.DisplayFormat;
import me.filoghost.holographicdisplays.plugin.hologram.base.HologramLocation;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPosition;
import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologram;
import org.bukkit.command.CommandSender;
@ -55,11 +55,11 @@ public class ListCommand extends HologramSubCommand {
for (int i = fromIndex; i < toIndex; i++) {
if (i < holograms.size()) {
InternalHologram hologram = holograms.get(i);
HologramLocation location = hologram.getHologramLocation();
BaseHologramPosition position = hologram.getBasePosition();
sender.sendMessage(ColorScheme.SECONDARY_DARKER + "- " + ColorScheme.SECONDARY_BOLD + hologram.getName()
+ " " + ColorScheme.SECONDARY_DARKER + "at"
+ " x: " + location.getBlockX() + ", y: " + location.getBlockY() + ", z: " + location.getBlockZ()
+ " (lines: " + hologram.getLineCount() + ", world: \"" + location.getWorld().getName() + "\")");
+ " x: " + position.getBlockX() + ", y: " + position.getBlockY() + ", z: " + position.getBlockZ()
+ " (lines: " + hologram.getLineCount() + ", world: \"" + position.getWorld().getName() + "\")");
}
}

View File

@ -34,7 +34,7 @@ public class MovehereCommand extends HologramSubCommand {
Player player = CommandValidate.getPlayerSender(sender);
InternalHologram hologram = hologramEditor.getHologram(args[0]);
hologram.teleport(player.getLocation());
hologram.setPosition(player.getLocation());
hologramEditor.saveChanges(hologram, ChangeType.EDIT_LOCATION);
hologramEditor.teleportLookingDown(player, player.getLocation());

View File

@ -12,7 +12,7 @@ import me.filoghost.holographicdisplays.plugin.commands.HologramSubCommand;
import me.filoghost.holographicdisplays.plugin.commands.InternalHologramEditor;
import me.filoghost.holographicdisplays.plugin.format.ColorScheme;
import me.filoghost.holographicdisplays.plugin.format.DisplayFormat;
import me.filoghost.holographicdisplays.plugin.hologram.base.HologramLocation;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPosition;
import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologram;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
@ -44,8 +44,8 @@ public class NearCommand extends HologramSubCommand {
List<InternalHologram> nearHolograms = new ArrayList<>();
for (InternalHologram hologram : hologramEditor.getHolograms()) {
HologramLocation location = hologram.getHologramLocation();
if (location.getWorld().equals(world) && location.distance(player.getLocation()) <= radius) {
BaseHologramPosition position = hologram.getBasePosition();
if (position.getWorld().equals(world) && position.distance(player.getLocation()) <= radius) {
nearHolograms.add(hologram);
}
}
@ -54,10 +54,10 @@ public class NearCommand extends HologramSubCommand {
DisplayFormat.sendTitle(player, "Near holograms");
for (InternalHologram nearHologram : nearHolograms) {
HologramLocation location = nearHologram.getHologramLocation();
BaseHologramPosition position = nearHologram.getBasePosition();
player.sendMessage(ColorScheme.SECONDARY_DARKER + "- "
+ ColorScheme.SECONDARY_BOLD + nearHologram.getName() + " " + ColorScheme.SECONDARY_DARKER + "at"
+ " x: " + location.getBlockX() + ", y: " + location.getBlockY() + ", z: " + location.getBlockZ()
+ " x: " + position.getBlockX() + ", y: " + position.getBlockY() + ", z: " + position.getBlockZ()
+ " (lines: " + nearHologram.getLineCount() + ")");
}
}

View File

@ -34,7 +34,7 @@ public class TeleportCommand extends HologramSubCommand {
Player player = CommandValidate.getPlayerSender(sender);
InternalHologram hologram = hologramEditor.getHologram(args[0]);
hologramEditor.teleportLookingDown(player, hologram.getHologramLocation().toBukkitLocation());
hologramEditor.teleportLookingDown(player, hologram.getBasePosition().toLocation());
player.sendMessage(ColorScheme.PRIMARY + "You were teleported to the hologram named '" + hologram.getName() + "'.");
}

View File

@ -7,12 +7,11 @@ package me.filoghost.holographicdisplays.plugin.config;
import me.filoghost.fcommons.Strings;
import me.filoghost.fcommons.config.ConfigSection;
import me.filoghost.holographicdisplays.plugin.hologram.base.HologramLocation;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPosition;
import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologram;
import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologramLine;
import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologramManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import java.text.DecimalFormat;
@ -23,17 +22,17 @@ import java.util.Locale;
public class HologramConfig {
private static final DecimalFormat LOCATION_NUMBER_FORMAT
private static final DecimalFormat POSITION_NUMBER_FORMAT
= new DecimalFormat("0.000", DecimalFormatSymbols.getInstance(Locale.ROOT));
private final String name;
private final List<String> serializedLines;
private final String serializedLocation;
private final String serializedPosition;
public HologramConfig(String name, ConfigSection configSection) {
this.name = name;
this.serializedLines = configSection.getStringList("lines");
this.serializedLocation = configSection.getString("location");
this.serializedPosition = configSection.getString("location");
}
public HologramConfig(InternalHologram hologram) {
@ -43,13 +42,13 @@ public class HologramConfig {
serializedLines.add(line.getSerializedConfigValue());
}
this.serializedLocation = serializeLocation(hologram.getHologramLocation());
this.serializedPosition = serializePosition(hologram.getBasePosition());
}
public ConfigSection toConfigSection() {
ConfigSection configSection = new ConfigSection();
configSection.setStringList("lines", serializedLines);
configSection.setString("location", serializedLocation);
configSection.setString("location", serializedPosition);
return configSection;
}
@ -57,12 +56,12 @@ public class HologramConfig {
if (serializedLines == null || serializedLines.size() == 0) {
throw new HologramLoadException("at least one line is required");
}
if (serializedLocation == null) {
if (serializedPosition == null) {
throw new HologramLoadException("no location set");
}
Location location = deserializeLocation(serializedLocation);
InternalHologram hologram = internalHologramManager.createHologram(location, name);
BaseHologramPosition position = deserializePosition(serializedPosition);
InternalHologram hologram = internalHologramManager.createHologram(position, name);
List<InternalHologramLine> lines = new ArrayList<>();
for (String serializedLine : serializedLines) {
@ -78,15 +77,15 @@ public class HologramConfig {
return hologram;
}
private String serializeLocation(HologramLocation location) {
return location.getWorld().getName()
+ ", " + LOCATION_NUMBER_FORMAT.format(location.getX())
+ ", " + LOCATION_NUMBER_FORMAT.format(location.getY())
+ ", " + LOCATION_NUMBER_FORMAT.format(location.getZ());
private String serializePosition(BaseHologramPosition position) {
return position.getWorld().getName()
+ ", " + POSITION_NUMBER_FORMAT.format(position.getX())
+ ", " + POSITION_NUMBER_FORMAT.format(position.getY())
+ ", " + POSITION_NUMBER_FORMAT.format(position.getZ());
}
private Location deserializeLocation(String serializedLocation) throws HologramLoadException {
String[] parts = Strings.splitAndTrim(serializedLocation, ",");
private BaseHologramPosition deserializePosition(String serializedPosition) throws HologramLoadException {
String[] parts = Strings.splitAndTrim(serializedPosition, ",");
if (parts.length != 4) {
throw new HologramLoadException("hologram \"" + name + "\" has an invalid location format:"
@ -105,7 +104,7 @@ public class HologramConfig {
+ " was in the world \"" + worldName + "\" but it wasn't loaded");
}
return new Location(world, x, y, z);
return new BaseHologramPosition(world, x, y, z);
} catch (NumberFormatException ex) {
throw new HologramLoadException("hologram \"" + name + "\""

View File

@ -7,12 +7,12 @@ package me.filoghost.holographicdisplays.plugin.hologram.api;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.holographicdisplays.api.hologram.Hologram;
import me.filoghost.holographicdisplays.api.hologram.HologramPosition;
import me.filoghost.holographicdisplays.plugin.api.v2.V2HologramAdapter;
import me.filoghost.holographicdisplays.plugin.config.Settings;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologram;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPosition;
import me.filoghost.holographicdisplays.plugin.hologram.tracking.LineTrackerManager;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
@ -32,11 +32,11 @@ public class APIHologram extends BaseHologram<APIHologramLine> implements Hologr
private boolean allowPlaceholders;
protected APIHologram(
Location location,
BaseHologramPosition position,
Plugin plugin,
APIHologramManager apiHologramManager,
LineTrackerManager lineTrackerManager) {
super(location, lineTrackerManager);
super(position, lineTrackerManager);
Preconditions.notNull(plugin, "plugin");
this.plugin = plugin;
this.apiHologramManager = apiHologramManager;
@ -135,28 +135,13 @@ public class APIHologram extends BaseHologram<APIHologramLine> implements Hologr
}
@Override
public @NotNull Location getLocation() {
return getHologramLocation().toBukkitLocation();
public @NotNull HologramPosition getPosition() {
return new APIHologramPosition(getPositionWorld(), getPositionX(), getPositionY(), getPositionZ());
}
@Override
public @NotNull World getWorld() {
return getHologramLocation().getWorld();
}
@Override
public double getX() {
return getHologramLocation().getX();
}
@Override
public double getY() {
return getHologramLocation().getY();
}
@Override
public double getZ() {
return getHologramLocation().getZ();
public void setPosition(@NotNull HologramPosition position) {
super.setPosition(position.getWorld(), position.getX(), position.getY(), position.getZ());
}
@Override

View File

@ -7,8 +7,8 @@ package me.filoghost.holographicdisplays.plugin.hologram.api;
import me.filoghost.holographicdisplays.api.hologram.Hologram;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramManager;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPosition;
import me.filoghost.holographicdisplays.plugin.hologram.tracking.LineTrackerManager;
import org.bukkit.Location;
import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
@ -24,8 +24,8 @@ public class APIHologramManager extends BaseHologramManager<APIHologram> {
this.lineTrackerManager = lineTrackerManager;
}
public APIHologram createHologram(Location source, Plugin plugin) {
APIHologram hologram = new APIHologram(source, plugin, this, lineTrackerManager);
public APIHologram createHologram(BaseHologramPosition position, Plugin plugin) {
APIHologram hologram = new APIHologram(position, plugin, this, lineTrackerManager);
super.addHologram(hologram);
return hologram;
}

View File

@ -0,0 +1,23 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.plugin.hologram.api;
import me.filoghost.holographicdisplays.api.hologram.HologramPosition;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPosition;
import org.bukkit.Location;
import org.bukkit.World;
public class APIHologramPosition extends BaseHologramPosition implements HologramPosition {
public APIHologramPosition(World world, double x, double y, double z) {
super(world, x, y, z);
}
public APIHologramPosition(Location location) {
super(location);
}
}

View File

@ -8,6 +8,8 @@ package me.filoghost.holographicdisplays.plugin.hologram.base;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.holographicdisplays.plugin.config.Settings;
import me.filoghost.holographicdisplays.plugin.hologram.tracking.LineTrackerManager;
import me.filoghost.holographicdisplays.plugin.util.CachedBoolean;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
@ -21,17 +23,20 @@ import java.util.List;
public abstract class BaseHologram<T extends EditableHologramLine> extends BaseHologramComponent {
private final HologramLocation location;
private final List<T> lines;
private final List<T> unmodifiableLinesView;
private final LineTrackerManager lineTrackerManager;
public BaseHologram(Location location, LineTrackerManager lineTrackerManager) {
Preconditions.notNull(location, "location");
this.location = new HologramLocation(location);
private World world;
private double x, y, z;
private int chunkX, chunkZ;
private final CachedBoolean isInLoadedChunk = new CachedBoolean(() -> world.isChunkLoaded(chunkX, chunkZ));
public BaseHologram(BaseHologramPosition position, LineTrackerManager lineTrackerManager) {
this.lines = new ArrayList<>();
this.unmodifiableLinesView = Collections.unmodifiableList(lines);
this.lineTrackerManager = lineTrackerManager;
setPosition(position.getWorld(), position.getX(), position.getY(), position.getZ());
}
protected abstract boolean isVisibleTo(Player player);
@ -123,20 +128,58 @@ public abstract class BaseHologram<T extends EditableHologramLine> extends BaseH
return lines.size();
}
public void teleport(@NotNull Location location) {
public BaseHologramPosition getBasePosition() {
return new BaseHologramPosition(getPositionWorld(), getPositionX(), getPositionY(), getPositionZ());
}
public @NotNull World getPositionWorld() {
return world;
}
public double getPositionX() {
return x;
}
public double getPositionY() {
return y;
}
public double getPositionZ() {
return z;
}
public void setPosition(@NotNull BaseHologramPosition position) {
Preconditions.notNull(position, "position");
setPosition(position.getWorld(), position.getX(), position.getY(), position.getZ());
}
public void setPosition(@NotNull Location location) {
Preconditions.notNull(location, "location");
setPosition(location.getWorld(), location.getX(), location.getY(), location.getZ());
}
public void setPosition(@NotNull World world, double x, double y, double z) {
Preconditions.notNull(world, "world");
checkNotDeleted();
this.location.set(location);
this.x = x;
this.y = y;
this.z = z;
int chunkX = getChunkCoordinate(x);
int chunkZ = getChunkCoordinate(z);
if (this.world != world || this.chunkX != chunkX || this.chunkZ != chunkZ) {
this.world = world;
this.chunkX = chunkX;
this.chunkZ = chunkZ;
this.isInLoadedChunk.invalidate();
}
updateLineLocations();
}
public void teleport(@NotNull World world, double x, double y, double z) {
checkNotDeleted();
this.location.set(world, x, y, z);
updateLineLocations();
}
public HologramLocation getHologramLocation() {
return location;
private int getChunkCoordinate(double positionCoordinate) {
return Location.locToBlock(positionCoordinate) >> 4;
}
/**
@ -144,7 +187,7 @@ public abstract class BaseHologram<T extends EditableHologramLine> extends BaseH
* The second line is below the first, and so on.
*/
private void updateLineLocations() {
double currentLineY = location.getY();
double currentLineY = y;
for (int i = 0; i < lines.size(); i++) {
T line = lines.get(i);
@ -154,13 +197,29 @@ public abstract class BaseHologram<T extends EditableHologramLine> extends BaseH
currentLineY -= Settings.spaceBetweenLines;
}
line.setLocation(location.getX(), currentLineY, location.getZ());
line.setLocation(x, currentLineY, z);
}
}
protected void onChunkLoad(Chunk chunk) {
if (world == chunk.getWorld() && chunkX == chunk.getX() && chunkZ == chunk.getZ()) {
isInLoadedChunk.set(true);
}
}
protected void onChunkUnload(Chunk chunk) {
if (world == chunk.getWorld() && chunkX == chunk.getX() && chunkZ == chunk.getZ()) {
isInLoadedChunk.set(false);
}
}
protected boolean isInLoadedChunk() {
return isInLoadedChunk.get();
}
@Override
public String toString() {
return "BaseHologram [location=" + location + ", lines=" + lines + ", deleted=" + isDeleted() + "]";
return "Hologram [position=" + getBasePosition() + ", lines=" + lines + ", deleted=" + isDeleted() + "]";
}
}

View File

@ -57,11 +57,11 @@ public abstract class BaseHologramLine extends BaseHologramComponent implements
}
public World getWorld() {
return hologram.getHologramLocation().getWorld();
return hologram.getPositionWorld();
}
public boolean isInLoadedChunk() {
return hologram.getHologramLocation().isInLoadedChunk();
return hologram.isInLoadedChunk();
}
public final boolean isVisibleTo(Player player) {

View File

@ -41,13 +41,13 @@ public abstract class BaseHologramManager<H extends BaseHologram<?>> {
public void onChunkLoad(Chunk chunk) {
for (H hologram : holograms) {
hologram.getHologramLocation().onChunkLoad(chunk);
hologram.onChunkLoad(chunk);
}
}
public void onChunkUnload(Chunk chunk) {
for (H hologram : holograms) {
hologram.getHologramLocation().onChunkUnload(chunk);
hologram.onChunkUnload(chunk);
}
}

View File

@ -0,0 +1,112 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.plugin.hologram.base;
import me.filoghost.fcommons.Preconditions;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.util.NumberConversions;
import org.jetbrains.annotations.NotNull;
public class BaseHologramPosition {
private World world;
private double x, y, z;
public BaseHologramPosition(World world, double x, double y, double z) {
Preconditions.notNull(world, "world");
this.world = world;
this.x = x;
this.y = y;
this.z = z;
}
public BaseHologramPosition(Location location) {
Preconditions.notNull(location, "location");
Preconditions.notNull(location.getWorld(), "location's world");
this.world = location.getWorld();
this.x = location.getX();
this.y = location.getY();
this.z = location.getZ();
}
public @NotNull World getWorld() {
return world;
}
public void setWorld(@NotNull World world) {
Preconditions.notNull(world, "world");
this.world = world;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
public double getZ() {
return z;
}
public void setZ(double z) {
this.z = z;
}
public void add(double x, double y, double z) {
this.x += x;
this.y += y;
this.z += z;
}
public int getBlockX() {
return Location.locToBlock(x);
}
public int getBlockY() {
return Location.locToBlock(y);
}
public int getBlockZ() {
return Location.locToBlock(z);
}
public double distance(@NotNull Location location) {
return Math.sqrt(distanceSquared(location));
}
public double distanceSquared(@NotNull Location location) {
Preconditions.notNull(location, "location");
return NumberConversions.square(this.x - location.getX())
+ NumberConversions.square(this.y - location.getY())
+ NumberConversions.square(this.z - location.getZ());
}
public @NotNull Location toLocation() {
return new Location(world, x, y, z);
}
@Override
public String toString() {
return "HologramPosition ["
+ "world=" + world
+ ", x=" + x
+ ", y=" + y
+ ", z=" + z
+ "]";
}
}

View File

@ -1,121 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.plugin.hologram.base;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.holographicdisplays.plugin.util.CachedBoolean;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.util.NumberConversions;
public class HologramLocation {
private World world;
private double x, y, z;
private int chunkX, chunkZ;
private final CachedBoolean chunkLoaded;
public HologramLocation(Location location) {
this.chunkLoaded = new CachedBoolean(() -> world.isChunkLoaded(chunkX, chunkZ));
set(location);
}
public World getWorld() {
return world;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public double getZ() {
return z;
}
public int getBlockX() {
return Location.locToBlock(x);
}
public int getBlockY() {
return Location.locToBlock(y);
}
public int getBlockZ() {
return Location.locToBlock(z);
}
protected void set(Location location) {
Preconditions.notNull(location, "location");
set(location.getWorld(), location.getX(), location.getY(), location.getZ());
}
protected void set(World world, double x, double y, double z) {
Preconditions.notNull(world, "world");
this.world = world;
this.x = x;
this.y = y;
this.z = z;
int newChunkX = getChunkCoord(x);
int newChunkZ = getChunkCoord(z);
if (this.chunkX != newChunkX || this.chunkZ != newChunkZ) {
this.chunkX = newChunkX;
this.chunkZ = newChunkZ;
this.chunkLoaded.invalidate();
}
}
private int getChunkCoord(double locationCoord) {
return Location.locToBlock(locationCoord) >> 4;
}
public boolean isInLoadedChunk() {
return chunkLoaded.get();
}
public void onChunkLoad(Chunk chunk) {
if (world == chunk.getWorld() && chunkX == chunk.getX() && chunkZ == chunk.getZ()) {
chunkLoaded.set(true);
}
}
public void onChunkUnload(Chunk chunk) {
if (world == chunk.getWorld() && chunkX == chunk.getX() && chunkZ == chunk.getZ()) {
chunkLoaded.set(false);
}
}
public Location toBukkitLocation() {
return new Location(world, x, y, z);
}
public double distance(Location location) {
return Math.sqrt(distanceSquared(location));
}
public double distanceSquared(Location location) {
return NumberConversions.square(this.x - location.getX())
+ NumberConversions.square(this.y - location.getY())
+ NumberConversions.square(this.z - location.getZ());
}
@Override
public String toString() {
return "HologramLocation ["
+ "world=" + world
+ ", x=" + x
+ ", y=" + y
+ ", z=" + z
+ "]";
}
}

View File

@ -7,8 +7,8 @@ package me.filoghost.holographicdisplays.plugin.hologram.internal;
import me.filoghost.holographicdisplays.plugin.HolographicDisplays;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologram;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPosition;
import me.filoghost.holographicdisplays.plugin.hologram.tracking.LineTrackerManager;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
@ -17,8 +17,8 @@ public class InternalHologram extends BaseHologram<InternalHologramLine> {
private final String name;
protected InternalHologram(Location location, String name, LineTrackerManager lineTrackerManager) {
super(location, lineTrackerManager);
protected InternalHologram(BaseHologramPosition position, String name, LineTrackerManager lineTrackerManager) {
super(position, lineTrackerManager);
this.name = name;
}

View File

@ -6,8 +6,8 @@
package me.filoghost.holographicdisplays.plugin.hologram.internal;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramManager;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPosition;
import me.filoghost.holographicdisplays.plugin.hologram.tracking.LineTrackerManager;
import org.bukkit.Location;
public class InternalHologramManager extends BaseHologramManager<InternalHologram> {
@ -17,8 +17,8 @@ public class InternalHologramManager extends BaseHologramManager<InternalHologra
this.lineTrackerManager = lineTrackerManager;
}
public InternalHologram createHologram(Location source, String name) {
InternalHologram hologram = new InternalHologram(source, name, lineTrackerManager);
public InternalHologram createHologram(BaseHologramPosition position, String name) {
InternalHologram hologram = new InternalHologram(position, name, lineTrackerManager);
super.addHologram(hologram);
return hologram;
}

View File

@ -10,10 +10,10 @@ import com.gmail.filoghost.holographicdisplays.api.line.TextLine;
import me.filoghost.holographicdisplays.api.hologram.ClickListener;
import me.filoghost.holographicdisplays.plugin.hologram.api.APIHologram;
import me.filoghost.holographicdisplays.plugin.hologram.api.APIHologramManager;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPosition;
import me.filoghost.holographicdisplays.plugin.hologram.api.APITextLine;
import me.filoghost.holographicdisplays.plugin.test.Mocks;
import me.filoghost.holographicdisplays.plugin.test.TestAPIHologramManager;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;
@ -26,7 +26,7 @@ class V2TouchableLineAdapterTest {
APIHologramManager apiHologramManager = new TestAPIHologramManager();
APIHologram hologram = apiHologramManager.createHologram(
new Location(Mocks.WORLD, 0, 0, 0),
new BaseHologramPosition(Mocks.WORLD, 0, 0, 0),
Mocks.PLUGIN
);