[ГАЙД] Кейсы(Тайники).

В этом гайде я опишу создание кейсов, рандом и анимации для кейсов. За идею спасибо @PbI6A.

База: инвентарь кейса. Перед тем как кодить поставьте в технической зоне(где-то за картой) двойной сундук с названием "Кейс"(Можно цветное)
Форматирование (BB-код):
# - объяснение кода.
#Жирным выделены сохранённые переменные и постоянные массивы.
#Слова в кавычках - текстовые переменные

Событие игрок заходит в игру
    #Создадим массив где будут хранится все кейсы игрока
    Если переменная НЕ существует(%player%CaseArray) {
        #Сделаем так, чтобы массив создавался всего 1 раз
        Установить значение переменной(%player%CaseArray, "True")
        Создать массив(%player%CaseArray)
        #Поместим предметы кейсов в переменные. Например донатный кейс будет головой золотого сундука в переменной donateCase
        Установить предмет в переменную(defaultCaseItem, ложим голову/предмет)
        #Устанавливаем столько переменных и предметов, сколько хотим сделать видов кейсов
    }

Событие игрок кликает правой кнопкой
    #Это когда игрок открывает меню кейсов. У меня для этого надо кликнуть по порталу энда
    Если игрок смотрит на(Ложим блок по которому надо кликнуть для открытия меню, число ложим 0 и отключаем дату блоков) {
        #Так как майнленд сильно ограничивает вызов функций, мы сделаем очередь для открытия кейсов.
        #То есть если два игрока пытаются одновременно открыть меню - одному из них придётся подождать
        #Если не сделать - могут быть ошибки + сломается код
        Если переменная(functionBusy = True) {
            Присвоить значение переменной +=(query)
            Отправить сообщение игроку("Кейсы уже используются! Место в очереди: " query)
        } Иначе {
            Сравнить число облегчённо(query > 1) {
                 Присвоить значение переменной -=(query)
            } Иначе {
                Установить значение переменной(query, 0)
            }
            #Тут мы сделаем открытие меню кейсов. Начнём.
            Установить значение переменной(functionBusy, "True")
Установить значение переменной(caseFillerLength, 0)
            #caseFillerLength - переменная, которая будет использовать для заполнения меню
            #0 - переменная "Число", не "Текст"
            Установить значение переменной(caseFillerLength, 0)
            #Тоже переменная пригодится позже
            Получить размер массива(%player%CaseArray, %player%ArrayLength)
            Отправить сообщение игроку на экран("Выдача кейсов..." "Это может занять до 2-х секунд...")
            #Очищаем сундук с кейсами после прошлого игрока
            Очистить контейнер(Ложим координаты того двойного сундука)
            #Эту строчку можно не делать. Я просто немного обрезал количество кейсов, теперь самая нижняя строка будет заполнена серым стеклом)
            #Если что, скриншот будет ниже
            Установить предметы в контейнер(Ложим координаты того двойного сундука, предмет - светло серая стеклянная панель, числа ложим от 45 до 53)
            #Собственно заполним сундук кейсами игрока
            Вызвать функцию(CaseFiller)
        }
   }

Функция(CaseFiller)
    #Очистим экран игрока, так как кейсы могли загрузиться быстрее
    Отправить сообщение игроку на экран("&f")
    Сравнить число облегчённо(%player%ArrayLength > 0) {
        #Будем выполнять код, пока не добавим все кейсы
        Сравнить число облегчённо(caseFillerLength < %player%ArrayLength) {
            Присвоить значение переменной +=(caseFillerLength)
            #Узнаем слот, куда надо ложить кейс
            Присвоить значение переменной -(caseFillerItemSlot, caseFillerLength, 1)
            #Так как у нас может быть несколько видов кейсов, мы узнаем, что именно это за кейс
            Получить элемент массива(%player%CaseArray, caseFillerLength, caseItem)
            #Положим кейс в инвентарь
            Установить предметы в контейнер(Ложим координаты того двойного сундука, Динамическая переменная: caseItem, число: caseFillerItemSlot)
            Ждать(1 тик)
            Вызвать функцию(caseFiller)
        } Иначе {
            #Когда мы добавим все предметы - мы откроем инвентарь игроку и покажем его кейсы
            Присвоить значение переменной(functionBusy, "False")
            Открыть инвентарь из игры(Ложим координаты того двойного сундука, выбираем "Копия")
        }
    } Иначе {
        #Если у игрока нету кейсов - отобразим пустой инвентарь(Можно положить предмет с названием "Пусто!")
        Открыть инвентарь из игры(Ложим координаты того двойного сундука, выбираем "Копия")
        Установить значение переменной(functionBusy, "False")
    }

Событие игрок пишет в чат
    #Это лимит кейсов, всего можно будет иметь 1 заполненную страницу.
    Сравнить число облегчённо(%player%ArrayLength < 45) {
        #Дальше - код для добавления кейса игроку
        #Повторяйте это "Если сообщение равно" сколько хотите
        Если сообщение равно("@giveDefaultCase") {
            Добавить в конец массива(%player%CaseArray, defaultCaseItem)
            Получить размер массива(%player%CaseArray, %player%ArrayLength)
        }
    }

Событие игрок кликает по инвентарю
    Если название открытого инвентаря("Кейс") {
        Отменить событие
        #Это код, когда игрок открывает кейс.
        Если переменная(caseBusy != "True") {
            Если кликнутый предмет равен(Ложим предмет-кейс, например голову ввиде золотого сундука) {
                Присвоить значение переменной(casePlayer, %player%)
                Присвоить значение переменной +(%player%ClickSlot, Значение события - кликнутый слот, 1)
                Удалить элемент из массива(%player%CaseArray, %player%ClickSlot)
                Присвоить значение переменной(caseBusy, "True")
                Закрыть инвентарь
                Присвоить значение переменной(caseCoordinates, координаты - центр блока кейсов(x и z координаты должны иметь .50, y координата на 1-1.5 блоков меньше координаты где стоит блок для открытия кейсов.))
                #Тут появляется проблема. Если поставить интеллект и гравитацию на "нету", то моб с головой не сможет подлетать вверх(подлетать вверх - анимация поднятия. А если поставить на "есть" - моб будет крутиться и будет не очень красиво. И будет ещё одна проблема, опишу дальше
                #Если есть идеи для решения этой проблемы - пишите.
                #Возраст 100 нужен для того, чтобы не спавнился зомби-малыш. Радиус зрения чтобы зомби не атаковал.
                Заспавнить моба(Яйцо зомби, координаты - центр блока кейсов(должно совпадать с координатами из "Присвоить значение переменной") Отключаем звуки, деспавн и урон. Радиус зрения - 0, возраст - 100. Имя - "КЕЙС". Ложим зелье невидимости 10 на 8 минут(я сделал через инфинити айтем эдитор), отключаем частицы и в слот для шлема ложим голову кейса. В данном случае - голову золотого кейса.)
                Вызвать функцию(caseAnimation)
            }
        } Иначе {
            Отправить сообщение игроку("Кейсы уже открываются!")
        }
    }


Анимация открытия. Сразу скажу, что она работает неидеально. Если есть идеи для решения проблем - пишите. Моя анимация - просто поднятие кейса наверх. Если есть желание и время - можете сделать как на мл, чтобы были линии из частиц. Можно ещё кучу разных придумать.
Форматирование (BB-код):
Функция(caseAnimation)
    #Можно экспериментировать с числом, например вместо 0.1 поставить 0.5
    Установить значения в местоположение(caseCoordinates, caseCoordinates, режим установки Y += и туда же ложим 0.1)
    #Можно экспериментировать с выборкой, например попробовать "Если находится рядом"
    Выбрать моба по типу(Яйцо зомби)
    #Шифт + пкм по табличке и выбираем "Выборка"
    Запустить к местоположению(caseCoordinates)
    Присвоить значение переменной +=(caseAnimationIter)
    #Это количество итераций. Проще говоря, на сколько блоков надо поднять(10 итераций - 1 блок)
    Сравнить число облегчённо(caseAnimationIter <= 20) {
        Ждать(1 тик)
        Вызвать функцию("caseAnimation")
    } Иначе {
        #Дальнейший код нужен чтобы зомби с головой кейса не упал вниз - тогда анимация не сломается.
        Заспавнить моба(Яйцо зомби, координаты - под блоком кейсов(Ну блок кейсов и по Y отнимаем 2-3 блока через IIE Отключаем звуки, деспавн, гравитацию, ИИ и урон. Возраст - 100. Ложим зелье невидимости 10 на 8 минут(я сделал через инфинити айтем эдитор.)
        #Можно экспериментировать с выборкой. Так же ставим через стрелочку "НЕ"
        #Дальнейший код - пересоздание головы кейса, чтобы зомби с головой не упал вниз(так как гравитация на него действует)
        Выбрать моба по условию(Имя равно "КЕЙС")
        #Все дальнейшие блоки действий будут с выборкой, не забудьте(Шифт + пкм по блоку)
        Телепортация(caseCoordinates)
        Ждать(1 тик)
        Надеть броню(В слот для шлема ложим голову кейса, например голову золотого сундука)
        Выбрать моба по условию(Имя равно "КЕЙС")
        Удалить сущность
        #Когда кейс полностью поднимется - вызовется рандом, чтобы определить что выпало
        #Если экономите место - все блоки из функции можно запихнуть сюда
        Установить значение переменной(caseAnimationIter, 0)
        Вызвать функцию("caseRandom")
    }

Итак. Теперь сделаем рандом. Есть два вида: Простой и сложный.

Простой рандом - рандом с одинаковыми шансами. То есть, мы ложим 5 предметов и у каждого предмета шанс на выпадение 20%(100%:5=20%). Ложим 10 предметов - у каждого шанс 10%. Это делается через "Установить случайное значение". Если вам лень кодить - делайте этот способ.

Сложный рандом - рандом с разными шансами. То есть, допустим, у нас есть 3 предмета - легендарный, обычный и редкий. Допустим, у легендарного шанс на выпадения 10%, у редкого 35% и у обычного 55%. Я сделаю код для этого отдельной функцией.

Итак, сам код-функция.

Форматирование (BB-код):
Функция("caseRandom")
    #Расскажу принцип работы. Мы как бы делим 100(100%) на несколько сегментов.
    #Чем меньше размер сегмента, тем меньше и процент попадания в данный сегмент
    Установить случайное число(caseRandomValue, 1, 100)
    #Это проверки, в какой сегмент попадаем. Их можно делать сколько хотите.
    Сравнить число(caseRandomValue, сверху: > 0, снизу: <= 10) {
        Установить предмет в переменную(caseRandomItem, легендарный предмет для выпадения)
    }
    Сравнить число(caseRandomValue, сверху: > 10, снизу: <= 45) {
        Установить предмет в переменную(caseRandomItem, редкий предмет для выпадения)
    }
    Сравнить число(caseRandomValue, сверху: > 45, снизу: <= 100) {
        Установить предмет в переменную(caseRandomItem, обычный предмет для выпадения)
    }
    #Дальше идёт выдача предметов и анимация(Появится предмет и будут партиклы, а ещё сообщение в чат)
    Выбрать моба по условию(Тип = зомби)
    Удалить сущность(Шифт + пкм и выбираешь "Выборка")
    #Тут мы создадим предмет(как на мл при открытии тайников), и настроим координаты: чтобы голова кейса заменилась на предмет
    Установить значения в местоположение(caseCoordinates, caseCoordinates, режим установки Y +=, число сделайте где-то 1.8, может 1.7)
    Создать предмет(caseCoordinates, caseRandomItem, название если хотите сделайте, задержку введите типа 100000000000, свечение включаем и гравитацию отключаем)
    Воспроизвести взрыв фейерверка(Фейерверк сделайте сами, местоположение - caseCoordinates)
    #Можно сделать тут какое-то сообщение в чат, типа такой-то игрок выбил такой-то предмет
    Выбрать игрока значение равно(casePlayer, %default%)
    #Тут тоже сделайте "Выборка"
    Выдать переменные(caseRandomItem)

Теперь сделаем предосторожность, если игрок выйдет во время чего-то.
Форматирование (BB-код):
Событие игрок выходит из игры
    Если переменная(casePlayer = %player%) {
        Установить значение переменной(casePlayer, "None")
        Установить значение переменной(caseBusy, "False")
        Установить значение переменной(functionBusy, "False")
        Присвоить значение переменной -=(query)
    }
В течении двух дней я напишу в комментарии код для категорий рандома(редкостей, в одной редкости может быть несколько предметов) и код для страниц, чтобы у игрока могло быть несколько страниц кейсов. Возможно так же добавлю напишу код для еще нескольких анимаций.

Если найдете какие-то ошибки/нелогичности в коде - пишите, я исправлю. Пишу статью второй день, потому могут быть недоработки. Вопросы тоже пишите.

Скриншот, который я обещал(если не обещал(мог стереть пометку эту) - напишите пожалуйста)
1687709503166.png
 
Последнее редактирование:

YouRaiBad

Гость
Регистрация
4 Июн 2023
Сообщения
62
Ема, Я лучше обосрусь чем весь код буду делать
 

maxim34a

Эксперт
Регистрация
10 Июн 2023
Сообщения
551
Ема, Я лучше обосрусь чем весь код буду делать
Да он не настолько большой. Строк 5-6, и то там каждая строка наполовину занята максимум. А вообще, кто хочет - тот сделает, ведь кейсы реально хорошие.

UPD: Ну лады, 10 строк, но это же годнота, а не код. Кто бы не хотел себе на режим тайники как на мл? сегодня залью код для страниц + еще один ивент с предосторожностями
 
Последнее редактирование:

maxim34a

Эксперт
Регистрация
10 Июн 2023
Сообщения
551
Код на страницы:

Вот у нас функция заполнения кейсов, мы добавим ограничитель - если заполнится 45 слотов, то надо останавливать цикл
Форматирование (BB-код):
Функция(CaseFiller)
    #Если эта переменная будет 45 - значит первая страница заполнена.
    Сравнить число(caseFillerFull < 45) {
            #Очистим экран игрока, так как кейсы могли загрузиться быстрее
            Отправить сообщение игроку на экран("&f")
            Сравнить число облегчённо(%player%ArrayLength > 0) {
                #Будем выполнять код, пока не добавим все кейсы
                Сравнить число облегчённо(caseFillerLength < %player%ArrayLength) {
                    Присвоить значение переменной +=(caseFillerLength)
                    #Это будет "триггер", когда caseFiller забьет все 45 слотов первой страницы
                    Присвоить значение переменной +=(caseFillerFull)
                    #Узнаем слот, куда надо ложить кейс
                    Присвоить значение переменной -(caseFillerItemSlot, caseFillerFull, 1)
                    #Так как у нас может быть несколько видов кейсов, мы узнаем, что именно это за кейс
                    Получить элемент массива(%player%CaseArray, caseFillerLength, caseItem)
                    #Положим кейс в инвентарь
                    Установить предметы в контейнер(Ложим координаты того двойного сундука, Динамическая переменная: caseItem, число: caseFillerItemSlot)
                    Ждать(1 тик)
                    Вызвать функцию(caseFiller)
                } Иначе {
                     #Когда мы добавим все предметы - мы откроем инвентарь игроку и покажем его кейсы
                     Присвоить значение переменной(%player%CaseFillerLength, caseFillerLength)
                     Присвоить значение переменной(functionBusy, "False")
                     Открыть инвентарь из игры(Ложим координаты того двойного сундука, выбираем "Копия")
                }
            } Иначе {
            #Если у игрока нету кейсов - отобразим пустой инвентарь(Можно положить предмет с названием "Пусто!")
            Открыть инвентарь из игры(Ложим координаты того двойного сундука, выбираем "Копия")
            Установить значение переменной(functionBusy, "False")
        }
    }

И сделаем небольшое событие, при клике на страницы(Если что, надо поправить тогда установку предметов в инвентарь в ивенте с кликом на блок кейсов. Надо добавить стрелочки туда.)

Форматирование (BB-код):
Событие игрок кликает по инвентарю
    #Весь дальнейший код мы делаем в скобках от "Если название открытого инвентаря = "КЕЙС""!!!!
    #Так же это всё надо сделать в "Если значение functionBusy != True"
    #Если у нас кейсов больше, чем может уместиться на одной странице
    Если переменная(%player%ArrayLength > 45) { 
        #У нас слот где лежит стрелка(для листания страниц вперёд) - последний слот в последнем ряду(6 ряд 9 слот)
        #Это где-то 53 слот(6*9=54, счёт с нуля)
        Если переменная(Игровое значение-кликнутый слот = 53) {
            #То есть тут будет код для листания страниц вперёд
            Очистить контейнер(координаты того двойного сундука)
            #Установку предметов я уже делал сверху, в событии когда игрок открывает меню кейсов
            Установить предметы в контейнер (Устанавливаем предметы в самую нижнюю строку, ставим там стрелочки и стекло)
            Установить значение(caseFillerFull, 0)
            #В идеале тут надо сделать привязку к очереди, но мне лень делать код. Просто скопируйте, вставьте и чуть-чуть подправьте
            #Кстати, если у вас высокий донат - можете сделать очередь меньше, чтобы например сразу 3 игрока могли загружать меню кейсов
            #Можно тут не делать очередь, но тогда может выдать ошибку
            Закрыть инвентарь
            #Прибавим +1 к странице, но так как счёт начинается с нуля, нам надо сделать при открытии меню кейсов(в том самом "Иначе") установку значения переменной %player%CasePage = 0
            Установить значение переменной +=(%player%CasePage)
            Установить значение переменной(functionBusy, "True")
            Запустить функцию("caseFiller")
        }
    }
    #Если страница больше 1, т.е мы не сможем перелистнуть на нулевую страницу
    Если переменная(%player%CasePage > 1) {
        #45 - слот где лежит стрела для перелистывания назад
        Если переменная(Игровое значение-кликнутый слот = 45) {
            #Тут код для листания страниц назад
            Очистить контейнер(координаты того двойного сундука)
            #Установку предметов я уже делал сверху, в событии когда игрок открывает меню кейсов
            Установить предметы в контейнер(Устанавливаем предметы в самую нижнюю строку, ставим там стрелочки и стекло)
            Установить значение переменной -=(%player%CasePage)
            #Это мы узнаем, по какому айди надо получать предмет. Если при использовании найдете баги - пишите их.
            Установить значение переменной -(caseFillerLength, caseFillerLength, 45, %player%CaseFillerLength)
            #Так же это "установить значение" надо поставить при выходе игрока и перед тем как заполнять сундук(В событии когда игрок открывает меню кейсов)
            Установить значение(caseFillerFull, 0)
            Установить значение переменной(functionBusy, "True")
            #Тут тоже по хорошему надо очередь сделать
            Закрыть инвентарь
            Запустить функцию("caseFiller")
        }
    }
События с предосторожностями не будет, но! Добавьте больше "Установить значение" при выходе игрока. Нам нужно устанавливать такие значения(переменная, значения; ): %player%CasePage, 0; %player%CaseFillerLength, 0; caseAnimationIter, 0; caseFillerFull, 0.

Вопросы, баги и предложения по оптимизации кода пишите.

Код на редкости скорее всего будет завтра. Олсо если есть идеи для гайдов - пишите в личные сообщения.​
 

maxim34a

Эксперт
Регистрация
10 Июн 2023
Сообщения
551
Код для редкостей.

Вот у нас код для генерации шансов(то, что я назвал сегментами). Мы будем использовать его для генерации именно редкости. То есть если мы попали в сегмент "Легендарно"(10% шанс), то дальше будем выбирать из предметов с редкостью "Легендарно", какой предмет выдавать игроку. Можно делать это двумя способами: простой и сложный.

Простой способ: у каждого предмета одинаковый шанс на выпадение. Представим это так: из древнего небесного тайника одинаковый шанс на выпадение и 250.000 монет, и доната "Hero"(если что это просто пример). Вот наш код:
Форматирование (BB-код):
Функция("caseRandom")
    Установить случайное число(caseRandomValue, 1, 100)
    Сравнить число(caseRandomValue, сверху: > 0, снизу: <= 10) {
        #Мы входим в сегмент легендарно
        Выдать случайный предмет(Ложим два предмета, херо и 250.000 монет. Шанс на выпадение каждого 50%)
        #Вместо "Выдать случайный предмет" можно сделать "Установить случайное значение", зависит от ваших потребностей
    }

Сложный способ. Тут уже шансы у каждого предмета разные. Допустим у нас много предметов на выпадение, скажем, 5: коллка, донат херо, донат скиллед, 250.000 монет и 3 генератора. У нас есть два пути сделать это: длинный и короткий.

Короткий способ плох тем, что поддерживает только числа типа 10, 50, 30. То есть +10. Вот код:
Форматирование (BB-код):
Функция("caseRandom")
    Установить случайное число(caseRandomValue, 1, 100)
    Сравнить число(caseRandomValue, сверху: > 0, снизу: <= 10) {
        #Мы входим в сегмент легендарно
        #Итак, можно тоже сделать и через "Выдать случайный предмет", и через "Установить случайное значение"
        #Принцип такой, мы ложим 10 предметов(100%), 1 предмет имеет шанс на выпадение 10%. Больше шанс - больше предметов
        Выдать случайный предмет(Херо, коллка, 250.000 монет, 250.000 монет, 250.000 монет, скиллед, скиллед, 3 генератора, 3 генератора, 3 генератора)
        #У нас получаются такие шансы: Херо 10%, коллка 10%, монеты 30%, скиллед 20%, генераторы 30%
    }

Длинный способ построен на if'ах. Он поддерживает любые проценты(можно сделать и 7.154185 процентов, тут пока не дойдёте до лимита float'а/double'а. Не знаю, что используется в к+). Вот такой код:
Форматирование (BB-код):
Функция("caseRandom")
    Установить случайное число(caseRandomValue, 1, 100)
    #Сгенерируем случайное число для предмета
    Установить случайное число(caseItemRandomValue, 1, 100)
    Сравнить число(caseRandomValue, сверху: > 0, снизу: <= 10) {
        #Берём тот же пример, но больше предметов. Вот такие шансы будут:
        #Херо 5%, Эксперт 10%, коллка 10%, миллион монет 15%, скиллед 25%, 5 генераторов 15%, 3 генератора 20%
        #Кто не понял - шанс в общем на генераторы 35 процентов, так что чаще всех будут генераторы
        Сравнить число(caseItemRandomValue, сверху: > 0, снизу: <= 5) {
            Установить значение переменной(caseRandomItem, "херо")
        }
        Сравнить число(caseItemRandomValue, сверху: > 5, снизу: <= 15) {
            Установить значение переменной(caseRandomItem, "коллка")
        }
        Сравнить число(caseItemRandomValue, сверху: > 15, снизу: <= 25) {
            Установить значение переменной(caseRandomItem, "эксперт")
        }
        Сравнить число(caseItemRandomValue, сверху: > 25, снизу: <= 40) {
            Установить значение переменной(caseRandomItem, "миллион монет")
        }
        Сравнить число(caseItemRandomValue, сверху: > 40, снизу: <= 65) {
            Установить значение переменной(caseRandomItem, "скиллед")
        }
        Сравнить число(caseItemRandomValue, сверху: > 65, снизу: <= 80) {
            Установить значение переменной(caseRandomItem, "5 генераторов")
        }
        Сравнить число(caseItemRandomValue, сверху: > 80, снизу: <= 100) {
            Установить значение переменной(caseRandomItem, "3 генератора")
        }
    }
    Отправить сообщение игроку(caseRandomItem)

Ещё можно делать десятичные шансы, типа 17.7%. Для этого надо генерировать случайное значение в промежутке от 1 до 1000(1 знак после запятой = 1 нолик), ну и при ифах тоже менять число. Тогда в "Сравнить число" "сверху: > 0, снизу: <= 10" будет значить всего 1 процент, а не 10.

Багов быть не должно(код лёгкий), но если найдёте - пишите​
 
Последнее редактирование:

PbI6A

Новичок
Регистрация
11 Июн 2023
Сообщения
8
Классно описал все, жду еще гайдов.
 

Mepleks

Участник
Регистрация
1 Июл 2023
Сообщения
3
В этом гайде я опишу создание кейсов, рандом и анимации для кейсов. За идею спасибо @PbI6A.

База: инвентарь кейса. Перед тем как кодить поставьте в технической зоне(где-то за картой) двойной сундук с названием "Кейс"(Можно цветное)
Форматирование (BB-код):
# - объяснение кода.
#Жирным выделены сохранённые переменные и постоянные массивы.
#Слова в кавычках - текстовые переменные

Событие игрок заходит в игру
    #Создадим массив где будут хранится все кейсы игрока
    Если переменная НЕ существует(%player%CaseArray) {
        #Сделаем так, чтобы массив создавался всего 1 раз
        Установить значение переменной(%player%CaseArray, "True")
        Создать массив(%player%CaseArray)
        #Поместим предметы кейсов в переменные. Например донатный кейс будет головой золотого сундука в переменной donateCase
        Установить предмет в переменную(defaultCaseItem, ложим голову/предмет)
        #Устанавливаем столько переменных и предметов, сколько хотим сделать видов кейсов
    }

Событие игрок кликает правой кнопкой
    #Это когда игрок открывает меню кейсов. У меня для этого надо кликнуть по порталу энда
    Если игрок смотрит на(Ложим блок по которому надо кликнуть для открытия меню, число ложим 0 и отключаем дату блоков) {
        #Так как майнленд сильно ограничивает вызов функций, мы сделаем очередь для открытия кейсов.
        #То есть если два игрока пытаются одновременно открыть меню - одному из них придётся подождать
        #Если не сделать - могут быть ошибки + сломается код
        Если переменная(functionBusy = True) {
            Присвоить значение переменной +=(query)
            Отправить сообщение игроку("Кейсы уже используются! Место в очереди: " query)
        } Иначе {
            Сравнить число облегчённо(query > 1) {
                 Присвоить значение переменной -=(query)
            } Иначе {
                Установить значение переменной(query, 0)
            }
            #Тут мы сделаем открытие меню кейсов. Начнём.
            Установить значение переменной(functionBusy, "True")
Установить значение переменной(caseFillerLength, 0)
            #caseFillerLength - переменная, которая будет использовать для заполнения меню
            #0 - переменная "Число", не "Текст"
            Установить значение переменной(caseFillerLength, 0)
            #Тоже переменная пригодится позже
            Получить размер массива(%player%CaseArray, %player%ArrayLength)
            Отправить сообщение игроку на экран("Выдача кейсов..." "Это может занять до 2-х секунд...")
            #Очищаем сундук с кейсами после прошлого игрока
            Очистить контейнер(Ложим координаты того двойного сундука)
            #Эту строчку можно не делать. Я просто немного обрезал количество кейсов, теперь самая нижняя строка будет заполнена серым стеклом)
            #Если что, скриншот будет ниже
            Установить предметы в контейнер(Ложим координаты того двойного сундука, предмет - светло серая стеклянная панель, числа ложим от 45 до 53)
            #Собственно заполним сундук кейсами игрока
            Вызвать функцию(CaseFiller)
        }
   }

Функция(CaseFiller)
    #Очистим экран игрока, так как кейсы могли загрузиться быстрее
    Отправить сообщение игроку на экран("&f")
    Сравнить число облегчённо(%player%ArrayLength > 0) {
        #Будем выполнять код, пока не добавим все кейсы
        Сравнить число облегчённо(caseFillerLength < %player%ArrayLength) {
            Присвоить значение переменной +=(caseFillerLength)
            #Узнаем слот, куда надо ложить кейс
            Присвоить значение переменной -(caseFillerItemSlot, caseFillerLength, 1)
            #Так как у нас может быть несколько видов кейсов, мы узнаем, что именно это за кейс
            Получить элемент массива(%player%CaseArray, caseFillerLength, caseItem)
            #Положим кейс в инвентарь
            Установить предметы в контейнер(Ложим координаты того двойного сундука, Динамическая переменная: caseItem, число: caseFillerItemSlot)
            Ждать(1 тик)
            Вызвать функцию(caseFiller)
        } Иначе {
            #Когда мы добавим все предметы - мы откроем инвентарь игроку и покажем его кейсы
            Присвоить значение переменной(functionBusy, "False")
            Открыть инвентарь из игры(Ложим координаты того двойного сундука, выбираем "Копия")
        }
    } Иначе {
        #Если у игрока нету кейсов - отобразим пустой инвентарь(Можно положить предмет с названием "Пусто!")
        Открыть инвентарь из игры(Ложим координаты того двойного сундука, выбираем "Копия")
        Установить значение переменной(functionBusy, "False")
    }

Событие игрок пишет в чат
    #Это лимит кейсов, всего можно будет иметь 1 заполненную страницу.
    Сравнить число облегчённо(%player%ArrayLength < 45) {
        #Дальше - код для добавления кейса игроку
        #Повторяйте это "Если сообщение равно" сколько хотите
        Если сообщение равно("@giveDefaultCase") {
            Добавить в конец массива(%player%CaseArray, defaultCaseItem)
            Получить размер массива(%player%CaseArray, %player%ArrayLength)
        }
    }

Событие игрок кликает по инвентарю
    Если название открытого инвентаря("Кейс") {
        Отменить событие
        #Это код, когда игрок открывает кейс.
        Если переменная(caseBusy != "True") {
            Если кликнутый предмет равен(Ложим предмет-кейс, например голову ввиде золотого сундука) {
                Присвоить значение переменной(casePlayer, %player%)
                Присвоить значение переменной +(%player%ClickSlot, Значение события - кликнутый слот, 1)
                Удалить элемент из массива(%player%CaseArray, %player%ClickSlot)
                Присвоить значение переменной(caseBusy, "True")
                Закрыть инвентарь
                Присвоить значение переменной(caseCoordinates, координаты - центр блока кейсов(x и z координаты должны иметь .50, y координата на 1-1.5 блоков меньше координаты где стоит блок для открытия кейсов.))
                #Тут появляется проблема. Если поставить интеллект и гравитацию на "нету", то моб с головой не сможет подлетать вверх(подлетать вверх - анимация поднятия. А если поставить на "есть" - моб будет крутиться и будет не очень красиво. И будет ещё одна проблема, опишу дальше
                #Если есть идеи для решения этой проблемы - пишите.
                #Возраст 100 нужен для того, чтобы не спавнился зомби-малыш. Радиус зрения чтобы зомби не атаковал.
                Заспавнить моба(Яйцо зомби, координаты - центр блока кейсов(должно совпадать с координатами из "Присвоить значение переменной") Отключаем звуки, деспавн и урон. Радиус зрения - 0, возраст - 100. Имя - "КЕЙС". Ложим зелье невидимости 10 на 8 минут(я сделал через инфинити айтем эдитор), отключаем частицы и в слот для шлема ложим голову кейса. В данном случае - голову золотого кейса.)
                Вызвать функцию(caseAnimation)
            }
        } Иначе {
            Отправить сообщение игроку("Кейсы уже открываются!")
        }
    }


Анимация открытия. Сразу скажу, что она работает неидеально. Если есть идеи для решения проблем - пишите. Моя анимация - просто поднятие кейса наверх. Если есть желание и время - можете сделать как на мл, чтобы были линии из частиц. Можно ещё кучу разных придумать.
Форматирование (BB-код):
Функция(caseAnimation)
    #Можно экспериментировать с числом, например вместо 0.1 поставить 0.5
    Установить значения в местоположение(caseCoordinates, caseCoordinates, режим установки Y += и туда же ложим 0.1)
    #Можно экспериментировать с выборкой, например попробовать "Если находится рядом"
    Выбрать моба по типу(Яйцо зомби)
    #Шифт + пкм по табличке и выбираем "Выборка"
    Запустить к местоположению(caseCoordinates)
    Присвоить значение переменной +=(caseAnimationIter)
    #Это количество итераций. Проще говоря, на сколько блоков надо поднять(10 итераций - 1 блок)
    Сравнить число облегчённо(caseAnimationIter <= 20) {
        Ждать(1 тик)
        Вызвать функцию("caseAnimation")
    } Иначе {
        #Дальнейший код нужен чтобы зомби с головой кейса не упал вниз - тогда анимация не сломается.
        Заспавнить моба(Яйцо зомби, координаты - под блоком кейсов(Ну блок кейсов и по Y отнимаем 2-3 блока через IIE Отключаем звуки, деспавн, гравитацию, ИИ и урон. Возраст - 100. Ложим зелье невидимости 10 на 8 минут(я сделал через инфинити айтем эдитор.)
        #Можно экспериментировать с выборкой. Так же ставим через стрелочку "НЕ"
        #Дальнейший код - пересоздание головы кейса, чтобы зомби с головой не упал вниз(так как гравитация на него действует)
        Выбрать моба по условию(Имя равно "КЕЙС")
        #Все дальнейшие блоки действий будут с выборкой, не забудьте(Шифт + пкм по блоку)
        Телепортация(caseCoordinates)
        Ждать(1 тик)
        Надеть броню(В слот для шлема ложим голову кейса, например голову золотого сундука)
        Выбрать моба по условию(Имя равно "КЕЙС")
        Удалить сущность
        #Когда кейс полностью поднимется - вызовется рандом, чтобы определить что выпало
        #Если экономите место - все блоки из функции можно запихнуть сюда
        Установить значение переменной(caseAnimationIter, 0)
        Вызвать функцию("caseRandom")
    }

Итак. Теперь сделаем рандом. Есть два вида: Простой и сложный.

Простой рандом - рандом с одинаковыми шансами. То есть, мы ложим 5 предметов и у каждого предмета шанс на выпадение 20%(100%:5=20%). Ложим 10 предметов - у каждого шанс 10%. Это делается через "Установить случайное значение". Если вам лень кодить - делайте этот способ.

Сложный рандом - рандом с разными шансами. То есть, допустим, у нас есть 3 предмета - легендарный, обычный и редкий. Допустим, у легендарного шанс на выпадения 10%, у редкого 35% и у обычного 55%. Я сделаю код для этого отдельной функцией.

Итак, сам код-функция.

Форматирование (BB-код):
Функция("caseRandom")
    #Расскажу принцип работы. Мы как бы делим 100(100%) на несколько сегментов.
    #Чем меньше размер сегмента, тем меньше и процент попадания в данный сегмент
    Установить случайное число(caseRandomValue, 1, 100)
    #Это проверки, в какой сегмент попадаем. Их можно делать сколько хотите.
    Сравнить число(caseRandomValue, сверху: > 0, снизу: <= 10) {
        Установить предмет в переменную(caseRandomItem, легендарный предмет для выпадения)
    }
    Сравнить число(caseRandomValue, сверху: > 10, снизу: <= 45) {
        Установить предмет в переменную(caseRandomItem, редкий предмет для выпадения)
    }
    Сравнить число(caseRandomValue, сверху: > 45, снизу: <= 100) {
        Установить предмет в переменную(caseRandomItem, обычный предмет для выпадения)
    }
    #Дальше идёт выдача предметов и анимация(Появится предмет и будут партиклы, а ещё сообщение в чат)
    Выбрать моба по условию(Тип = зомби)
    Удалить сущность(Шифт + пкм и выбираешь "Выборка")
    #Тут мы создадим предмет(как на мл при открытии тайников), и настроим координаты: чтобы голова кейса заменилась на предмет
    Установить значения в местоположение(caseCoordinates, caseCoordinates, режим установки Y +=, число сделайте где-то 1.8, может 1.7)
    Создать предмет(caseCoordinates, caseRandomItem, название если хотите сделайте, задержку введите типа 100000000000, свечение включаем и гравитацию отключаем)
    Воспроизвести взрыв фейерверка(Фейерверк сделайте сами, местоположение - caseCoordinates)
    #Можно сделать тут какое-то сообщение в чат, типа такой-то игрок выбил такой-то предмет
    Выбрать игрока значение равно(casePlayer, %default%)
    #Тут тоже сделайте "Выборка"
    Выдать переменные(caseRandomItem)

Теперь сделаем предосторожность, если игрок выйдет во время чего-то.
Форматирование (BB-код):
Событие игрок выходит из игры
    Если переменная(casePlayer = %player%) {
        Установить значение переменной(casePlayer, "None")
        Установить значение переменной(caseBusy, "False")
        Установить значение переменной(functionBusy, "False")
        Присвоить значение переменной -=(query)
    }
В течении двух дней я напишу в комментарии код для категорий рандома(редкостей, в одной редкости может быть несколько предметов) и код для страниц, чтобы у игрока могло быть несколько страниц кейсов. Возможно так же добавлю напишу код для еще нескольких анимаций.

Если найдете какие-то ошибки/нелогичности в коде - пишите, я исправлю. Пишу статью второй день, потому могут быть недоработки. Вопросы тоже пишите.

Скриншот, который я обещал(если не обещал(мог стереть пометку эту) - напишите пожалуйста)
Посмотреть вложение 1318
Хороший гайд, я в 2 функции сделал весь код.
 

Mee8YT

Эксперт
Регистрация
3 Май 2023
Сообщения
357
Да он не настолько большой. Строк 5-6, и то там каждая строка наполовину занята максимум. А вообще, кто хочет - тот сделает, ведь кейсы реально хорошие.

UPD: Ну лады, 10 строк, но это же годнота, а не код. Кто бы не хотел себе на режим тайники как на мл? сегодня залью код для страниц + еще один ивент с предосторожностями
Хз, у меня в 7 строк с анимацией, с рандом шансом, с частицами и со страницами списка кейсов. Такой кст у меня продаётся) Пускай только попробует какая-нибудь дура сказать, что "это ты с форума взял код и продаёшь его", сразу скину все даты c:
Хотя к чему это тут?
 

maxim34a

Эксперт
Регистрация
10 Июн 2023
Сообщения
551
попробует какая-нибудь дура сказать, что "это ты с форума взял код и продаёшь его", сразу скину все даты c:
боже своровал мой код...
Хз, у меня в 7 строк с анимацией, с рандом шансом, с частицами и со страницами списка кейсов.
А у меня разве не в 7 строк? Я вот посчитал, 7 строк, но можно попробовать в одну функцию сделать и анимацию для открытия кейса, и рандом. А ты вообще рандом делал как? Если че я сверху описывал разные способы, какой из них? А ещё я рандом там где можно любые проценты украл со стаковерфлоу 😄
 

Mee8YT

Эксперт
Регистрация
3 Май 2023
Сообщения
357
так уж и быть, Up
 
Сверху