Вопрос Проблема с голограммой

Версия Minecraft
1.16.X

1Krokko3213

Пользователь
Сообщения
27
тема такая: мистик появляется с голограмой сверху, а иногда бывает так: голограмма с ничего теряет валидность. следствие: мистик не может с ней ничего сделать. когда даже сам мистик удаляется, голограмма остается. потеря валидности видна в логах, так как я сделал выведение этого. не понятно почему так происходит, проверяю валидность через .isValid() :
Код:
package krokko.clockmyst;

import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.session.ClipboardHolder;
import org.bukkit.*;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;

import java.util.*;

public class MysticInstance {

    private static final Set<Location> nigger = new HashSet<>();

    private final Location chestLocation;
    private final MysticType type;
    private final List<ArmorStand> holograms = new ArrayList<>();
    private ArmorStand timerHologram;

    private boolean opening = false;
    private boolean opened = false;

    private int timeRemaining;
    private final Inventory dropInventory;

    private ClipboardHolder clipboard;
    private BlockVector3 pasteOrigin;

    private final ClockMyst plugin = ClockMyst.getInstance();

    public MysticInstance(Location loc, MysticType type, ClipboardHolder clipboard, BlockVector3 pasteOrigin) {
        if (isLocationOccupied(loc)) {
            throw new IllegalStateException("Уже есть на" + loc);
        }

        this.chestLocation = loc;
        this.type = type;
        this.clipboard = clipboard;
        this.pasteOrigin = pasteOrigin;

        nigger.add(loc);

        this.timeRemaining = plugin.getConfig().getInt("mystic.open_time_seconds", 480);
        this.dropInventory = Bukkit.createInventory(null, 54, type.getDisplayName());

        loc.getChunk().load();

        spawnInitialHolograms();

        new BukkitRunnable() {
            @Override
            public void run() {
                if (!opening && !opened) {
                    destroyMystic();
                }
            }
        }.runTaskLater(plugin, 20L * 300); //300/60=5minut
    }

    private static boolean isLocationOccupied(Location loc) {
        for (Location occupied : nigger) {
            if (occupied.getWorld().equals(loc.getWorld())
                    && occupied.getBlockX() == loc.getBlockX()
                    && occupied.getBlockY() == loc.getBlockY()
                    && occupied.getBlockZ() == loc.getBlockZ()) {
                return true;
            }
        }
        return false;
    }

    private void spawnInitialHolograms() {
        holograms.add(spawnHologram(chestLocation.clone().add(0.5, 1.8, 0.5), "§6§lМистический сундук"));
        holograms.add(spawnHologram(chestLocation.clone().add(0.5, 1.55, 0.5), type.getDisplayName()));
        timerHologram = spawnHologram(chestLocation.clone().add(0.5, 1.2, 0.5), getTimerText());
        holograms.add(timerHologram);
    }

    private ArmorStand spawnHologram(Location loc, String name) {
        ArmorStand stand = (ArmorStand) loc.getWorld().spawnEntity(loc, EntityType.ARMOR_STAND);
        stand.setCustomName(name);
        stand.setCustomNameVisible(true);
        stand.setVisible(false);
        stand.setMarker(true);
        stand.setGravity(false);
        return stand;
    }

    private String getTimerText() {
        int min = timeRemaining / 60;
        int sec = timeRemaining % 60;
        return "§7До открытия: §c§l" + min + "м " + sec + "с";
    }

    public void startOpening() {
        if (opening || opened) return;
        opening = true;


        new BukkitRunnable() {
            @Override
            public void run() {
                if (timeRemaining <= 0) {
                    opened = true;
                    opening = false;


                    updateTimerHologram("§aМистик открыт1");
                    chestLocation.getWorld().playSound(
                            chestLocation,
                            Sound.BLOCK_NOTE_BLOCK_BIT,
                            0.6f, 0.8f
                    );
                    fillInventory();

                    new BukkitRunnable() {
                        @Override
                        public void run() {
                            destroyMystic();
                        }
                    }.runTaskLater(plugin, 20 * 20);

                    cancel();
                    return;
                }

                if (timeRemaining <= 10) {
                    chestLocation.getWorld().playSound(
                            chestLocation,
                            Sound.BLOCK_NOTE_BLOCK_BIT,
                            0.6f, 0.8f
                    );
                }

                timeRemaining--;

                updateTimerHologram(getTimerText());
            }
        }.runTaskTimer(plugin, 0, 20);
    }

    private void updateTimerHologram(String text) {
        if(!timerHologram.isValid()) Bukkit.getLogger().info("Голограма потеряоа свою валидность");
        if (timerHologram == null) {

            timerHologram = spawnHologram(chestLocation.clone().add(0.5, 1.2, 0.5), text);
            holograms.add(timerHologram);

        } else {
            timerHologram.setCustomName(text);
            timerHologram.setCustomNameVisible(false);
            timerHologram.setCustomNameVisible(true);
        }
    }


    private void fillInventory() {
        List<ItemStack> drops = plugin.getDropGUI().getDropsForType(type);
        if (drops.isEmpty()) return;

        List<Integer> slots = new ArrayList<>();
        for (int i = 0; i < dropInventory.getSize(); i++) slots.add(i);
        Collections.shuffle(slots);

        Random random = new Random();

        int dropCount = Math.min(slots.size(), drops.size());
        for (int i = 0; i < dropCount; i++) {
            if (random.nextInt(100) >= 45) {
                dropInventory.setItem(slots.get(i), drops.get(i));
            }
        }
    }

    public void openInventory(Player player) {
        if (opened) player.openInventory(dropInventory);
        else player.sendMessage("§cМистик не открыт");
    }

    public boolean isOpened() {
        return opened;
    }

    public boolean isOpening() {
        return opening;
    }

    public Location getChestLocation() {
        return chestLocation;
    }

    public void destroyMystic() {

        for (ArmorStand hologram : new ArrayList<>(holograms)) {
            if (hologram != null && hologram.isValid()) {
                hologram.remove();
            }
        }
        holograms.clear();

        chestLocation.getBlock().setType(Material.AIR);
        chestLocation.getWorld().createExplosion(
                chestLocation.clone().add(0.5, 0.5, 0.5),
                0f,
                false,
                false
        );

        if (clipboard != null && pasteOrigin != null) {
            try (EditSession session = WorldEdit.getInstance().newEditSession(BukkitAdapter.adapt(chestLocation.getWorld()))) {
                BlockVector3 min = pasteOrigin;
                BlockVector3 max = pasteOrigin.add(
                        clipboard.getClipboard().getDimensions().getX() - 1,
                        clipboard.getClipboard().getDimensions().getY() - 1,
                        clipboard.getClipboard().getDimensions().getZ() - 1
                );

                CuboidRegion region = new CuboidRegion(min, max);
                session.setBlocks((Region) region, (Pattern) BukkitAdapter.asBlockType(Material.AIR));
                session.flushSession();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        nigger.remove(chestLocation);
    }
}
сори за говнокод
 

Вложения

  • 2025-07-10_23.54.33.png
    2025-07-10_23.54.33.png
    1.5 MB · Просмотры: 10
  • 2025-07-10_23.55.29.png
    2025-07-10_23.55.29.png
    1.2 MB · Просмотры: 12
Назад
Сверху Снизу