Refactor hologram position fields into separate class
This commit is contained in:
parent
150cc4c62b
commit
7fb38d82e4
|
@ -8,8 +8,6 @@ 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.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
|
@ -22,25 +20,19 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class BaseHologram<T extends EditableHologramLine> extends BaseHologramComponent {
|
||||
|
||||
private final WorldAwareHologramPosition position;
|
||||
private final List<T> lines;
|
||||
private final List<T> unmodifiableLinesView;
|
||||
private final LineTrackerManager lineTrackerManager;
|
||||
|
||||
private @Nullable World world;
|
||||
private String worldName;
|
||||
private double x, y, z;
|
||||
private int chunkX, chunkZ;
|
||||
private final CachedBoolean isInLoadedChunk = new CachedBoolean(() -> world != null && world.isChunkLoaded(chunkX, chunkZ));
|
||||
|
||||
public BaseHologram(BaseHologramPosition position, LineTrackerManager lineTrackerManager) {
|
||||
this.position = new WorldAwareHologramPosition(position);
|
||||
this.lines = new ArrayList<>();
|
||||
this.unmodifiableLinesView = Collections.unmodifiableList(lines);
|
||||
this.lineTrackerManager = lineTrackerManager;
|
||||
setPosition(position);
|
||||
}
|
||||
|
||||
protected abstract boolean isVisibleTo(Player player);
|
||||
|
@ -133,27 +125,27 @@ public abstract class BaseHologram<T extends EditableHologramLine> extends BaseH
|
|||
}
|
||||
|
||||
public BaseHologramPosition getBasePosition() {
|
||||
return new BaseHologramPosition(getPositionWorldName(), getPositionX(), getPositionY(), getPositionZ());
|
||||
return position.toBasePosition();
|
||||
}
|
||||
|
||||
public @Nullable World getPositionWorldIfLoaded() {
|
||||
return world;
|
||||
return position.getWorldIfLoaded();
|
||||
}
|
||||
|
||||
public @NotNull String getPositionWorldName() {
|
||||
return worldName;
|
||||
return position.getWorldName();
|
||||
}
|
||||
|
||||
public double getPositionX() {
|
||||
return x;
|
||||
return position.getX();
|
||||
}
|
||||
|
||||
public double getPositionY() {
|
||||
return y;
|
||||
return position.getY();
|
||||
}
|
||||
|
||||
public double getPositionZ() {
|
||||
return z;
|
||||
return position.getZ();
|
||||
}
|
||||
|
||||
public void setPosition(@NotNull BaseHologramPosition position) {
|
||||
|
@ -176,33 +168,16 @@ public abstract class BaseHologram<T extends EditableHologramLine> extends BaseH
|
|||
Preconditions.notNull(worldName, "worldName");
|
||||
checkNotDeleted();
|
||||
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
|
||||
int chunkX = getChunkCoordinate(x);
|
||||
int chunkZ = getChunkCoordinate(z);
|
||||
if (!Objects.equals(this.worldName, worldName) || this.chunkX != chunkX || this.chunkZ != chunkZ) {
|
||||
this.world = Bukkit.getWorld(worldName);
|
||||
this.worldName = worldName;
|
||||
this.chunkX = chunkX;
|
||||
this.chunkZ = chunkZ;
|
||||
this.isInLoadedChunk.invalidate();
|
||||
}
|
||||
|
||||
position.set(worldName, x, y, z);
|
||||
updateLinePositions();
|
||||
}
|
||||
|
||||
private int getChunkCoordinate(double positionCoordinate) {
|
||||
return Location.locToBlock(positionCoordinate) >> 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* When spawning at a location, the top part of the first line should be exactly on that location.
|
||||
* The second line is below the first, and so on.
|
||||
*/
|
||||
private void updateLinePositions() {
|
||||
double currentLineY = y;
|
||||
double currentLineY = position.getY();
|
||||
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
T line = lines.get(i);
|
||||
|
@ -212,44 +187,34 @@ public abstract class BaseHologram<T extends EditableHologramLine> extends BaseH
|
|||
currentLineY -= Settings.spaceBetweenLines;
|
||||
}
|
||||
|
||||
line.setPosition(x, currentLineY, z);
|
||||
line.setPosition(position.getX(), currentLineY, position.getZ());
|
||||
}
|
||||
}
|
||||
|
||||
protected void onWorldLoad(World world) {
|
||||
if (BaseHologramPosition.isSameWorld(world, this.worldName)) {
|
||||
this.world = world;
|
||||
isInLoadedChunk.invalidate();
|
||||
}
|
||||
position.onWorldLoad(world);
|
||||
}
|
||||
|
||||
protected void onWorldUnload(World world) {
|
||||
if (BaseHologramPosition.isSameWorld(world, this.worldName)) {
|
||||
this.world = null;
|
||||
isInLoadedChunk.set(false);
|
||||
}
|
||||
position.onWorldUnload(world);
|
||||
}
|
||||
|
||||
protected void onChunkLoad(Chunk chunk) {
|
||||
if (world == chunk.getWorld() && chunkX == chunk.getX() && chunkZ == chunk.getZ()) {
|
||||
isInLoadedChunk.set(true);
|
||||
}
|
||||
position.onChunkLoad(chunk);
|
||||
}
|
||||
|
||||
protected void onChunkUnload(Chunk chunk) {
|
||||
if (world == chunk.getWorld() && chunkX == chunk.getX() && chunkZ == chunk.getZ()) {
|
||||
isInLoadedChunk.set(false);
|
||||
}
|
||||
position.onChunkUnload(chunk);
|
||||
}
|
||||
|
||||
protected boolean isInLoadedChunk() {
|
||||
return isInLoadedChunk.get();
|
||||
return position.isChunkLoaded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Hologram{"
|
||||
+ "position=" + getBasePosition()
|
||||
+ "position=" + position
|
||||
+ ", lines=" + lines
|
||||
+ ", deleted=" + isDeleted()
|
||||
+ "}";
|
||||
|
|
|
@ -17,10 +17,18 @@ import java.util.Locale;
|
|||
|
||||
public class BaseHologramPosition {
|
||||
|
||||
private String worldName;
|
||||
private @NotNull String worldName;
|
||||
private double x, y, z;
|
||||
|
||||
public BaseHologramPosition(String worldName, double x, double y, double z) {
|
||||
public BaseHologramPosition(BaseHologramPosition position) {
|
||||
Preconditions.notNull(position, "position");
|
||||
this.worldName = position.worldName;
|
||||
this.x = position.x;
|
||||
this.y = position.y;
|
||||
this.z = position.z;
|
||||
}
|
||||
|
||||
public BaseHologramPosition(@NotNull String worldName, double x, double y, double z) {
|
||||
Preconditions.notNull(worldName, "worldName");
|
||||
this.worldName = worldName;
|
||||
this.x = x;
|
||||
|
@ -47,7 +55,12 @@ public class BaseHologramPosition {
|
|||
}
|
||||
|
||||
public boolean isInWorld(World world) {
|
||||
return world != null && isSameWorld(world, this.worldName);
|
||||
return world != null && isInWorld(world.getName());
|
||||
}
|
||||
|
||||
public boolean isInWorld(String worldName) {
|
||||
// Use the same comparison used by Bukkit.getWorld(...)
|
||||
return worldName != null && worldName.toLowerCase(Locale.ENGLISH).equals(this.worldName.toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
public @Nullable World getWorldIfLoaded() {
|
||||
|
@ -89,6 +102,13 @@ public class BaseHologramPosition {
|
|||
this.z += z;
|
||||
}
|
||||
|
||||
public void set(String worldName, double x, double y, double z) {
|
||||
this.worldName = worldName;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public int getBlockX() {
|
||||
return Location.locToBlock(x);
|
||||
}
|
||||
|
@ -126,9 +146,4 @@ public class BaseHologramPosition {
|
|||
+ "}";
|
||||
}
|
||||
|
||||
static boolean isSameWorld(World world, String worldName) {
|
||||
// Use the same comparison used by Bukkit.getWorld(...)
|
||||
return world.getName().toLowerCase(Locale.ENGLISH).equals(worldName.toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright (C) filoghost and contributors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
package me.filoghost.holographicdisplays.plugin.hologram.base;
|
||||
|
||||
import me.filoghost.holographicdisplays.plugin.util.CachedBoolean;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
class WorldAwareHologramPosition {
|
||||
|
||||
private final BaseHologramPosition basePosition;
|
||||
private @Nullable World world;
|
||||
private int chunkX, chunkZ;
|
||||
private final CachedBoolean chunkLoaded;
|
||||
|
||||
WorldAwareHologramPosition(BaseHologramPosition basePosition) {
|
||||
this.basePosition = new BaseHologramPosition(basePosition);
|
||||
this.world = Bukkit.getWorld(basePosition.getWorldName());
|
||||
this.chunkX = getChunkCoordinate(basePosition.getX());
|
||||
this.chunkZ = getChunkCoordinate(basePosition.getZ());
|
||||
this.chunkLoaded = new CachedBoolean(() -> world != null && world.isChunkLoaded(chunkX, chunkZ));
|
||||
}
|
||||
|
||||
final void set(String worldName, double x, double y, double z) {
|
||||
boolean worldChanged = !basePosition.isInWorld(worldName);
|
||||
int chunkX = getChunkCoordinate(x);
|
||||
int chunkZ = getChunkCoordinate(z);
|
||||
|
||||
basePosition.set(worldName, x, y, z);
|
||||
|
||||
if (worldChanged || this.chunkX != chunkX || this.chunkZ != chunkZ) {
|
||||
if (worldChanged) {
|
||||
this.world = Bukkit.getWorld(worldName);
|
||||
}
|
||||
this.chunkX = chunkX;
|
||||
this.chunkZ = chunkZ;
|
||||
this.chunkLoaded.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private int getChunkCoordinate(double positionCoordinate) {
|
||||
return Location.locToBlock(positionCoordinate) >> 4;
|
||||
}
|
||||
|
||||
void onWorldLoad(World world) {
|
||||
if (basePosition.isInWorld(world)) {
|
||||
this.world = world;
|
||||
chunkLoaded.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void onWorldUnload(World world) {
|
||||
if (basePosition.isInWorld(world)) {
|
||||
this.world = null;
|
||||
chunkLoaded.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
void onChunkLoad(Chunk chunk) {
|
||||
if (world != null && world == chunk.getWorld() && chunkX == chunk.getX() && chunkZ == chunk.getZ()) {
|
||||
chunkLoaded.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
void onChunkUnload(Chunk chunk) {
|
||||
if (world != null && world == chunk.getWorld() && chunkX == chunk.getX() && chunkZ == chunk.getZ()) {
|
||||
chunkLoaded.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
boolean isChunkLoaded() {
|
||||
return chunkLoaded.get();
|
||||
}
|
||||
|
||||
@Nullable World getWorldIfLoaded() {
|
||||
return world;
|
||||
}
|
||||
|
||||
@NotNull String getWorldName() {
|
||||
return basePosition.getWorldName();
|
||||
}
|
||||
|
||||
double getX() {
|
||||
return basePosition.getX();
|
||||
}
|
||||
|
||||
double getY() {
|
||||
return basePosition.getY();
|
||||
}
|
||||
|
||||
double getZ() {
|
||||
return basePosition.getZ();
|
||||
}
|
||||
|
||||
BaseHologramPosition toBasePosition() {
|
||||
return new BaseHologramPosition(basePosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return basePosition.toString();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue