[Решено] Обработка печи во время переплавки

Статус
Закрыто для дальнейших ответов.

_TheZit445_

Активный участник
Пользователь
Баллы
76
Имя в Minecraft
_TheZit445_
Привет. Вопрос следующий, как лучше всего обрабатывать печь в то время, когда она переправляет предмет? Скорее всего не точно описал суть, сейчас объясню. Мне нужно, чтобы процесс переплавки не начинался, если в слоте стоит не интересующий меня предмет. Допустим надо переплавить алмаз с кастомным названием, но при попытке переплавить обычный, процесс не начинался. Ивент FurnaceBurnEvent для целей не подходит, так как он вызывается только тогда, когда сгарает одна единица топлива. Если после возгорания запихнуть обычный предмет, он начнет переплавляться. Заранее был создан FurnaceRecipe. На данный момент я использую выше указанный ивент, чтобы плавка не начиналась, при старте запускаю BukkitRunnable на 1 тик и создаю лист. В лист кидаю печь, которой хочу прикрыть возможность плавить и в таймере устанавливаю печи из листа время готовки на нуль. После обжарки удаляю печь из листа. Но эта реализация мне не нравится. Во-первых возникает несколько багов, один визуальный, а другой не обновляет печь, если в то время, когда в ней горит топливо, положить предмет, переплавку которого надо предотвратить и дождаться пока топливо прогорит, то по окончании печь ещё горит. И будет гореть до тех пор, пока не обновить ее. Может у вас есть мысли, как это реализовать лучше?
 
А если использовать InventoryClickEvent и разрешить только необходимые предметы? Ну такое о_О

А еще вот это e.setBurning(false)
 
Последнее редактирование:
А если использовать InventoryClickEvent и разрешить только необходимые предметы? Ну такое о_О

А еще вот это e.setBurning(false)
Я клик ивент юзаю чтобы добавить печь в лист. Разрешать только нужные предметы мне не подходит, хочу визуально сделать аналог ванили. Там же в печь все что угодно пихать можно.
 
Регай прямо в нмс предметом со своим названием. RecipesFurnace#a
 
Регай прямо в нмс предметом со своим названием. RecipesFurnace#a
В нмс я по этому поводу даже не заглядывал. То есть тот айтемстак который я впихну и будет задействован? Даже не догадывался. Спасибо за наводку. И с другими типами рецептов такое проворачивается?
 
В нмс я по этому поводу даже не заглядывал. То есть тот айтемстак который я впихну и будет задействован? Даже не догадывался. Спасибо за наводку. И с другими типами рецептов такое проворачивается?
В нмс все рецепты хранятся по ItemStack.
 
Ты про нмс какой версии говоришь? Я забыл сказать, что юзаю апи 1.13.2. В 1.13 не поменялась ли система эта?
Ну нажми shift+shift в идеи, вбей название класса и посмотри, я на 1.12 чекал.
 
Ну нажми shift+shift в идеи, вбей название класса и посмотри, я на 1.12 чекал.
Спасибо, что отвечаешь. Кинь пожалуйста пример. С нмс редко сталкиваюсь, а в итоге мало о нём знаю. Я сейчас пытаюсь так, это под 1.13.2.
Код:
ItemStack i = new ItemStack(Material.DIAMOND);
ItemMeta m = i.getItemMeta();
m.setDisplayName("GOLD");
i.setItemMeta(m);

MinecraftKey key = new MinecraftKey(this.getName().toLowerCase(), "test");
net.minecraft.server.v1_13_R2.ItemStack is = CraftItemStack.asNMSCopy(i);
RecipeItemStack ris = RecipeItemStack.a;
ris.choices = new net.minecraft.server.v1_13_R2.ItemStack[1];
ris.choices[0] = is;

FurnaceRecipe rec = new FurnaceRecipe(key, "test_group", ris, is, 100, 200);
MinecraftServer server = ((CraftServer) Bukkit.getServer()).getServer();
server.getCraftingManager().a(rec);

Сам рецепт вроде как добавляется, ибо если попытаться создать рецепт с таким же ключом, то он кидает исключение, мол уже есть такой. Но при этом не плавится ни обычный алмаз, ни кастомный. А если зарегистрировать рецепт через баккит, то плавятся все. А еще я тут понаписал, конечно, но это пока единственное, что в голову пришло. Помоги пожалуйста.
 
Спасибо, что отвечаешь. Кинь пожалуйста пример. С нмс редко сталкиваюсь, а в итоге мало о нём знаю. Я сейчас пытаюсь так, это под 1.13.2.
Код:
ItemStack i = new ItemStack(Material.DIAMOND);
ItemMeta m = i.getItemMeta();
m.setDisplayName("GOLD");
i.setItemMeta(m);

MinecraftKey key = new MinecraftKey(this.getName().toLowerCase(), "test");
net.minecraft.server.v1_13_R2.ItemStack is = CraftItemStack.asNMSCopy(i);
RecipeItemStack ris = RecipeItemStack.a;
ris.choices = new net.minecraft.server.v1_13_R2.ItemStack[1];
ris.choices[0] = is;

FurnaceRecipe rec = new FurnaceRecipe(key, "test_group", ris, is, 100, 200);
MinecraftServer server = ((CraftServer) Bukkit.getServer()).getServer();
server.getCraftingManager().a(rec);

Сам рецепт вроде как добавляется, ибо если попытаться создать рецепт с таким же ключом, то он кидает исключение, мол уже есть такой. Но при этом не плавится ни обычный алмаз, ни кастомный. А если зарегистрировать рецепт через баккит, то плавятся все. А еще я тут понаписал, конечно, но это пока единственное, что в голову пришло. Помоги пожалуйста.
RecipesFurnace.getInstance().a(сырье, результат, длительность_плавки)
 
@AbstractCoder И снова здравствуйте. В общем не знаю насчёт 1.12, я там даже не смотрел, но на 1.13 подобного класса нет. Есть только FurnaceRecipe, но данного метода там нет. На 1.13 же много переписали, так что возможно и это изменили. Есть еще идеи? Можешь глянуть? А то мои попытки не увенчались успехом.
 
@AbstractCoder И снова здравствуйте. В общем не знаю насчёт 1.12, я там даже не смотрел, но на 1.13 подобного класса нет. Есть только FurnaceRecipe, но данного метода там нет. На 1.13 же много переписали, так что возможно и это изменили. Есть еще идеи? Можешь глянуть? А то мои попытки не увенчались успехом.
Я в 1.13 не смотрел, так что тож порыться надо, не буду вместо тебя это делать. Смотри как там оно работает и разбирайся.
 
@AbstractCoder В общем я покопался, поэкспериментировал. В итоге у меня ничего не вышло. В доках к spigot говорят есть класс RecipeChoice.ExactChoice, но его нет. Реализовывать свой смысла нет, ибо при регистрации рецепта идёт проверка, является ли RecipeChoice MaterialChoice. Если нет, то кидает эксепшн. Пробовал еще всякие вариации извращенства с nms, но безуспешно. Сейчас используется RecipeItemStack в качестве ингридиента в nms. Ты смотрел, вышло что-нибудь? Или придётся костыли использовать?
 
@AbstractCoder В общем я покопался, поэкспериментировал. В итоге у меня ничего не вышло. В доках к spigot говорят есть класс RecipeChoice.ExactChoice, но его нет. Реализовывать свой смысла нет, ибо при регистрации рецепта идёт проверка, является ли RecipeChoice MaterialChoice. Если нет, то кидает эксепшн. Пробовал еще всякие вариации извращенства с nms, но безуспешно. Сейчас используется RecipeItemStack в качестве ингридиента в nms. Ты смотрел, вышло что-нибудь? Или придётся костыли использовать?
Не смотрел.
 
@alexandrage Привет. Глянь пожалуйста, может у тебя мысли будут.

Не уверен, что то, но посмотри org.bukkit.craftbukkit.v1_13_R2.inventory.CraftFurnaceRecipe.

Если хочешь на НМС, то можешь разобраться с кодом, который используется ими (ниже)

PHP:
/* из CraftFurnaceRecipe#addToCraftingManager */

MinecraftServer.getServer().getCraftingManager().a(new net.minecraft.server.v1_13_R2.FurnaceRecipe(CraftNamespacedKey.toMinecraft(ключ), группа, toNMS(ингредиент, true), айтем_результат, опыт, время_готовки));

/* из org.bukkit.craftbukkit.v1_13_R2.inventory.CraftRecipe */

RecipeItemStack toNMS(RecipeChoice bukkit, boolean requireNotEmpty) {
    RecipeItemStack stack;

    if (bukkit == null) {
        stack = RecipeItemStack.a;
    } else if (bukkit instanceof MaterialChoice) {
        stack = new RecipeItemStack(((MaterialChoice)bukkit).getChoices().stream().map((mat) -> {
            return new StackProvider(CraftItemStack.asNMSCopy(new ItemStack(mat)));
        }));
    } else {
        if (!(bukkit instanceof ExactChoice)) {
            throw new IllegalArgumentException("Unknown recipe stack instance " + bukkit);
        }

        stack = new RecipeItemStack(((ExactChoice)bukkit).getChoices().stream().map((mat) -> {
            return new StackProvider(CraftItemStack.asNMSCopy(mat));
        }));

        stack.exact = true;
    }

    stack.buildChoices();

    if (requireNotEmpty && stack.choices.length == 0) {
        throw new IllegalArgumentException("Recipe requires at least one non-air choice!");
    } else {
        return stack;
    }
}
 
В этом то и есть проблема, в билде нету класса ExactChoice. Он отсутствует, поэтому я не могу это использовать.
Вот всё что есть:
Код:
    default RecipeItemStack toNMS(final RecipeChoice bukkit) {
        if (bukkit == null) {
            return RecipeItemStack.a;
        }
        if (bukkit instanceof RecipeChoice.MaterialChoice) {
            final RecipeItemStack.StackProvider stackProvider;
            return new RecipeItemStack(((RecipeChoice.MaterialChoice)bukkit).getChoices().stream().map(mat -> {
                new RecipeItemStack.StackProvider(CraftItemStack.asNMSCopy(new ItemStack(mat)));
                return stackProvider;
            }));
        }
        throw new IllegalArgumentException("Unknown recipe stack instance " + bukkit);
    }
Не знаю, будет ли работать, если самому написать класс CraftRecipe, а от него и другие, уже с участием ExactChoice, и попробовать зарегистрировать, но можно попробовать.
 
Статус
Закрыто для дальнейших ответов.
Назад
Верх