diff --git a/src/de/steamwar/lobby/Displayable.java b/src/de/steamwar/lobby/Displayable.java new file mode 100644 index 0000000..7fd21c5 --- /dev/null +++ b/src/de/steamwar/lobby/Displayable.java @@ -0,0 +1,91 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.lobby; + +import de.steamwar.lobby.listener.BasicListener; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import java.util.HashSet; +import java.util.Set; +import java.util.function.Consumer; + +public class Displayable extends BasicListener { + + private final Set visible = new HashSet<>(); + + private final int chunkX; + private final int chunkZ; + private final Consumer show; + private final Consumer hide; + + public Displayable(Location location, Consumer show, Consumer hide) { + this.chunkX = posToChunk(location.getX()); + this.chunkZ = posToChunk(location.getZ()); + this.show = show; + this.hide = hide; + } + + @EventHandler + public void onJoin(PlayerJoinEvent e) { + checkLocation(e.getPlayer(), e.getPlayer().getLocation()); + } + + @EventHandler + public void onMove(PlayerMoveEvent e) { + checkLocation(e.getPlayer(), e.getTo()); + } + + private void checkLocation(Player player, Location at) { + boolean shown = visible.contains(player); + int viewDistance = player.getClientViewDistance(); + boolean see = Math.abs(chunkX - posToChunk(at.getX())) < viewDistance && Math.abs(chunkZ - posToChunk(at.getZ())) < viewDistance; + + if(!shown && see) { + show.accept(player); + visible.add(player); + } + + if(shown && !see) { + hide.accept(player); + visible.remove(player); + } + } + + @EventHandler + public void onQuit(PlayerQuitEvent e) { + visible.remove(e.getPlayer()); + } + + public void delete() { + visible.forEach(hide); + visible.clear(); + HandlerList.unregisterAll(this); + } + + private int posToChunk(double coord) { + return (int)(coord / 16) - (coord < 0 ? 1 : 0); + } +}