Кастомный шрифт на кастомной табличке

Версия Minecraft
1.12.2
5,149
49
899
Здравствуйте!
В общем появилась идея сделать в ванильке свои таблички, но со своим шрифтом.
Но при этом мне например не нужны какие то монструозные либы, моды по типу SmoothFonts и подобном.
Хотелось бы для начала изучить как это все работает в ванили и может, сделать по аналогии.
Каким образом в ванили работают шрифты? ttf ? или там свой формат? Если да, как его делать, чем редактировать? Каким образом можно подгружать свой шрифт конкретно для моей таблички?
 
Е мое. Так это че обычная текстура?)

Я так понял мне надо кастомный FontRenderer сделать с расширением от ванильного?
 
А его надо где то регать, этот мой новый фонтрендерер?
 
И еще вопрос. Может есть какие то автоматические конвертаторы? Или мне сидеть вручную эту картинку с буквами делать?:cry:
 
TrueType — Википедия
Можно написать код своего генератора атласа текстуры, со своим принципом хранения к определённым координатам как в glyph_sizes.bin, для определённого TTF'а с нужным набором символов.
 
Да понятное дело что можно все это самому сделать. Хотелось бы без запары.

Тут кстати еще один вопрос возникает - каким образом правильно сделать атлас, чтобы каждый символ попал так как надо? В ванилле там много всяких, очень много.
 
Хотелось бы без запары.
http://www.java-gaming.org/topics/rendering-text-in-lwjgl-without-slick/35535/view.html
чтобы каждый символ попал так как надо?
Можно по простому, типа первая строчка цифры, вторая маленькие буквы, третья для больших, последняя строчка для всяких знаков.
В TTF вроде как храниться их ширина и высота и типа их смещение (типа в сполере есть видео, где типа это объяснялось.).
 
timaxa007, а ты сам пробовал делать похожие таблички? Не помнишь, нужно как то свой кастомный FontRenderer регистрировать?
 
Да, уже нашел. P.S Тут внезапно оказалось что табличка вовсе Json модели не имеет.
 
timaxa007, а ты сам пробовал делать похожие таблички?
Таблички нет.
Не помнишь, нужно как то свой кастомный FontRenderer регистрировать?
Вроде как регистрировать не надо было. Просто создать объект или константу к классу, который-бы хранил атлас и размеры и смещения для символов.
 
Так, этот способ регистрации не работает. Там крашится на стадии преинита
попробуем без этого пока.
 
Хм, вроде сделал, ошибок нет, но почему то при установке не открывается окошко ввода. Странно, блок ведь копия ванильного:(
 
Выяснил что style почему то равен нулю. По совершенно непонятной причине..
Ввиду этого кликэвент и не срабатывает. Это не зависит кстати от моего шрифта который я там делал.
Java:
public class TileEntitySovietSign extends TileEntity
{
    public final ITextComponent[] signText = new ITextComponent[] {new TextComponentString(""), new TextComponentString(""), new TextComponentString(""), new TextComponentString("")};
    /**
     * The index of the line currently being edited. Only used on client side, but defined on both. Note this is only
     * really used when the > < are going to be visible.
     */
    public int lineBeingEdited = -1;
    private boolean isEditable = true;
    private EntityPlayer player;
    private final CommandResultStats stats = new CommandResultStats();

    public NBTTagCompound writeToNBT(NBTTagCompound compound)
    {
        super.writeToNBT(compound);

        for (int i = 0; i < 4; ++i)
        {
            String s = ITextComponent.Serializer.componentToJson(this.signText[i]);
            compound.setString("Text" + (i + 1), s);
        }

        this.stats.writeStatsToNBT(compound);
        return compound;
    }

    protected void setWorldCreate(World worldIn)
    {
        this.setWorld(worldIn);
    }

    public void readFromNBT(NBTTagCompound compound)
    {
        this.isEditable = false;
        super.readFromNBT(compound);
        ICommandSender icommandsender = new ICommandSender()
        {
            /**
             * Get the name of this object. For players this returns their username
             */
            public String getName()
            {
                return "Sign";
            }
            /**
             * Returns {@code true} if the CommandSender is allowed to execute the command, {@code false} if not
             */
            public boolean canUseCommand(int permLevel, String commandName)
            {
                return permLevel <= 2; //Forge: Fixes  MC-75630 - Exploit with signs and command blocks
            }
            /**
             * Get the position in the world. <b>{@code null} is not allowed!</b> If you are not an entity in the world,
             * return the coordinates 0, 0, 0
             */
            public BlockPos getPosition()
            {
                return TileEntitySovietSign.this.pos;
            }
            /**
             * Get the position vector. <b>{@code null} is not allowed!</b> If you are not an entity in the world,
             * return 0.0D, 0.0D, 0.0D
             */
            public Vec3d getPositionVector()
            {
                return new Vec3d((double)TileEntitySovietSign.this.pos.getX() + 0.5D, (double)TileEntitySovietSign.this.pos.getY() + 0.5D, (double)TileEntitySovietSign.this.pos.getZ() + 0.5D);
            }
            /**
             * Get the world, if available. <b>{@code null} is not allowed!</b> If you are not an entity in the world,
             * return the overworld
             */
            public World getEntityWorld()
            {
                return TileEntitySovietSign.this.world;
            }
            /**
             * Get the Minecraft server instance
             */
            public MinecraftServer getServer()
            {
                return TileEntitySovietSign.this.world.getMinecraftServer();
            }
        };

        for (int i = 0; i < 4; ++i)
        {
            String s = compound.getString("Text" + (i + 1));
            ITextComponent itextcomponent = ITextComponent.Serializer.jsonToComponent(s);

            try
            {
                this.signText[i] = TextComponentUtils.processComponent(icommandsender, itextcomponent, (Entity)null);
            }
            catch (CommandException var7)
            {
                this.signText[i] = itextcomponent;
            }
        }

        this.stats.readStatsFromNBT(compound);
    }

    @Nullable
    public SPacketUpdateTileEntity getUpdatePacket()
    {
        return new SPacketUpdateTileEntity(this.pos, 9, this.getUpdateTag());
    }

    public NBTTagCompound getUpdateTag()
    {
        return this.writeToNBT(new NBTTagCompound());
    }

    public boolean onlyOpsCanSetNbt()
    {
        return true;
    }

    public boolean getIsEditable()
    {
        return this.isEditable;
    }

    /**
     * Sets the sign's isEditable flag to the specified parameter.
     */
    @SideOnly(Side.CLIENT)
    public void setEditable(boolean isEditableIn)
    {
        this.isEditable = isEditableIn;

        if (!isEditableIn)
        {
            this.player = null;
        }
    }

    public void setPlayer(EntityPlayer playerIn)
    {
        this.player = playerIn;
    }

    public EntityPlayer getPlayer()
    {
        return this.player;
    }

    public boolean executeCommand(final EntityPlayer playerIn)
    {
        ICommandSender icommandsender = new ICommandSender()
        {
            /**
             * Get the name of this object. For players this returns their username
             */
            public String getName()
            {
                return playerIn.getName();
            }
            /**
             * Get the formatted ChatComponent that will be used for the sender's username in chat
             */
            public ITextComponent getDisplayName()
            {
                return playerIn.getDisplayName();
            }
            /**
             * Send a chat message to the CommandSender
             */
            public void sendMessage(ITextComponent component)
            {
            }
            /**
             * Returns {@code true} if the CommandSender is allowed to execute the command, {@code false} if not
             */
            public boolean canUseCommand(int permLevel, String commandName)
            {
                return permLevel <= 2;
            }
            /**
             * Get the position in the world. <b>{@code null} is not allowed!</b> If you are not an entity in the world,
             * return the coordinates 0, 0, 0
             */
            public BlockPos getPosition()
            {
                return TileEntitySovietSign.this.pos;
            }
            /**
             * Get the position vector. <b>{@code null} is not allowed!</b> If you are not an entity in the world,
             * return 0.0D, 0.0D, 0.0D
             */
            public Vec3d getPositionVector()
            {
                return new Vec3d((double)TileEntitySovietSign.this.pos.getX() + 0.5D, (double)TileEntitySovietSign.this.pos.getY() + 0.5D, (double)TileEntitySovietSign.this.pos.getZ() + 0.5D);
            }
            /**
             * Get the world, if available. <b>{@code null} is not allowed!</b> If you are not an entity in the world,
             * return the overworld
             */
            public World getEntityWorld()
            {
                return playerIn.getEntityWorld();
            }
            /**
             * Returns the entity associated with the command sender. MAY BE NULL!
             */
            public Entity getCommandSenderEntity()
            {
                return playerIn;
            }
            /**
             * Returns true if the command sender should be sent feedback about executed commands
             */
            public boolean sendCommandFeedback()
            {
                return false;
            }
            public void setCommandStat(CommandResultStats.Type type, int amount)
            {
                if (TileEntitySovietSign.this.world != null && !TileEntitySovietSign.this.world.isRemote)
                {
                    TileEntitySovietSign.this.stats.setCommandStatForSender(TileEntitySovietSign.this.world.getMinecraftServer(), this, type, amount);
                }
            }
            /**
             * Get the Minecraft server instance
             */
            public MinecraftServer getServer()
            {
                return playerIn.getServer();
            }
        };

        for (ITextComponent itextcomponent : this.signText)
        {
            Style style = itextcomponent == null ? null : itextcomponent.getStyle();
         
            if (style != null && style.getClickEvent() != null)
            {
                ClickEvent clickevent = style.getClickEvent();
               
                if (clickevent.getAction() == ClickEvent.Action.RUN_COMMAND)
                {
                    System.out.println("true" );
                    playerIn.getServer().getCommandManager().executeCommand(icommandsender, clickevent.getValue());
                }
            }
        }

        return true;
    }

    public CommandResultStats getStats()
    {
        return this.stats;
    }
}
 
Ну вот еще, деньги за эту херню платить. Я лучше два дня угрохаю и сам разберусь, нежели отдавать кому то деньги. тема кстати не для предложения своих услуг. И кстати мод который поддерживает ttf существует уже давно
 
Назад
Сверху