Jump to content

[1.14.4] Entity in ServerWorld but not in ClientWorld


Keheck

Recommended Posts

I have this problem where (as far as I could deduct from debugging) a entity from my mod gets summoned into the server world, but the client world didn't recieve that entity.

The symptom of that problem is that the entity can't get rendered .

Spoiler
 
Spoiler

which was the initial problem that first led me to believe that the renderer didn't get registered, but the renderer did get registered.

My entity is a simple descendant (class name: io.github.keheck.mobfighters.entity.MobBall) of the net.minecraft.entity.ProjectileItemEntity class that only implements the onImpact(net.minecraft.util.math.RayTraceResult) method like this:

@Override
@SuppressWarnings("NullableProblems")
protected void onImpact(RayTraceResult result)
{
    if(!world.isRemote())
        this.remove();
}

The other methods overriden are the remove() method, which only loggs the death and then removes the entity as normal, and two methods that return an Item and ItemStack respectively, so not really, if at all, connected to my problem.

 

I did some more digging while writing this, and it seems like the root of the problem lies in the method "net.minecraft.client.network.play.ClientPlayNetHandler#handleSpawnObject(net.minecraft.network.play.server.SSpawnObjectPacket)"

Here it is:

Spoiler
 
 
 
 
Spoiler

public void handleSpawnObject(SSpawnObjectPacket packetIn) {
      PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
      double d0 = packetIn.getX();
      double d1 = packetIn.getY();
      double d2 = packetIn.getZ();
      EntityType<?> entitytype = packetIn.getType();
      Entity entity;
      if (entitytype == EntityType.CHEST_MINECART) {
         entity = new ChestMinecartEntity(this.world, d0, d1, d2);
      } else if (entitytype == EntityType.FURNACE_MINECART) {
         entity = new FurnaceMinecartEntity(this.world, d0, d1, d2);
      } else if (entitytype == EntityType.TNT_MINECART) {
         entity = new TNTMinecartEntity(this.world, d0, d1, d2);
      } else if (entitytype == EntityType.SPAWNER_MINECART) {
         entity = new SpawnerMinecartEntity(this.world, d0, d1, d2);
      } else if (entitytype == EntityType.HOPPER_MINECART) {
         entity = new HopperMinecartEntity(this.world, d0, d1, d2);
      } else if (entitytype == EntityType.COMMAND_BLOCK_MINECART) {
         entity = new MinecartCommandBlockEntity(this.world, d0, d1, d2);
      } else if (entitytype == EntityType.MINECART) {
         entity = new MinecartEntity(this.world, d0, d1, d2);
      } else if (entitytype == EntityType.FISHING_BOBBER) {
         Entity entity1 = this.world.getEntityByID(packetIn.getData());
         if (entity1 instanceof PlayerEntity) {
            entity = new FishingBobberEntity(this.world, (PlayerEntity)entity1, d0, d1, d2);
         } else {
            entity = null;
         }
      } else if (entitytype == EntityType.ARROW) {
         entity = new ArrowEntity(this.world, d0, d1, d2);
         Entity entity2 = this.world.getEntityByID(packetIn.getData());
         if (entity2 != null) {
            ((AbstractArrowEntity)entity).setShooter(entity2);
         }
      } else if (entitytype == EntityType.SPECTRAL_ARROW) {
         entity = new SpectralArrowEntity(this.world, d0, d1, d2);
         Entity entity3 = this.world.getEntityByID(packetIn.getData());
         if (entity3 != null) {
            ((AbstractArrowEntity)entity).setShooter(entity3);
         }
      } else if (entitytype == EntityType.TRIDENT) {
         entity = new TridentEntity(this.world, d0, d1, d2);
         Entity entity4 = this.world.getEntityByID(packetIn.getData());
         if (entity4 != null) {
            ((AbstractArrowEntity)entity).setShooter(entity4);
         }
      } else if (entitytype == EntityType.SNOWBALL) {
         entity = new SnowballEntity(this.world, d0, d1, d2);
      } else if (entitytype == EntityType.LLAMA_SPIT) {
         entity = new LlamaSpitEntity(this.world, d0, d1, d2, packetIn.func_218693_g(), packetIn.func_218695_h(), packetIn.func_218692_i());
      } else if (entitytype == EntityType.ITEM_FRAME) {
         entity = new ItemFrameEntity(this.world, new BlockPos(d0, d1, d2), Direction.byIndex(packetIn.getData()));
      } else if (entitytype == EntityType.LEASH_KNOT) {
         entity = new LeashKnotEntity(this.world, new BlockPos(d0, d1, d2));
      } else if (entitytype == EntityType.ENDER_PEARL) {
         entity = new EnderPearlEntity(this.world, d0, d1, d2);
      } else if (entitytype == EntityType.EYE_OF_ENDER) {
         entity = new EyeOfEnderEntity(this.world, d0, d1, d2);
      } else if (entitytype == EntityType.FIREWORK_ROCKET) {
         entity = new FireworkRocketEntity(this.world, d0, d1, d2, ItemStack.EMPTY);
      } else if (entitytype == EntityType.FIREBALL) {
         entity = new FireballEntity(this.world, d0, d1, d2, packetIn.func_218693_g(), packetIn.func_218695_h(), packetIn.func_218692_i());
      } else if (entitytype == EntityType.DRAGON_FIREBALL) {
         entity = new DragonFireballEntity(this.world, d0, d1, d2, packetIn.func_218693_g(), packetIn.func_218695_h(), packetIn.func_218692_i());
      } else if (entitytype == EntityType.SMALL_FIREBALL) {
         entity = new SmallFireballEntity(this.world, d0, d1, d2, packetIn.func_218693_g(), packetIn.func_218695_h(), packetIn.func_218692_i());
      } else if (entitytype == EntityType.WITHER_SKULL) {
         entity = new WitherSkullEntity(this.world, d0, d1, d2, packetIn.func_218693_g(), packetIn.func_218695_h(), packetIn.func_218692_i());
      } else if (entitytype == EntityType.SHULKER_BULLET) {
         entity = new ShulkerBulletEntity(this.world, d0, d1, d2, packetIn.func_218693_g(), packetIn.func_218695_h(), packetIn.func_218692_i());
      } else if (entitytype == EntityType.EGG) {
         entity = new EggEntity(this.world, d0, d1, d2);
      } else if (entitytype == EntityType.EVOKER_FANGS) {
         entity = new EvokerFangsEntity(this.world, d0, d1, d2, 0.0F, 0, (LivingEntity)null);
      } else if (entitytype == EntityType.POTION) {
         entity = new PotionEntity(this.world, d0, d1, d2);
      } else if (entitytype == EntityType.EXPERIENCE_BOTTLE) {
         entity = new ExperienceBottleEntity(this.world, d0, d1, d2);
      } else if (entitytype == EntityType.BOAT) {
         entity = new BoatEntity(this.world, d0, d1, d2);
      } else if (entitytype == EntityType.TNT) {
         entity = new TNTEntity(this.world, d0, d1, d2, (LivingEntity)null);
      } else if (entitytype == EntityType.ARMOR_STAND) {
         entity = new ArmorStandEntity(this.world, d0, d1, d2);
      } else if (entitytype == EntityType.END_CRYSTAL) {
         entity = new EnderCrystalEntity(this.world, d0, d1, d2);
      } else if (entitytype == EntityType.ITEM) {
         entity = new ItemEntity(this.world, d0, d1, d2);
      } else if (entitytype == EntityType.FALLING_BLOCK) {
         entity = new FallingBlockEntity(this.world, d0, d1, d2, Block.getStateById(packetIn.getData()));
      } else if (entitytype == EntityType.AREA_EFFECT_CLOUD) {
         entity = new AreaEffectCloudEntity(this.world, d0, d1, d2);
      } else {
         entity = null;
      }

      if (entity != null) {
         int i = packetIn.getEntityID();
         entity.func_213312_b(d0, d1, d2);
         entity.rotationPitch = (float)(packetIn.getPitch() * 360) / 256.0F;
         entity.rotationYaw = (float)(packetIn.getYaw() * 360) / 256.0F;
         entity.setEntityId(i);
         entity.setUniqueId(packetIn.getUniqueId());
         this.world.addEntity(i, entity);
         if (entity instanceof AbstractMinecartEntity) {
            this.client.getSoundHandler().play(new MinecartTickableSound((AbstractMinecartEntity)entity));
         }
      }

   }

 

 

As one might notice, this method compares the EntityType in the recieved packet with every vanilla EntityType, and if it finds a match, an Entity instance is created by using a constructor of the according class. But since the EntityType of my mob is not equal to any of the listed EntityTypes in that method, it gets assigned to null and because of that doesn't get added to the ClientWorld (see bottom of the method).

This is how I register my entity and the renderer, respectively:

Spoiler
 
 
 
 
Spoiler

 


@SubscribeEvent
public static void registerEntities(RegistryEvent.Register<EntityType<?>> entityTypeRegister)
{
    entityTypeRegister.getRegistry().registerAll(
            EntityType.Builder
                    .<MobBallEntity>create(MobBallEntity::new, EntityClassification.MISC)
                    .size(.25f, .25f)
                    .setCustomClientFactory((entity, world) -> new MobBallEntity(Entities.mob_ball, world)) //I saw this getting used in the SecurityCraft mod, didn't seem to help however...
                    .build("mob_ball") //what does the string here mean anyway?
                    .setRegistryName(MobFighters.getModLocation("mob_ball")));
}

public static void registerRenderers() //in io.github.keheck.mobfighters.registry.ClientRegistry
{
    ItemRenderer renderer = Minecraft.getInstance().getItemRenderer();

    RenderingRegistry.registerEntityRenderingHandler(MobBallEntity.class, manager -> new SpriteRenderer<>(manager, renderer));
}
//gets called by:
public void setupClientStuff(FMLClientSetupEvent event) { ClientRegistry.registerRenderers(); } //in io.github.keheck.mobfighters.MobFighters

public MobFighters()
{
    FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setupClientStuff);
}

    

 

If you want to explore my project yourself, I have a repository on github (it needs to be setup though, see README.md). The latest log can be found here.

 

The question that arises now: How can I [make Minecraft] add the entity to the ClientWorld instance as well? (if the problem is that simple to solve...)

 

Edited by Keheck
fixed typo
Link to comment
Share on other sites

19 minutes ago, Keheck said:

Note: Idk why the hidden contents are so long...

Because of WYSIWYG copy pasting, probably.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

2 hours ago, Keheck said:

How can I [make Minecraft] add the entity to the ClientWorld instance as well?

You need to override Entity::createSpawnPacket and inside use NetworkHooks.getEntitySpawningPacket. I believe this is automatically handled for LivingEntity subclasses. But I'm unsure.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

3 hours ago, Keheck said:

What?

When you copy from a location that has WYSIWYG font support, the forum gobbles up that extra formatting information (and promptly adds 4000 pixels of extra white space).

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

8 hours ago, Animefan8888 said:

You need to override Entity::createSpawnPacket and inside use NetworkHooks.getEntitySpawningPacket. I believe this is automatically handled for LivingEntity subclasses. But I'm unsure.

Yes, that was it! Thank you, now I can go and run into new problems as I move on :D

Edited by Keheck
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.