Делайте магазины "предмет - переменная" правильно

Есть 3 предмета:


Картошка
Цена: 10
Морковь
Цена: 15


Как сделает этот код лютый новичок:

Код:
Событие игрока - Клик
    Если игрок - Предмет равен (Картошка):
        Игровое действие - Отменить событие
        Если переменная - Сравнить число (%player%_деньги >= 10):
            Присв переменную - Убавить (%player%_деньги -= 10)
            Действие игрока - Выдать предмет (Картошка)
            Действие игрока - Отправить сообщение ("Куплено")
            Действие игрока - Проиграть звук (#)
        Иначе:
            Действие игрока - Отправить сообщение ("Мало денек")
           
    Если игрок - Предмет равен (Морковка):
        Игровое действие - Отменить событие
        Если переменная - Сравнить число (%player%_деньги >= 15):
            Присв переменную - Убавить (%player%_деньги -= 15)
            Действие игрока - Выдать предмет (МОРКОВКА)
            Действие игрока - Отправить сообщение ("Куплено")
            Действие игрока - Проиграть звук (#)
        Иначе:
            Действие игрока - Отправить сообщение ("Мало денек")
           
    Если игрок - Предмет равен (Свекла):
        Игровое действие - Отменить событие
        Если переменная - Сравнить число (%player%_деньги >= 20):
            Присв переменную - Убавить (%player%_деньги -= 20)
            Действие игрока - Выдать предмет (СВЕКЛА)
            Действие игрока - Отправить сообщение ("Куплено")
            Действие игрока - Проиграть звук (#)
        Иначе:
            Действие игрока - Отправить сообщение ("Мало денек")

# И копипаста


Теперь код, который 1. оптимизирован 2. читабелен 3. проще фиксить 4. меньше весит:

Код:
Событие игрока - Клик
    Если игрок - Предмет равен (Картошка, морковь, свекла):
        Игровое действие - Отменить событие
        Вызвать функцию - купить.Инфо ($Синхронный_запуск)
        Если переменная - Сравнить число (%player%_деньги >= %player%_купить.цена):
            Присв переменную - Убивить (%player%_деньги -= %player%_купить.цена)
            Действие игрока - Выдать предмет из переменной (%player%_купить.предмет)
            Действие игрока - Отправить сообщение ("Куплено")
            Действие игрока - Проиграть звук (#)
        Иначе:
            Действи игрока - Отправить сообщение ("Мало денек")
            Действие игрока - Проиграть звук (#)

Функция (купить.Инфо)
    Если игрок - Предмет равен (Картошка):
        Присв переменную - Равно (%player%_купить.цена = 10)
        Присв переменную - Установить предмет (%player%_купить.предмет = КАРТОШКА)
    Если игрок - Предмет равен (Морковка):
        Присв переменную - Равно (%player%_купить.цена = 15)
        Присв переменную - Установить предмет (%player%_купить.предмет = МОРКОВКА)
    Если игрок - Предмет равен (Свекла):
        Присв переменную - Равно (%player%_купить.цена = 20)
        Присв переменную - Установить предмет (%player%_купить.предмет = СВЕКЛА)


Предметы во втором способе добавлять ооочень легко, его можно переделать под больший лут (не только пустой предмет, а например выдача брони)
 

Mee8YT

Эксперт
Регистрация
3 Май 2023
Сообщения
357
Почему не сделал тогда в функции "купить.Инфо" получение цены из описания предмета
я просто в таких условиях работаю (а именно - зсм, проект от векоина), где везде разное кол-во строк описания (и до, и после ценника), по этому парсить это дело долго
Сообщение объединено:

огда не придётся занимать по 4 блока кода на проверку каждого такого предмета купли-продажи.
придётся, ты из воздуха предмет для выдачи не возьмёшь
 

Mee8YT

Эксперт
Регистрация
3 Май 2023
Сообщения
357
В чём проблема в предмет из магазина встроить скрытое айди
смотри, тут тоже не всё просто
с 70% шансом после релиза игры я уйду, и придётся мне объяснять разрабу-идиоту как и всё устроено?
в 100% случаев после оригинального разработчика игры, который отлично шарит за все механики ставят чела слабже, и он уже не будет разбираться в твоих механиках


отличный пример1719085406450.png
это делал кодер маестро, отличный кодер, его механики он понимает
но как только этот код дали мне - я отказался в нём разбираться, мне проще с нуля эту-же распределялку игроков по зомби/человек распределить

говорю сугубо из своего опыта, разрабатывая режим в команде

если бы режим был лично моим, и я бы не передавал его другому человеку - я бы запарился над гениальным магазином, чтобы были механики авто-определения цены и тд, но тут мне приходится мелочиться
Сообщение объединено:

а вообще, если речь заходит он магазе, и мы не учитываем то где я щас работаю, то могу предложить такую реализацию
в какой-нибудь пустой строке я расположу "§" с каким-нибудь не стандартным символом (пусть будет "✪")
в случае, если текст учитывая цвет содержит "§✪", то рекурсивно я буду извлекать айди товара

этим айди я получу цену из массива, и по твоему методу могу из сундука извлечь итоговый предмет
но тут есть ньюансы, некоторые теги тупо не перенесутся, например нерушимость
 

Mee8YT

Эксперт
Регистрация
3 Май 2023
Сообщения
357
Почему не сделал тогда в функции "купить.Инфо" получение цены из описания предмета? Тогда не придётся занимать по 4 блока кода на проверку каждого такого предмета купли-продажи.

UPD. Такое сделать не так уж и сложно, код читабельнее, и паста уже не будет присутствовать, как в первых двух вариантах.
и ещё, гайд был рассчитан на людей, кто делает говно-код, но понимает что такое функции
 

GromoverGets

Эксперт
Регистрация
2 Май 2023
Сообщения
254
Есть 3 предмета:







Как сделает этот код лютый новичок:

Код:
Событие игрока - Клик
    Если игрок - Предмет равен (Картошка):
        Игровое действие - Отменить событие
        Если переменная - Сравнить число (%player%_деньги >= 10):
            Присв переменную - Убавить (%player%_деньги -= 10)
            Действие игрока - Выдать предмет (Картошка)
            Действие игрока - Отправить сообщение ("Куплено")
            Действие игрока - Проиграть звук (#)
        Иначе:
            Действие игрока - Отправить сообщение ("Мало денек")
         
    Если игрок - Предмет равен (Морковка):
        Игровое действие - Отменить событие
        Если переменная - Сравнить число (%player%_деньги >= 15):
            Присв переменную - Убавить (%player%_деньги -= 15)
            Действие игрока - Выдать предмет (МОРКОВКА)
            Действие игрока - Отправить сообщение ("Куплено")
            Действие игрока - Проиграть звук (#)
        Иначе:
            Действие игрока - Отправить сообщение ("Мало денек")
         
    Если игрок - Предмет равен (Свекла):
        Игровое действие - Отменить событие
        Если переменная - Сравнить число (%player%_деньги >= 20):
            Присв переменную - Убавить (%player%_деньги -= 20)
            Действие игрока - Выдать предмет (СВЕКЛА)
            Действие игрока - Отправить сообщение ("Куплено")
            Действие игрока - Проиграть звук (#)
        Иначе:
            Действие игрока - Отправить сообщение ("Мало денек")

# И копипаста


Теперь код, который 1. оптимизирован 2. читабелен 3. проще фиксить 4. меньше весит:

Код:
Событие игрока - Клик
    Если игрок - Предмет равен (Картошка, морковь, свекла):
        Игровое действие - Отменить событие
        Вызвать функцию - купить.Инфо ($Синхронный_запуск)
        Если переменная - Сравнить число (%player%_деньги >= %player%_купить.цена):
            Присв переменную - Убивить (%player%_деньги -= %player%_купить.цена)
            Действие игрока - Выдать предмет из переменной (%player%_купить.предмет)
            Действие игрока - Отправить сообщение ("Куплено")
            Действие игрока - Проиграть звук (#)
        Иначе:
            Действи игрока - Отправить сообщение ("Мало денек")
            Действие игрока - Проиграть звук (#)

Функция (купить.Инфо)
    Если игрок - Предмет равен (Картошка):
        Присв переменную - Равно (%player%_купить.цена = 10)
        Присв переменную - Установить предмет (%player%_купить.предмет = КАРТОШКА)
    Если игрок - Предмет равен (Морковка):
        Присв переменную - Равно (%player%_купить.цена = 15)
        Присв переменную - Установить предмет (%player%_купить.предмет = МОРКОВКА)
    Если игрок - Предмет равен (Свекла):
        Присв переменную - Равно (%player%_купить.цена = 20)
        Присв переменную - Установить предмет (%player%_купить.предмет = СВЕКЛА)


Предметы во втором способе добавлять ооочень легко, его можно переделать под больший лут (не только пустой предмет, а например выдача брони)
Будь на мл хэшмапы, эта задача бы решалась раз в 20 быстрее

Java:
// Да, мне лень писать лишний код на заполнение этой хэшмапы, представим, что аля у нас уже она есть и забита ценами-материалами


@EventHandler
public void onPlayerClickedInventory (InventoryClickEvent event) {
    int price = getPrice(event.getCurrentItem(), воображаемаяХэшМапа);
    // Далее делаем с ней что надо
}

private int getPrice (ItemStack item, HashMap<Material, Integer> prices) {
    return prices.get(item.getType()) != null ? prices.get(item.getType()) : 0;
}
 
Последнее редактирование:

Mee8YT

Эксперт
Регистрация
3 Май 2023
Сообщения
357
Если у тебя условно айди §1§3§9, заменяешь § на пустоту и просто получившееся парсишь, на выходе 139
как вариант, спасибо
Не увидел, чтобы где-то было написано о "говно кодерах, непонимающих что такое функции"
зачем ты так грубо, сам был когда-то говнокодером
многие люди понимают, что такое функции, просто пока они только адаптируются к этим возможностям они не видят решения многих проблем, по типу большого объёма кода, и одно из решений таких проблем я показал в этом гайде
 

Apotheoses

Эксперт
Регистрация
19 Июн 2023
Сообщения
67
Будь на мл хэшмапы, эта задача бы решалась раз в 20 быстрее

Java:
// Да, мне лень писать лишний код на заполнение этой хэшмапы, представим, что аля у нас уже она есть и забита ценами-материалами


@EventHandler
public void onPlayerClickedInventory (InventoryClickEvent event) {
    int price = getPrice(event.getCurrentItem(), воображаемаяХэшМапа);
    // Далее делаем с ней что надо
}

private int getPrice (ItemStack item, HashMap<Material, Integer> prices) {
    return prices.get(item.getType()) != null ? prices.get(item.getType()) : 0;
}
Код:
public final class Main extends JavaPlugin implements Listener {
    public final Map<String, Long> prices = new HashMap<>();

    @Override
    public void onEnable() {
        prices.put("Камень", 500L);
        prices.put("Дерево", 1000L);
    }

    @EventHandler
    public void onPlayerClickedInventory(InventoryClickEvent event) {
        Entity entity = event.getWhoClicked();
        if (entity instanceof Player player) {
            ItemStack item = event.getCurrentItem();
            if (item.getType() != Material.AIR) {
                ItemMeta itemMeta = item.getItemMeta();
                String nameOfItem = itemMeta.getDisplayName();
                if (nameOfItem != null) {
                    String nameWithoutColors = nameOfItem.substring(3);
                    long price = prices.get(nameWithoutColors);
                    player.sendMessage(" Информация о предмете:\n Название: " + nameWithoutColors + "\n Цена: " + price);
                }
             }
          }
      }
}

На названиях будет лучше, ибо материалы могут повторяться + фулл рабочий код (если я правильно все вырезал)
Примечание: название предмета должно быть в формате " &2Камень", т.е. пробел и цвет в начале (можно доработать как-нибудь, но не судьба) + спорить не буду код кринж
 
Последнее редактирование:

Mee8YT

Эксперт
Регистрация
3 Май 2023
Сообщения
357
На названиях будет лучше, ибо материалы могут повторяться
чт
Код:
public final class Main extends JavaPlugin implements Listener {
    public final Map<String, Long> prices = new HashMap<>();

    @Override
    public void onEnable() {
        prices.put("Камень", 500L);
        prices.put("Дерево", 1000L);
    }

    @EventHandler
    public void onPlayerClickedInventory(InventoryClickEvent event) {
        Entity entity = event.getWhoClicked();
        if (entity instanceof Player player) {
            ItemStack item = event.getCurrentItem();
            if (item.getType() != Material.AIR) {
                ItemMeta itemMeta = item.getItemMeta();
                String nameOfItem = itemMeta.getDisplayName();
                if (nameOfItem != null) {
                    String nameWithoutColors = nameOfItem.substring(3);
                    long price = prices.get(nameWithoutColors);
                    player.sendMessage(" Информация о предмете:\n Название: " + nameWithoutColors + "\n Цена: " + price);
                }
             }
          }
      }
}

На названиях будет лучше, ибо материалы могут повторяться + фулл рабочий код (если я правильно все вырезал)
Примечание: название предмета должно быть в формате " &2Камень", т.е. пробел и цвет в начале (можно доработать как-нибудь, но не судьба) + спорить не буду код кринж
ты буквально интерпретировал сюда код, который мл обрабатывает
 

Mee8YT

Эксперт
Регистрация
3 Май 2023
Сообщения
357
1ecqXx4.png

сделал всё-таки магазин на описании
могло выйти и 3 строки, даже 2, но по желанию заказчика нужно больше вариаций выдачи лута, например не тупо предмет в инвентарь, а например выдача брони, эффектов
так-же нужно в отдельной строке непосредственно проводить проверку баланса, и возможности выдачи лута, т.к. на это планируется нагруженный звуковой и текстовый дизайн, по этому вышло 4 строки
Сообщение объединено:

1ecqXx4.png

сделал всё-таки магазин на описании
могло выйти и 3 строки, даже 2, но по желанию заказчика нужно больше вариаций выдачи лута, например не тупо предмет в инвентарь, а например выдача брони, эффектов
так-же нужно в отдельной строке непосредственно проводить проверку баланса, и возможности выдачи лута, т.к. на это планируется нагруженный звуковой и текстовый дизайн, по этому вышло 4 строки
делать на это гайд?
 
Сверху