Вопрос Плагин на тнт

QuickMan

Разработчик
Пользователь
Сообщения
82
Java:
package mc.qtnt;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;

import java.util.ArrayList;
import java.util.List;

public class Main extends JavaPlugin implements Listener {
    private int tntAmount = 0;

    @Override
    public void onEnable() {
        Bukkit.getPluginManager().registerEvents(this, this);
    }

    String prefix = ChatColor.YELLOW + "QTNT: ";

    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
        if (cmd.getName().equalsIgnoreCase("qtnt")) {
            if (!sender.hasPermission("qtnt.give")) {
                sender.sendMessage(prefix + ChatColor.RED + "У вас нет прав для выполнения этой команды!");
                return true;
            }

            if (args.length < 2) {
                sender.sendMessage(prefix + ChatColor.RED + "Использование: /qtnt <имя_игрока> <количество>.");
                return true;
            }

            String playerName = args[0];
            int amount;
            try {
                amount = Integer.parseInt(args[1]);
            } catch (NumberFormatException e) {
                sender.sendMessage(prefix + ChatColor.RED + "Использование: /qtnt <имя_игрока> <количество>.");
                return true;
            }
            Player player = Bukkit.getPlayer(playerName);
            if (player == null) {
                sender.sendMessage(prefix + ChatColor.RED + "Игрок " + playerName + " не найден!");
                return true;
            }

            // Создание ItemStack тнт с тегом контейнера
            ItemStack tnt = new ItemStack(Material.TNT, amount);
            ItemMeta tntMeta = tnt.getItemMeta();
            List<String> lore = new ArrayList<String>();
            lore.add(ChatColor.YELLOW + "" + ChatColor.ITALIC + "TNT TIER");
            tntMeta.setLore(lore);
            tnt.setItemMeta(tntMeta);

            player.getInventory().addItem(tnt);
            sender.sendMessage(prefix + ChatColor.GREEN + "Игроку " + playerName + " было выдано " + amount + " TNT!");
            return true;
        }

        return false;
    }

    @EventHandler
    public void onBlockBreak(BlockBreakEvent event) {
        Block block = event.getBlock();
        if (block.getType() == Material.OBSIDIAN) {
            ItemStack item = event.getPlayer().getInventory().getItemInMainHand();
            if (item != null && item.getType() == Material.TNT) {
                ItemMeta meta = item.getItemMeta();
                if (meta != null && meta.getLore() != null && meta.getLore().contains(ChatColor.YELLOW + "" + ChatColor.ITALIC + "TNT TIER")) {
                    // Если тнт имеет тег контейнера, то ломаем блок обсидиана
                    block.breakNaturally(item);
                } else {
                    event.setCancelled(true);
                    event.getPlayer().sendMessage(prefix + ChatColor.RED + "Вы не можете ломать обсидиан с обычным TNT!");
                }
            }
        }
    }
}

Как заставить обсидиан ломаться только при взрыве тнт выданного с помощью команды /qtnt?
 
Последнее редактирование:
Решение
Сделай так, что когда ставят тнт, оно заменялось на ентити, это ентити ты уже можешь изменять и отслеживать. Ещё вариант, если ты хочешь, чтобы игроки поджигали тнт самостоятельно, то когда ставят тнт, отслеживай блок, так же отслеживай ивент когда тнт поджигается и опять же изменяй и отслеживай ентити. Всё банально просто
Объединено

Я конечно не работал с тнт, но у меня в голове два варианта реализации взрыва, первый через изменения параметров тнт, мб в бакките такого нет, тогда отслеживать взрыв, проверять нужное ли тнт взрывается и изменять параметры взрыва, если взрыв не может зацепить нужные блоки, то писать цикл на радиусе и чем дальше от центра, тем больше снижать рандом на уничтожение блока
1) Проверить название динамита
2) Проверить что игрок его использует
3) Поставить частицы взрыва
4) Выбрать все блоки в радиусе взрыва
5) Поменять блоки в радиусе на воздух
6) Не обязательно - Включить звук взрыва для всех игроков в радиусе
 
event.getPlayer().getInventory().getItemInMainHand();
Это, конечно, не моя задумка, но я не думаю, что ломать динамитом обсидиан (по коду ломание не взрывом, а динамитом) - это хорошая идея для игроков...

Проверить название динамита
Тогда уж не название, а какой-нибудь тег. Иначе игроки через наковальню или команду на изменение названия предмету, если доступ к такой есть, будут получать такой динамит без проблем.
 
аххрхахп, писал я плагин на такой тнт, всё не так просто как это ожидалось. ))
Объединено

Держи код.
Теперь этот тнт будет на каждом сервере, хпххпххп
Java:
                Location loc = e.getLocation();

                int x = (int) loc.getX();
                int y = (int) loc.getY();
                int z = (int) loc.getZ();

                if(loc.getBlock().getType() != Material.WATER) {
                    for(int i = x-2; i<= x+2; i++) {
                        for(int j = y-1; j<= y+1; j++) {
                            for (int k = z-2; k <= z+2; k++) {
                                Block targetBlock = loc.getWorld().getBlockAt(i,j,k);
                                if(targetBlock.getType() == Material.OBSIDIAN || targetBlock.getType() == Material.CRYING_OBSIDIAN) {
                                    int chance = (int) (Math.random()*100);

                                    if(chance < 60) {
                                        targetBlock.breakNaturally();
                                        loc.getWorld().playSound(loc, Sound.BLOCK_STONE_BREAK, 10,1.5f);
                                    }
                                }
                            }
                        }
                    }
                }
Объединено

она супер тупая. Пока ты ей не скажешь как сделать что-то - она не сделает.
 
Последнее редактирование:
Destroy, Подскажи , что не так в данной строчке?

Код:
Location loc = event.getLocation();
выдает ошибку Cannot resolve method 'getLocation' in 'BlockBreakEvent'
Объединено

Код:
package mc.qtnt;

import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;

import java.util.ArrayList;
import java.util.List;

public class Main extends JavaPlugin implements Listener {
    private int tntAmount = 0;

    @Override
    public void onEnable() {
        Bukkit.getPluginManager().registerEvents(this, this);
    }

    String prefix = ChatColor.YELLOW + "QTNT: ";

    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
        if (cmd.getName().equalsIgnoreCase("qtnt")) {
            if (!sender.hasPermission("qtnt.give")) {
                sender.sendMessage(prefix + ChatColor.RED + "У вас нет прав для выполнения этой команды!");
                return true;
            }

            if (args.length < 2) {
                sender.sendMessage(prefix + ChatColor.RED + "Использование: /qtnt <имя_игрока> <количество>.");
                return true;
            }

            String playerName = args[0];
            int amount;
            try {
                amount = Integer.parseInt(args[1]);
            } catch (NumberFormatException e) {
                sender.sendMessage(prefix + ChatColor.RED + "Использование: /qtnt <имя_игрока> <количество>.");
                return true;
            }
            Player player = Bukkit.getPlayer(playerName);
            if (player == null) {
                sender.sendMessage(prefix + ChatColor.RED + "Игрок " + playerName + " не найден!");
                return true;
            }

            // Создание ItemStack тнт с тегом контейнера
            ItemStack tnt = new ItemStack(Material.TNT, amount);
            ItemMeta tntMeta = tnt.getItemMeta();
            List<String> lore = new ArrayList<String>();
            lore.add(ChatColor.YELLOW + "" + ChatColor.ITALIC + "TNT TIER");
            tntMeta.setLore(lore);
            tnt.setItemMeta(tntMeta);

            player.getInventory().addItem(tnt);
            sender.sendMessage(prefix + ChatColor.GREEN + "Игроку " + playerName + " было выдано " + amount + " TNT!");
            return true;
        }

        return false;
    }

    @EventHandler
    public void onBlockBreak(BlockBreakEvent event) {

        Location loc = event.getLocation();

        int x = (int) loc.getX();
        int y = (int) loc.getY();
        int z = (int) loc.getZ();

        if (loc.getBlock().getType() != Material.WATER) {
            for (int i = x - 2; i <= x + 2; i++) {
                for (int j = y - 1; j <= y + 1; j++) {
                    for (int k = z - 2; k <= z + 2; k++) {
                        Block targetBlock = loc.getWorld().getBlockAt(i, j, k);
                        if (targetBlock.getType() == Material.OBSIDIAN || targetBlock.getType() == Material.CRYING_OBSIDIAN) {
                            int chance = (int) (Math.random() * 100);

                            if (chance < 60) {
                                targetBlock.breakNaturally();
                                loc.getWorld().playSound(loc, Sound.BLOCK_STONE_BREAK, 10, 1.5f);
                            }
                        }
                    }
                }
            }
        }
    }
}

Полный код
 
Destroy, Подскажи , что не так в данной строчке?

Код:
Location loc = event.getLocation();
выдает ошибку Cannot resolve method 'getLocation' in 'BlockBreakEvent'
Объединено

Код:
package mc.qtnt;

import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;

import java.util.ArrayList;
import java.util.List;

public class Main extends JavaPlugin implements Listener {
    private int tntAmount = 0;

    @Override
    public void onEnable() {
        Bukkit.getPluginManager().registerEvents(this, this);
    }

    String prefix = ChatColor.YELLOW + "QTNT: ";

    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
        if (cmd.getName().equalsIgnoreCase("qtnt")) {
            if (!sender.hasPermission("qtnt.give")) {
                sender.sendMessage(prefix + ChatColor.RED + "У вас нет прав для выполнения этой команды!");
                return true;
            }

            if (args.length < 2) {
                sender.sendMessage(prefix + ChatColor.RED + "Использование: /qtnt <имя_игрока> <количество>.");
                return true;
            }

            String playerName = args[0];
            int amount;
            try {
                amount = Integer.parseInt(args[1]);
            } catch (NumberFormatException e) {
                sender.sendMessage(prefix + ChatColor.RED + "Использование: /qtnt <имя_игрока> <количество>.");
                return true;
            }
            Player player = Bukkit.getPlayer(playerName);
            if (player == null) {
                sender.sendMessage(prefix + ChatColor.RED + "Игрок " + playerName + " не найден!");
                return true;
            }

            // Создание ItemStack тнт с тегом контейнера
            ItemStack tnt = new ItemStack(Material.TNT, amount);
            ItemMeta tntMeta = tnt.getItemMeta();
            List<String> lore = new ArrayList<String>();
            lore.add(ChatColor.YELLOW + "" + ChatColor.ITALIC + "TNT TIER");
            tntMeta.setLore(lore);
            tnt.setItemMeta(tntMeta);

            player.getInventory().addItem(tnt);
            sender.sendMessage(prefix + ChatColor.GREEN + "Игроку " + playerName + " было выдано " + amount + " TNT!");
            return true;
        }

        return false;
    }

    @EventHandler
    public void onBlockBreak(BlockBreakEvent event) {

        Location loc = event.getLocation();

        int x = (int) loc.getX();
        int y = (int) loc.getY();
        int z = (int) loc.getZ();

        if (loc.getBlock().getType() != Material.WATER) {
            for (int i = x - 2; i <= x + 2; i++) {
                for (int j = y - 1; j <= y + 1; j++) {
                    for (int k = z - 2; k <= z + 2; k++) {
                        Block targetBlock = loc.getWorld().getBlockAt(i, j, k);
                        if (targetBlock.getType() == Material.OBSIDIAN || targetBlock.getType() == Material.CRYING_OBSIDIAN) {
                            int chance = (int) (Math.random() * 100);

                            if (chance < 60) {
                                targetBlock.breakNaturally();
                                loc.getWorld().playSound(loc, Sound.BLOCK_STONE_BREAK, 10, 1.5f);
                            }
                        }
                    }
                }
            }
        }
    }
}

Полный код
подумай, может эвент не тот?
 
Будьте осторожны с рекомендациями этого пользователя.
Исправил , подскажите , как мне теперь реализовать метод чтобы взрыв обсидиана происходил в случае если тнт имеет название TNT TIER?
Объединено

Вернее , если инициатор взрыв является тнт с названием TNT TIER
 
Исправил , подскажите , как мне теперь реализовать метод чтобы взрыв обсидиана происходил в случае если тнт имеет название TNT TIER?
Объединено

Вернее , если инициатор взрыв является тнт с названием TNT TIER
изучи это

в команде выдачи присваивай ключ, а в ивенте взрыва проверяй его
 
Будьте осторожны с рекомендациями этого пользователя.
Кактус, а разве можно узнать является ли инициатором взрыв предмет с ключом?
Объединено

Кактус,
Тут я выдаю с ключом

Код:
            ItemStack tnt = new ItemStack(Material.TNT, amount);
            ItemMeta tntMeta = tnt.getItemMeta();
            List<String> lore = new ArrayList<String>();
            lore.add(ChatColor.YELLOW + "" + ChatColor.ITALIC + "TNT TIER");
            tntMeta.setLore(lore);
            tntMeta.getPersistentDataContainer().set(new NamespacedKey(this, "qtnt"), PersistentDataType.STRING, "TNT TIER");
            tnt.setItemMeta(tntMeta);
            player.getInventory().addItem(tnt);

            sender.sendMessage(prefix + ChatColor.GREEN + "Игроку " + playerName + " было выдано " + amount + " TNT!");
            return true;
А как проверить я не пойму?
 
Последнее редактирование:
Сделай так, что когда ставят тнт, оно заменялось на ентити, это ентити ты уже можешь изменять и отслеживать. Ещё вариант, если ты хочешь, чтобы игроки поджигали тнт самостоятельно, то когда ставят тнт, отслеживай блок, так же отслеживай ивент когда тнт поджигается и опять же изменяй и отслеживай ентити. Всё банально просто
Объединено

Я конечно не работал с тнт, но у меня в голове два варианта реализации взрыва, первый через изменения параметров тнт, мб в бакките такого нет, тогда отслеживать взрыв, проверять нужное ли тнт взрывается и изменять параметры взрыва, если взрыв не может зацепить нужные блоки, то писать цикл на радиусе и чем дальше от центра, тем больше снижать рандом на уничтожение блока
 
Назад
Сверху Снизу