Replaced jail head skript, fixed TrimManager bugs and added update to admin utils.
This commit is contained in:
@@ -40,6 +40,7 @@ public class Manager {
|
||||
trimManager.register(new NetheriteAnimation());
|
||||
trimManager.register(new QuartzAnimation());
|
||||
trimManager.register(new RedstoneAnimation());
|
||||
trimManager.register();
|
||||
trimManager.startTicking();
|
||||
}
|
||||
|
||||
|
||||
@@ -74,16 +74,12 @@ public class AdminCommand implements QuickCommand, Data {
|
||||
)
|
||||
)
|
||||
).then(
|
||||
b.arg("update")
|
||||
).then(
|
||||
b.arg("reload")
|
||||
).then(
|
||||
b.arg("cleanup")
|
||||
b.arg("update","reload","cleanup")
|
||||
);
|
||||
}
|
||||
|
||||
private void handleUpdate(CommandSender sender, Args args) {
|
||||
infoAny(sender,"Checking for an updated...");
|
||||
infoAny(sender,"Checking for an update...");
|
||||
Bukkit.getScheduler().runTask(main.getPlugin(),()->{
|
||||
if (AutoUpdater.checkUpdate(main.getPlugin(),main.getCommon())) {
|
||||
successAny(sender,"Updated plugin has been downloaded to {0}.","plugins/update");
|
||||
@@ -108,7 +104,7 @@ public class AdminCommand implements QuickCommand, Data {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count > 0) successAny(sender,"Successfully removed {0} temporary entities.");
|
||||
if (count > 0) successAny(sender,"Successfully removed {0} temporary entities.",count);
|
||||
else errorAny(sender,"Could not find any temporary entities.");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ public class FreezeEvents implements QuickListener {
|
||||
public void onMove(PlayerMoveEvent e) {
|
||||
Freeze.FrozenPlayer frozen = Freeze.getFrozen().get(e.getPlayer().getUniqueId());
|
||||
if (frozen == null) return;
|
||||
if (frozen.movementAllowed()) return;
|
||||
|
||||
if (!e.getFrom().toVector().equals(e.getTo().toVector())) {
|
||||
e.setTo(e.getFrom());
|
||||
@@ -37,6 +38,7 @@ public class FreezeEvents implements QuickListener {
|
||||
public void onCommand(PlayerCommandPreprocessEvent e) {
|
||||
Freeze.FrozenPlayer frozen = Freeze.getFrozen().get(e.getPlayer().getUniqueId());
|
||||
if (frozen == null) return;
|
||||
if (frozen.commandsAllowed()) return;
|
||||
|
||||
String baseCmd = e.getMessage().replace("/", "").split(" ")[0].toLowerCase();
|
||||
if (!Data.data.getConfig().allowedFreezeCommands.contains(baseCmd)) {
|
||||
@@ -50,6 +52,7 @@ public class FreezeEvents implements QuickListener {
|
||||
if (!(e.getEntity() instanceof Player p)) return;
|
||||
Freeze.FrozenPlayer frozen = Freeze.getFrozen().get(p.getUniqueId());
|
||||
if (frozen == null) return;
|
||||
if (frozen.damageAllowed()) return;
|
||||
|
||||
e.setCancelled(true);
|
||||
if (frozen.getOnMove() != null) frozen.getOnMove().accept(p);
|
||||
@@ -60,6 +63,7 @@ public class FreezeEvents implements QuickListener {
|
||||
if (!(e.getEntity() instanceof Player p)) return;
|
||||
Freeze.FrozenPlayer frozen = Freeze.getFrozen().get(p.getUniqueId());
|
||||
if (frozen == null) return;
|
||||
if (frozen.damageAllowed()) return;
|
||||
|
||||
e.setCancelled(true);
|
||||
if (frozen.getOnMove() != null) frozen.getOnMove().accept(p);
|
||||
|
||||
@@ -48,6 +48,9 @@ public class Freeze {
|
||||
private final Location backLocation;
|
||||
private final Consumer<OfflinePlayer> onQuit;
|
||||
private final Consumer<Player> onMove;
|
||||
private boolean allowMovement = false;
|
||||
private boolean allowDamage = false;
|
||||
private boolean allowCommands = false;
|
||||
|
||||
public FrozenPlayer(UUID uuid, Location backLocation, Consumer<OfflinePlayer> onQuit, Consumer<Player> onMove) {
|
||||
this.uuid = uuid;
|
||||
@@ -73,5 +76,29 @@ public class Freeze {
|
||||
if (player == null) return;
|
||||
player.teleport(backLocation);
|
||||
}
|
||||
|
||||
public void setAllowDamage(boolean allowDamage) {
|
||||
this.allowDamage = allowDamage;
|
||||
}
|
||||
|
||||
public void setAllowMovement(boolean allowMovement) {
|
||||
this.allowMovement = allowMovement;
|
||||
}
|
||||
|
||||
public boolean commandsAllowed() {
|
||||
return allowCommands;
|
||||
}
|
||||
|
||||
public void setAllowCommands(boolean allowCommands) {
|
||||
this.allowCommands = allowCommands;
|
||||
}
|
||||
|
||||
public boolean damageAllowed() {
|
||||
return allowDamage;
|
||||
}
|
||||
|
||||
public boolean movementAllowed() {
|
||||
return allowMovement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,45 +4,96 @@ import me.trouper.alias.server.events.QuickListener;
|
||||
import me.trouper.alias.server.systems.AbstractWand;
|
||||
import me.trouper.alias.server.systems.world.Snapshot;
|
||||
import me.trouper.alias.utils.ItemBuilder;
|
||||
import me.trouper.alias.utils.TargetingUtils;
|
||||
import me.trouper.clonedupecore.server.punishment.Freeze;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public class JailHeadWand extends AbstractWand implements QuickListener {
|
||||
public JailHeadWand() {
|
||||
super("clonedupe.jailwand", ItemBuilder.of(Material.PLAYER_HEAD)
|
||||
.createCustomHead("http://textures.minecraft.net/texture/a63b87ee6a55f2bf0135b26bd96ec279eded175f948c036d88a60725e127371c","Port-a-Jail")
|
||||
.loreComponent(Component.text("Right click to use on a player!", NamedTextColor.GRAY).decoration(TextDecoration.ITALIC,false))
|
||||
.build());
|
||||
}
|
||||
|
||||
private final Map<UUID,Jail> jailed = new HashMap<>();
|
||||
|
||||
@Override
|
||||
protected void onRightClick(Player player) {
|
||||
Optional<LivingEntity> optional = TargetingUtils.livingClosestAngle(player.getEyeLocation(),player.getEyeLocation().getDirection(),10,0.5);
|
||||
if (optional.isEmpty() || !(optional.get() instanceof Player target)) return;
|
||||
if (jailed.containsKey(target.getUniqueId())) {
|
||||
Freeze.thawPlayer(target.getUniqueId());
|
||||
jailed.remove(target.getUniqueId()).revertCage();
|
||||
return;
|
||||
}
|
||||
Freeze.quickFreeze(target);
|
||||
Freeze.FrozenPlayer fp = new Freeze.FrozenPlayer(target.getUniqueId(),target.getLocation().clone(),null,null);
|
||||
fp.setAllowMovement(true);
|
||||
Freeze.freezePlayer(fp);
|
||||
|
||||
Jail jail = new Jail(target);
|
||||
jail.createCage();
|
||||
jailed.put(target.getUniqueId(),jail);
|
||||
}
|
||||
|
||||
private class Jail {
|
||||
private final UUID prisoner;
|
||||
private final List<Snapshot> changedBlocks = new ArrayList<>();
|
||||
private final Map<Block, Snapshot> snapshots = new HashMap<>();
|
||||
public Jail(Player prisoner) {
|
||||
this.prisoner = prisoner.getUniqueId();
|
||||
Location loc = prisoner.getLocation();
|
||||
}
|
||||
|
||||
public void createCage() {
|
||||
Player p = Bukkit.getPlayer(prisoner);
|
||||
if (p == null) return;
|
||||
|
||||
Location loc = p.getLocation().clone().subtract(0,1,0);
|
||||
final int x = loc.getBlockX();
|
||||
final int y = loc.getBlockY();
|
||||
final int z = loc.getBlockZ();
|
||||
for (int dx = x - 1; dx < x + 1; dx++) {
|
||||
for (int dy = y - 1; dy < y + 2; dy++) {
|
||||
for (int dz = z - 1; dz < z + 1; dz++) {
|
||||
Location pointer = loc.clone();
|
||||
pointer.setX(dx);
|
||||
pointer.setY(dy);
|
||||
pointer.setZ(dz);
|
||||
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
for (int dy = 0; dy <= 3; dy++) {
|
||||
for (int dz = -1; dz <= 1; dz++) {
|
||||
int bx = x + dx;
|
||||
int by = y + dy;
|
||||
int bz = z + dz;
|
||||
|
||||
Location blockLoc = new Location(loc.getWorld(), bx, by, bz);
|
||||
Block block = blockLoc.getBlock();
|
||||
snapshots.put(block, new Snapshot(block));
|
||||
|
||||
if (dy == 0 || dy == 3) {
|
||||
block.setType(Material.IRON_BLOCK);
|
||||
} else if (dy == 1 || dy == 2) {
|
||||
if (Math.abs(dx) == 1 || Math.abs(dz) == 1) {
|
||||
block.setType(Material.IRON_BARS);
|
||||
} else {
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void revertCage() {
|
||||
snapshots.forEach((block,snapshot) -> snapshot.restore(block));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,111 +1,105 @@
|
||||
package me.trouper.clonedupecore.server.trims;
|
||||
|
||||
import me.trouper.alias.server.Main;
|
||||
import me.trouper.alias.server.events.QuickListener;
|
||||
import me.trouper.alias.server.events.Registrar;
|
||||
import me.trouper.alias.server.systems.Verbose;
|
||||
import me.trouper.clonedupecore.data.Data;
|
||||
import me.trouper.clonedupecore.utils.ArmorUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ArmorMeta;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.trim.ArmorTrim;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Registrar(exclude = true)
|
||||
public class TrimManager implements QuickListener, Data {
|
||||
private final Map<ValidMaterial, MaterialAnimation> animations = new EnumMap<>(ValidMaterial.class);
|
||||
private final Map<UUID, ActiveTrim> activePlayers = new HashMap<>();
|
||||
|
||||
private final Set<MaterialAnimation> allAnimations = new HashSet<>();
|
||||
private final Map<UUID, MovementTracker> trackerMap = new HashMap<>();
|
||||
private final ConcurrentHashMap<UUID, MaterialAnimation> lastAnimationMap = new ConcurrentHashMap<>();
|
||||
private final Set<UUID> isStationary = new HashSet<>();
|
||||
|
||||
public void register(MaterialAnimation animation) {
|
||||
animations.put(animation.getMaterial(), animation);
|
||||
}
|
||||
|
||||
public void tickPlayer(Player player) {
|
||||
UUID uuid = player.getUniqueId();
|
||||
if (shouldHide(player)) {
|
||||
safeRemove(player);
|
||||
return;
|
||||
}
|
||||
|
||||
ValidMaterial currentMaterial = getActiveMaterial(player);
|
||||
ActiveTrim active = activePlayers.get(uuid);
|
||||
Location currentLocation = player.getLocation();
|
||||
|
||||
if (currentMaterial == null) {
|
||||
safeRemove(player);
|
||||
return;
|
||||
}
|
||||
|
||||
if (active != null && active.material == currentMaterial) {
|
||||
active.ticks++;
|
||||
|
||||
if (active.lastCheckedLocation != null && active.lastCheckedLocation.getWorld().equals(currentLocation.getWorld()) && currentLocation.distanceSquared(active.lastCheckedLocation) > 0.001) {
|
||||
active.lastMoveTimestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
active.lastCheckedLocation = currentLocation;
|
||||
} else {
|
||||
active = new ActiveTrim(currentMaterial, currentLocation);
|
||||
safeRemove(player);
|
||||
activePlayers.put(uuid, active);
|
||||
}
|
||||
|
||||
MaterialAnimation animation = animations.get(currentMaterial);
|
||||
if (animation != null) {
|
||||
long loopTime = active.ticks % animation.getLoopDuration();
|
||||
long timeSinceLastMove = System.currentTimeMillis() - active.lastMoveTimestamp;
|
||||
|
||||
if (timeSinceLastMove < 1000) {
|
||||
animation.onRemove(player);
|
||||
animation.tickMoving(player, getViewers(player), loopTime);
|
||||
} else {
|
||||
animation.tickStationary(player, getViewers(player), loopTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void safeRemove(OfflinePlayer player) {
|
||||
UUID id = player.getUniqueId();
|
||||
if (activePlayers.containsKey(id)) animations.get(activePlayers.get(id).material).onRemove(player);
|
||||
activePlayers.remove(id);
|
||||
allAnimations.add(animation);
|
||||
}
|
||||
|
||||
public void startTicking() {
|
||||
Bukkit.getScheduler().runTaskTimer(main.getPlugin(), () -> Bukkit.getOnlinePlayers().forEach(this::tickPlayer),0,1);
|
||||
AtomicInteger globalTime = new AtomicInteger(0);
|
||||
Bukkit.getScheduler().runTaskTimer(main.getPlugin(), () -> {
|
||||
Bukkit.getOnlinePlayers().forEach(player->{
|
||||
if (!player.isOnline()) return;
|
||||
tickPlayer(player, globalTime.get());
|
||||
});
|
||||
globalTime.getAndIncrement();
|
||||
}, 0, 1);
|
||||
}
|
||||
|
||||
private ValidMaterial getActiveMaterial(Player player) {
|
||||
ItemStack[] armor = player.getInventory().getArmorContents();
|
||||
if (armor.length != 4) return null;
|
||||
|
||||
ValidMaterial found = null;
|
||||
for (ItemStack piece : armor) {
|
||||
if (!ArmorUtils.isArmor(piece)) return null;
|
||||
|
||||
ItemMeta meta = piece.getItemMeta();
|
||||
if (!(meta instanceof ArmorMeta armorMeta)) return null;
|
||||
if (!armorMeta.hasTrim()) return null;
|
||||
|
||||
ArmorTrim trim = armorMeta.getTrim();
|
||||
if (trim == null) return null;
|
||||
|
||||
ValidMaterial vm = ValidMaterial.validate(trim.getMaterial());
|
||||
if (vm == null) return null;
|
||||
|
||||
if (found == null) {
|
||||
found = vm;
|
||||
} else if (found != vm) {
|
||||
return null;
|
||||
}
|
||||
public void tickPlayer(Player player, int globalTime) {
|
||||
UUID playerId = player.getUniqueId();
|
||||
MaterialAnimation activeAnimation = getAnimation(player);
|
||||
if (!player.isOnline()) return;
|
||||
if (activeAnimation == null && lastAnimationMap.containsKey(playerId)) {
|
||||
MaterialAnimation lastAnimation = lastAnimationMap.remove(playerId);
|
||||
Verbose.send("Player has no active animation, removing and stopping {0}, their last active animation.", lastAnimation.getMaterial().name());
|
||||
lastAnimation.onRemove(player);
|
||||
return;
|
||||
}
|
||||
return found;
|
||||
|
||||
if (activeAnimation == null) {
|
||||
return;
|
||||
} else if (lastAnimationMap.containsKey(playerId) && !lastAnimationMap.get(playerId).equals(activeAnimation)) {
|
||||
lastAnimationMap.put(playerId,activeAnimation);
|
||||
} else if (!lastAnimationMap.containsKey(playerId)) {
|
||||
lastAnimationMap.put(playerId,activeAnimation);
|
||||
}
|
||||
|
||||
MovementTracker tracker = trackerMap.computeIfAbsent(playerId,k -> new MovementTracker(player.getLocation()));
|
||||
long loopTime = globalTime % activeAnimation.getLoopDuration();
|
||||
|
||||
if (tracker.isStationary) {
|
||||
isStationary.add(playerId);
|
||||
activeAnimation.tickStationary(player,getViewers(player),loopTime);
|
||||
} else {
|
||||
if (isStationary.remove(playerId)) activeAnimation.onRemove(player);
|
||||
activeAnimation.tickMoving(player,getViewers(player),loopTime);
|
||||
}
|
||||
|
||||
tracker.tick(player.getLocation());
|
||||
}
|
||||
|
||||
public static class MovementTracker {
|
||||
private Location lastLocation;
|
||||
private long lastMovedTime;
|
||||
private boolean isStationary;
|
||||
|
||||
public MovementTracker(Location currentLocation) {
|
||||
lastMovedTime = System.currentTimeMillis();
|
||||
isStationary = true;
|
||||
lastLocation = currentLocation;
|
||||
}
|
||||
|
||||
public void tick(Location currentLocation) {
|
||||
long now = System.currentTimeMillis();
|
||||
if (lastLocation.distanceSquared(currentLocation) > 0.01) {
|
||||
lastMovedTime = now;
|
||||
}
|
||||
isStationary = (now - lastMovedTime) >= 1000;
|
||||
|
||||
lastLocation = currentLocation;
|
||||
}
|
||||
}
|
||||
|
||||
public MaterialAnimation getAnimation(Player player) {
|
||||
ValidMaterial playerMaterial = ValidMaterial.getActiveMaterial(player);
|
||||
if (playerMaterial == null) return null;
|
||||
for (MaterialAnimation animation : allAnimations) {
|
||||
if (animation.getMaterial().equals(playerMaterial)) return animation;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean shouldHide(Player player) {
|
||||
@@ -113,26 +107,26 @@ public class TrimManager implements QuickListener, Data {
|
||||
}
|
||||
|
||||
private Set<Player> getViewers(Player player) {
|
||||
if (shouldHide(player)) return new HashSet<>();
|
||||
return Bukkit.getOnlinePlayers().stream().filter(viewer-> !getStorage().disabledGlobalParticles.contains(viewer.getUniqueId().toString())).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private static class ActiveTrim {
|
||||
final ValidMaterial material;
|
||||
long ticks;
|
||||
long lastMoveTimestamp;
|
||||
Location lastCheckedLocation;
|
||||
|
||||
ActiveTrim(ValidMaterial material, Location initialLocation) {
|
||||
this.material = material;
|
||||
this.ticks = 0;
|
||||
this.lastMoveTimestamp = System.currentTimeMillis();
|
||||
this.lastCheckedLocation = initialLocation;
|
||||
if (shouldHide(player)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
return Bukkit.getOnlinePlayers().stream()
|
||||
.filter(viewer -> !getStorage().disabledGlobalParticles.contains(viewer.getUniqueId().toString()))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onLeave(PlayerQuitEvent e) {
|
||||
safeRemove(e.getPlayer());
|
||||
public void onQuit(PlayerQuitEvent e) {
|
||||
Player player = e.getPlayer();
|
||||
UUID playerId = player.getUniqueId();
|
||||
Verbose.send("{0} has quit!",player.getName());
|
||||
if (lastAnimationMap.containsKey(playerId)) {
|
||||
MaterialAnimation lastAnimation = lastAnimationMap.get(playerId);
|
||||
Verbose.send("Last animation for {0} is {1}.",player.getName(),lastAnimation.getMaterial().name());
|
||||
lastAnimation.onRemove(player);
|
||||
} else {
|
||||
Verbose.send("{0} had no active animations.",player.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,11 @@
|
||||
package me.trouper.clonedupecore.server.trims;
|
||||
|
||||
import me.trouper.clonedupecore.utils.ArmorUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ArmorMeta;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.trim.ArmorTrim;
|
||||
import org.bukkit.inventory.meta.trim.TrimMaterial;
|
||||
|
||||
public enum ValidMaterial {
|
||||
@@ -36,4 +42,34 @@ public enum ValidMaterial {
|
||||
name = name.toUpperCase();
|
||||
return ValidMaterial.valueOf(name).getCanonical();
|
||||
}
|
||||
|
||||
public static ValidMaterial getActiveMaterial(Player player) {
|
||||
ItemStack[] armor = player.getInventory().getArmorContents();
|
||||
if (armor.length != 4) return null;
|
||||
|
||||
ValidMaterial trimMaterial = null;
|
||||
|
||||
for (ItemStack piece : armor) {
|
||||
if (!ArmorUtils.isArmor(piece)) return null;
|
||||
|
||||
ItemMeta meta = piece.getItemMeta();
|
||||
if (!(meta instanceof ArmorMeta armorMeta) || !armorMeta.hasTrim()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ArmorTrim trim = armorMeta.getTrim();
|
||||
if (trim == null) return null;
|
||||
|
||||
ValidMaterial currentPieceMaterial = ValidMaterial.validate(trim.getMaterial());
|
||||
if (currentPieceMaterial == null) return null;
|
||||
|
||||
if (trimMaterial == null) {
|
||||
trimMaterial = currentPieceMaterial;
|
||||
} else if (trimMaterial != currentPieceMaterial) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return trimMaterial;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package me.trouper.clonedupecore.server.trims.animations;
|
||||
|
||||
import me.trouper.alias.server.systems.Verbose;
|
||||
import me.trouper.alias.server.systems.visual.DisplayUtils;
|
||||
import me.trouper.alias.server.systems.visual.ParticleUtils;
|
||||
import me.trouper.clonedupecore.server.trims.MaterialAnimation;
|
||||
@@ -43,6 +44,7 @@ public class NetheriteAnimation extends MaterialAnimation {
|
||||
double angle = (loopTime / (double) LOOP_DURATION) * 2 * Math.PI;
|
||||
|
||||
List<BlockDisplay> displays = activeDisplays.computeIfAbsent(playerId, id -> {
|
||||
Verbose.send("{0} needed new BlockDisplays",player.getName());
|
||||
List<BlockDisplay> list = new ArrayList<>();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Location initialLoc = player.getLocation().add(0, 1, 0);
|
||||
@@ -132,13 +134,9 @@ public class NetheriteAnimation extends MaterialAnimation {
|
||||
|
||||
@Override
|
||||
public void onRemove(OfflinePlayer player) {
|
||||
List<BlockDisplay> displays = activeDisplays.remove(player.getUniqueId());
|
||||
if (displays != null) {
|
||||
for (BlockDisplay display : displays) {
|
||||
if (!display.isDead()) {
|
||||
display.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
List<BlockDisplay> displays = activeDisplays.get(player.getUniqueId());
|
||||
if (displays == null || displays.isEmpty()) return;
|
||||
displays.forEach(BlockDisplay::remove);
|
||||
activeDisplays.remove(player.getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user