package openmods.tileentity;
import io.netty.buffer.ByteBuf;
import java.io.IOException;
import java.util.Set;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.Packet;
import openmods.Log;
import openmods.network.rpc.IRpcTarget;
import openmods.network.rpc.RpcCallDispatcher;
import openmods.network.rpc.targets.SyncRpcTarget;
import openmods.network.senders.IPacketSender;
import openmods.reflection.TypeUtils;
import openmods.sync.ISyncListener;
import openmods.sync.ISyncMapProvider;
import openmods.sync.ISyncableObject;
import openmods.sync.SyncChannelHolder;
import openmods.sync.SyncMap;
import openmods.sync.SyncMapTile;
import openmods.sync.SyncObjectScanner;
import openmods.sync.drops.DropTagSerializer;
public abstract class SyncedTileEntity extends OpenTileEntity implements ISyncMapProvider {
protected SyncMapTile<SyncedTileEntity> syncMap;
private DropTagSerializer tagSerializer;
public SyncedTileEntity() {
syncMap = new SyncMapTile<SyncedTileEntity>(this);
createSyncedFields();
SyncObjectScanner.INSTANCE.registerAllFields(syncMap, this);
syncMap.addSyncListener(new ISyncListener() {
@Override
public void onSync(Set<ISyncableObject> changes) {
markUpdated();
}
});
}
protected DropTagSerializer getDropSerializer() {
if (tagSerializer == null) tagSerializer = new DropTagSerializer();
return tagSerializer;
}
protected ISyncListener createRenderUpdateListener() {
return new ISyncListener() {
@Override
public void onSync(Set<ISyncableObject> changes) {
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
};
}
protected ISyncListener createRenderUpdateListener(final ISyncableObject target) {
return new ISyncListener() {
@Override
public void onSync(Set<ISyncableObject> changes) {
if (changes.contains(target)) worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
};
}
protected abstract void createSyncedFields();
public void addSyncedObject(String name, ISyncableObject obj) {
syncMap.put(name, obj);
}
public void sync() {
syncMap.sync();
}
@Override
public SyncMap<SyncedTileEntity> getSyncMap() {
return syncMap;
}
@Override
public Packet getDescriptionPacket() {
try {
ByteBuf payload = syncMap.createPayload(true);
return SyncChannelHolder.createPacket(payload);
} catch (IOException e) {
Log.severe(e, "Error during description packet creation");
return null;
}
}
@Override
public void writeToNBT(NBTTagCompound tag) {
super.writeToNBT(tag);
syncMap.writeToNBT(tag);
}
@Override
public void readFromNBT(NBTTagCompound tag) {
super.readFromNBT(tag);
syncMap.readFromNBT(tag);
}
public <T> T createRpcProxy(ISyncableObject object, Class<? extends T> mainIntf, Class<?>... extraIntf) {
TypeUtils.isInstance(object, mainIntf, extraIntf);
IRpcTarget target = new SyncRpcTarget.SyncTileEntityRpcTarget(this, object);
final IPacketSender sender = RpcCallDispatcher.INSTANCE.senders.client;
return RpcCallDispatcher.INSTANCE.createProxy(target, sender, mainIntf, extraIntf);
}
}