Hello, been trying to learn recently and network has been stalling my progress for some time now. I've been avoiding it but I don't think I can much more
Anyway, basically, when any entity dies, the server will listen to that event and change a value inside an entity, this value should then be updated to the client
Maybe, probably, the problem isn't really in the network code. But I'd appreciate feedback on it since I'm not sure if I'm doing it properly
This is the intended workflow:
1. A player spawns an entity in the world, EntityBank
2. A death event occurs - onEntityLivingDeath(LivingDeathEvent event) is called
2.1 Inside the method for the event, (which I noticed is only called in the server), the server checks for entities inside a radius around the position where the death occurred, and if it finds an instance of EntityBank, it calls the method entityBank.add(x);
3. The method entityBank.add(int i) increments a value inside EntityBank called storage. (this value is saved/loaded to nbt)
4. So far it's all good, everything happened well on the server side, but now the client is supposed to know about all this, I made Message and MessageHandler classes to communicate the change to all players, and I believe the issue is here.
Cleaned up code: (to show what is relevant)
EntityBank:
public class EntityBank extends EntityFlying {
private int stored;
public EntityBank(World world) {
super(world);
setSize(0.5f, 0.5f);
}
public void add(int inc) {
stored += inc;
System.out.println("~~~ storage was increased by " + inc);
}
public void updateClients() {
NBTTagCompound ntc = new NBTTagCompound();
ntc.setInteger("s", stored);
ntc.setInteger("e", getEntityId());
StorageMessage message = new StorageMessage(ntc);
System.out.println("Sending message to clients.");
MyMod.networkWrapper.sendToAll(message);
}
@Override
protected boolean interact(EntityPlayer player) {
System.out.println(stored); // server prints the correct value, client doesn't (after restarting the server/world)
return false;
}
@Override
public void readEntityFromNBT(NBTTagCompound ntc) {
super.readEntityFromNBT(ntc);
stored = ntc.getInteger("stored");
}
@Override
public void writeEntityToNBT(NBTTagCompound ntc) {
super.writeEntityToNBT(ntc);
ntc.setInteger("stored", stored);
}
}
The EventHandler:
public class EventHandler {
private static final float DEATH_RANGE = 10f;
@SubscribeEvent
public void onEntityLivingDeath(LivingDeathEvent event) {
Entity entity = event.entity;
if (entity instanceof EntityLiving) {
int inc = 10; // ...
if (inc > 0) {
AxisAlignedBB radiusBB = AxisAlignedBB.getBoundingBox
(entity.posX - DEATH_RANGE, entity.posY - DEATH_RANGE, entity.posZ - DEATH_RANGE,
entity.posX + DEATH_RANGE, entity.posY + DEATH_RANGE, entity.posZ + DEATH_RANGE);
Entity closestEntity = Utils.selectNearestEntityWithinAABB(entity.worldObj, Entity.class, radiusBB, entity,
(ent) -> ent instanceof EntityBank);
if (closestEntity != null) {
System.out.println("Found an EntityBank nearby... adding to storage: " + inc);
((EntityBank) closestEntity).add(inc);
((EntityBank) closestEntity).updateClients();
}
}
}
}
}
StorageMessage (probably not important?)
public class StorageMessage implements IMessage {
public NBTTagCompound stackTagCompound;
public StorageMessage() {
}
public StorageMessage(NBTTagCompound stackTagCompound) {
this.stackTagCompound = stackTagCompound;
}
@Override
public void fromBytes(ByteBuf buf) {
stackTagCompound = ByteBufUtils.readTag(buf);
}
@Override
public void toBytes(ByteBuf buf) {
ByteBufUtils.writeTag(buf, stackTagCompound);
}
}
StorageMessageHandler
public class StorageMessageHandler implements IMessageHandler<StorageMessage, IMessage> {
@Override
public IMessage onMessage(StorageMessage message, MessageContext ctx) {
NBTTagCompound ntc = message.stackTagCompound;
int id = ntc.getInteger("e");
System.out.println("Received storage message!"); // this gets printed
for (Object obj : Minecraft.getMinecraft().theWorld.loadedEntityList) {
Entity ent = (Entity) obj;
if (id == ent.getEntityId()) {
System.out.println("Entity found! Updating storage..."); // all good here too
((EntityBank) ent).add(ntc.getInteger("s"));
break;
}
}
return null;
}
}
The network message/handler etc is all registered.
The client does receive the message, the entity gets update (if I interact with the entity, it shows the correct stored value)
but as soons as I leave the world (shutting down the server) and re-enter it again, the information on the client side is no longer in accordance to the server.
I'm probably missing something really stupid, just have no idea what it is, have only got to modding recently too.
Why does the value on the client side reset when I rejoin? Shouldn't things that are loaded on NBT be passed back to the client when he joins the world so he gets the updated information on an entity? What should happen here?
And lastly, what do you think of my network code? It looks a bit network intensive/inneficient to me
Any help is appreciated