Skip to content

Commit

Permalink
Finish new visibility updates?
Browse files Browse the repository at this point in the history
  • Loading branch information
d0by1 committed Nov 15, 2023
1 parent 21f2721 commit 5056316
Show file tree
Hide file tree
Showing 13 changed files with 162 additions and 225 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,8 @@ private void setupUpdateChecker() {
// Compare the versions
Config.setUpdateAvailable(
(latest[0] > current[0]) || // Major
(latest[0] == current[0] && latest[1] > current[1]) || // Minor
(latest[0] == current[0] && latest[1] == current[1] && latest[2] > current[2]) // Patch
(latest[0] == current[0] && latest[1] > current[1]) || // Minor
(latest[0] == current[0] && latest[1] == current[1] && latest[2] > current[2]) // Patch
);

// Notify if an update is available
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ private void complexRecalculate(
}

if (renderer != null) {
renderer.updateLocation(player, i, location);
renderer.updateLocation(player, location);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,8 @@ public void destroy() {
public void display(@NonNull Player player) {
checkDestroyed();

for (int i = 0; i < this.lines.size(); i++) {
LINE line = this.lines.get(i);
line.display(player, i);
for (LINE line : this.lines) {
line.display(player);
}
}

Expand All @@ -74,9 +73,8 @@ public void display(@NonNull Player player) {
public void hide(@NonNull Player player) {
checkDestroyed();

for (int i = 0; i < this.lines.size(); i++) {
LINE line = this.lines.get(i);
line.hide(player, i);
for (LINE line : this.lines) {
line.hide(player);
}
}

Expand All @@ -89,9 +87,8 @@ public void hide(@NonNull Player player) {
public void updateContent(@NonNull Player player) {
checkDestroyed();

for (int i = 0; i < this.lines.size(); i++) {
LINE line = this.lines.get(i);
line.updateContent(player, i);
for (LINE line : this.lines) {
line.updateContent(player);
}
}

Expand All @@ -104,9 +101,8 @@ public void updateContent(@NonNull Player player) {
public void updateLocation(@NonNull Player player) {
checkDestroyed();

for (int i = 0; i < this.lines.size(); i++) {
LINE line = this.lines.get(i);
line.updateLocation(player, i);
for (LINE line : this.lines) {
line.updateLocation(player);
}
}

Expand Down Expand Up @@ -158,7 +154,7 @@ public int getIndex(@NonNull CoreHologramLine line) {
public void removeLine(int index) {
LINE line = this.lines.remove(index);

forEachViewerUseLineRendererSafe(line, (renderer, player) -> renderer.hide(player, index));
forEachViewerUseLineRendererSafe(line, HologramLineRenderer::hide);
updateLinePositions();
this.parent.recalculate();
}
Expand All @@ -171,9 +167,8 @@ public void appendLine(@NonNull LINE line) {
checkDestroyed();

this.lines.add(line);
int index = this.lines.size() - 1;

forEachViewerUseLineRendererSafe(line, (renderer, player) -> renderer.display(player, index));
forEachViewerUseLineRendererSafe(line, HologramLineRenderer::display);
updateLinePositions();
this.parent.recalculate();
}
Expand All @@ -184,7 +179,7 @@ public void insertLine(int index, @NonNull String content) {
LINE line = createLine(getNextLineLocation(), content);
this.lines.add(index, line);

forEachViewerUseLineRendererSafe(line, (renderer, player) -> renderer.display(player, index));
forEachViewerUseLineRendererSafe(line, HologramLineRenderer::display);
updateLinePositions();
this.parent.recalculate();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public synchronized void updateVisibleLines() {
}

if (this.visibleLines.size() <= visibleLinesIndex) {
line.display(this.player, visibleLinesIndex);
line.display(this.player);
this.visibleLines.add(line);
continue;
}
Expand All @@ -121,46 +121,42 @@ public synchronized void updateVisibleLines() {
* more efficient than hiding the old line and displaying the new one. It
* also prevents flickering when the line is updated.
*/
line.updateContent(this.player, visibleLinesIndex);
line.updateContent(this.player);
} else {
currentLine.hide(this.player, visibleLinesIndex);
line.display(this.player, visibleLinesIndex);
currentLine.hide(this.player);
line.display(this.player);
}
}

if (newVisibleLinesCount < this.visibleLines.size()) {
for (int i = newVisibleLinesCount; i < this.visibleLines.size(); i++) {
CoreHologramLine currentLine = this.visibleLines.remove(i);
currentLine.hide(this.player, i);
currentLine.hide(this.player);
}
}
}

protected synchronized void hideVisibleLines() {
for (int i = 0; i < this.visibleLines.size(); i++) {
CoreHologramLine line = this.visibleLines.get(i);
line.hide(this.player, i);
for (CoreHologramLine line : this.visibleLines) {
line.hide(this.player);
}
}

protected synchronized void displayVisibleLines() {
for (int i = 0; i < this.visibleLines.size(); i++) {
CoreHologramLine line = this.visibleLines.get(i);
line.display(this.player, i);
for (CoreHologramLine line : this.visibleLines) {
line.display(this.player);
}
}

protected synchronized void updateVisibleLinesContents() {
for (int i = 0; i < this.visibleLines.size(); i++) {
CoreHologramLine line = this.visibleLines.get(i);
line.updateContent(this.player, i);
for (CoreHologramLine line : this.visibleLines) {
line.updateContent(this.player);
}
}

protected synchronized void updateVisibleLinesLocations() {
for (int i = 0; i < this.visibleLines.size(); i++) {
CoreHologramLine line = this.visibleLines.get(i);
line.updateLocation(this.player, i);
for (CoreHologramLine line : this.visibleLines) {
line.updateLocation(this.player);
}
}

Expand Down Expand Up @@ -208,6 +204,16 @@ public synchronized void setCurrentPage(int index) {
this.setCurrentPage(page, index);
}

/**
* Check if the specified line is currently visible to the player.
*
* @param line The line to check.
* @return True if the line is visible, false otherwise.
*/
public boolean canSeeLine(@NonNull CoreHologramLine line) {
return this.visibleLines.contains(line);
}

@NonNull
public CoreHologramPage<?> getCurrentPage() {
return this.currentPage;
Expand All @@ -219,7 +225,7 @@ public int getCurrentPageIndex() {

@NonNull
public Player getPlayer() {
return player;
return this.player;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,20 @@

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import eu.decentsoftware.holograms.api.hologram.HologramVisibilityManager;
import eu.decentsoftware.holograms.api.hologram.Visibility;
import eu.decentsoftware.holograms.utils.math.MathUtil;
import eu.decentsoftware.holograms.core.line.CoreHologramLine;
import lombok.NonNull;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;

import java.util.*;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -83,29 +87,20 @@ public void destroy() {
this.defaultVisibility = Visibility.HIDDEN;
this.playerVisibilityMap.clear();

getViewersAsPlayers().forEach(player -> updateVisibility(player, false));
getViewersAsPlayers().forEach(this::removePlayer);

this.currentViewers.clear();
}

/**
* Completely remove the given player from the visibility cache. This means that the player
* will only be able to see the hologram again, if the hologram is visible by default and
* the player meets the view conditions.
* <p>
* But all custom visibility settings for the player will be removed and all hologram lines
* that the player is currently viewing will be hidden. (Not permanently, but until the
* next update of the hologram's visibility.)
*
* @param player The player to remove.
* @see #updateVisibility(Player, boolean)
*/
public void removePlayer(@NonNull Player player) {
this.playerVisibilityMap.remove(player.getUniqueId());

if (isViewing(player)) {
updateVisibility(player, false);
CoreHologramView view = getView(player).orElse(null);
if (view == null) {
return;
}

view.destroy();

this.currentViewers.remove(player.getUniqueId());
}

/**
Expand All @@ -116,59 +111,18 @@ public void removePlayer(@NonNull Player player) {
* @param player The player to update the visibility for.
*/
public void updateVisibility(@NonNull Player player) {
if (!canSee(player)) {
if (isViewing(player)) {
updateVisibility(player, false);
CoreHologramView view = getView(player).orElse(null);
if (view == null) {
CoreHologramPage<?> page = parent.getPage(0);
if (page == null) {
return;
}
return;
}

boolean inViewDistance = isInViewDistance(player);
boolean isAllowed = checkHologramViewConditions(player);
boolean canSee = canSee(player);
if (isViewing(player) && (!inViewDistance || !canSee || !isAllowed)) {
updateVisibility(player, false);
} else if (!isViewing(player) && inViewDistance && canSee && isAllowed) {
updateVisibility(player, true);
view = createView(player, page);
this.currentViewers.put(player.getUniqueId(), view);
}
}

/**
* Updates the visibility of the hologram for the specified player. This
* method displays or hides the hologram according to the specified boolean.
* This method does not check the holograms view distance setting and view
* conditions. This method does not update the list of players that are allowed
* to see this hologram, it only updates the list of players that are currently
* viewing this hologram.
*
* <p>If the specified player is in the allowed players list, the visibility
* is going to be automatically updated for them on the next update. If not,
* the visibility will stay at the given value.</p>
*
* <p>Keep in mind, that if you only display the hologram to the player using
* this method, the visibility will not be updated according to the view distance
* setting and view conditions which may cause visibility problems like the player
* not seeing the hologram when they go farther away from it and then come back.</p>
*
* <p>This method is mainly used internally by the {@link HologramVisibilityManager}
* and should not be used anywhere else as it may cause unexpected behavior.</p>
*
* @param player The player to update the visibility for.
* @param visible True to show the hologram, false to hide it.
* @see #getViewers()
* @see #getAllowedPlayers()
*/
public void updateVisibility(@NonNull Player player, boolean visible) {
Optional<CoreHologramPage<?>> pageOpt = getPageObject(player);
pageOpt.ifPresent(page -> {
if (visible) {
page.display(player);
this.currentViewers.put(player.getUniqueId(), createView(player, page));
} else {
page.hide(player);
this.currentViewers.remove(player.getUniqueId()).destroy();
}
});
view.updateVisibleLines();
}

/**
Expand Down Expand Up @@ -233,18 +187,6 @@ public void resetPlayerPages() {
}
}

/**
* Check if the given player is currently seeing this hologram according
* to the view conditions and the view distance setting of this hologram,
* i.e. if the player is in the set returned by {@link #getViewers()}.
*
* @param player The player to check.
* @return True if the player is currently seeing this hologram, false otherwise.
*/
private boolean isViewing(@NonNull Player player) {
return getViewers().contains(player.getUniqueId());
}

/**
* Check if the given player is allowed to see this hologram.
*
Expand All @@ -258,21 +200,6 @@ private boolean canSee(@NonNull Player player) {
return isVisibleByDefault();
}

/**
* Check if the given player is within the view distance of this hologram. Meaning
* that the player is close enough to the hologram to be able to see it.
*
* @param player The player to check.
* @return True if the player is within the view distance of this hologram, false otherwise.
*/
private boolean isInViewDistance(@NonNull Player player) {
return MathUtil.inDistance(
this.parent.getPositionManager().getActualBukkitLocation(),
player.getLocation(),
this.parent.getSettings().getViewDistance()
);
}

/**
* Check if the given player is allowed to see this hologram.
*
Expand All @@ -299,6 +226,23 @@ public Set<Player> getViewersAsPlayers() {
.collect(Collectors.toSet());
}

/**
* Get all the players that currently see the given line according to
* the view conditions and the view distance setting of this hologram.
* The hologram line's contents are updated for all players in this list.
*
* @param line The line to get the viewers for.
* @return The set of players that see the given line.
*/
@NonNull
public Set<Player> getViewersAsPlayers(@NonNull CoreHologramLine line) {
return getViewers().stream()
.map(Bukkit::getPlayer)
.filter(Objects::nonNull)
.filter(player -> getView(player).map(view -> view.canSeeLine(line)).orElse(false))
.collect(Collectors.toSet());
}

/**
* Get the players that are allowed to see the hologram.
*
Expand Down
Loading

0 comments on commit 5056316

Please sign in to comment.