UNIX, как использовать, как не допустить баги

Mee8YT

Эксперт
Регистрация
3 Май 2023
Сообщения
348

UNIX время - время, представленное в виде миллисекунд.


На Майнленде его можно использовать по разному, в основном для отмечания промежутков времени.
Представим, что у нас есть цикл, который каждую секунду прибавляет в переменную time 1 секунду
через минуту у нас уже будет 60 секунд

Представим ситуацию, у нас есть команда @bonus, которая даёт бонус раз в 60 секунд. Чтобы отметить временную точку, на которой будет возможным взять бонус нам нужно к текущему времени прибавить 60 секунд, тогда текущему времени нужно ещё 60 секунд, чтобы игрок взял бонус.

К примеру ранее игровое время было 60, значит при отметке 120 секунд нам станет доступной эта команда, и в этой переменной у нас будет 120.
Как проверить, что игрок может взять бонус? Легко, достаточно сравнить, больше ли текущее время относительно временной точки.
Если больше - значит временная точка уже в прошлом, её КД давно истёк
В ином случае текущее время ещё не догнало временную точку, и мы можем вывести оставшееся время, которое нужно подождать, прежде чем взять бонус.

Чтобы получить оставшееся время у временной точки относительно текущего времени нужно от него отнять текущее время.

Примерный код:
[
Форматирование (BB-код):
Событие игрока - Вход
    Присв переменную - Прибавить += (%player%_bonus_time += 0 ) // создаём переменную с временной точкой
    Запустить цикл ('time')

Цикл ('time', 20)
    Выбрать объект - Случайный игрок
    Присв переменную - Прибавить += (time += 1)

Событие игрока - Отправил сообщение
    Если игрок - Сообщение равно (@bonus, $игнорировать)
        Если переменная - Сравнить число обле версия (time >= %player%_bonus_time): // Проверяем, доступен ли игроку бонус
            Присв переменную - Установить + (%player%_bonus_time = time + 60) // Создаём новую временную точку
            Действие игрока - Отправить сообщение ("Бонус получен")
        Иначе:
            Присв переменную - Установить - (%player%_bonus_time_remained = %player%_bonus_time - time)
            Действие игрока - Отправить сообщение ('Осталось ', %player%_bonus_time_remained, 'сек.')

Однако у такого цикла есть минус - он работает только пока в игре есть кто-то

На помощь приходит UNIX, который вшит в Java, и позволяет в любую миллисекунду получить мировое время, которое идёт начиная с 1970 года
Майнленд позволяет с ним работать. Однако вас могло напугать 1) слишком большое число 2) непонятные 'E' символы

Разберём первое:
Счёт идёт с 1970 года, следовательно в нём как минимум 54 года. В каждом году 12 месяцев, в месяце +-30 дней, в каждом дне 24 часа, в часу 60 минут, в минуте 60 секунд, в секунде 1000 миллисекунд.
Вот и выходит, что UNIX время выходит на триллионы.

Теперь второе
Точно не знаю, майнленд-ли подкручивает числа Е, или джава, но в любом случае если парсить любое большое число, то они появятся.
По факту, число '1.0E12' это '1.0 * 10^12', с таким свойством можно работать, чтобы текст с юниксом перевести в число.

Вернёмся к проблеме с циклами, или к решению проблемы. Если мы вместо цикла будем использовать UNIX, то будет 2 небольшие проблемы в плане удобства: 1) трудно текстовый вариант вернуть в число 2) нужно постоянно его получать 3) он показывает значения в 1000 раз больше, чем наш цикл

Составим инструкцию для нашей ежедневной награды, чтобы адаптировать под юникс: 1) надо миллисекунды для игрока показывать как секунды 2) нужно его получать в самом коде бонуса

Код:
[
Форматирование (BB-код):
Событие игрока - Вход
    Присв переменную - Прибавить += (%player%_bonus_time += 0 ) // создаём переменную с временной точкой

Событие игрока - Отправил сообщение
    Если игрок - Сообщение равно (@bonus, $игнорировать)
        Присв переменную - Получить время UNIX (%player%_unix)
        Если переменная - Сравнить число обле версия (%player%_unix >= %player%_bonus_time): // Проверяем, доступен ли игроку бонус
            Присв переменную - Установить + (%player%_bonus_time = %player%_unix + 60000) // Создаём новую временную точку
            Действие игрока - Отправить сообщение ("Бонус получен")
        Иначе:
            Присв переменную - Установить - (%player%_bonus_time_remained = %player%_bonus_time - time)
            Присв переменную - Разделить (%player%_bonus_time_remained = %player%_bonus_time_remained / 1000)
            Присв переменную - Округлить (%player%_bonus_time_remained = %player%_bonus_time_remained $к_меньшему)
            Действие игрока - Отправить сообщение ('Осталось ', %player%_bonus_time_remained, 'сек.')

В чём отличия от прошлого кода:
1) Получаем UNIX, а не используем постоянную переменную
2) Вместо "прибавить 60" мы использовали "прибавить 60000", т.к. в представлении UNIX 60 секунд надо записать в виде миллисекунд, то есть 60*1000=60000
3) В сообщении об оставшемся времени мы написали дополнительно разделили на 1000 и округлили к меньшему, потому что у нас есть лишние миллисекунды

Как превратить текст в число​

Небольшая микротема, относящаяся к UNIX. Дело в том, что UNIX, как и любое большое число просто так не парсится из текста.
К таким случаям предлагаю сделать функцию, которая принимает текст, и возвращает число.

Для этого нужно свойство больших чисел, описанное выше

Код:
Форматирование (BB-код):
// Функция будет иметь входную переменную: %player%_parseBigInt.input
// На выходе функция вернёт результат в %player%_parseBigInt.output


Любой обработчик - Любое событие:
    // ...
    Присв переменную - Присв переменную равно (%player%_parseBigInt.input = '1.0E7')
    Вызвать

Функция (parseBigInt) :
    Присв переменную - Установить равно (%player%_parseBigInt.output = %player%_parseBigInt.input)
    Если переменная - Текст содержит (%player%_parseBigInt.input .содержит 'E'):
        Присв переменную - Разделить текст на элементы (%player%_parseBigInt.array .разделить %player%_parseBigInt.input .на 'E')
        Массивы - Получить элемент (.из %player%_parseBigInt.array .индекс 1 .в %player%_parseBigInt.calc.number)
        Массивы - Получить элемент (.из %player%_parseBigInt.array .индекс 2 .в %player%_parseBigInt.calc.degree)
        Присв переменную - Парсить число (.в %player%_parseBigInt.calc.number .парсить %player%_parseBigInt.calc.number)
        Присв переменную - Парсить число (.в %player%_parseBigInt.calc.degree .парсить %player%_parseBigInt.calc.degree)
        Присв переменную - Возвести в степень (.в %player%_parseBigInt.calc.multiplier .число 10 .степень %player%_parseBigInt.calc.degree)
        Присв переменную - Умножить (.в %player%_parseBigInt.output .числа %player%_parseBigInt.calc.multiplier * %player%_parseBigInt.calc.number)
    Иначе:
        Действие игрока - Отправить сообщение ("Это не большое число")
 
Сверху