Нет текстурки на модели щита

Версия Minecraft
1.20.1
API
Forge
21
2
0
В общем, в чём суть. Делаю аддон к моду Epic Knights, там есть такой прекрасный щит, как павеза, который вдобавок можно разместить на земле через Shift+ПКМ. Проблема в следующем: в руках, при виде от первого и третьего лица, всё отлично, текстура есть, но при размещении на землю текстура пропадает. Излазил все сурсы оригинального мода, не нашёл фикса. Была такая же проблема с отображением щитов в руке, решилась регистрацией атласов для щитов. Пробовал зарегать для щита-как-блока, не помогает.
 

Вложения

  • 1724241832501.png
    1724241832501.png
    154.8 KB · Просмотры: 8
  • 1724241924933.png
    1724241924933.png
    126.2 KB · Просмотры: 8
21
2
0
Покажи код щита, попробую помочь чем смогу
Тут всё малость сложно, но вот код из сурсов оригинального мода:

ModBlockEntityTypes
Java:
package com.magistuarmory.block;

import com.mojang.datafixers.types.Type;
import dev.architectury.registry.registries.DeferredRegister;
import dev.architectury.registry.registries.RegistrySupplier;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.entity.BlockEntityType.Builder;

public class ModBlockEntityTypes {
    public static DeferredRegister<BlockEntityType<?>> BLOCK_ENTITY_TYPES;
    public static RegistrySupplier<BlockEntityType<PaviseBlockEntity>> PAVISE;

    public ModBlockEntityTypes() {
    }

    public static void init() {
        BLOCK_ENTITY_TYPES.register();
    }

    static {
        BLOCK_ENTITY_TYPES = DeferredRegister.create("magistuarmory", Registries.BLOCK_ENTITY_TYPE);
        PAVISE = BLOCK_ENTITY_TYPES.register("pavise", () -> {
            return Builder.of(PaviseBlockEntity::new, new Block[]{(Block)ModBlocks.PAVISE.get()}).build((Type)null);
        });
    }
}


ModBlocks:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.magistuarmory.block;

import dev.architectury.registry.registries.DeferredRegister;
import dev.architectury.registry.registries.RegistrySupplier;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.level.block.Block;

public class ModBlocks {
    public static DeferredRegister<Block> BLOCKS;
    public static RegistrySupplier<PaviseBlock> PAVISE;
    public static RegistrySupplier<PaviseUpperCollisionBlock> PAVISE_UPPER_COLLISION;

    public ModBlocks() {
    }

    public static void init() {
        BLOCKS.register();
    }

    static {
        BLOCKS = DeferredRegister.create("magistuarmory", Registries.BLOCK);
        PAVISE = BLOCKS.register("pavise", PaviseBlock::new);
        PAVISE_UPPER_COLLISION = BLOCKS.register("pavise_upper_collision", PaviseUpperCollisionBlock::new);
    }
}


PaviseBlock:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.magistuarmory.block;

import com.magistuarmory.item.MedievalShieldItem;
import com.magistuarmory.item.ModItems;
import com.mojang.math.Axis;
import dev.architectury.registry.registries.RegistrySupplier;
import net.minecraft.core.BlockPos;
import net.minecraft.stats.Stats;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.BannerBlock;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.BlockBehaviour.Properties;
import net.minecraft.world.level.block.state.properties.RotationSegment;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.joml.Quaternionf;
import org.joml.Vector3d;

public class PaviseBlock extends BannerBlock {
    static final AABB COLLISION_AABB = new AABB(0.0, 0.0, 0.46875, 1.0, 1.0, 0.53125);
    static final Vector3d CENTER = new Vector3d(0.5, 0.5, 0.5);
    static final Vector3d BOXMIN = new Vector3d(0.0, 0.0, 0.0);
    static final Vector3d BOXMAX = new Vector3d(1.0, 1.0, 1.0);

    public PaviseBlock() {
        super(DyeColor.WHITE, Properties.of().dynamicShape().noParticlesOnBreak().sound(SoundType.WOOD).ignitedByLava());
    }

    public BlockEntity newBlockEntity(BlockPos blockpos, BlockState blockstate) {
        return new PaviseBlockEntity(blockpos, blockstate);
    }

    public @NotNull Item asItem() {
        RegistrySupplier<MedievalShieldItem> item = ModItems.PAVISES.wood;
        return item != null ? (Item)item.get() : Items.AIR;
    }

    public BlockState getStateForPlacement(BlockPlaceContext blockPlaceContext) {
        return (BlockState)this.defaultBlockState().setValue(ROTATION, RotationSegment.convertToSegment(blockPlaceContext.getRotation()));
    }

    public @NotNull ItemStack getCloneItemStack(BlockGetter blockgetter, BlockPos blockpos, BlockState blockstate) {
        BlockEntity var5 = blockgetter.getBlockEntity(blockpos);
        if (var5 instanceof PaviseBlockEntity pavise) {
            return pavise.getItem();
        } else {
            return ItemStack.EMPTY;
        }
    }

    public VoxelShape getShape(BlockState blockstate, BlockGetter blockgetter, BlockPos blockpos, CollisionContext context) {
        AABB aabb = COLLISION_AABB;
        float yrot = -RotationSegment.convertToDegrees((Integer)blockstate.getValue(BannerBlock.ROTATION));
        aabb = rotateAABB(aabb, Axis.YP.rotationDegrees(yrot));
        return Shapes.create(aabb);
    }

    public static AABB rotateAABB(AABB axisAlignedBB, Quaternionf quaternion) {
        Vector3d mincoords = new Vector3d(axisAlignedBB.minX, axisAlignedBB.minY, axisAlignedBB.minZ);
        Vector3d maxcoords = new Vector3d(axisAlignedBB.maxX, axisAlignedBB.maxY, axisAlignedBB.maxZ);
        mincoords.sub(CENTER);
        maxcoords.sub(CENTER);
        quaternion.transform(mincoords);
        quaternion.transform(maxcoords);
        mincoords.add(CENTER).max(BOXMIN);
        maxcoords.add(CENTER).min(BOXMAX);
        return new AABB(mincoords.x(), mincoords.y(), mincoords.z(), maxcoords.x(), maxcoords.y(), maxcoords.z());
    }

    public void playerDestroy(Level level, Player player, BlockPos blockpos, BlockState blockstate, @Nullable BlockEntity blockentity, ItemStack stack) {
        player.awardStat(Stats.BLOCK_MINED.get(this));
        player.causeFoodExhaustion(0.005F);
        dropResources(blockstate, level, blockpos, blockentity, player, stack);
        if (blockentity instanceof PaviseBlockEntity pavise) {
            if (pavise.getLevel() != null) {
                level.addFreshEntity(new ItemEntity(pavise.getLevel(), (double)blockpos.getX() + 0.5, (double)blockpos.getY() + 0.5, (double)blockpos.getZ() + 0.5, pavise.getItem()));
            }
        }

    }

    public void destroy(LevelAccessor accessor, BlockPos blockpos, BlockState blockstate) {
        if (accessor.getBlockState(blockpos.above()).getBlock() == ModBlocks.PAVISE_UPPER_COLLISION.get()) {
            accessor.destroyBlock(blockpos.above(), false);
        }

        super.destroy(accessor, blockpos, blockstate);
    }
}


PaviseBlockEntity:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.magistuarmory.block;

import com.google.common.collect.Lists;
import com.mojang.datafixers.util.Pair;
import java.util.List;
import me.shedaniel.cloth.clothconfig.shadowed.blue.endless.jankson.annotation.Nullable;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.ShieldItem;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.entity.BannerPattern;
import net.minecraft.world.level.block.entity.BannerPatterns;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;

public class PaviseBlockEntity extends BlockEntity {
    String shieldId = "wood_pavese";
    @Nullable
    private DyeColor baseColor;
    @Nullable
    private ListTag itemPatterns;
    private boolean enchanted = false;
    private CompoundTag stackCompound;
    @Nullable
    private List<Pair<Holder<BannerPattern>, DyeColor>> patterns;

    public PaviseBlockEntity(BlockPos blockpos, BlockState blockstate) {
        super((BlockEntityType)ModBlockEntityTypes.PAVISE.get(), blockpos, blockstate);
    }

    @Nullable
    public static ListTag getItemPatterns(ItemStack stack) {
        ListTag listtag = null;
        CompoundTag compound = BlockItem.getBlockEntityData(stack);
        if (compound != null && compound.contains("Patterns", 9)) {
            listtag = compound.getList("Patterns", 10).copy();
        }

        return listtag;
    }

    public void fromItem(ItemStack stack) {
        this.itemPatterns = getItemPatterns(stack);
        this.baseColor = ShieldItem.getColor(stack);
        this.stackCompound = stack.getTag();
        this.enchanted = stack.isEnchanted();
        this.patterns = null;
    }

    protected void saveAdditional(CompoundTag compound) {
        super.saveAdditional(compound);
        compound.putString("ShieldId", this.shieldId);
        if (this.baseColor != null) {
            compound.putInt("Base", this.baseColor.getId());
        }

        compound.putBoolean("Enchanted", this.enchanted);
        if (this.stackCompound != null) {
            compound.put("ItemStack", this.stackCompound);
        }

        if (this.itemPatterns != null) {
            compound.put("Patterns", this.itemPatterns);
        }

    }

    public boolean hasFoil() {
        return this.enchanted;
    }

    public boolean isPainted() {
        return this.getBaseColor() != null;
    }

    public void load(CompoundTag compound) {
        super.load(compound);
        this.shieldId = compound.getString("ShieldId");
        if (compound.contains("Base")) {
            this.baseColor = DyeColor.byId(compound.getInt("Base"));
        }

        this.stackCompound = compound.getCompound("ItemStack");
        this.enchanted = compound.getBoolean("Enchanted");
        this.itemPatterns = compound.getList("Patterns", 10);
        this.patterns = null;
    }

    public ClientboundBlockEntityDataPacket getUpdatePacket() {
        return ClientboundBlockEntityDataPacket.create(this);
    }

    public CompoundTag getUpdateTag() {
        return this.saveWithoutMetadata();
    }

    public static int getPatternCount(ItemStack stack) {
        CompoundTag compound = BlockItem.getBlockEntityData(stack);
        return compound != null && compound.contains("Patterns") ? compound.getList("Patterns", 10).size() : 0;
    }

    public List<Pair<Holder<BannerPattern>, DyeColor>> getPatterns() {
        if (this.patterns == null) {
            this.patterns = createPatterns(this.baseColor, this.itemPatterns);
        }

        return this.patterns;
    }

    public static List<Pair<Holder<BannerPattern>, DyeColor>> createPatterns(DyeColor color, @Nullable ListTag listtag) {
        List<Pair<Holder<BannerPattern>, DyeColor>> list = Lists.newArrayList();
        list.add(Pair.of(BuiltInRegistries.BANNER_PATTERN.getHolderOrThrow(BannerPatterns.BASE), color));
        if (listtag == null) {
            return list;
        } else {
            for(int i = 0; i < listtag.size(); ++i) {
                CompoundTag compound = listtag.getCompound(i);
                Holder<BannerPattern> holder = BannerPattern.byHash(compound.getString("Pattern"));
                if (holder != null) {
                    int j = compound.getInt("Color");
                    list.add(Pair.of(holder, DyeColor.byId(j)));
                }
            }

            return list;
        }
    }

    public static void removeLastPattern(ItemStack stack) {
        CompoundTag compound = BlockItem.getBlockEntityData(stack);
        if (compound != null && compound.contains("Patterns", 9)) {
            ListTag listtag = compound.getList("Patterns", 10);
            if (listtag.isEmpty()) {
                return;
            }

            listtag.remove(listtag.size() - 1);
            if (listtag.isEmpty()) {
                compound.remove("Patterns");
            }

            BlockItem.setBlockEntityData(stack, (BlockEntityType)ModBlockEntityTypes.PAVISE.get(), compound);
        }

    }

    public ItemStack getItem() {
        ItemStack stack = new ItemStack((ItemLike)BuiltInRegistries.ITEM.get(new ResourceLocation("magistuarmory", this.shieldId)));
        stack.setTag(this.stackCompound.copy());
        return stack;
    }

    public DyeColor getBaseColor() {
        return this.baseColor;
    }

    public String getShieldId() {
        return this.shieldId;
    }
}


PaviseUpperCollisionBlock:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.magistuarmory.block;

import com.mojang.math.Axis;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.BannerBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.BlockBehaviour.Properties;
import net.minecraft.world.level.block.state.properties.RotationSegment;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.NotNull;
import org.joml.Quaternionf;
import org.joml.Vector3d;

public class PaviseUpperCollisionBlock extends Block {
    static final AABB COLLISION_AABB = new AABB(0.0, 0.0, 0.46875, 1.0, 0.5, 0.53125);
    static final Vector3d CENTER = new Vector3d(0.5, 0.5, 0.5);
    static final Vector3d BOXMIN = new Vector3d(0.0, 0.0, 0.0);
    static final Vector3d BOXMAX = new Vector3d(1.0, 1.0, 1.0);

    public PaviseUpperCollisionBlock() {
        super(Properties.of().dynamicShape().noParticlesOnBreak().sound(SoundType.EMPTY));
    }

    public BlockState getStateForPlacement(BlockPlaceContext context) {
        return this.defaultBlockState();
    }

    public @NotNull ItemStack getCloneItemStack(BlockGetter blockgetter, BlockPos blockpos, BlockState blockstate) {
        BlockEntity var5 = blockgetter.getBlockEntity(blockpos.below());
        if (var5 instanceof PaviseBlockEntity pavise) {
            return pavise.getItem();
        } else {
            return ItemStack.EMPTY;
        }
    }

    public VoxelShape getShape(BlockState blockstate, BlockGetter blockgetter, BlockPos blockpos, CollisionContext context) {
        AABB aabb = COLLISION_AABB;
        BlockEntity var7 = blockgetter.getBlockEntity(blockpos.below());
        if (var7 instanceof PaviseBlockEntity pavise) {
            BlockState blockstate2 = pavise.getBlockState();
            float yrot = -RotationSegment.convertToDegrees((Integer)blockstate2.getValue(BannerBlock.ROTATION));
            aabb = rotateAABB(aabb, Axis.YP.rotationDegrees(yrot));
        }

        return Shapes.create(aabb);
    }

    public static AABB rotateAABB(AABB axisAlignedBB, Quaternionf quaternion) {
        Vector3d mincoords = new Vector3d(axisAlignedBB.minX, axisAlignedBB.minY, axisAlignedBB.minZ);
        Vector3d maxcoords = new Vector3d(axisAlignedBB.maxX, axisAlignedBB.maxY, axisAlignedBB.maxZ);
        mincoords.sub(CENTER);
        maxcoords.sub(CENTER);
        quaternion.transform(mincoords);
        quaternion.transform(maxcoords);
        mincoords.add(CENTER).max(BOXMIN);
        maxcoords.add(CENTER).min(BOXMAX);
        return new AABB(mincoords.x(), mincoords.y(), mincoords.z(), maxcoords.x(), maxcoords.y(), maxcoords.z());
    }

    public void destroy(LevelAccessor accessor, BlockPos blockpos, BlockState blockstate) {
        BlockEntity blockentity = accessor.getBlockEntity(blockpos.below());
        if (blockentity instanceof PaviseBlockEntity pavise) {
            if (pavise.getLevel() != null) {
                accessor.addFreshEntity(new ItemEntity(pavise.getLevel(), (double)blockpos.getX() + 0.5, (double)blockpos.getY() - 0.5, (double)blockpos.getZ() + 0.5, pavise.getItem()));
            }
        }

        if (accessor.getBlockState(blockpos.below()).getBlock() == ModBlocks.PAVISE.get()) {
            accessor.destroyBlock(blockpos.below(), false);
        }

        super.destroy(accessor, blockpos, blockstate);
    }
}



есть ещё гит оригинального мода, но под 1.18.2, на новой версии немножко переписана логика, но щиты это не должно было затронуть.
 
Сверху