Странная ошибка в Screen

Версия Minecraft
1.20.1
95
4
6
Уже добавлял в мод меню и экраны, но в этот раз выдаёт странную ошибку, причём эта ошибка возникает не всегда, и экран может открыться. Майнкрафт жалуется на то что поле Screen.minecraft является null и поэтому он не может получить нарратора, подскажите в чём проблема

java.lang.NullPointerException: Cannot invoke "net.minecraft.client.Minecraft.getNarrator()" because "this.minecraft" is null
 
Уже добавлял в мод меню и экраны, но в этот раз выдаёт странную ошибку, причём эта ошибка возникает не всегда, и экран может открыться. Майнкрафт жалуется на то что поле Screen.minecraft является null и поэтому он не может получить нарратора, подскажите в чём проблема

java.lang.NullPointerException: Cannot invoke "net.minecraft.client.Minecraft.getNarrator()" because "this.minecraft" is null
Покажи часть, где Screen открываешь.
 
Вот метод, в котором открывается экран:
    @Override
    public InteractionResultHolder<ItemStack> use(Level pLevel, Player pPlayer, InteractionHand pUsedHand) {
        if(!pLevel.isClientSide){
            if(Minecraft.getInstance().player.isShiftKeyDown()){
                NetworkHooks.openScreen((ServerPlayer) pPlayer, ((ChromaticLexicon)pPlayer.getItemInHand(pUsedHand).getItem()));
            }
            else { Minecraft.getInstance().setScreen(new LexiconMainPageScreen(LexiconTitle)); }
        }
        pPlayer.getCooldowns().addCooldown(this, 20);

        return super.use(pLevel, pPlayer, pUsedHand);
    }
 
Последнее редактирование:
А когда вызывается shouldRunNarration? Думаю с этого стоит начать. Потому что если этот метод вызывается в конструкторе у Screen, то хоть как не открывай оно будет ломаться(если в конструкторе не присваивается значение minecraft)
 
Пробовал сейчас несколько способов решения проблемы:
1. добавить в конструктор this.minecraft = Minecraft.getInstance()
после этого майнкрафт вылетел и пожаловался, что font is null, я добавил в констрктор ещё this.font = Minecraft.getInstance().font;
после этого игра перестала вылетать, но этот экран стал некорректно открываться, а именно поверх него накладываются несколько пустых слоёв и, пока не закроешь 2-5 пустых экранов нужный не видно, иногда эти экраны не полностью пустые, а являются копиями исходного без заднего фона

2. сделать @Override всех методов где вызывается shouldRunNarration
изменённые методы:
    @Override
    public void handleDelayedNarration() {

    }

    @Override
    public void triggerImmediateNarration(boolean pOnlyNarrateNew) {

    }
после этого майнкрафт перестал корректно отрисовывать экран, как и в первом случае и стал вылетать при закрытии экрана, это удалось починить, переписав метод onClose, используя вместо Screen.minecraft Minecraft.getInstance()

P.S. Посмотрел в логе: пустые экраны появляются, потому что RenderSystem, по только богу известной причине, пытается вызваться в серверного потока, вместо рендер потока

P.S P.S ну конечно оно вызываетcя на сервере я же дурак даже проверку поставил в методе use. В общем я переделал метод в это:
Java:
    @Override
    public InteractionResultHolder<ItemStack> use(Level pLevel, Player pPlayer, InteractionHand pUsedHand) {
        if(!pLevel.isClientSide && Minecraft.getInstance().player.isShiftKeyDown()){
            NetworkHooks.openScreen((ServerPlayer) pPlayer, ((ChromaticLexicon)pPlayer.getItemInHand(pUsedHand).getItem()));
        } else { Minecraft.getInstance().setScreen(new LexiconMainPageScreen(LexiconTitle)); }
        pPlayer.getCooldowns().addCooldown(this, 20);

        return super.use(pLevel, pPlayer, pUsedHand);
    }
И теперь всё работает, вроде как

P.S. P.S. P.S. Я проверил, все проблемы с полем Screen.minecraft были следствием вызова клиентского экрана на серверной стороне
 
Последнее редактирование:
(1):
!pLevel.isClientSide && Minecraft.getInstance().player.isShiftKeyDown()
(2):
Minecraft.getInstance().setScreen(new LexiconMainPageScreen(LexiconTitle));
Ага, а теперь запусти в среде сервер, и смотри как он крашится (даже не заходя на него).

По-хорошему, для случая (1) тебе нужно проверять pPLayer на isSneaking(), для случая (2) нужен пакет.
Всё то, что ты делал для решения - попытка вылечить симптомы, а не болезнь. Потому их даже костылём не назовёшь.
 
зачем нужен пакет в случае пользовательского интерфейса
Потому что Item#use существует и на стороне сервера -> сервер пытается посмотреть этот метод -> в методе где-то есть клиентский пакет (тот же класс Minecraft, через который ты открываешь Screen) -> серверу плохо.
Для того, чтобы такого не было, нужен пакет.

UPD:
pPlayer.getCooldowns().addCooldown(this, 20);
У меня вызывает сомнение, зачем это.
 
Назад
Сверху