GsE-26 Posted August 31 Posted August 31 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? Quote
Xoroshio Posted August 31 Posted August 31 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 1 Quote
GsE-26 Posted September 1 Author Posted September 1 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)? Quote
Xoroshio Posted September 1 Posted September 1 no you dont need EntityData, and yes, read and write your string in the read/writeSpawn data 1 Quote
GsE-26 Posted September 1 Author Posted September 1 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? Quote
Xoroshio Posted September 1 Posted September 1 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. Quote
Xoroshio Posted September 1 Posted September 1 (edited) 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 by Xoroshio Quote
Recommended Posts
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.