Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

Помогите Некорректная работа PrepareCraftItemEvent [Решено]

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

_TheZit445_

Активный участник
Пользователь
Баллы
76
Имя в Minecraft
_TheZit445_
Приветствую. Маленькая предыстория. Хочу реализовать кастомный крафт. Использую данный ивент. Сами крафты работают исправно, то что надо крафтится, но предметы в слотах верстака ведут себя некорректно. Допустим такой крафт: из одного алмаза получаем изумруд. Так вот если положить один алмаз, то все нормально, алмаз исчезнет, а мы получим изумруд, ео если два, то мы получим изумруд, но в слоте как было два алмаза, так и останется два алмаза. Дальше вообще абсурд. Если было 3 алмаза, станет 4, если 4, будет 6, если 5, то станет 8, если 6, то будет 10 и так далее, закономерность думаю ясна. Реализовано так - я грубо говоря проверяю слот верстака с необходимым предметом. Если всё успешно, то выводим результат. И вообще, кастомные рецепты так реализуются или как-то иначе. Я стараюсь сделать с поддержкой NBT, ибо иначе зачем вообще морочится. Если нужен будет код, кину.

upload_2019-2-13_19-36-55.png
 
Приветствую. Маленькая предыстория. Хочу реализовать кастомный крафт. Использую данный ивент. Сами крафты работают исправно, то что надо крафтится, но предметы в слотах верстака ведут себя некорректно. Допустим такой крафт: из одного алмаза получаем изумруд. Так вот если положить один алмаз, то все нормально, алмаз исчезнет, а мы получим изумруд, ео если два, то мы получим изумруд, но в слоте как было два алмаза, так и останется два алмаза. Дальше вообще абсурд. Если было 3 алмаза, станет 4, если 4, будет 6, если 5, то станет 8, если 6, то будет 10 и так далее, закономерность думаю ясна. Реализовано так - я грубо говоря проверяю слот верстака с необходимым предметом. Если всё успешно, то выводим результат. И вообще, кастомные рецепты так реализуются или как-то иначе. Я стараюсь сделать с поддержкой NBT, ибо иначе зачем вообще морочится. Если нужен будет код, кину.

Ну код безусловно нужен. Тут же ясно, что у вас что-то не так с кодом. Каждый алгоритм реализовать можно бесчисленным количеством способов. Я, например, для кастомных крафтов с NBT использовал добавление рецепта в список стандартных, после чего его отслеживал и заменял результат на нужный элемент в том же событии.
 
Ну код безусловно нужен. Тут же ясно, что у вас что-то не так с кодом. Каждый алгоритм реализовать можно бесчисленным количеством способов. Я, например, для кастомных крафтов с NBT использовал добавление рецепта в список стандартных, после чего его отслеживал и заменял результат на нужный элемент в том же событии.
Код чуть позже. Если бы мне нужно было заменить именно результат, я бы поступил так же наверное, но я ещё проверяю сами ингредиенты, на наличие nbt.
 
Ну код безусловно нужен. Тут же ясно, что у вас что-то не так с кодом. Каждый алгоритм реализовать можно бесчисленным количеством способов. Я, например, для кастомных крафтов с NBT использовал добавление рецепта в список стандартных, после чего его отслеживал и заменял результат на нужный элемент в том же событии.

Класс с конструктором рецепта
Код:
package ru.thezit445.CraftingAPI.recipes;

import java.util.HashMap;

import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_13_R2.inventory.CraftItemStack;
import org.*********ventory.ItemStack;

import com.google.gson.Gson;

import net.minecraft.server.v1_13_R2.NBTTagCompound;
import ru.thezit445.CraftingAPI.crafting.DummyItem;

public class ShapedNBT_Recipe extends NBT_Recipe{
   
    private String[] PATTERN = new String[3];
    private HashMap<String, DummyItem> ITEMS = new HashMap<String, DummyItem>();
    private DummyItem RESULT;
   
    public ShapedNBT_Recipe(RecipeType type) {
        super(type);
        ITEMS.put(" ", new DummyItem(Material.AIR, null));
    }
   
    public int getHorizontalPatternSize() {
        int size = 0;
        for (String layer : PATTERN) {
            if (layer == null) continue;
            if (size < layer.length()) {
                size = layer.length();
            }
        }
        return size;
    }
   
    public int getVerticalPatternSize() {
        int size = 0;
        for (int i = 0; i<3; i++) {
            if (PATTERN[i]!=null && !PATTERN[i].isEmpty()) size++;
        }
        return size;
    }
   
    public void setResult(ItemStack item) {
       
        CraftItemStack craftItem = CraftItemStack.asCraftCopy(item);
        NBTTagCompound NBT = new NBTTagCompound();
        CraftItemStack.asNMSCopy(craftItem).save(NBT);
        RESULT = new DummyItem(item.getType(), NBT);
       
    }
   
    public ItemStack getResult() {
       
        NBTTagCompound NBT = RESULT.getNBT();
        net.minecraft.server.v1_13_R2.ItemStack nmsItem = net.minecraft.server.v1_13_R2.ItemStack.a(NBT);
        ItemStack item = CraftItemStack.asBukkitCopy(nmsItem);
       
        return item;
       
    }
   
    public void setItemKey(String key, ItemStack item) {
       
        CraftItemStack craftItem = CraftItemStack.asCraftCopy(item);
        NBTTagCompound NBT = new NBTTagCompound();
        CraftItemStack.asNMSCopy(craftItem).save(NBT);
        ITEMS.put(key, new DummyItem(item.getType(), NBT));
       
    }
   
    public DummyItem getDummyItemKey(String key) {
        return ITEMS.get(key);
    }
   
    public void setItems(HashMap<String, DummyItem> items) {
        ITEMS = items;
    }
   
    public ItemStack getItem(String key) {
       
        NBTTagCompound NBT = ITEMS.get(key).getNBT();
        net.minecraft.server.v1_13_R2.ItemStack nmsItem = net.minecraft.server.v1_13_R2.ItemStack.a(NBT);
        ItemStack item = CraftItemStack.asBukkitCopy(nmsItem);
        return item;
       
    }
   
    public void setFirstLayerForPattern(String layer) {
        PATTERN[0] = layer;
    }

    public void setSecondLayerForPattern(String layer) {
        PATTERN[1] = layer;
    }
   
    public void setThriedLayerForPattern(String layer) {
        PATTERN[2] = layer;
    }
   
    public void setPattern(String[] pattern) {
        PATTERN = pattern;
    }
   
    public String[] getPattern() {
        return PATTERN;
    }
   
    public String getLayer(int layerNumber) {
        return PATTERN[layerNumber];
    }
   
    @Override
    public String toJsonString() {
        Gson gson = new Gson();
        return gson.toJson(this, ShapedNBT_Recipe.class);
    }

    public static NBT_Recipe getCraft(String json) {
        Gson gson = new Gson();
        return gson.fromJson(json, ShapedNBT_Recipe.class);
    }

}

Класс с обработчиком события крафта
Код:
package ru.thezit445.CraftingAPI.crafting_handlers;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.PrepareItemCraftEvent;
import org.*********ventory.ItemStack;

import ru.thezit445.CraftingAPI.crafting.DummyItem;
import ru.thezit445.CraftingAPI.main.CraftingAPI;
import ru.thezit445.CraftingAPI.recipes.ShapedNBT_Recipe;
import ru.thezit445.CraftingAPI.util.NBT_Manager;

public class ShapedHandler implements Listener{

    @EventHandler
    public void handler(PrepareItemCraftEvent event) {
        Iterator<ShapedNBT_Recipe> iterator = CraftingAPI.SHAPED_RECIPES.iterator();
        ItemStack[] matrix = event.getInventory().getMatrix();
        while (iterator.hasNext()) {
            ShapedNBT_Recipe recipe = iterator.next();
            boolean[] confirmItems = new boolean[recipe.getHorizontalPatternSize()*recipe.getVerticalPatternSize()];
            Arrays.fill(confirmItems, false);
            int hx = 3-recipe.getHorizontalPatternSize();
            int hy = 3-recipe.getVerticalPatternSize();
            List<Integer> activeItems = new ArrayList<Integer>();
            for (int i = 0; i<=hy; i++) {
                for (int j = 0; j<=hx; j++) {
                    activeItems.clear();
                    for (int y = (0+i); y<(recipe.getVerticalPatternSize()+i); y++) {
                        for (int x = (0+j); x<(recipe.getHorizontalPatternSize()+j); x++) {
                           
                            activeItems.add(x+y*3);
                           
                           
                            ItemStack item = matrix[x+y*3];
                            ItemStack sample = recipe.getItem(""+recipe.getPattern()[y-i].charAt(x-j));
                            DummyItem dummy = recipe.getDummyItemKey(""+recipe.getPattern()[y-i].charAt(x-j));
                           
                            if (item==null && dummy.getMaterial()==Material.AIR) {
                                confirmItems[(x-j)+((y-i)*3)] = true;
                            } else 
                                if (item!=null && item.getType()==dummy.getMaterial()) {
                                    if (dummy.hasCustomNBT()) {
                                        if (dummy.getNBT().get("tag").equals(NBT_Manager.getNBT(item))) {
                                            confirmItems[(x-j)+((y-i)*3)] = true;
                                        } else {
                                            confirmItems[(x-j)+((y-i)*3)] = false;
                                        }
                                    } else {
                                        confirmItems[(x-j)+((y-i)*3)] = true;
                                    }
                                } else { 
                                    confirmItems[(x-j)+((y-i)*3)] = false;
                                }
                           
                        }
                    }
                   
                    boolean complete = true;
                    for (int g = 0; g<confirmItems.length; g++) {
                        complete = (complete && confirmItems[g]);
                    }
                   
                    for (int s = 0; s<9; s++) {
                        if (activeItems.contains(s)) continue;
                        if (matrix[s]!=null) complete = false;
                    }
                   
                    if (complete) {
                        event.getInventory().setResult(recipe.getResult());
                        return;
                    } else {
                        if (event.getInventory().getRecipe() != null) {
                            event.getInventory().setResult(event.getInventory().getRecipe().getResult());
                        } else {
                            event.getInventory().setResult(new ItemStack(Material.AIR));
                        }
                    }
                   
                    Arrays.fill(confirmItems, false);
                }
            }
        }
    }
   
}
 
Код чуть позже. Если бы мне нужно было заменить именно результат, я бы поступил так же наверное, но я ещё проверяю сами ингредиенты, на наличие nbt.
Ну так я и проверяю наличие nbt у ингредиентов, потому что мне нужно, чтобы из предметов с разными названиями крафтились разные результаты.
 
Ну так я и проверяю наличие nbt у ингредиентов, потому что мне нужно, чтобы из предметов с разными названиями крафтились разные результаты.

Есть какой-нибудь клочок кода, я бы глянул. И я еще кое-что нашёл, но пока не разбирался, но там это реализовано. Если можешь, поделись пожалуйста.
 
Есть какой-нибудь клочок кода, я бы глянул. И я еще кое-что нашёл, но пока не разбирался, но там это реализовано. Если можешь, поделись пожалуйста.
У меня это так делается:
Java:
@EventHandler
    public void onCraft(org.bukkit.event.inventory.PrepareItemCraftEvent e)
    {
        if(e.getRecipe()==null || e.getRecipe().getResult()==null)
            return;
        for(EternalRecipe er: recipes.get(e.getRecipe().getResult().getType()))
            if(er.isIt(e.getInventory()))
            {
                e.getInventory().setResult(er.getResult());
                return;
            }
        e.getInventory().setResult(null);
    }
 
@alexandrage , @Ission , спасибо за помощь. Добил свою реализацию, полностью ее переписал, оставив идею. Перенял некоторые вещи у вас. В общем то сатанинское кол-во, которое получалось в сетке крафта, не мой грех (ну или немножко мой). После того как переписал с нуля, количество предметов в сетке просчитывается правильно, но с визуальным багом. Было нечто похожее на то, что описано в проблеме, но через долю секунды количество устанавливалось правильным. Я так понял, что это связанно с новой реализацией крафтов на 1.13, ибо я использовал ShapedRecipe(ItemStack result), который уже считается устаревшим, возможно он даёт осложнение, ведь даже когда я не использую обработку ивента, визуальный баг есть.
 
Статус
Закрыто для дальнейших ответов.

Поделиться этой страницей

Назад
Верх