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

Помогите Создание кастомных крафтов

Можно подробнее про следующие моменты?
Перебираешь все кастомные крафты при старте сервера
Кастомные крафты, по вашему методу, хранятся в конфигах?
Сортируешь все материалы крафта как-либо(по названию или Material#ordinal)
А что это даст?
Сохраняешь это дело в какой-нибудь вид Map<Integer, List<LargeRecipe>> (List в случае коллизий). Можно ещё FastUtils воспользоваться, там есть мапа с ключами int.
Тут я правильно понимаю, что в мапе будут храниться рецепты, с которыми потом будут сравниваться инвентари верстаков игроков?
При крафте:
- Сортируешь все материалы крафта
- Получаешь общий хэш
Тут не могу понять. Т.е. взять верстак игрока и сделать хэш мапу с использованными айтемами? А затем сравнивать получившийся хэш с загруженной мапой?
Если shaped, проверяешь слоты на соответствие; в случае, если рецепт меньше 4х4, то не забудь про проверку с отступами
Единственное, что пришло в голову. Так это то, что в загруженной и верстачной мапах используются хэши именно с относительным расположением айтемов: отступы игнорируются.

Пока писал, вскипел мозг. Я имею представление о мапах, но использовал пока только для хранения меты блоков по их координатам. Есть какие-нибудь источники, где можно больше узнать для реализации второго способа?
 
Некое имя крафта, класс рецепта, что и логично.
С именем окей, а зачем класс рецепта? Я хочу сделать возможность создавать крафты в самой игре через "Верстак админа", чтобы рецепты сохранялись в файлы
 
С именем окей, а зачем класс рецепта? Я хочу сделать возможность создавать крафты в самой игре через "Верстак админа", чтобы рецепты сохранялись в файлы
Ну а как и чем ты будешь проверять крафт? Это же не просто так класс рецепта.
 
Кастомные крафты, по вашему методу, хранятся в конфигах?
Это уж зависит от тебя. Можно в JSON хранить.
Это нужно для получения хэша, ведь порядок зачастую имеет значение.
Тут я правильно понимаю, что в мапе будут храниться рецепты, с которыми потом будут сравниваться инвентари верстаков игроков?
Да. На всякий случай поясню - ключём будет этот самый хэш, значением - списки с кастомными рецептами. Списки нужны, чтобы не произошло коллизий.
Тут не могу понять. Т.е. взять верстак игрока и сделать хэш мапу с использованными айтемами? А затем сравнивать получившийся хэш с загруженной мапой?
Единственное, что пришло в голову. Так это то, что в загруженной и верстачной мапах используются хэши именно с относительным расположением айтемов: отступы игнорируются.
Нет, тебе не нужно делать ещё одну мапу при крафте. Здесь ты берешь всё, что игрок положил в верстак, и проделываешь тоже самое, что и при старте сервера - сортируешь материалы и получаешь хэш - только вместо того, чтобы вставлять в мапу, ты получаешь из неё. Ключём служит хэш.
Есть какие-нибудь источники, где можно больше узнать для реализации второго способа?
Боюсь, что нет, ибо это всё я взял из головы.

Могу чуть больше пояснить, но лишь вечером, ибо сейчас занят.
 
Если я правильно понял @imDaniX, то суть такова:

Создаем хэшмап, ключем которого будет hash, а значение - наш рецепт.

HashMap<Integer, Recipe> recipeses = new HashMap<>();

https://pastebin.com/yPsbcfVR

в onEnable() достаешь рецепт твоего предмета и пихаешь в мапу- пример:
https://pastebin.com/Bak0CB6i
Там так же находятся методы sort() и hash() (сам придумаешь как тебе хешировать и сортировать все это )
ну и
public enum RecipeType {
SHAPLESS, SHAPED
}

Теперь поясним немного про работу shapedRecipe:
https://imgur.com/a/30s3SUE
Вот эта картинка подходит к коду метода createSimpleShapedReciepe.

Писал на скорою руку, поэтому заговнокодил чу-чуть. Думаю сам потом исправишь на более красивый код.
 
Спасибо за пример. Только я всё не догоняю, что за хэш, который ключ в мапе. К чему он привязан?
PHP:
public int hash(ArrayList<ItemStack> list) {
        int hash = 1;
        return hash;//Как хэш должен формироваться? 
    }
 
Как ты хочешь. Можешь формировать хэш по ид, например.
depreacted, кончено, но вроде рабочий. Не тестил в майнкрафте еще.
@SuppressWarnings("deprecation")
public int hash(ArrayList<ItemStack> list) {
int hash = 0;
for(ItemStack s : list) {
hash += s.getData().getItemTypeId();
}
return hash;
}
 
Как ты хочешь. Можешь формировать хэш по ид, например.
depreacted, кончено, но вроде рабочий. Не тестил в майнкрафте еще.
@SuppressWarnings("deprecation")
public int hash(ArrayList<ItemStack> list) {
int hash = 0;
for(ItemStack s : list) {
hash += s.getData().getItemTypeId();
}
return hash;
}
Мб как-то так. Метод включает в себя и сортировку материалов крафта
PHP:
public static int materialsHash(List<ItemStack> items) {
    Material[] materials = new Material[items.size()];
    for (int i = 0; i < materials.length; i++) {
        materials[i] = items.get(i).getType();
    }
    Arrays.sort(materials);
    int hash = 17;
    for (Material material : materials) {
        hash = hash * 31 + material.hashCode() ;
    }
    return hash;
}
Если подавать в метод уже сортированное
PHP:
public static int materialsHash(List<ItemStack> items) {
    int hash = 17;
    for (ItemStack item : items) {
        hash = hash * 31 + item.getType().hashCode(); 
    }
    return hash;
}
 
Ещё раз приветствую всех! Только сейчас смог вернуться к плагину
На счёт сортировки. Если подразумевается сортировка айтемстаков (iron, air, iron -> iron,iron,air), то в результате хэши железного шлема и вагонетки будут совпадать. Также для хранения надо использовать тип long, для инта хэш великоват.
 
На счёт сортировки. Если подразумевается сортировка айтемстаков (iron, air, iron -> iron,iron,air), то в результате хэши железного шлема и вагонетки будут совпадать. Также для хранения надо использовать тип long, для инта хэш великоват.
Поэтому я и написал про коллизии и сразу предложил хранить список рецептов.
 
Поэтому я и написал про коллизии и сразу предложил хранить список рецептов
Только сейчас понял, что подразумевалось под коллизией.
Только вот всё не могу понять надобность сортировки. Если создавать хэши без неё, то вероятность повторения столь больших чисел, как мне кажется, ну очень мала, тем более если брать hashCode у айтемстаков, а не материалов.
 
Только вот всё не могу понять надобность сортировки. Если создавать хэши без неё, то вероятность повторения столь больших чисел, как мне кажется, ну очень мала, тем более если брать hashCode у айтемстаков, а не материалов.
Можно было бы генерировать хэш без сортировки, но только в том случае, если бы мы могли размещать предметы только в очень определенных местах. Допустим рецепт вагонетки
Код:
ж в ж в
ж ж ж в
в в в в
в в в в
Но игрок ставит
Код:
в в в в
в ж в ж
в ж ж ж
в в в в
В случае с сортировкой хэш совпадет и мы успешно найдем рецепт, но без неё, увы.

По поводу использования сразу стаков для хэша - в таком случае хэш изменится даже если предмет, например, переименован.
 
Можно было бы генерировать хэш без сортировки, но только в том случае, если бы мы могли размещать предметы только в очень определенных местах. Допустим рецепт вагонетки
Код:
ж в ж в
ж ж ж в
в в в в
в в в в
Но игрок ставит
Код:
в в в в
в ж в ж
в ж ж ж
в в в в
В случае с сортировкой хэш совпадет и мы успешно найдем рецепт, но без неё, увы.

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

По поводу использования сразу стаков для хэша - в таком случае хэш изменится даже если предмет, например, переименован.
Я вот думал в класс рецепта добавить двумерный массив (матрицу) рецепта.
Типа если админ сделает крафт
Код:
i  - железо
t - дерево
0 - пусто
i 0 0 0
i 0 0 0
t 0 0 0
0 0 0 0
То перед сохранением (с помощью рекурсии или while) обрезать пустые строки и столбцы до состояния
Код:
i
i
t

Ну и аналогично уже со стороны игрока. Положил предмет: обрезка, вычисление хэша, поиск по хэшу
 
Я вот думал в класс рецепта добавить двумерный массив (матрицу) рецепта.
Типа если админ сделает крафт
Код:
i  - железо
t - дерево
0 - пусто
i 0 0 0
i 0 0 0
t 0 0 0
0 0 0 0
То перед сохранением (с помощью рекурсии или while) обрезать пустые строки и столбцы до состояния
Код:
i
i
t

Ну и аналогично уже со стороны игрока. Положил предмет: обрезка, вычисление хэша, поиск по хэшу
В таком варианте shapeless рецепты будет сложно сделать, разве нет?
 
В таком варианте shapeless рецепты будет сложно сделать, разве нет?
Блин. О них забыл.
Ну наверное можно как раз для таких со стороны админа сохранять только айтемы в массив и после сортировать его. А со стороны игрока сначала проверять на shapeless (айтемы>массив>сортировка>хэш), а потом на shaped (матрица>обрезка>хэш)
 

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

Назад
Верх