当前位置: 首页 > 知识库问答 >
问题:

Minecraft Forge 1.7.10定制实体未在客户端生成?

壤驷阳波
2023-03-14

在我1.7.10的Minecraft Forge mod中。我知道这个版本可以说是旧消息,但它是我最喜欢的版本,我所有的改装经验都是这个版本。

我正在创建一个自定义的梯恩梯块。问题是底漆版本没有渲染。当点燃时,梯恩梯消失了,然后不久就发生了爆炸。如果梯恩梯被放置在空中,爆炸就在下面,就像它应该是由于底漆梯恩梯落下一样。问题是它没有渲染。当我使用fnf3b显示hitbox时,不显示hitbox。

问题是服务器上生成的实体没有复制到客户端。我知道这一点是因为:

>

用copy-paste-vanillaentitytntpromedcode关闭我的自定义实体类也不能解决这个问题。如果问题出在我的自定义实体类上,那么使用真正的普通代码可以解决问题,但事实并非如此。

正在使用RenderingRegistry注册实体及其渲染器。registerEntityRenderingHandler()从客户端代理和EntityRegistry。registerGlobalEntityID()。registerModEntity()在init()中(我已经用System.out.println()测试了客户端代理,客户端代理工作正常)。

虽然问题的最大证据是TNT在服务器上产生,而不是在客户端产生,但事实是,从我的BlockTNT类中的处理程序中删除if(world.isRemote)返回;会导致TNT呈现。然而,我不应该处理在客户端上点燃TNT,所以如果(world.isRemote)返回,我不应该删除。此外,这样做是一个伪修复,因为当/call编辑时,实体仍然是不可见的。

tntpremedcharged的构造函数仅从服务器调用,而tntpremedchargedonUpdate()的构造函数也仅由服务器调用,正如添加打印语句所示,日志仅显示从服务器线程打印的语句。

BlockTNT类(这其中很多都是从普通代码中派生出来的,但在实例化时被设计为使用相应的定制预处理TNT实体类,问题不在这里,因为实例化一个默认的EntityTNTPromed而不是提供的primed类确实可以正确地呈现,但我之所以包含它,是因为这段代码有帮助。)ed演示了问题的根源):

class BlockTNT extends net.minecraft.block.BlockTNT {
    private final Class primed;
    public BlockTNT(final Class primed) {
        this.primed = primed;
        stepSound = net.minecraft.block.Block.soundTypeGrass;
    }
    protected EntityTNTPrimed getPrimed(final World world, final int x, final int y, final int z, final EntityLivingBase igniter) {
        try {
            return (EntityTNTPrimed)primed.getDeclaredConstructor(World.class, double.class, double.class, double.class, EntityLivingBase.class).newInstance(world, (double)((float)x+0.5F), (double)((float)y+0.5F), (double)((float)z+0.5F), igniter);
        } catch (Exception exception) {
            return null;
        }
    }
    @Override public void onBlockDestroyedByExplosion(final World world, final int x, final int y, final int z, final Explosion explosion) {
        if(world.isRemote)
            return;
        final EntityTNTPrimed tnt = getPrimed(world, x, y, z, explosion.getExplosivePlacedBy());
        tnt.fuse = world.rand.nextInt(tnt.fuse>>2)+(tnt.fuse>>3);
        world.spawnEntityInWorld(tnt);
    }
    @Override public void func_150114_a(final World world, final int x, final int y, final int z, final int meta, final EntityLivingBase igniter) {
        if(world.isRemote || (meta&1) == 0)
            return;
        final EntityTNTPrimed tnt = getPrimed(world, x, y, z, igniter);
        world.spawnEntityInWorld(tnt);
        world.playSoundAtEntity(tnt, "game.tnt.primed", 1.0F, 1.0F);
    }
}

在主mod类中,我注册实体:

@Instance public static ExampleMod instance;
@SidedProxy(clientSide="com.examplemod.ClientProxy", serverSide="com.examplemod.CommonProxy") public static com.examplemod.CommonProxy proxy;
private static void registerTnt(final Class primed, String name, final int id) {
    proxy.registerTntRenderer(primed, registerBlock(new BlockTNT(primed), name.toLowerCase()+"_tnt"));
    EntityRegistry.registerGlobalEntityID(primed, name = "PrimedTnt"+name, EntityRegistry.findGlobalUniqueEntityId());
    EntityRegistry.registerModEntity(primed, name, id, instance, 160, 10, true);
}
@EventHandler public void init(FMLInitializationEvent event) {
    registerTnt(com.examplemod.TNTPrimedCharged.class, "Charged", 0);
    // ...
}

我们在客户端代理中注册渲染器(再次测试并工作):

@Override public void registerTntRenderer(final Class primed, final Block block) {
    RenderingRegistry.registerEntityRenderingHandler(primed, new com.examplemod.RenderTNTPrimed(block));
}

下面是自定义实体的类:

public abstract class TNTPrimed extends net.minecraft.entity.item.EntityTNTPrimed {
    public TNTPrimed(final World world, final double x, final double y, final double z, final EntityLivingBase igniter) {
        super(world, x, y, z, igniter);
    }
    public TNTPrimed(final World world) {
        super(world);
    }
    @Override public void onUpdate() {
        prevPosX = posX;
        prevPosY = posY;
        prevPosZ = posZ;
        moveEntity(motionX, motionY -= 0.04D, motionZ);
        motionX *= 0.98D;
        motionY *= 0.98D;
        motionZ *= 0.98D;
        if(onGround) {
            motionX *= 0.7D;
            motionZ *= 0.7D;
            motionY *= -0.5D;
        }
        if(fuse-- <= 0) {
            setDead();
            if(!worldObj.isRemote)
                explode();
        } else
            worldObj.spawnParticle("smoke", posX, posY+0.5D, posZ, 0.0D, 0.0D, 0.0D);
    }
    protected abstract void explode();
}
public class TNTPrimedCharged extends com.examplemod.TNTPrimed {
    public TNTPrimedCharged(final World world, final double x, final double y, final double z, final EntityLivingBase igniter) {
        super(world, x, y, z, igniter);
    }
    public TNTPrimedCharged(final World world) {
        super(world);
    }
    @Override protected void explode() {
        worldObj.newExplosion(this, posX, posY, posZ, 8, false, true);
    }
}

虽然我可以明确指出,自定义实体渲染器类不是罪魁祸首,但我提供它以供参考:

class RenderTNTPrimed extends net.minecraft.client.renderer.entity.RenderTNTPrimed {
    private final RenderBlocks renderer = new RenderBlocks();
    private final Block block;
    public RenderTNTPrimed(final Block block) {
        super();
        this.block = block;
    }
    @Override public void doRender(final EntityTNTPrimed entity, final double x, final double y, final double z, final float yaw, final float tick) {
        GL11.glPushMatrix();
        GL11.glTranslatef((float)x, (float)y, (float)z);
        float var0 = entity.fuse-tick+1.0F;
        if (var0 < 10.0F) {
            final float scale = (float)Math.pow(Math.max(Math.min(1-var0/10, 1.0F), 0.0F), 4.0F)*0.3F+1.0F;
            GL11.glScalef(scale, scale, scale);
        }
        bindEntityTexture(entity);
        renderer.renderBlockAsItem(block, 0, entity.getBrightness(tick));
        if (((entity.fuse/5)&1) == 0) {
            GL11.glDisable(GL11.GL_TEXTURE_2D);
            GL11.glDisable(GL11.GL_LIGHTING);
            GL11.glEnable(GL11.GL_BLEND);
            GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_DST_ALPHA);
            GL11.glColor4f(1.0F, 1.0F, 1.0F, (1.0F-var0/100.0F)*0.8F);
            renderer.renderBlockAsItem(block, 0, 1.0F);
            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
            GL11.glDisable(GL11.GL_BLEND);
            GL11.glEnable(GL11.GL_LIGHTING);
            GL11.glEnable(GL11.GL_TEXTURE_2D);
        }
        GL11.glPopMatrix();
    }
}

所以当服务器调用world时。我的自定义实体上的spawentityinworld()为什么它也无法在客户端上生成它?我怎样才能解决这个问题,因为TNT在被点燃时就消失是不可取的,我不知道还能尝试什么。我怎样才能让定制的TNT出现在客户身上?

在对其他类似的mod(特别是太多TNT mod)进行反向工程后,当使用/call时,它们的TNT预处理实体成功呈现,并且它们在TNT块类中检查客户端。经过调查,我无法判断他们正在做什么不同的事情,这将导致他们的实体呈现,而不是我的实体。

我花了几个小时研究这个问题,但都没有结果。考虑到截至本次编辑,这个问题在谷歌搜索“Minecraft Forge 1.7.10 Entity Not Rendering”和“Minecraft Forge 1.7.10 Entity Invisible”等基本搜索词时是第二个热门问题,进一步的研究很可能是徒劳的。

问题很简单,当我的mod添加实体在服务器线程上生成时,它不会也在客户端线程上生成,即使它应该是。如何解决这个问题?我尝试了所有方法。


共有1个答案

庄文栋
2023-03-14

事实证明,问题其实不是没有在客户机上生成的实体。问题在于,客户机上的fuse属性被设置为0,即使服务器上的属性被设置为80。因此,客户端TNT会立即setDead()ing自身。实现cpw。mods。fml。常见的注册处。IENTITYAAdditionalSpawnData,然后在readSpawnData中将fuse属性设置为正确的值,似乎解决了这个问题。

 类似资料:
  • 我正在为我的应用程序进行自动化移动测试。在输入用户名后登录页面 我无法解决这个问题。。你能给我推荐一些示例代码来解决这个问题吗。

  • 你好,我有一个与SAAS模型和多租户相关的问题。 据我所知,SAAS多租户应用程序意味着所有客户机的通用功能,以及一些用户界面和功能的定制。 如果我需要为一些客户进行额外的客户特定定制,我如何实现它? 我了解SalesForce的方法 至于答案,我很高兴看到你们在数据库级别的定制,后端架构,或者这个主题的任何链接方面都有经验。

  • 同时遵循此处概述的步骤: https://cloud.google.com/developers/articles/how-to-build-mobile-app-with-app-engine-backend-tutorial/ 为了创建一个云endpoint,但使用Android Studio而不是Eclipse,我陷入了实体类设计模式的第9步,如下所述: https://cloud.goog

  • 我创建了一个WinForm应用程序,它有一些带有特殊字体的标签,这些标签没有安装在客户端的电脑上,因此当我的任何客户端运行我的应用程序时,标签的字体都不同。我已对此进行了搜索,以找到解决方案 第一个问题:我该怎么做? 如果不可能, 第二个问题:我如何在客户的电脑上安装字体而不让他们知道?我的意思是,我如何不仅在我的项目上,而且在Cliens的操作系统上以编程方式安装字体?

  • 1.2 boss上是有实习转正的但是HR说我的简历不符合转正要求(估计是我不是计算机专业的吧) C#GC GC优化 数据结构,堆,队列,二叉树,数组,链表的一些基本操作 冒泡,归并排序 A*算法 C#和lua怎么进行调用,为什么c#不能热更新 TCP和UDP的区别 状态同步和帧同步,状态同步一次性处理这么多数据不会死机吗 Image和rawimage有什么区别 锚点 渲染管线,然后讲到判断像素在不

  • 4.1晚上约面的,4.3一面,许愿二面,面试官全程引导,面试体验可以说是相当好了。 一. 自我介绍之后,面试官看我是人工智能专业的,问了我一些有关推荐算法的场景题,虽然我忘的差不多了,但还是凭借微弱的本科课设经历编了编,然后面试官说思路还行(大体围绕着训练推荐模型,用户爱好建模,带点深度学习那味) 二. 1.之后问了java基础,hashmap是不是线程安全的,然后介绍了hashtable和con