Помогите (РЕШЕНО) Метание огненных шаров

StrayDog31

Новичок
Пользователь
Баллы
6
Приветствую, форумчане! Недавно начал учить Java и пытаюсь писать плагины. Я в этом дилетант, потому попрошу реагировать на мои местами глупые вопросы без особой желчи. Так вот, я хочу создать предмет, который по нажатию ПКМ будет выпускать огненный шар в направлении взгляда игрока. С последним появились проблемы. Во-первых, я не совсем понимаю синтаксис функции .spawnEntity, в моем случае она просто значится как ошибочная, притом среда разработки не дает четких объяснений почему. Во-вторых, не совсем понимаю, как задать направление шара по взгляду, ну, то есть мне понятно, что нужно считать yaw и pitch, но как заставить entity двигаться в этом направлении не очень. Буду очень благодарен за помощь с кодод, ниже прилагаю имеющиеся наработка (небольшие, но все же)!
P.S. Среда - Eclipse, если это имеет значение. Плагин на 1.16

public class MagicianWands extends JavaPlugin {

public void onEnable() {
Bukkit.getPluginManager().registerEvents(new FrSt(), this);
getLogger().info("Enable!");
FireStick();

}

public void onDisable() {
getLogger().info("Disable!");
}

private void FireStick() {

ItemStack FireStick = new ItemStack(Material.BLAZE_ROD);
ItemMeta meta = FireStick.getItemMeta();
meta.setDisplayName(ChatColor.GOLD + "Жезл Искр");
FireStick.setItemMeta(meta);
meta.addEnchant(Enchantment.ARROW_DAMAGE, 1, true);
NamespacedKey dsKey = new NamespacedKey(this, "fire");
ShapedRecipe FireStickR = new ShapedRecipe(dsKey, FireStick);

FireStickR.shape("ggg", "uo#", "ggg");
FireStickR.setIngredient('o', Material.BLAZE_ROD);
FireStickR.setIngredient('#', Material.FIRE_CHARGE);
FireStickR.setIngredient('u', Material.BLAZE_POWDER);
FireStickR.setIngredient('g', Material.AIR);


getServer().addRecipe(FireStickR);
}

}

public class FrSt implements Listener {
@EventHandler

public void use(PlayerInteractEvent e) {
if(e.getAction() != Action.RIGHT_CLICK_AIR && e.getAction() != Action.RIGHT_CLICK_BLOCK) return;
if(e.getPlayer().getInventory().getItemInMainHand().getType() != Material.BLAZE_ROD) return;
Player p = e.getPlayer();
ItemStack Firestick = e.getPlayer().getInventory().getItemInMainHand();
if(!Firestick.getItemMeta().getDisplayName().equals(ChatColor.GOLD + "Жезл Искр")) return;
if(!Firestick.getItemMeta().hasDisplayName()) return;
effect(p);


}

private void effect(Player p) {
p.playSound(p.getLocation(), Sound.ENTITY_BLAZE_SHOOT, 8, 1);
p.spawnParticle(Particle.LAVA, p.getLocation().add(0.5D, 0.5D, 0.5D), 25 , 1.2F, 1.2F, 1.2F);
p


}

private void spawnTamedFireball(Location location, Player p) {
Location loc = p.getLocation();
float yaw = loc.getYaw();
float pitch = loc.getPitch();
Fireball fb = (Fireball) p.spawnEntity(location, EntityType.FIREBALL);

}

private void onPlayerInteract(PlayerInteractEvent event) {
Player p = p.getPlayer();
Entity en = en.
Location loc = p.getLocation();
Location loc1 = en.getLocation();
float yaw = loc.getYaw();
float pitch = loc.getPitch();
if(pitch < -40) {
Entity en = spawnEntity(loc, EntityType.FIREBALL);
Fireball fr = (Fireball) p.spawnEntity(loc, EntityType.WOLF);
while (loc1.getY() < 120) {
Thread.sleep(2000);
loc1.setY(loc1.getY() + 2);
}

}

}
}
 
Во-первых, я не совсем понимаю синтаксис функции spawnEntity(), в моем случае она просто значится как ошибочная
вот, сверяйся https://hub.spigotmc.org/javadocs/s...bukkit.Location,org.bukkit.entity.EntityType)

По поводу спавна fireball тут лучше подойдет не spawnEntity(), а launchProjectile()
Вот примерчик - спавн fireball по взгляду игрока и проигрывание звука выстрела:
Код:
@EventHandler
public void onPlayerClick (PlayerInteractEvent e) {
    Player player = e.getPlayer();
    player.launchProjectile(Fireball.class, player.getEyeLocation().getDirection());
    player.playSound(player.getLocation(), Sound.ENTITY_BLAZE_SHOOT, 8, 1);
}
 
И еще несколько советов:
Код:
if(!Firestick.getItemMeta().getDisplayName().equals(ChatColor.GOLD + "Жезл Искр")) return;
if(!Firestick.getItemMeta().hasDisplayName()) return;
это явно должно быть в обратном порядке)


И вот тут:
Код:
while (loc1.getY() < 120) {
        Thread.sleep(2000);
        loc1.setY(loc1.getY() + 2);
}
Никогда. Так. Не делай.

Обработчики событий (как и многая другая логика плагина) выполняется прямо в главном потоке сервера. И когда ты вызываешь Thread.sleep(2000); то ждать будет весь сервер (все, что делаются другие плагины будет приостановлено, действия игроков не будут обрабатываться, в общем то же самое, что и в случае зависания сервера).
Но!
Ты можешь создать отдельный поток или
использовать Scheduler (рекомендуется)
в этих случаях такой sleep() не будет задерживать сервер, но возможно, все равно не обязателен.

P.S да, я видел, что этот код не выполнится, просто сказал)
 
вот, сверяйся https://hub.spigotmc.org/javadocs/s...bukkit.Location,org.bukkit.entity.EntityType)

По поводу спавна fireball тут лучше подойдет не spawnEntity(), а launchProjectile()
Вот примерчик - спавн fireball по взгляду игрока и проигрывание звука выстрела:
Код:
@EventHandler
public void onPlayerClick (PlayerInteractEvent e) {
    Player player = e.getPlayer();
    player.launchProjectile(Fireball.class, player.getEyeLocation().getDirection());
    player.playSound(player.getLocation(), Sound.ENTITY_BLAZE_SHOOT, 8, 1);
}
Благодарю! Метод отлично работает, но всплыла еще одна проблема. До его введения звуки и частицы работали корректно, то есть только при нужном предмете в руках и правому клику. Теперь же все воспроизводится вообще с любым предметом и при любом клике. Я переделал изначальные if, но это ничего не дало.


@EventHandler

public void use(PlayerInteractEvent e) {

ItemStack Firestick = e.getPlayer().getInventory().getItemInMainHand();
if(e.getPlayer().getInventory().getItemInMainHand().getType() == Material.BLAZE_ROD && Firestick.getItemMeta().getDisplayName().equals(ChatColor.GOLD + "Жезл Искр") && e.getAction() == Action.RIGHT_CLICK_AIR && e.getAction() == Action.RIGHT_CLICK_BLOCK) {
ball(e);
}



}

@EventHandler

private void ball(PlayerInteractEvent e) {
Player player = e.getPlayer();
player.launchProjectile(Fireball.class, player.getEyeLocation().getDirection());
player.playSound(player.getLocation(), Sound.ENTITY_BLAZE_SHOOT, 8, 1);
player.spawnParticle(Particle.LAVA, player.getLocation().add(0.5D, 0.5D, 0.5D), 25 , 1.2F, 1.2F, 1.2F);
}
 
Благодарю! Метод отлично работает, но всплыла еще одна проблема. До его введения звуки и частицы работали корректно, то есть только при нужном предмете в руках и правому клику. Теперь же все воспроизводится вообще с любым предметом и при любом клике. Я переделал изначальные if, но это ничего не дало.


@EventHandler

public void use(PlayerInteractEvent e) {

ItemStack Firestick = e.getPlayer().getInventory().getItemInMainHand();
if(e.getPlayer().getInventory().getItemInMainHand().getType() == Material.BLAZE_ROD && Firestick.getItemMeta().getDisplayName().equals(ChatColor.GOLD + "Жезл Искр") && e.getAction() == Action.RIGHT_CLICK_AIR && e.getAction() == Action.RIGHT_CLICK_BLOCK) {
ball(e);
}



}

@EventHandler

private void ball(PlayerInteractEvent e) {
Player player = e.getPlayer();
player.launchProjectile(Fireball.class, player.getEyeLocation().getDirection());
player.playSound(player.getLocation(), Sound.ENTITY_BLAZE_SHOOT, 8, 1);
player.spawnParticle(Particle.LAVA, player.getLocation().add(0.5D, 0.5D, 0.5D), 25 , 1.2F, 1.2F, 1.2F);
}
Ну так у тебя проверки на предмет в руке нету в методе ball. Убери аннотацию EventHandler над ball и тогда все нормально должно быть.
 
Ну так у тебя проверки на предмет в руке нету в методе ball. Убери аннотацию EventHandler над ball и тогда все нормально должно быть.
Спасибо за совет! В данном случае я решил в принципе избавиться от него и прописал все в void`е проверки. Тоже хорошо работает)
 
Назад
Верх