Как сделать след из партиклов за проджектайлом?

MarinCod

Пользователь
Сообщения
81
Мне нужно, чтобы за зельем, пока оно летит, оставался партикл дымок.

Искал информацию, но чего-то похожего не нашёл. Не знаю какой ивент для этого нужен и как спавнить партиклы за проджектайлом раз во сколько-то тиков. Видел что-то типо spawnParticle(), но там нельзя указать задержку, то есть партиклы будут спавнится каждый тик. Учитывая, что эффект у меня довольно большой, каждый тик его спавнить это перебор.

Подскажите как это сделать, пожалуйста.
 
Решение
Тебе останется только под себя подстроить и всё.
Java:
public class ParticleArrow {

    private final Entity arrow;
    private final Particle particle;

    public ParticleArrow(Entity arrow, Particle particle) {
        this.arrow = arrow;
        this.particle = particle;
    }

    public void spawnParticle() {
        if (arrow != null)
            arrow.getWorld().spawnParticle(particle, arrow.getLocation(), 0);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ParticleArrow that = (ParticleArrow) o;
        return Objects.equals(arrow.getUniqueId(), that.arrow.getUniqueId());
    }

    @Override
    public...
Мне нужно, чтобы за зельем, пока оно летит, оставался партикл дымок.

Искал информацию, но чего-то похожего не нашёл. Не знаю какой ивент для этого нужен и как спавнить партиклы за проджектайлом раз во сколько-то тиков. Видел что-то типо spawnParticle(), но там нельзя указать задержку, то есть партиклы будут спавнится каждый тик. Учитывая, что эффект у меня довольно большой, каждый тик его спавнить это перебор.

Подскажите как это сделать, пожалуйста.
You must be registered for see medias
 
EntityShootBowEvent? Ну или EntitySpawnEvent на крайняк...

Запускать шедуляр (таймер) и в нём уже делать, что нужно (спавнить частицы).
Эти два ивента же вызываются, когда ентити запускается.
В таком случае, если я всё правильно понимаю, то лишь одна частица заспавнится, а потом все.

Мне нужно именно trail, как выше. Видео смотрел, пробовал использовать функции, но как там вызвать партикл не получается. Такого класса попросту нет.
 
Эти два ивента же вызываются, когда ентити запускается.
В таком случае, если я всё правильно понимаю, то лишь одна частица заспавнится, а потом все.
Я же не просто так написал запускать шедуляр)

Из ивента сохраняешь в какой-нибудь List или Map стрелу или что собираешься запускать
В запущенном шедуляре проходишься по списку/мапе со стрелами и спавнишь на их локации нужные частицы.
 
Я же не просто так написал запускать шедуляр)

Из ивента сохраняешь в какой-нибудь List или Map стрелу или что собираешься запускать
В запущенном шедуляре проходишься по списку/мапе со стрелами и спавнишь на их локации нужные частицы.
Посмотрел насчёт шедуляров, но уже сейчас выдало ошибку.

Код:
@EventHandler
    public void ParticlesForMolotov(ProjectileLaunchEvent e) {
        Player p = (Player) e.getEntity().getShooter();
        World world = (World) Bukkit.getServer().getWorld("World");
        if (e.getEntity().hasMetadata("firePotion")) {
            BukkitScheduler scheduler = Bukkit.getScheduler();
            scheduler.runTask(plugin, () -> {
                p.sendMessage("Партикл должен спавнится");
                world.spawnParticle(Particle.SMOKE_LARGE, e.getLocation(), 1);
            },0L,20L);
        }
    }

С этой вещью первый раз работаю, поэтому надеюсь на понимание.

Насчёт списка также хотел спросить. Мне то есть из этого ивента нужно получить ентити и добавить его в список, а дальше что?
Ну и да, spawnParticle всё равно не работает, он не спавнил даже одну частицу, хотя вроде как должен был.
 
выдало ошибку.
Какую?
Под код и под спойлер отправь.

из этого ивента нужно получить ентити и добавить его в список, а дальше что?
Java:
for (Arrow arrow : список стрел) {
    //Проверка, что стрела не в блоке (if(arrow.isInBlock())) и удаление из списка, если она в блоке
    arrow.getLocation().getWorld().spawnParticle(...);
}

И лучше запускать шедуляр при запуске сервера (сделать его в отдельном классе, например)
 
Код:
@EventHandler
    public void ParticlesForMolotov(ProjectileLaunchEvent e) {
        Player p = (Player) e.getEntity().getShooter();
        World world = (World) Bukkit.getServer().getWorld("World");
        if (e.getEntity().hasMetadata("firePotion")) {
            BukkitScheduler scheduler = Bukkit.getScheduler();
            scheduler.runTask(plugin, () -> {
                p.sendMessage("Партикл должен спавнится");
                world.spawnParticle(Particle.SMOKE_LARGE, e.getLocation(), 1);
            },0L,20L);
        }
    }
Код:
Cannot resolve method 'runTask(marinbay.PlusDamageOnArbalet.Main, <lambda expression>, long, long)'

Насчёт стрел принцип понял, но разве это будет работать на зельях?
По идее принцип тот же, но класс другой.
Объединено

Какую?
Под код и под спойлер отправь.


Java:
for (Arrow arrow : список стрел) {
    //Проверка, что стрела не в блоке (if(arrow.isInBlock())) и удаление из списка, если она в блоке
    arrow.getLocation().getWorld().spawnParticle(...);
}

И лучше запускать шедуляр при запуске сервера (сделать его в отдельном классе, например)
 
Cannot resolve method 'runTask(marinbay.PlusDamageOnArbalet.Main, <lambda expression>, long, long)'
Метода такого нет. В ошибке написано же.
Вам необходимо зарегистрироваться для просмотра изображений-вложений
 
Судя по этому ты хочешь использовать метод runTaskTimer
Код:
ArrayList<Arrow> potions = new ArrayList<Arrow>();

    @EventHandler
    public void ParticlesForMolotov(ProjectileLaunchEvent e) {
        Player p = (Player) e.getEntity().getShooter();
        World world = (World) Bukkit.getServer().getWorld("World");
        if (e.getEntity().hasMetadata("firePotion")) {
            BukkitScheduler scheduler = Bukkit.getScheduler();
            Arrow potion = (Arrow) e.getEntity();
            potions.add(potion);
            scheduler.runTaskTimer(plugin, () -> {
                for (Arrow arrow : potions) {
                    if(arrow.isInBlock()) {
                        potions.remove(arrow);
                    }
                    else {
                        arrow.getLocation().getWorld().spawnParticle(Particle.SMOKE_LARGE, arrow.getLocation(), 1);
                    }
                }
            },0L,20L);
        }
    }

Да, так и есть, хочу сделать появление эффекта раз в секунду, ну или больше, там уже подстроить не проблема.
Написал пока что-то такое, еще не успел запустить, но уже сейчас мне кажется, что что-то не так я делаю.

Случаем не в шедулере должен быть ивент? Или всё же правильный вариант выше?
Если делать шедулер в классе, то наследовать он уже будет BukkitSheduler, да?

Ещё видел Tasks, их здесь не получится использовать?
 
Тебе останется только под себя подстроить и всё.
Java:
public class ParticleArrow {

    private final Entity arrow;
    private final Particle particle;

    public ParticleArrow(Entity arrow, Particle particle) {
        this.arrow = arrow;
        this.particle = particle;
    }

    public void spawnParticle() {
        if (arrow != null)
            arrow.getWorld().spawnParticle(particle, arrow.getLocation(), 0);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ParticleArrow that = (ParticleArrow) o;
        return Objects.equals(arrow.getUniqueId(), that.arrow.getUniqueId());
    }

    @Override
    public int hashCode() {
        return Objects.hash(arrow.getUniqueId());
    }
}
Java:
    private final Map<UUID, ParticleArrow> arrowMap = new HashMap<>();

    @Override
    public void onEnable() {
        Bukkit.getPluginManager().registerEvents(this, this);
        Bukkit.getScheduler().runTaskTimer(this, (task) -> {
            for (ParticleArrow arrow : arrowMap.values())
                arrow.spawnParticle();
        }, 0L, 1L);
    }

    @EventHandler
    public void onBowShoot(EntityShootBowEvent e) {
        if (e.getEntity() instanceof Player)
            arrowMap.put(e.getProjectile().getUniqueId(), new ParticleArrow(e.getProjectile(), Particle.FLAME));
    }

    @EventHandler
    public void onProjectileHit(ProjectileHitEvent e) {
        if (e.getEntity() instanceof Arrow)
            arrowMap.remove(e.getEntity().getUniqueId());
    }
 
Код:
public final Map<UUID, Arrow> arrowMap = new HashMap<>();

    @Override
    public void onEnable() {
        getServer().getPluginManager().registerEvents(new MolotovEventHandler(this), this);

        Bukkit.getScheduler().runTaskTimer(this, (task) -> {
            for (Arrow arrow : arrowMap.values()) {
                arrow.getLocation().getWorld().spawnParticle(Particle.SMOKE_LARGE, arrow.getLocation(), 1);
            }
        }, 0L, 20L);
    }
    
    public void addToMapArrows(Arrow a, UUID u) {
        arrowMap.put(u, a);
    }

    public void removeToMapArrows(Arrow a, UUID u) {
        arrowMap.remove(u);
    }

В классе Main написал что-то такое, так как мне кажется, что все ивенты в других классах должны быть. Но теперь не могу вызвать функции addToMapArrows и removeToMapArrows.

Класс ParticleArrow у меня вообще не находит. И я так и не пойму, Arrow - это абсолютно все проджектайлы или только стрелы из лука? Мне нужно провернуть то же самое, но с зельем.
 
Но теперь не могу вызвать функции addToMapArrows и removeToMapArrows.
Подробнее.

Класс ParticleArrow у меня вообще не находит.
Так ты создай его.

И я так и не пойму, Arrow - это абсолютно все проджектайлы или только стрелы из лука?
В моём примере - стрелы из лука.

Мне нужно провернуть то же самое, но с зельем.
Ну так переделай под себя, основу я тебе дал.
 
Пытаюсь вызвать эти функции из класса main в класс ивентов.

Так ты создай его.
Пожалуй, не стоит мне в такое лезть, раз у меня даже с таким сложности.

Ну так переделай под себя, основу я тебе дал.
Да, пытаюсь, по-тихоньку начинаю понимать в чём тут дело, благодаря вам)
 
Утром наконец-то дошёл до всего сказанного выше, теперь всё работает отлично. Спасибо!

Только пока что эффект подбираю, потому что например SMOKE_LARGE беспорядочно летает в разные стороны, из-за чего выглядит всё не очень.
 
Назад
Сверху Снизу