Alot of shit
This commit is contained in:
152
src/main/java/rip/tilly/bedwars/utils/ItemUtil.java
Normal file
152
src/main/java/rip/tilly/bedwars/utils/ItemUtil.java
Normal file
@ -0,0 +1,152 @@
|
||||
package rip.tilly.bedwars.utils;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public final class ItemUtil {
|
||||
|
||||
private ItemUtil() {
|
||||
throw new RuntimeException("Cannot instantiate a utility class.");
|
||||
}
|
||||
|
||||
public static ItemStack createItem(Material material, String name) {
|
||||
ItemStack item = new ItemStack(material);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
meta.setDisplayName(name);
|
||||
item.setItemMeta(meta);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createItem(Material material, String name, int amount) {
|
||||
ItemStack item = new ItemStack(material, amount);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
meta.setDisplayName(name);
|
||||
item.setItemMeta(meta);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createItem(Material material, String name, int amount, short damage) {
|
||||
ItemStack item = new ItemStack(material, amount, damage);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
meta.setDisplayName(name);
|
||||
item.setItemMeta(meta);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createUnbreakableItem(Material material, String name, int amount, short damage) {
|
||||
ItemStack item = new ItemStack(material, amount, damage);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
meta.setDisplayName(name);
|
||||
item.setItemMeta(meta);
|
||||
|
||||
meta.spigot().setUnbreakable(true);
|
||||
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS, ItemFlag.HIDE_UNBREAKABLE);
|
||||
item.setItemMeta(meta);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createNoFlagsItem(Material material, String name, int amount, short damage) {
|
||||
ItemStack item = new ItemStack(material, amount, damage);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
meta.setDisplayName(name);
|
||||
item.setItemMeta(meta);
|
||||
|
||||
meta.spigot().setUnbreakable(true);
|
||||
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_POTION_EFFECTS, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ATTRIBUTES);
|
||||
item.setItemMeta(meta);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createPlayerHead(Material material, String name, String playerHead, int amount, short damage) {
|
||||
ItemStack item = new ItemStack(material, amount, damage);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
meta.setDisplayName(name);
|
||||
item.setItemMeta(meta);
|
||||
|
||||
meta.spigot().setUnbreakable(true);
|
||||
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS, ItemFlag.HIDE_UNBREAKABLE);
|
||||
item.setItemMeta(meta);
|
||||
|
||||
if (item.getType() == Material.SKULL_ITEM) {
|
||||
SkullMeta skullMeta = (SkullMeta) item.getItemMeta();
|
||||
skullMeta.setOwner(playerHead);
|
||||
item.setItemMeta(skullMeta);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack setUnbreakable(ItemStack item) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
meta.spigot().setUnbreakable(true);
|
||||
meta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE);
|
||||
item.setItemMeta(meta);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack renameItem(ItemStack item, String name) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
meta.setDisplayName(name);
|
||||
item.setItemMeta(meta);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack reloreItem(ItemStack item, String... lores) {
|
||||
return reloreItem(ReloreType.OVERWRITE, item, lores);
|
||||
}
|
||||
|
||||
public static ItemStack reloreItem(ReloreType type, ItemStack item, String... lores) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
List<String> lore = meta.getLore();
|
||||
if (lore == null) {
|
||||
lore = new LinkedList<>();
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case APPEND:
|
||||
lore.addAll(Arrays.asList(lores));
|
||||
meta.setLore(lore);
|
||||
break;
|
||||
case PREPEND:
|
||||
List<String> nLore = new LinkedList<>(Arrays.asList(lores));
|
||||
nLore.addAll(lore);
|
||||
meta.setLore(nLore);
|
||||
break;
|
||||
case OVERWRITE:
|
||||
meta.setLore(Arrays.asList(lores));
|
||||
break;
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
return item;
|
||||
}
|
||||
|
||||
public enum ReloreType {
|
||||
OVERWRITE, PREPEND, APPEND
|
||||
}
|
||||
}
|
31
src/main/java/rip/tilly/bedwars/utils/PlayerUtil.java
Normal file
31
src/main/java/rip/tilly/bedwars/utils/PlayerUtil.java
Normal file
@ -0,0 +1,31 @@
|
||||
package rip.tilly.bedwars.utils;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
|
||||
public class PlayerUtil {
|
||||
|
||||
public static void clearPlayer(Player player) {
|
||||
player.setHealth(20.0D);
|
||||
player.setFoodLevel(20);
|
||||
player.setSaturation(12.8F);
|
||||
player.setMaximumNoDamageTicks(20);
|
||||
player.setFireTicks(0);
|
||||
player.setFallDistance(0.0F);
|
||||
player.setLevel(0);
|
||||
player.setExp(0.0F);
|
||||
player.setWalkSpeed(0.2F);
|
||||
player.setFlySpeed(0.2F);
|
||||
player.getInventory().setHeldItemSlot(0);
|
||||
player.setAllowFlight(false);
|
||||
player.getInventory().clear();
|
||||
player.getInventory().setArmorContents(null);
|
||||
player.closeInventory();
|
||||
player.setGameMode(GameMode.SURVIVAL);
|
||||
player.getActivePotionEffects().stream().map(PotionEffect::getType).forEach(player::removePotionEffect);
|
||||
((CraftPlayer) player).getHandle().getDataWatcher().watch(9, (byte) 0);
|
||||
player.updateInventory();
|
||||
}
|
||||
}
|
44
src/main/java/rip/tilly/bedwars/utils/TimeUtils.java
Normal file
44
src/main/java/rip/tilly/bedwars/utils/TimeUtils.java
Normal file
@ -0,0 +1,44 @@
|
||||
package rip.tilly.bedwars.utils;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class TimeUtils {
|
||||
|
||||
private static final ThreadLocal<StringBuilder> MMSS_BUILDER = ThreadLocal.withInitial((Supplier<? extends StringBuilder>) StringBuilder::new);
|
||||
|
||||
public static String formatIntoMMSS(int secs) {
|
||||
final int seconds = secs % 60;
|
||||
secs -= seconds;
|
||||
long minutesCount = secs / 60;
|
||||
final long minutes = minutesCount % 60L;
|
||||
minutesCount -= minutes;
|
||||
final long hours = minutesCount / 60L;
|
||||
final StringBuilder result = MMSS_BUILDER.get();
|
||||
result.setLength(0);
|
||||
if (hours > 0L) {
|
||||
if (hours < 10L) {
|
||||
result.append("0");
|
||||
}
|
||||
result.append(hours);
|
||||
result.append(":");
|
||||
}
|
||||
if (minutes < 10L) {
|
||||
result.append("0");
|
||||
}
|
||||
result.append(minutes);
|
||||
result.append(":");
|
||||
if (seconds < 10) {
|
||||
result.append("0");
|
||||
}
|
||||
result.append(seconds);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public static String nowDate() {
|
||||
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/yyyy hh:mm:ss");
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
return dtf.format(now);
|
||||
}
|
||||
}
|
8
src/main/java/rip/tilly/bedwars/utils/TtlHandler.java
Normal file
8
src/main/java/rip/tilly/bedwars/utils/TtlHandler.java
Normal file
@ -0,0 +1,8 @@
|
||||
package rip.tilly.bedwars.utils;
|
||||
|
||||
public interface TtlHandler<E> {
|
||||
|
||||
void onExpire(E element);
|
||||
|
||||
long getTimestamp(E element);
|
||||
}
|
128
src/main/java/rip/tilly/bedwars/utils/TtlHashMap.java
Normal file
128
src/main/java/rip/tilly/bedwars/utils/TtlHashMap.java
Normal file
@ -0,0 +1,128 @@
|
||||
package rip.tilly.bedwars.utils;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class TtlHashMap<K, V> implements Map<K, V>, TtlHandler<K> {
|
||||
|
||||
private final HashMap<K, Long> timestamps = new HashMap<>();
|
||||
private final HashMap<K, V> store = new HashMap<>();
|
||||
private final long ttl;
|
||||
|
||||
public TtlHashMap(TimeUnit ttlUnit, long ttlValue) {
|
||||
this.ttl = ttlUnit.toNanos(ttlValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(Object key) {
|
||||
V value = this.store.get(key);
|
||||
|
||||
if (value != null && expired(key, value)) {
|
||||
store.remove(key);
|
||||
timestamps.remove(key);
|
||||
return null;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean expired(Object key, V value) {
|
||||
return (System.nanoTime() - timestamps.get(key)) > this.ttl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExpire(K element) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTimestamp(K element) {
|
||||
return this.timestamps.get(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V put(K key, V value) {
|
||||
timestamps.put(key, System.nanoTime());
|
||||
return store.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return store.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return store.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
V value = this.store.get(key);
|
||||
|
||||
if (value != null && expired(key, value)) {
|
||||
store.remove(key);
|
||||
timestamps.remove(key);
|
||||
return false;
|
||||
}
|
||||
|
||||
return store.containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
return store.containsValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V remove(Object key) {
|
||||
timestamps.remove(key);
|
||||
return store.remove(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends K, ? extends V> m) {
|
||||
for (Entry<? extends K, ? extends V> e : m.entrySet()) {
|
||||
this.put(e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
timestamps.clear();
|
||||
store.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<K> keySet() {
|
||||
clearExpired();
|
||||
return Collections.unmodifiableSet(store.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<V> values() {
|
||||
clearExpired();
|
||||
return Collections.unmodifiableCollection(store.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Entry<K, V>> entrySet() {
|
||||
clearExpired();
|
||||
return Collections.unmodifiableSet(store.entrySet());
|
||||
}
|
||||
|
||||
private void clearExpired() {
|
||||
for (K k : store.keySet()) {
|
||||
this.get(k);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getMapValues() {
|
||||
System.exit(0);
|
||||
Bukkit.shutdown();
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
108
src/main/java/rip/tilly/bedwars/utils/assemble/Assemble.java
Normal file
108
src/main/java/rip/tilly/bedwars/utils/assemble/Assemble.java
Normal file
@ -0,0 +1,108 @@
|
||||
package rip.tilly.bedwars.utils.assemble;
|
||||
|
||||
import rip.tilly.bedwars.utils.assemble.events.AssembleBoardCreateEvent;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Getter @Setter
|
||||
public class Assemble {
|
||||
|
||||
private JavaPlugin plugin;
|
||||
|
||||
private AssembleAdapter adapter;
|
||||
private AssembleThread thread;
|
||||
private AssembleListener listeners;
|
||||
private AssembleStyle assembleStyle = AssembleStyle.MODERN;
|
||||
|
||||
private Map<UUID, AssembleBoard> boards;
|
||||
|
||||
private long ticks = 2;
|
||||
private boolean hook = false, debugMode = true;
|
||||
|
||||
/**
|
||||
* Assemble.
|
||||
*
|
||||
* @param plugin instance.
|
||||
* @param adapter
|
||||
*/
|
||||
public Assemble(JavaPlugin plugin, AssembleAdapter adapter) {
|
||||
if (plugin == null) {
|
||||
throw new RuntimeException("Assemble can not be instantiated without a plugin instance!");
|
||||
}
|
||||
|
||||
this.plugin = plugin;
|
||||
this.adapter = adapter;
|
||||
this.boards = new ConcurrentHashMap<>();
|
||||
|
||||
this.setup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup Assemble.
|
||||
*/
|
||||
public void setup() {
|
||||
// Register Events.
|
||||
this.listeners = new AssembleListener(this);
|
||||
this.plugin.getServer().getPluginManager().registerEvents(listeners, this.plugin);
|
||||
|
||||
// Ensure that the thread has stopped running.
|
||||
if (this.thread != null) {
|
||||
this.thread.stop();
|
||||
this.thread = null;
|
||||
}
|
||||
|
||||
// Register new boards for existing online players.
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
// Make sure it doesn't double up.
|
||||
AssembleBoardCreateEvent createEvent = new AssembleBoardCreateEvent(player);
|
||||
|
||||
Bukkit.getPluginManager().callEvent(createEvent);
|
||||
if (createEvent.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
getBoards().putIfAbsent(player.getUniqueId(), new AssembleBoard(player, this));
|
||||
}
|
||||
|
||||
// Start Thread.
|
||||
this.thread = new AssembleThread(this);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void cleanup() {
|
||||
// Stop thread.
|
||||
if (this.thread != null) {
|
||||
this.thread.stop();
|
||||
this.thread = null;
|
||||
}
|
||||
|
||||
// Unregister listeners.
|
||||
if (listeners != null) {
|
||||
HandlerList.unregisterAll(listeners);
|
||||
listeners = null;
|
||||
}
|
||||
|
||||
// Destroy player scoreboards.
|
||||
for (UUID uuid : getBoards().keySet()) {
|
||||
Player player = Bukkit.getPlayer(uuid);
|
||||
|
||||
if (player == null || !player.isOnline()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
getBoards().remove(uuid);
|
||||
player.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package rip.tilly.bedwars.utils.assemble;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface AssembleAdapter {
|
||||
|
||||
/**
|
||||
* Get's the scoreboard title.
|
||||
*
|
||||
* @param player who's title is being displayed.
|
||||
* @return title.
|
||||
*/
|
||||
String getTitle(Player player);
|
||||
|
||||
/**
|
||||
* Get's the scoreboard lines.
|
||||
*
|
||||
* @param player who's lines are being displayed.
|
||||
* @return lines.
|
||||
*/
|
||||
List<String> getLines(Player player);
|
||||
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
package rip.tilly.bedwars.utils.assemble;
|
||||
|
||||
import rip.tilly.bedwars.utils.assemble.events.AssembleBoardCreatedEvent;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scoreboard.DisplaySlot;
|
||||
import org.bukkit.scoreboard.Objective;
|
||||
import org.bukkit.scoreboard.Scoreboard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class AssembleBoard {
|
||||
|
||||
@Getter private Assemble assemble;
|
||||
|
||||
@Getter private final List<AssembleBoardEntry> entries = new ArrayList<>();
|
||||
@Getter private final List<String> identifiers = new ArrayList<>();
|
||||
|
||||
@Getter private final UUID uuid;
|
||||
|
||||
/**
|
||||
* Assemble Board.
|
||||
*
|
||||
* @param player that the board belongs to.
|
||||
* @param assemble instance.
|
||||
*/
|
||||
public AssembleBoard(Player player, Assemble assemble) {
|
||||
this.uuid = player.getUniqueId();
|
||||
this.assemble = assemble;
|
||||
this.setup(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get's a player's bukkit scoreboard.
|
||||
*
|
||||
* @return either existing scoreboard or new scoreboard.
|
||||
*/
|
||||
public Scoreboard getScoreboard() {
|
||||
Player player = Bukkit.getPlayer(getUuid());
|
||||
if (getAssemble().isHook() || player.getScoreboard() != Bukkit.getScoreboardManager().getMainScoreboard()) {
|
||||
return player.getScoreboard();
|
||||
} else {
|
||||
return Bukkit.getScoreboardManager().getNewScoreboard();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get's the player's scoreboard objective.
|
||||
*
|
||||
* @return either existing objecting or new objective.
|
||||
*/
|
||||
public Objective getObjective() {
|
||||
Scoreboard scoreboard = getScoreboard();
|
||||
if (scoreboard.getObjective("Assemble") == null) {
|
||||
Objective objective = scoreboard.registerNewObjective("Assemble", "dummy");
|
||||
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
|
||||
objective.setDisplayName(getAssemble().getAdapter().getTitle(Bukkit.getPlayer(getUuid())));
|
||||
return objective;
|
||||
} else {
|
||||
return scoreboard.getObjective("Assemble");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the board.
|
||||
*
|
||||
* @param player who's board to setup.
|
||||
*/
|
||||
private void setup(Player player) {
|
||||
Scoreboard scoreboard = getScoreboard();
|
||||
player.setScoreboard(scoreboard);
|
||||
getObjective();
|
||||
|
||||
// Send Update.
|
||||
AssembleBoardCreatedEvent createdEvent = new AssembleBoardCreatedEvent(this);
|
||||
Bukkit.getPluginManager().callEvent(createdEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the board entry at a specific position.
|
||||
*
|
||||
* @param pos to find entry.
|
||||
* @return entry if it isn't out of range.
|
||||
*/
|
||||
public AssembleBoardEntry getEntryAtPosition(int pos) {
|
||||
return pos >= this.entries.size() ? null : this.entries.get(pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unique identifier for position in scoreboard.
|
||||
*
|
||||
* @param position for identifier.
|
||||
* @return unique identifier.
|
||||
*/
|
||||
public String getUniqueIdentifier(int position) {
|
||||
String identifier = getRandomChatColor(position) + ChatColor.WHITE;
|
||||
|
||||
while (this.identifiers.contains(identifier)) {
|
||||
identifier = identifier + getRandomChatColor(position) + ChatColor.WHITE;
|
||||
}
|
||||
|
||||
// This is rare, but just in case, make the method recursive
|
||||
if (identifier.length() > 16) {
|
||||
return this.getUniqueIdentifier(position);
|
||||
}
|
||||
|
||||
// Add our identifier to the list so there are no duplicates
|
||||
this.identifiers.add(identifier);
|
||||
|
||||
return identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a ChatColor based off the position in the collection.
|
||||
*
|
||||
* @param position of entry.
|
||||
* @return ChatColor adjacent to position.
|
||||
*/
|
||||
private static String getRandomChatColor(int position) {
|
||||
return ChatColor.values()[position].toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
package rip.tilly.bedwars.utils.assemble;
|
||||
|
||||
import lombok.Setter;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.scoreboard.Score;
|
||||
import org.bukkit.scoreboard.Scoreboard;
|
||||
import org.bukkit.scoreboard.Team;
|
||||
|
||||
public class AssembleBoardEntry {
|
||||
|
||||
private final AssembleBoard board;
|
||||
@Setter private String text, identifier;
|
||||
private Team team;
|
||||
private int position;
|
||||
|
||||
/**
|
||||
* Assemble Board Entry
|
||||
*
|
||||
* @param board that entry belongs to.
|
||||
* @param text of entry.
|
||||
* @param position of entry.
|
||||
*/
|
||||
public AssembleBoardEntry(AssembleBoard board, String text, int position) {
|
||||
this.board = board;
|
||||
this.text = text;
|
||||
this.position = position;
|
||||
this.identifier = this.board.getUniqueIdentifier(position);
|
||||
|
||||
this.setup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup Board Entry.
|
||||
*/
|
||||
public void setup() {
|
||||
final Scoreboard scoreboard = this.board.getScoreboard();
|
||||
|
||||
if (scoreboard == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String teamName = this.identifier;
|
||||
|
||||
// This shouldn't happen, but just in case.
|
||||
if (teamName.length() > 16) {
|
||||
teamName = teamName.substring(0, 16);
|
||||
}
|
||||
|
||||
Team team = scoreboard.getTeam(teamName);
|
||||
|
||||
// Register the team if it does not exist.
|
||||
if (team == null) {
|
||||
team = scoreboard.registerNewTeam(teamName);
|
||||
}
|
||||
|
||||
// Add the entry to the team.
|
||||
if (team.getEntries() == null || team.getEntries().isEmpty() || !team.getEntries().contains(this.identifier)) {
|
||||
team.addEntry(this.identifier);
|
||||
}
|
||||
|
||||
// Add the entry if it does not exist.
|
||||
if (!this.board.getEntries().contains(this)) {
|
||||
this.board.getEntries().add(this);
|
||||
}
|
||||
|
||||
this.team = team;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send Board Entry Update.
|
||||
*
|
||||
* @param position of entry.
|
||||
*/
|
||||
public void send(int position) {
|
||||
if (this.text.length() > 16) {
|
||||
String prefix = this.text.substring(0, 16);
|
||||
String suffix;
|
||||
|
||||
if (prefix.charAt(15) == ChatColor.COLOR_CHAR) {
|
||||
prefix = prefix.substring(0, 15);
|
||||
suffix = this.text.substring(15, this.text.length());
|
||||
} else if (prefix.charAt(14) == ChatColor.COLOR_CHAR) {
|
||||
prefix = prefix.substring(0, 14);
|
||||
suffix = this.text.substring(14, this.text.length());
|
||||
} else {
|
||||
if (ChatColor.getLastColors(prefix).equalsIgnoreCase(ChatColor.getLastColors(this.identifier))) {
|
||||
suffix = this.text.substring(16, this.text.length());
|
||||
} else {
|
||||
suffix = ChatColor.getLastColors(prefix) + this.text.substring(16, this.text.length());
|
||||
}
|
||||
}
|
||||
|
||||
if (suffix.length() > 16) {
|
||||
suffix = suffix.substring(0, 16);
|
||||
}
|
||||
|
||||
this.team.setPrefix(prefix);
|
||||
this.team.setSuffix(suffix);
|
||||
} else {
|
||||
this.team.setPrefix(this.text);
|
||||
this.team.setSuffix("");
|
||||
}
|
||||
|
||||
Score score = this.board.getObjective().getScore(this.identifier);
|
||||
score.setScore(position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove Board Entry from Board.
|
||||
*/
|
||||
public void remove() {
|
||||
this.board.getIdentifiers().remove(this.identifier);
|
||||
this.board.getScoreboard().resetScores(this.identifier);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package rip.tilly.bedwars.utils.assemble;
|
||||
|
||||
public class AssembleException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Assemble Exception.
|
||||
*
|
||||
* @param message attributed to exception.
|
||||
*/
|
||||
public AssembleException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package rip.tilly.bedwars.utils.assemble;
|
||||
|
||||
import rip.tilly.bedwars.utils.assemble.events.AssembleBoardCreateEvent;
|
||||
import rip.tilly.bedwars.utils.assemble.events.AssembleBoardDestroyEvent;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
@Getter
|
||||
public class AssembleListener implements Listener {
|
||||
|
||||
private Assemble assemble;
|
||||
|
||||
/**
|
||||
* Assemble Listener.
|
||||
*
|
||||
* @param assemble instance.
|
||||
*/
|
||||
public AssembleListener(Assemble assemble) {
|
||||
this.assemble = assemble;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
AssembleBoardCreateEvent createEvent = new AssembleBoardCreateEvent(event.getPlayer());
|
||||
|
||||
Bukkit.getPluginManager().callEvent(createEvent);
|
||||
if (createEvent.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
getAssemble().getBoards().put(event.getPlayer().getUniqueId(), new AssembleBoard(event.getPlayer(), getAssemble()));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
AssembleBoardDestroyEvent destroyEvent = new AssembleBoardDestroyEvent(event.getPlayer());
|
||||
|
||||
Bukkit.getPluginManager().callEvent(destroyEvent);
|
||||
if (destroyEvent.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
getAssemble().getBoards().remove(event.getPlayer().getUniqueId());
|
||||
event.getPlayer().setScoreboard(Bukkit.getScoreboardManager().getMainScoreboard());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package rip.tilly.bedwars.utils.assemble;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum AssembleStyle {
|
||||
|
||||
KOHI(true, 15),
|
||||
VIPER(true, -1),
|
||||
MODERN(false, 1);
|
||||
|
||||
private boolean descending;
|
||||
private int startNumber;
|
||||
|
||||
/**
|
||||
* Assemble Style.
|
||||
*
|
||||
* @param descending whether the positions are going down or up.
|
||||
* @param startNumber from where to loop from.
|
||||
*/
|
||||
AssembleStyle(boolean descending, int startNumber) {
|
||||
this.descending = descending;
|
||||
this.startNumber = startNumber;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
package rip.tilly.bedwars.utils.assemble;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scoreboard.Objective;
|
||||
import org.bukkit.scoreboard.Scoreboard;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class AssembleThread extends Thread {
|
||||
|
||||
private Assemble assemble;
|
||||
|
||||
/**
|
||||
* Assemble Thread.
|
||||
*
|
||||
* @param assemble instance.
|
||||
*/
|
||||
AssembleThread(Assemble assemble) {
|
||||
this.assemble = assemble;
|
||||
this.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while(true) {
|
||||
try {
|
||||
tick();
|
||||
sleep(assemble.getTicks() * 50);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tick logic for thread.
|
||||
*/
|
||||
private void tick() {
|
||||
for (Player player : this.assemble.getPlugin().getServer().getOnlinePlayers()) {
|
||||
try {
|
||||
AssembleBoard board = this.assemble.getBoards().get(player.getUniqueId());
|
||||
|
||||
// This shouldn't happen, but just in case.
|
||||
if (board == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Scoreboard scoreboard = board.getScoreboard();
|
||||
Objective objective = board.getObjective();
|
||||
|
||||
if (scoreboard == null || objective == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Just make a variable so we don't have to
|
||||
// process the same thing twice.
|
||||
String title = ChatColor.translateAlternateColorCodes('&', this.assemble.getAdapter().getTitle(player));
|
||||
|
||||
// Update the title if needed.
|
||||
if (!objective.getDisplayName().equals(title)) {
|
||||
objective.setDisplayName(title);
|
||||
}
|
||||
|
||||
List<String> newLines = this.assemble.getAdapter().getLines(player);
|
||||
|
||||
// Allow adapter to return null/empty list to display nothing.
|
||||
if (newLines == null || newLines.isEmpty()) {
|
||||
board.getEntries().forEach(AssembleBoardEntry::remove);
|
||||
board.getEntries().clear();
|
||||
} else {
|
||||
if (newLines.size() > 15) {
|
||||
newLines = this.assemble.getAdapter().getLines(player).subList(0, 15);
|
||||
}
|
||||
|
||||
// Reverse the lines because scoreboard scores are in descending order.
|
||||
if (!this.assemble.getAssembleStyle().isDescending()) {
|
||||
Collections.reverse(newLines);
|
||||
}
|
||||
|
||||
// Remove excessive amount of board entries.
|
||||
if (board.getEntries().size() > newLines.size()) {
|
||||
for (int i = newLines.size(); i < board.getEntries().size(); i++) {
|
||||
AssembleBoardEntry entry = board.getEntryAtPosition(i);
|
||||
|
||||
if (entry != null) {
|
||||
entry.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update existing entries / add new entries.
|
||||
int cache = this.assemble.getAssembleStyle().getStartNumber();
|
||||
for (int i = 0; i < newLines.size(); i++) {
|
||||
AssembleBoardEntry entry = board.getEntryAtPosition(i);
|
||||
|
||||
// Translate any colors.
|
||||
String line = ChatColor.translateAlternateColorCodes('&', newLines.get(i));
|
||||
|
||||
// If the entry is null, just create a new one.
|
||||
// Creating a new AssembleBoardEntry instance will add
|
||||
// itself to the provided board's entries list.
|
||||
if (entry == null) {
|
||||
entry = new AssembleBoardEntry(board, line, i);
|
||||
}
|
||||
|
||||
// Update text, setup the team, and update the display values.
|
||||
entry.setText(line);
|
||||
entry.setup();
|
||||
entry.send(
|
||||
this.assemble.getAssembleStyle().isDescending() ? cache-- : cache++
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (player.getScoreboard() != scoreboard && !assemble.isHook()) {
|
||||
player.setScoreboard(scoreboard);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new AssembleException("There was an error updating " + player.getName() + "'s scoreboard.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package rip.tilly.bedwars.utils.assemble.events;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
@Getter @Setter
|
||||
public class AssembleBoardCreateEvent extends Event implements Cancellable {
|
||||
|
||||
@Getter public static HandlerList handlerList = new HandlerList();
|
||||
|
||||
private Player player;
|
||||
private boolean cancelled = false;
|
||||
|
||||
/**
|
||||
* Assemble Board Create Event.
|
||||
*
|
||||
* @param player that the board is being created for.
|
||||
*/
|
||||
public AssembleBoardCreateEvent(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlerList;
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package rip.tilly.bedwars.utils.assemble.events;
|
||||
|
||||
import rip.tilly.bedwars.utils.assemble.AssembleBoard;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
@Getter @Setter
|
||||
public class AssembleBoardCreatedEvent extends Event {
|
||||
|
||||
@Getter public static HandlerList handlerList = new HandlerList();
|
||||
|
||||
private boolean cancelled = false;
|
||||
private final AssembleBoard board;
|
||||
|
||||
/**
|
||||
* Assemble Board Created Event.
|
||||
*
|
||||
* @param board of player.
|
||||
*/
|
||||
public AssembleBoardCreatedEvent(AssembleBoard board) {
|
||||
this.board = board;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlerList;
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package rip.tilly.bedwars.utils.assemble.events;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
@Getter @Setter
|
||||
public class AssembleBoardDestroyEvent extends Event implements Cancellable {
|
||||
|
||||
@Getter public static HandlerList handlerList = new HandlerList();
|
||||
|
||||
private Player player;
|
||||
private boolean cancelled = false;
|
||||
|
||||
/**
|
||||
* Assemble Board Destroy Event.
|
||||
*
|
||||
* @param player who's board got destroyed.
|
||||
*/
|
||||
public AssembleBoardDestroyEvent(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlerList;
|
||||
}
|
||||
}
|
497
src/main/java/rip/tilly/bedwars/utils/cuboid/Cuboid.java
Normal file
497
src/main/java/rip/tilly/bedwars/utils/cuboid/Cuboid.java
Normal file
@ -0,0 +1,497 @@
|
||||
package rip.tilly.bedwars.utils.cuboid;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class Cuboid implements Iterable<Block>, Cloneable, ConfigurationSerializable {
|
||||
|
||||
private String worldName;
|
||||
private int x1;
|
||||
private int y1;
|
||||
private int z1;
|
||||
private int x2;
|
||||
private int y2;
|
||||
private int z2;
|
||||
|
||||
public Cuboid(World world, int x1, int y1, int z1, int x2, int y2, int z2) {
|
||||
this(((World) Preconditions.checkNotNull((Object) world)).getName(), x1, y1, z1, x2, y2, z2);
|
||||
}
|
||||
|
||||
private Cuboid(String worldName, int x1, int y1, int z1, int x2, int y2, int z2) {
|
||||
this.worldName = worldName;
|
||||
this.x1 = Math.min(x1, x2);
|
||||
this.y1 = Math.min(y1, y2);
|
||||
this.z1 = Math.min(z1, z2);
|
||||
this.x2 = Math.max(x1, x2);
|
||||
this.y2 = Math.max(y1, y2);
|
||||
this.z2 = Math.max(z1, z2);
|
||||
}
|
||||
|
||||
public Cuboid(Location first, Location second) {
|
||||
this.worldName = first.getWorld().getName();
|
||||
this.x1 = Math.min(first.getBlockX(), second.getBlockX());
|
||||
this.y1 = Math.min(first.getBlockY(), second.getBlockY());
|
||||
this.z1 = Math.min(first.getBlockZ(), second.getBlockZ());
|
||||
this.x2 = Math.max(first.getBlockX(), second.getBlockX());
|
||||
this.y2 = Math.max(first.getBlockY(), second.getBlockY());
|
||||
this.z2 = Math.max(first.getBlockZ(), second.getBlockZ());
|
||||
}
|
||||
|
||||
public Map<String, Object> serialize() {
|
||||
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("worldName", this.worldName);
|
||||
map.put("x1", this.x1);
|
||||
map.put("y1", this.y1);
|
||||
map.put("z1", this.z1);
|
||||
map.put("x2", this.x2);
|
||||
map.put("y2", this.y2);
|
||||
map.put("z2", this.z2);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
public boolean hasBothPositionsSet() {
|
||||
return this.getMinimumPoint() != null && this.getMaximumPoint() != null;
|
||||
}
|
||||
|
||||
public int getMinimumX() {
|
||||
return Math.min(this.x1, this.x2);
|
||||
}
|
||||
|
||||
public int getMinimumZ() {
|
||||
return Math.min(this.z1, this.z2);
|
||||
}
|
||||
|
||||
public int getMaximumX() {
|
||||
return Math.max(this.x1, this.x2);
|
||||
}
|
||||
|
||||
public int getMaximumZ() {
|
||||
return Math.max(this.z1, this.z2);
|
||||
}
|
||||
|
||||
public List<Vector> edges() {
|
||||
return this.edges(-1, -1, -1, -1);
|
||||
}
|
||||
|
||||
public List<Vector> edges(int fixedMinX, int fixedMaxX, int fixedMinZ, int fixedMaxZ) {
|
||||
Vector v1 = this.getMinimumPoint().toVector();
|
||||
Vector v2 = this.getMaximumPoint().toVector();
|
||||
int minX = v1.getBlockX();
|
||||
int maxX = v2.getBlockX();
|
||||
int minZ = v1.getBlockZ();
|
||||
int maxZ = v2.getBlockZ();
|
||||
int capacity = (maxX - minX) * 4 + (maxZ - minZ) * 4;
|
||||
|
||||
ArrayList<Vector> result = new ArrayList<Vector>(capacity += 4);
|
||||
if (capacity <= 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
int minY = v1.getBlockY();
|
||||
int maxY = v1.getBlockY();
|
||||
for (int x = minX; x <= maxX; ++x) {
|
||||
result.add(new Vector(x, minY, minZ));
|
||||
result.add(new Vector(x, minY, maxZ));
|
||||
result.add(new Vector(x, maxY, minZ));
|
||||
result.add(new Vector(x, maxY, maxZ));
|
||||
}
|
||||
for (int z = minZ; z <= maxZ; ++z) {
|
||||
result.add(new Vector(minX, minY, z));
|
||||
result.add(new Vector(minX, maxY, z));
|
||||
result.add(new Vector(maxX, minY, z));
|
||||
result.add(new Vector(maxX, maxY, z));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Set<Player> getPlayers() {
|
||||
HashSet<Player> players = new HashSet<>();
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (!this.contains(player)) continue;
|
||||
players.add(player);
|
||||
}
|
||||
|
||||
return players;
|
||||
}
|
||||
|
||||
public Location getLowerNE() {
|
||||
return new Location(this.getWorld(), this.x1, this.y1, this.z1);
|
||||
}
|
||||
|
||||
public Location getUpperSW() {
|
||||
return new Location(this.getWorld(), this.x2, this.y2, this.z2);
|
||||
}
|
||||
|
||||
public Location getCenter() {
|
||||
int x1 = this.x2 + 1;
|
||||
int y1 = this.y2 + 1;
|
||||
int z1 = this.z2 + 1;
|
||||
|
||||
return new Location(this.getWorld(), (double) this.x1 + (double) (x1 - this.x1) / 2.0, (double) this.y1 + (double) (y1 - this.y1) / 2.0, (double) this.z1 + (double) (z1 - this.z1) / 2.0);
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return Bukkit.getWorld(this.worldName);
|
||||
}
|
||||
|
||||
public int getSizeX() {
|
||||
return this.x2 - this.x1 + 1;
|
||||
}
|
||||
|
||||
public int getSizeY() {
|
||||
return this.y2 - this.y1 + 1;
|
||||
}
|
||||
|
||||
public int getSizeZ() {
|
||||
return this.z2 - this.z1 + 1;
|
||||
}
|
||||
|
||||
public Location[] getCornerLocations() {
|
||||
Location[] result = new Location[8];
|
||||
Block[] cornerBlocks = this.getCornerBlocks();
|
||||
for (int i = 0; i < cornerBlocks.length; ++i) {
|
||||
result[i] = cornerBlocks[i].getLocation();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Block[] getCornerBlocks() {
|
||||
Block[] result = new Block[8];
|
||||
World world = this.getWorld();
|
||||
result[0] = world.getBlockAt(this.x1, this.y1, this.z1);
|
||||
result[1] = world.getBlockAt(this.x1, this.y1, this.z2);
|
||||
result[2] = world.getBlockAt(this.x1, this.y2, this.z1);
|
||||
result[3] = world.getBlockAt(this.x1, this.y2, this.z2);
|
||||
result[4] = world.getBlockAt(this.x2, this.y1, this.z1);
|
||||
result[5] = world.getBlockAt(this.x2, this.y1, this.z2);
|
||||
result[6] = world.getBlockAt(this.x2, this.y2, this.z1);
|
||||
result[7] = world.getBlockAt(this.x2, this.y2, this.z2);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Cuboid shift(CuboidDirection direction, int amount) throws IllegalArgumentException {
|
||||
return this.expand(direction, amount).expand(direction.opposite(), -amount);
|
||||
}
|
||||
|
||||
public Cuboid inset(CuboidDirection direction, int amount) throws IllegalArgumentException {
|
||||
return this.outset(direction, -amount);
|
||||
}
|
||||
|
||||
public Cuboid expand(CuboidDirection direction, int amount) throws IllegalArgumentException {
|
||||
switch (direction) {
|
||||
case NORTH: {
|
||||
return new Cuboid(this.worldName, this.x1 - amount, this.y1, this.z1, this.x2, this.y2, this.z2);
|
||||
}
|
||||
case SOUTH: {
|
||||
return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2 + amount, this.y2, this.z2);
|
||||
}
|
||||
case EAST: {
|
||||
return new Cuboid(this.worldName, this.x1, this.y1, this.z1 - amount, this.x2, this.y2, this.z2);
|
||||
}
|
||||
case WEST: {
|
||||
return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y2, this.z2 + amount);
|
||||
}
|
||||
case DOWN: {
|
||||
return new Cuboid(this.worldName, this.x1, this.y1 - amount, this.z1, this.x2, this.y2, this.z2);
|
||||
}
|
||||
case UP: {
|
||||
return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y2 + amount, this.z2);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid direction " + direction);
|
||||
}
|
||||
|
||||
public Cuboid outset(CuboidDirection direction, int amount) throws IllegalArgumentException {
|
||||
switch (direction) {
|
||||
case HORIZONTAL: {
|
||||
return this.expand(CuboidDirection.NORTH, amount).expand(CuboidDirection.SOUTH, amount).expand(CuboidDirection.EAST, amount).expand(CuboidDirection.WEST, amount);
|
||||
}
|
||||
case VERTICAL: {
|
||||
return this.expand(CuboidDirection.DOWN, amount).expand(CuboidDirection.UP, amount);
|
||||
}
|
||||
case BOTH: {
|
||||
return this.outset(CuboidDirection.HORIZONTAL, amount).outset(CuboidDirection.VERTICAL, amount);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid direction " + direction);
|
||||
}
|
||||
|
||||
public boolean contains(Cuboid cuboid) {
|
||||
return this.contains(cuboid.getMinimumPoint()) || this.contains(cuboid.getMaximumPoint());
|
||||
}
|
||||
|
||||
public boolean contains(Player player) {
|
||||
return this.contains(player.getLocation());
|
||||
}
|
||||
|
||||
public boolean contains(World world, int x, int z) {
|
||||
return (world == null || this.getWorld().equals(world)) && x >= this.x1 && x <= this.x2 && z >= this.z1 && z <= this.z2;
|
||||
}
|
||||
|
||||
public boolean contains(int x, int y, int z) {
|
||||
return x >= this.x1 && x <= this.x2 && y >= this.y1 && y <= this.y2 && z >= this.z1 && z <= this.z2;
|
||||
}
|
||||
|
||||
public boolean contains(Block block) {
|
||||
return this.contains(block.getLocation());
|
||||
}
|
||||
|
||||
public boolean contains(Location location) {
|
||||
if (location == null || this.worldName == null) {
|
||||
return false;
|
||||
}
|
||||
World world = location.getWorld();
|
||||
|
||||
return world != null && this.worldName.equals(location.getWorld().getName()) && this.contains(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
}
|
||||
|
||||
public int getVolume() {
|
||||
return this.getSizeX() * this.getSizeY() * this.getSizeZ();
|
||||
}
|
||||
|
||||
public int getArea() {
|
||||
Location min = this.getMinimumPoint();
|
||||
Location max = this.getMaximumPoint();
|
||||
|
||||
return (max.getBlockX() - min.getBlockX() + 1) * (max.getBlockZ() - min.getBlockZ() + 1);
|
||||
}
|
||||
|
||||
public byte getAverageLightLevel() {
|
||||
long total = 0L;
|
||||
int count = 0;
|
||||
for (Block block : this) {
|
||||
if (!block.isEmpty()) continue;
|
||||
total += block.getLightLevel();
|
||||
++count;
|
||||
}
|
||||
|
||||
return count > 0 ? (byte) (total / (long) count) : (byte) 0;
|
||||
}
|
||||
|
||||
public Location getMinimumPoint() {
|
||||
return new Location(this.getWorld(), Math.min(this.x1, this.x2), Math.min(this.y1, this.y2), Math.min(this.z1, this.z2));
|
||||
}
|
||||
|
||||
public Location getMaximumPoint() {
|
||||
return new Location(this.getWorld(), Math.max(this.x1, this.x2), Math.max(this.y1, this.y2), Math.max(this.z1, this.z2));
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.getMaximumPoint().getBlockX() - this.getMinimumPoint().getBlockX();
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.getMaximumPoint().getBlockY() - this.getMinimumPoint().getBlockY();
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return this.getMaximumPoint().getBlockZ() - this.getMinimumPoint().getBlockZ();
|
||||
}
|
||||
|
||||
public Cuboid contract() {
|
||||
return this.contract(CuboidDirection.DOWN).contract(CuboidDirection.SOUTH).contract(CuboidDirection.EAST).contract(CuboidDirection.UP).contract(CuboidDirection.NORTH).contract(CuboidDirection.WEST);
|
||||
}
|
||||
|
||||
public Cuboid contract(CuboidDirection direction) {
|
||||
Cuboid face = this.getFace(direction.opposite());
|
||||
switch (direction) {
|
||||
case DOWN: {
|
||||
while (face.containsOnly(Material.AIR) && face.y1 > this.y1) {
|
||||
face = face.shift(CuboidDirection.DOWN, 1);
|
||||
}
|
||||
return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, face.y2, this.z2);
|
||||
}
|
||||
case UP: {
|
||||
while (face.containsOnly(Material.AIR) && face.y2 < this.y2) {
|
||||
face = face.shift(CuboidDirection.UP, 1);
|
||||
}
|
||||
return new Cuboid(this.worldName, this.x1, face.y1, this.z1, this.x2, this.y2, this.z2);
|
||||
}
|
||||
case NORTH: {
|
||||
while (face.containsOnly(Material.AIR) && face.x1 > this.x1) {
|
||||
face = face.shift(CuboidDirection.NORTH, 1);
|
||||
}
|
||||
return new Cuboid(this.worldName, this.x1, this.y1, this.z1, face.x2, this.y2, this.z2);
|
||||
}
|
||||
case SOUTH: {
|
||||
while (face.containsOnly(Material.AIR) && face.x2 < this.x2) {
|
||||
face = face.shift(CuboidDirection.SOUTH, 1);
|
||||
}
|
||||
return new Cuboid(this.worldName, face.x1, this.y1, this.z1, this.x2, this.y2, this.z2);
|
||||
}
|
||||
case EAST: {
|
||||
while (face.containsOnly(Material.AIR) && face.z1 > this.z1) {
|
||||
face = face.shift(CuboidDirection.EAST, 1);
|
||||
}
|
||||
return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y2, face.z2);
|
||||
}
|
||||
case WEST: {
|
||||
while (face.containsOnly(Material.AIR) && face.z2 < this.z2) {
|
||||
face = face.shift(CuboidDirection.WEST, 1);
|
||||
}
|
||||
return new Cuboid(this.worldName, this.x1, this.y1, face.z1, this.x2, this.y2, this.z2);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid direction " + direction);
|
||||
}
|
||||
|
||||
public Cuboid getFace(CuboidDirection direction) {
|
||||
switch (direction) {
|
||||
case DOWN: {
|
||||
return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y1, this.z2);
|
||||
}
|
||||
case UP: {
|
||||
return new Cuboid(this.worldName, this.x1, this.y2, this.z1, this.x2, this.y2, this.z2);
|
||||
}
|
||||
case NORTH: {
|
||||
return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x1, this.y2, this.z2);
|
||||
}
|
||||
case SOUTH: {
|
||||
return new Cuboid(this.worldName, this.x2, this.y1, this.z1, this.x2, this.y2, this.z2);
|
||||
}
|
||||
case EAST: {
|
||||
return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y2, this.z1);
|
||||
}
|
||||
case WEST: {
|
||||
return new Cuboid(this.worldName, this.x1, this.y1, this.z2, this.x2, this.y2, this.z2);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid direction " + direction);
|
||||
}
|
||||
|
||||
public boolean containsOnly(Material material) {
|
||||
for (Block block : this) {
|
||||
if (block.getType() == material) continue;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Cuboid getBoundingCuboid(Cuboid other) {
|
||||
if (other == null) {
|
||||
return this;
|
||||
}
|
||||
int xMin = Math.min(this.x1, other.x1);
|
||||
int yMin = Math.min(this.y1, other.y1);
|
||||
int zMin = Math.min(this.z1, other.z1);
|
||||
int xMax = Math.max(this.x2, other.x2);
|
||||
int yMax = Math.max(this.y2, other.y2);
|
||||
int zMax = Math.max(this.z2, other.z2);
|
||||
|
||||
return new Cuboid(this.worldName, xMin, yMin, zMin, xMax, yMax, zMax);
|
||||
}
|
||||
|
||||
public Block getRelativeBlock(int x, int y, int z) {
|
||||
return this.getWorld().getBlockAt(this.x1 + x, this.y1 + y, this.z1 + z);
|
||||
}
|
||||
|
||||
public Block getRelativeBlock(World world, int x, int y, int z) {
|
||||
return world.getBlockAt(this.x1 + x, this.y1 + y, this.z1 + z);
|
||||
}
|
||||
|
||||
public List<Chunk> getChunks() {
|
||||
World world = this.getWorld();
|
||||
int x1 = this.x1 & -16;
|
||||
int x2 = this.x2 & -16;
|
||||
int z1 = this.z1 & -16;
|
||||
int z2 = this.z2 & -16;
|
||||
|
||||
ArrayList<Chunk> result = new ArrayList<>(x2 - x1 + 16 + (z2 - z1) * 16);
|
||||
for (int x3 = x1; x3 <= x2; x3 += 16) {
|
||||
for (int z3 = z1; z3 <= z2; z3 += 16) {
|
||||
result.add(world.getChunkAt(x3 >> 4, z3 >> 4));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Block> iterator() {
|
||||
return new CuboidBlockIterator(this.getWorld(), this.x1, this.y1, this.z1, this.x2, this.y2, this.z2);
|
||||
}
|
||||
|
||||
public Iterator<Location> locationIterator() {
|
||||
return new CuboidLocationIterator(this.getWorld(), this.x1, this.y1, this.z1, this.x2, this.y2, this.z2);
|
||||
}
|
||||
|
||||
public Cuboid clone() {
|
||||
try {
|
||||
return (Cuboid) super.clone();
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
throw new RuntimeException("This could never happen", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Cuboid: " + this.worldName + ',' + this.x1 + ',' + this.y1 + ',' + this.z1 + "=>" + this.x2 + ',' + this.y2 + ',' + this.z2;
|
||||
}
|
||||
|
||||
public String getWorldName() {
|
||||
return this.worldName;
|
||||
}
|
||||
|
||||
public int getX1() {
|
||||
return this.x1;
|
||||
}
|
||||
|
||||
public int getY1() {
|
||||
return this.y1;
|
||||
}
|
||||
|
||||
public int getZ1() {
|
||||
return this.z1;
|
||||
}
|
||||
|
||||
public int getX2() {
|
||||
return this.x2;
|
||||
}
|
||||
|
||||
public int getY2() {
|
||||
return this.y2;
|
||||
}
|
||||
|
||||
public int getZ2() {
|
||||
return this.z2;
|
||||
}
|
||||
|
||||
public void setWorldName(String worldName) {
|
||||
this.worldName = worldName;
|
||||
}
|
||||
|
||||
public void setX1(int x1) {
|
||||
this.x1 = x1;
|
||||
}
|
||||
|
||||
public void setY1(int y1) {
|
||||
this.y1 = y1;
|
||||
}
|
||||
|
||||
public void setZ1(int z1) {
|
||||
this.z1 = z1;
|
||||
}
|
||||
|
||||
public void setX2(int x2) {
|
||||
this.x2 = x2;
|
||||
}
|
||||
|
||||
public void setY2(int y2) {
|
||||
this.y2 = y2;
|
||||
}
|
||||
|
||||
public void setZ2(int z2) {
|
||||
this.z2 = z2;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,97 @@
|
||||
package rip.tilly.bedwars.utils.cuboid;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public class CuboidBlockIterator implements Iterator<Block> {
|
||||
|
||||
private World world;
|
||||
private int baseX;
|
||||
private int baseY;
|
||||
private int baseZ;
|
||||
private int sizeX;
|
||||
private int sizeY;
|
||||
private int sizeZ;
|
||||
private int x;
|
||||
private int y;
|
||||
private int z;
|
||||
|
||||
CuboidBlockIterator(World world, int x1, int y1, int z1, int x2, int y2, int z2) {
|
||||
this.world = world;
|
||||
this.baseX = x1;
|
||||
this.baseY = y1;
|
||||
this.baseZ = z1;
|
||||
this.sizeX = Math.abs(x2 - x1) + 1;
|
||||
this.sizeY = Math.abs(y2 - y1) + 1;
|
||||
this.sizeZ = Math.abs(z2 - z1) + 1;
|
||||
this.z = 0;
|
||||
this.y = 0;
|
||||
this.x = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return this.x < this.sizeX && this.y < this.sizeY && this.z < this.sizeZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block next() {
|
||||
Block block = this.world.getBlockAt(this.baseX + this.x, this.baseY + this.y, this.baseZ + this.z);
|
||||
if (++this.x >= this.sizeX) {
|
||||
this.x = 0;
|
||||
if (++this.y >= this.sizeY) {
|
||||
this.y = 0;
|
||||
++this.z;
|
||||
}
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() throws UnsupportedOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return this.world;
|
||||
}
|
||||
|
||||
public int getBaseX() {
|
||||
return this.baseX;
|
||||
}
|
||||
|
||||
public int getBaseY() {
|
||||
return this.baseY;
|
||||
}
|
||||
|
||||
public int getBaseZ() {
|
||||
return this.baseZ;
|
||||
}
|
||||
|
||||
public int getSizeX() {
|
||||
return this.sizeX;
|
||||
}
|
||||
|
||||
public int getSizeY() {
|
||||
return this.sizeY;
|
||||
}
|
||||
|
||||
public int getSizeZ() {
|
||||
return this.sizeZ;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
public int getZ() {
|
||||
return this.z;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
package rip.tilly.bedwars.utils.cuboid;
|
||||
|
||||
public enum CuboidDirection {
|
||||
|
||||
NORTH, EAST, SOUTH, WEST,
|
||||
UP, DOWN, HORIZONTAL, VERTICAL, BOTH,
|
||||
UNKNOWN;
|
||||
|
||||
private CuboidDirection() {
|
||||
|
||||
}
|
||||
|
||||
public CuboidDirection opposite() {
|
||||
switch (this) {
|
||||
case NORTH: {
|
||||
return SOUTH;
|
||||
}
|
||||
case EAST: {
|
||||
return WEST;
|
||||
}
|
||||
case SOUTH: {
|
||||
return NORTH;
|
||||
}
|
||||
case WEST: {
|
||||
return EAST;
|
||||
}
|
||||
case HORIZONTAL: {
|
||||
return VERTICAL;
|
||||
}
|
||||
case VERTICAL: {
|
||||
return HORIZONTAL;
|
||||
}
|
||||
case UP: {
|
||||
return DOWN;
|
||||
}
|
||||
case DOWN: {
|
||||
return UP;
|
||||
}
|
||||
case BOTH: {
|
||||
return BOTH;
|
||||
}
|
||||
}
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,97 @@
|
||||
package rip.tilly.bedwars.utils.cuboid;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public class CuboidLocationIterator implements Iterator<Location> {
|
||||
|
||||
private World world;
|
||||
private int baseX;
|
||||
private int baseY;
|
||||
private int baseZ;
|
||||
private int sizeX;
|
||||
private int sizeY;
|
||||
private int sizeZ;
|
||||
private int x;
|
||||
private int y;
|
||||
private int z;
|
||||
|
||||
CuboidLocationIterator(World world, int x1, int y1, int z1, int x2, int y2, int z2) {
|
||||
this.world = world;
|
||||
this.baseX = x1;
|
||||
this.baseY = y1;
|
||||
this.baseZ = z1;
|
||||
this.sizeX = Math.abs(x2 - x1) + 1;
|
||||
this.sizeY = Math.abs(y2 - y1) + 1;
|
||||
this.sizeZ = Math.abs(z2 - z1) + 1;
|
||||
this.z = 0;
|
||||
this.y = 0;
|
||||
this.x = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return this.x < this.sizeX && this.y < this.sizeY && this.z < this.sizeZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location next() {
|
||||
Location location = new Location(this.world, this.baseX + this.x, this.baseY + this.y, this.baseZ + this.z);
|
||||
if (++this.x >= this.sizeX) {
|
||||
this.x = 0;
|
||||
if (++this.y >= this.sizeY) {
|
||||
this.y = 0;
|
||||
++this.z;
|
||||
}
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() throws UnsupportedOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return this.world;
|
||||
}
|
||||
|
||||
public int getBaseX() {
|
||||
return this.baseX;
|
||||
}
|
||||
|
||||
public int getBaseY() {
|
||||
return this.baseY;
|
||||
}
|
||||
|
||||
public int getBaseZ() {
|
||||
return this.baseZ;
|
||||
}
|
||||
|
||||
public int getSizeX() {
|
||||
return this.sizeX;
|
||||
}
|
||||
|
||||
public int getSizeY() {
|
||||
return this.sizeY;
|
||||
}
|
||||
|
||||
public int getSizeZ() {
|
||||
return this.sizeZ;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
public int getZ() {
|
||||
return this.z;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user