Отображение другого предмета в руке вместо настоящего

Версия Minecraft
1.12.2

will0376

Токсичная личность
2,079
55
585
Добра всем. пришла идея в голову - сделать мод, который бы визуально подменял меч в руке на другой предмет(держишь железный меч, но ты и другие видят другой предмет и т.п.)
Но не могу подступиться.
Пытался напрямую в EntityPlayer'e при помощи миксина подменять активный айтем в методе onUpdate игрока, не помогло
Как вариант - можно в тиках игрока(с проверками есс-но) отсылать на сервер нужный айтем и не мучаться.... Но я не допру, как я на других игроках буду подменять этот предмет(да и у себя тоже...)

Идеи?
 

will0376

Токсичная личность
2,079
55
585
Почему у игрока А меч в руке должен выглядеть как другой предмет?
потому-что он решил выпендриться и поставил в ново-созданный слот в ново-созданном инвентаре предмет, которым он хочет подменять железный меч(к примеру). У других игроков его железный меч подменялся предметом, который он положил в свой слот...(пакеты)
 
7,099
324
1,510
У других игроков его железный меч подменялся предметом, который он положил в свой слот...(пакеты)
Агрованя уже задал вопрос, наводящий на это
А там есть игрок у которого эта модель? Чот сомневаюсь.
Есть, и не только игрок, для зомби тут же фичу можно сделать
Посмотреть вложение 8999
В handletemState есть сущность, держащая предмет, из нее можно взять стейт, от которого зависит, какие квады будет возвращать финализированная модель
 

will0376

Токсичная личность
2,079
55
585
Ну... Чёт я уже запутался. Мы подменяем в мапе текстуру предмета на свой WandModel, при этом который заменяет getOverrides, в котором я и должен подменять текстуру на произвольный предмет... вот только:
1) в 1.12 ItemOverrideList требует лист<ItemOverride>, который я не особо в курсе,откуда брать.
2)ModelBakeEvent вызывается в момент загрузки(ну и еще в нескольких, я так и не понял)
3)именно getQuads и возвращает квады предмета...(или CustomOverrideList где-то еще надо использовать?)
 
7,099
324
1,510
1) Свой экземпляр. Прочти тутор наконец. Там примеры на скала, но там нет ничего особенного
2) После загрузки моделей, после ModelRegistryEvent
3) handletemState вызывается каждый кадр(ну или почти), также часто, как и getQuads, поэтому его аргументы тоже могут влиять на квады финализированной модели.
getOverrides возвращает экземпляр ItemOverrideList у которого handletemState возвращает экземпляр финализированной модели, у которой будет вызван getQuads, который вернет квады.
getOverrides->handletemState->getQuads

Чтобы понять, как это все работает попробуй сделать тестовый враппер модели, вставь в интересных методах println и подебажь
 

will0376

Токсичная личность
2,079
55
585
1 - ок, пустой лист отдам.
3 - Если я правильно понял - могу забить на getQuads(в враппере возвращать пустой лист) и в handletemState в зависимости от игрока дёргать нужный предмет, а из предмета возвращать нужный IBakedModel(ну или дефолтный)

тобы понять, как это все работает попробуй сделать тестовый враппер модели
Да я пробовал. получил смещение модели в центр + смещение иконки в слоте...
1591438059131.png
 
7,099
324
1,510
смещение модели в центр + смещение иконки в слоте...
Это можно поправить, если все остальные методы модели делегировать оригинальной модели
handlePerspective отвечает за матрицу трансформации
 

will0376

Токсичная личность
2,079
55
585
Да, примерно так можно
ну я попробовал. в руке ничего не рендерится, но она поднимается как от меча. hastebin
Попробовал напрямую айтем отрендерить. где-то у меня ошибка была :D ибо всё пашет
1591453848978.png
 
Последнее редактирование:

will0376

Токсичная личность
2,079
55
585
Так-с ладно) мечи и луки я смог завести. а вот на щит почему-то не действует. 1591469684468.png
Хотя брекпоинт срабатывает на return
Java:
else if(stack.getItem() instanceof ItemShield)
                            return super.handleItemState(getFromItem(player.getReplaceShield().getItem()), player.getReplaceShield(), world, entity);
 

will0376

Токсичная личность
2,079
55
585
класс модели и ItemOverrideList
анонимный класс использовал.
Java:
public class TmpModel implements IBakedModel {

    private IBakedModel getFromStack(ItemStack is) {
        return getFromItem(is.getItem());
    }

    private IBakedModel getFromItem(Item item) {
        return Minecraft.getMinecraft().getRenderItem()
                .getItemModelWithOverrides(new ItemStack(item), Minecraft.getMinecraft().world, null);
    }

    @Override
    public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) {
        return Collections.emptyList();
    }

    @Override
    public boolean isAmbientOcclusion() {
        return false;
    }

    @Override
    public boolean isGui3d() {
        return false;
    }

    @Override
    public boolean isBuiltInRenderer() {
        return false;
    }

    @Override
    public TextureAtlasSprite getParticleTexture() {
        return null;
    }

    @Override
    public ItemOverrideList getOverrides() {
        return new ItemOverrideList(Collections.emptyList()) {

            public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, @Nullable World world, @Nullable EntityLivingBase entity) {
                try {
                    if (entity != null && entity.getName() != null && Main.clientMap.containsKey(entity.getName())) {
                        PojoPlayer player = Main.clientMap.get(entity.getName());
                        if (stack.getItem() instanceof ItemSword)
                            return super.handleItemState(getFromItem(player.getReplaceSword().getItem()), player.getReplaceSword(), world, entity);
                        if(stack.getItem() instanceof ItemBow)
                            return super.handleItemState(getFromItem(player.getReplaceBow().getItem()), player.getReplaceBow(), world, entity);
                        if(stack.getItem() instanceof ItemShield)
                            return super.handleItemState(getFromItem(player.getReplaceShield().getItem()), player.getReplaceShield(), world, entity);
                    }
                    return super.handleItemState(originalModel, stack, world, entity);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return super.handleItemState(originalModel, stack, world, entity);
            }
        };
    }
}
 
Последнее редактирование:
7,099
324
1,510
Попробуй сразу же возвращать результат getFromItem, не пихая его в super.handleItemState
Еще, возможно, вот в этой проверке Main.clientMap.containsKey(entity.getName()) проблема какая-то

Попробовал у себя: когда игрок приседает, то рендерится компас, иначе яблоко
1591488850959.png
d804950043564c43f82159bde3262be4.gif

 

will0376

Токсичная личность
2,079
55
585
Сверху