From 99eff9bda84ce316eaac3bf27dd4315ee5ad8929 Mon Sep 17 00:00:00 2001 From: Brianna Date: Mon, 14 Oct 2019 12:59:18 -0400 Subject: [PATCH] Added command "show" so you can see the claimed chunk. --- .../com/songoda/epicanchors/EpicAnchors.java | 10 +- .../songoda/epicanchors/anchor/Anchor.java | 20 ++-- .../epicanchors/anchor/AnchorManager.java | 5 + .../epicanchors/commands/CommandShow.java | 59 ++++++++++ .../epicanchors/tasks/VisualizeTask.java | 104 ++++++++++++++++++ src/main/resources/en_US.lang | 2 + 6 files changed, 184 insertions(+), 16 deletions(-) create mode 100644 src/main/java/com/songoda/epicanchors/commands/CommandShow.java create mode 100644 src/main/java/com/songoda/epicanchors/tasks/VisualizeTask.java diff --git a/src/main/java/com/songoda/epicanchors/EpicAnchors.java b/src/main/java/com/songoda/epicanchors/EpicAnchors.java index 2fd1c3d..95a293b 100644 --- a/src/main/java/com/songoda/epicanchors/EpicAnchors.java +++ b/src/main/java/com/songoda/epicanchors/EpicAnchors.java @@ -10,14 +10,12 @@ import com.songoda.core.hooks.EconomyManager; import com.songoda.core.hooks.HologramManager; import com.songoda.epicanchors.anchor.Anchor; import com.songoda.epicanchors.anchor.AnchorManager; -import com.songoda.epicanchors.commands.CommandEpicAnchors; -import com.songoda.epicanchors.commands.CommandGive; -import com.songoda.epicanchors.commands.CommandReload; -import com.songoda.epicanchors.commands.CommandSettings; +import com.songoda.epicanchors.commands.*; import com.songoda.epicanchors.listeners.BlockListeners; import com.songoda.epicanchors.listeners.InteractListeners; import com.songoda.epicanchors.settings.Settings; import com.songoda.epicanchors.tasks.AnchorTask; +import com.songoda.epicanchors.tasks.VisualizeTask; import com.songoda.epicanchors.utils.Methods; import org.apache.commons.lang.math.NumberUtils; import org.bukkit.Bukkit; @@ -76,7 +74,8 @@ public class EpicAnchors extends SongodaPlugin { .addSubCommands( new CommandGive(this), new CommandReload(this), - new CommandSettings(this, guiManager) + new CommandSettings(this, guiManager), + new CommandShow(this) ); anchorManager = new AnchorManager(); @@ -84,6 +83,7 @@ public class EpicAnchors extends SongodaPlugin { // Start tasks new AnchorTask(this); + new VisualizeTask(this); // Register Listeners guiManager.init(); diff --git a/src/main/java/com/songoda/epicanchors/anchor/Anchor.java b/src/main/java/com/songoda/epicanchors/anchor/Anchor.java index b52c1de..e2d726f 100644 --- a/src/main/java/com/songoda/epicanchors/anchor/Anchor.java +++ b/src/main/java/com/songoda/epicanchors/anchor/Anchor.java @@ -12,8 +12,13 @@ public class Anchor { private Location location; private int ticksLeft; + private final int chunkX; + private final int chunkZ; + public Anchor(Location location, int ticksLeft) { this.location = location; + this.chunkX = location.getBlockX() >> 4; + this.chunkZ = location.getBlockZ() >> 4; this.ticksLeft = ticksLeft; } @@ -72,21 +77,14 @@ public class Anchor { return location.clone(); } - public int getX() { - return location.getBlockX(); + public int getChunkX() { + return chunkX; } - - public int getY() { - return location.getBlockY(); + public int getChunkZ() { + return chunkZ; } - - public int getZ() { - return location.getBlockZ(); - } - - public World getWorld() { return location.getWorld(); } diff --git a/src/main/java/com/songoda/epicanchors/anchor/AnchorManager.java b/src/main/java/com/songoda/epicanchors/anchor/AnchorManager.java index a9af901..1edbb81 100644 --- a/src/main/java/com/songoda/epicanchors/anchor/AnchorManager.java +++ b/src/main/java/com/songoda/epicanchors/anchor/AnchorManager.java @@ -22,6 +22,11 @@ public class AnchorManager { return registeredAnchors.get(roundLocation(location)); } + public Anchor getAnchor(String world, int chunkX, int chunkZ) { + return this.registeredAnchors.values().stream() + .filter(anchor -> anchor.getWorld().getName().equals(world) && anchor.getChunkX() == chunkX && anchor.getChunkZ() == chunkZ).findFirst().orElse(null); + } + public boolean isAnchor(Location location) { return registeredAnchors.containsKey(location); } diff --git a/src/main/java/com/songoda/epicanchors/commands/CommandShow.java b/src/main/java/com/songoda/epicanchors/commands/CommandShow.java new file mode 100644 index 0000000..30f7161 --- /dev/null +++ b/src/main/java/com/songoda/epicanchors/commands/CommandShow.java @@ -0,0 +1,59 @@ +package com.songoda.epicanchors.commands; + +import com.songoda.core.commands.AbstractCommand; +import com.songoda.epicanchors.EpicAnchors; +import com.songoda.epicanchors.tasks.VisualizeTask; +import net.md_5.bungee.api.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; + +public class CommandShow extends AbstractCommand { + + private final EpicAnchors plugin; + + public CommandShow(EpicAnchors plugin) { + super(true, "show"); + this.plugin = plugin; + } + + @Override + protected ReturnType runCommand(CommandSender sender, String... args) { + if(!(sender instanceof Player)) { + sender.sendMessage(ChatColor.RED + "Command must be called as a player"); + return ReturnType.FAILURE; + } + Player player = (Player) sender; + + if (args.length != 0) + return ReturnType.SYNTAX_ERROR; + + if(VisualizeTask.togglePlayer(player)) + plugin.getLocale().getMessage("command.show.start").sendPrefixedMessage(player); + else + plugin.getLocale().getMessage("command.show.stop").sendPrefixedMessage(player); + + return ReturnType.SUCCESS; + } + + @Override + protected List onTab(CommandSender sender, String... args) { + return null; + } + + @Override + public String getPermissionNode() { + return "epicanchors.show"; + } + + @Override + public String getSyntax() { + return "show"; + } + + @Override + public String getDescription() { + return "Visualize anchors around you"; + } +} diff --git a/src/main/java/com/songoda/epicanchors/tasks/VisualizeTask.java b/src/main/java/com/songoda/epicanchors/tasks/VisualizeTask.java new file mode 100644 index 0000000..b1e1cd6 --- /dev/null +++ b/src/main/java/com/songoda/epicanchors/tasks/VisualizeTask.java @@ -0,0 +1,104 @@ +package com.songoda.epicanchors.tasks; + +import com.songoda.epicanchors.EpicAnchors; +import com.songoda.epicanchors.anchor.Anchor; +import com.songoda.epicanchors.anchor.AnchorManager; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.Map; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; + +public class VisualizeTask extends BukkitRunnable { + + private static VisualizeTask instance; + private static EpicAnchors plugin; + private final static Map active = new ConcurrentHashMap(); + private final static Random random = new Random(); + int radius; + + public VisualizeTask(EpicAnchors plug) { + plugin = plug; + radius = Bukkit.getServer().getViewDistance(); + if (instance == null) { + instance = this; + instance.runTaskTimerAsynchronously(plugin, 60, 10); + } + } + + public static boolean togglePlayer(Player p) { + Boolean isActive = active.get(p); + active.put(p, isActive = (isActive == null || !isActive)); + return isActive; + } + + public static void removePlayer(Player p) { + active.remove(p); + } + + @Override + public void run() { + active.entrySet().stream() + .filter(e -> e.getValue() && e.getKey().isOnline()) + .forEach(e -> particleTick((Player) e.getKey())); + } + + void particleTick(Player player) { + final AnchorManager anchorManager = plugin.getAnchorManager(); + final Location playerLocation = player.getLocation(); + final World world = playerLocation.getWorld(); + // start and stop chunk coordinates + int startY = playerLocation.getBlockY() + 1; + int cxi = (playerLocation.getBlockX() >> 4) - radius, cxn = cxi + radius * 2; + int czi = (playerLocation.getBlockZ() >> 4) - radius, czn = czi + radius * 2; + // loop through the chunks to find applicable ones + for (int cx = cxi; cx < cxn; cx++) { + for (int cz = czi; cz < czn; cz++) { + // sanity check + if (!world.isChunkLoaded(cx, cz)) + continue; + + // so! Is this a claimed chunk? + Anchor anchor = anchorManager.getAnchor(world.getName(), cx, cz); + if (anchor != null) { + // we found one! + // now we get to spawn the silly particles for the player + showChunkParticles(player, world.getChunkAt(cx, cz), startY); + } + } + } + } + + void showChunkParticles(Player player, Chunk c, int startY) { + // loop through the chunk + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + // show about 1/5 of the blocks per tick + boolean show = random.nextFloat() < .2; + if (!show) + continue; + + // Exclude everything over max height + if (startY >= c.getWorld().getMaxHeight()) continue; + + // only show if there is a space to show above a solid block + Block b = c.getBlock(x, startY, z); + int maxDown = 8; + do { + show = b.getType().isTransparent() && !(b = b.getRelative(BlockFace.DOWN)).getType().isTransparent(); + } while (--maxDown > 0 && !show); + + // can we do this? + if (show) { + final Location loc = b.getLocation().add(.5, 1.5, .5); + + player.spawnParticle(Particle.VILLAGER_HAPPY, loc, 0, 0, 0, 0, 1); + } + } + } + } +} diff --git a/src/main/resources/en_US.lang b/src/main/resources/en_US.lang index 3811c7b..5446901 100644 --- a/src/main/resources/en_US.lang +++ b/src/main/resources/en_US.lang @@ -16,6 +16,8 @@ interface.anchor.smalltitle = "&eChunkAnchor" #Command Messages command.give.success = "&7You have been given a ChunkAnchor." +command.show.start = "&7Anchor visualizer &2enabled." +command.show.stop = "&7Anchor visualizer &cdisabled." #Event Messages