Posted August 31, 20241 yr Hello! I was trying to create a mob which has two different textures: "red" and "black". It should be chosen randomly when the mob spawns and then never change. I had to find some way to save data about the variant of the mob when player go out from the game. I thought that using read/addAdditionalSaveData can help, but nothing has changed, it still doesn't remember what color each mob had. Did I something wrong? Here are methods in MyEntity class, related to the problem: private final static EntityDataAccessor<String> DATA_VARIANT_NAME = SynchedEntityData.defineId(MyEntity.class, EntityDataSerializers.STRING); //Entity variant is set in constructor public MyEntity(EntityType<? extends Animal> pEntityType, Level pLevel) { super(pEntityType, pLevel); setMyEntityVariant(RandomMyEntityVariant()); } @Override protected void defineSynchedData() { super.defineSynchedData(); this.entityData.define(DATA_VARIANT_NAME, RandomMyEntityVariant().getSerializedName()); } public static enum MyEntityVariant implements StringRepresentable{ RED("red"), BLACK("black"); private final String name; private MyEntityVariant(String name){ this.name = name; } @Override public String getSerializedName() { return name; } public static MyEntityVariant byName(String pName) { if (Objects.equals(pName, "black")){ return BLACK; } else return RED; } } private MyEntityVariant RandomMyEntityVariant(){ switch (this.random.nextIntBetweenInclusive(1,2)){ case 1: return MyEntityVariant.BLACK; default: return MyEntityVariant.RED; } } public MyEntityVariant getMyEntityVariant(){ return MyEntityVariant.byName(this.entityData.get(DATA_VARIANT_NAME)); } public void setMyEntityVariant(MyEntityVariant variant){ this.entityData.set(DATA_VARIANT_NAME,variant.getSerializedName()); } @Override public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putString("MyEntityVariant",this.getVariant().getSerializedName()); } @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.setMyEntityVariant(MyEntityVariant.byName(pCompound.getString("MyEntityVariant"))); } Maybe, I should call SetMyEntityVariant somewhere in another place?
August 31, 20241 yr You could store your variant as a plain string, then implement IEntityAdditionalSpawnData, and write and read your string to the client there. Then just read and write your string inside read/addAdditionalSaveData
September 1, 20241 yr Author 9 hours ago, Xoroshio said: You could store your variant as a plain string, then implement IEntityAdditionalSpawnData, and write and read your string to the client there. Then just read and write your string inside read/addAdditionalSaveData Thank you! So I mustn't to use EntityData to store the variant? Also, when implementing IEntityAdditionalSpawnData I must override two additional methods (write/readSpawnData). Should I write and read my string in two places (write/readSpawnData and read/addAdditionalSaveData)?
September 1, 20241 yr no you dont need EntityData, and yes, read and write your string in the read/writeSpawn data
September 1, 20241 yr Author 55 minutes ago, Xoroshio said: no you dont need EntityData, and yes, read and write your string in the read/writeSpawn data Something still goes wrong. I've changed my code: added new field Variant, which also is set randomly in constructor. Here are my write/readSpawnData: @Override public void writeSpawnData(FriendlyByteBuf friendlyByteBuf) { System.out.print("WRITING"); friendlyByteBuf.writeEnum(this.getVariant()); } @Override public void readSpawnData(FriendlyByteBuf friendlyByteBuf) { System.out.print("READING"); friendlyByteBuf.readEnum(MyEntityType.class); } But in my log WRITING or READING never appears. So when these methods should be called?
September 1, 20241 yr I should be working, I’m not sure what’s going on. Have you registered the entity, and are you spawning it in the world? Also, you need to do variant = friendlyByteBuff.readEnum(MyEntityType.class); currently you are just reading the data and not doing anything with it, but that’s a minor problem compared to the methods not firing. The read and write spawn data methods are called automatically by the games client packet manager.
September 1, 20241 yr Ok here is some code that I think might do the job public class MyEntity extends Animal { // 0 : black // 1 : red private int colorId; public MyEntity(EntityType<? extends Animal> pEntityType, Level pLevel) { super(pEntityType, pLevel); colourId = pLevel.random().nextInt(0,1); } @Override public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("MyEntityVariant",colourId); } @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); colorId = pCompound.getInt(“MyEntityVarient”); } public Packet<ClientGamePacketListener> getAddEntityPacket() { return new ClientboundAddEntityPacket(this, colourId); } public void recreateFromPacket(ClientboundAddEntityPacket packet) { super.recreateFromPacket(packet); colorId = packet.getData(); } } Edited September 1, 20241 yr by Xoroshio
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.