Получить игрока, который сломал блок, на сервере

Версия Minecraft
1.12.2

Maxik

Золотой Петушок
4,942
46
711
Суть вопроса в заголовке. Необходимо каким то образом получить игрока или его UUID из листа всех игроков, который сломал блок на какой-то позиции. Как можно это сделать?
Мне нужен игрок в breakBlock, но там игрока нету в принципе, так как этот метод вызывается соло в чанк
В качестве старта имеем стейт, мир и позицию(

Java:
    public void breakBlock(World w, BlockPos pos, IBlockState state)
 
Последнее редактирование:

tox1cozZ

aka Agravaine
Модератор
7,124
455
2,148
BlockEvent.Break или что-то подобное, ивент был точно, ищи.
Есть еще метод вроде onBlockDestroyedByPlayer.
 

Maxik

Золотой Петушок
4,942
46
711
этот эвент идет в canHarvestBlock,я могу его и просто переопределить, это не совсем то что надо.
onBlockDestroyedByPlayer как раз таки делает проверку НА игрока, а мне нужно наоборот НЕ НА игрока, причем в абсолютном методе breakBlock, котороый отвечает за удаление блока из чанка любым способом.
Вот немного о сути:
Игрок ломает ствол или ветку
Например ствол: итератором идет проверка всех блоков ствола, веток и листвы рядом( но листва чисто за компанию)
Если они совпадают с типом дерева - ломаются
ветки же уже отвечают за ломание листвы в большей степени - когда ветки ломаются, они тоже проверяют соседей и ломают ветки и листву если те совпадают с типом дерева
дальше, уже листва ломается - и тоже проверяет всех своих соседей
то дело в том, что я сделал это все в абсолютном методе breakBlock
то есть на данный момент так, что если игрок сломает блок кроны, то обрушится вся крона
 

Maxik

Золотой Петушок
4,942
46
711
При том что если игрок ломает блок листвы, то breakBlock из моего класса вызывать не нужно, только из родительского Block. А если не игрок ломает - то нужно.
Если оставить как есть, то ломается вся крона при тыке игрока. А она должна ломатся целиком только в том случае, если не игрок ее ломает, а соседний блок, к примеру, вызывается destroyBlock(pos.offset()). А иначе она должна себя вести как обычный блок когда его ломают полностью.
 

Icosider

iMixin
Администратор
3,285
85
485
А что у тебя такого в классе "особенного", что не нужно вызывать breakBlock при ломании игроком?
 

Maxik

Золотой Петушок
4,942
46
711
Ванильный breakBlock ломает только тот блок, который ломает игрок. Мой класс ломает еще все блоки вокруг если они соответсвуют условию:

Java:
    public void breakBlock(World w, BlockPos pos, IBlockState state)
    {
        
        for(EnumFacing f : EnumFacing.VALUES) {
            if(w.getBlockState(pos.offset(f)).getBlock() == state.getBlock()) {
                w.destroyBlock(pos.offset(f), false);       
            } else {
        
            }
    
        }

    }
 

Maxik

Золотой Петушок
4,942
46
711
breakBlock нужно вызывать, но только не этот, а тот, родительский, дефолтный.
 

Icosider

iMixin
Администратор
3,285
85
485
Ну так заюзай BlockEvent.BreakEvent, просто туда перенеси всю логику из своего breakBlock. А ещё у тебя стрёмный оффсет
 

Maxik

Золотой Петушок
4,942
46
711
А ещё у тебя стрёмный оффсет
А можно сделать более оптимизированно?:unsure:
С эвентом не хочу делать, это будут запутанные связки. Лучше все таки, по теме вопроса, есть какие мысли?
 
Последнее редактирование:

Maxik

Золотой Петушок
4,942
46
711
Пока есть мысль о таком:
EntityPlayer player = w.getPlayerEntityByUUID(EntityPlayer.getUUID(gameprofile));
Но мне нужен таки геймпрофайл игрока
 

Icosider

iMixin
Администратор
3,285
85
485
Пока есть мысль о таком:
EntityPlayer player = w.getPlayerEntityByUUID(EntityPlayer.getUUID(gameprofile));
Но мне нужен таки геймпрофайл игрока
Крч, используй onBlockDestroyedByPlayer для проверки, что разрушил игрок, а в случаи другого разрушения используй подобные методы и всё
 

Maxik

Золотой Петушок
4,942
46
711

Maxik

Золотой Петушок
4,942
46
711
Основная проблема в том, что все эти методы ломания игроком вызываются до breakBlock. И в конечном итоге все равно вызывается breakBlock. От него никак не избавится, нету другого метода, удаляющего блок из чанка, он всегда вызывается последним. Есть еще вариант хукнуть чанк и добавить туда этот другой метод... Но там нужен будет пакет. В таком случае мне проще при ломании отправить пакет с игроком с клиента и потом на сервере использовать его в breakBlock. Походу, придется так и сделать, другого выхода я не вижу.

Кстати, как отправлять игрока в пакете? :)
 
5,397
179
984
А что ты хочешь получить в итоге? Чтобы, когда игрок ломал основание кроны, зависящие от этого ветки тоже ломались?
 

Maxik

Золотой Петушок
4,942
46
711
Если игрок подрубает снизу дерево - ломается все дерево, включая крону. Если игрок ломает ветку - ломается ветка и прилегающая к ней листва.
Если игрок ломает блок листвы, соседние блоки листвы не должны ломатся этим итератором, код которого я скидывал выше
 
5,397
179
984
Пусть каждая ветка знает, от какой она зависит, тогда если обновляется соседний блок и это та сторона, от которой зависит текущая ветка и там теперь пустота, то ветка ломает себя
 

Maxik

Золотой Петушок
4,942
46
711
Ветки тут вообще не причем, я оперирую на уровне блоков. В принципе я придумал уже как. Щас вопрос у меня такой - как отослать в пакете игрока или uuid игрока?
 
5,397
179
984
Под веткой я имею ввиду блок ветки
Если блок знает от какого блока он растет, то не обнаружив этот блок при обновлении соседей, это значит что блок на котором он растет был чем-то убран и он должен удалить себя, это спровоцирует обновление его соседей, они сделают тоже самое и т.д.
 
Сверху