I have create a new capability for PlayerEntity and I want to know how can I sync the data from server to client ?
my Interface IXiuXianState.java
package egod.mc.lingkiworld.capabilities;
public interface IXiuXianState {
public Realm getRealm();
public void setRealm(Realm newRealm);
public float getXiuWei();
public void setXiuWei(float newValue);
public void addXiuWei(float delta);
public float getMagic();
public void setMagic(float value);
public void healMagic();
public void costMagic(float value);
public float getMaxMagic();
public void setMaxMagic(float value);
public void copyForRespawn(IXiuXianState deadPlayer);
}
implementation of the interface XiuXianStateClass.java
package egod.mc.lingkiworld.capabilities;
import net.minecraft.entity.player.PlayerEntity;
public class XiuXianStateClass implements IXiuXianState {
private Realm realm;
private float xiuWei;
private float magic;
private float maxMagic;
public XiuXianStateClass(){
realm = Realm.FANREN;
xiuWei = 0f;
magic = 0f;
maxMagic = 0f;
}
@Override
public Realm getRealm() {
return realm;
}
@Override
public void setRealm(Realm newRealm) {
this.realm = newRealm;
}
@Override
public float getXiuWei() {
return xiuWei;
}
@Override
public void setXiuWei(float newValue) {
this.xiuWei = newValue;
}
@Override
public void addXiuWei(float delta) {
this.xiuWei += delta;
this.magic += delta;
this.maxMagic += delta;
}
@Override
public float getMagic() {
return magic;
}
@Override
public void setMagic(float value) {
this.magic = value;
}
@Override
public void healMagic() {
magic += maxMagic/20f;
}
@Override
public void costMagic(float value) {
magic -= value;
}
@Override
public float getMaxMagic() {
return maxMagic;
}
@Override
public void setMaxMagic(float value) {
this.maxMagic = value;
}
public static IXiuXianState getFromPlayer(PlayerEntity player){
return player
.getCapability(XiuXianStateProvider.XiuXianStateCap,null)
.orElseThrow(()->new IllegalArgumentException("LazyOptional must be not empty!"));
}
@Override
public void copyForRespawn(IXiuXianState deadPlayer){
this.setRealm(deadPlayer.getRealm());
this.setXiuWei(deadPlayer.getXiuWei());
this.setMagic(deadPlayer.getMaxMagic());
this.setMaxMagic(deadPlayer.getMaxMagic());
}
}
Storage for that XiuXianStateProvider.java
package egod.mc.lingkiworld.capabilities;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.INBT;
import net.minecraft.util.Direction;
import net.minecraftforge.common.capabilities.Capability;
import javax.annotation.Nullable;
public class XiuXianStateStorage implements Capability.IStorage<IXiuXianState> {
@Nullable
@Override
public INBT writeNBT(Capability<IXiuXianState> capability, IXiuXianState instance, Direction side) {
CompoundNBT tag =new CompoundNBT();
tag.putString("realm", instance.getRealm().name);
tag.putFloat("xiuWei", instance.getXiuWei());
tag.putFloat("magic", instance.getMagic());
tag.putFloat("maxMagic", instance.getMaxMagic());
return tag;
}
@Override
public void readNBT(Capability<IXiuXianState> capability, IXiuXianState instance, Direction side, INBT nbt) {
CompoundNBT tag = (CompoundNBT)nbt;
instance.setRealm(Realm.fromName(tag.getString("realm")));
instance.setXiuWei(tag.getFloat("xiuWei"));
instance.setMagic(tag.getFloat("magic"));
instance.setMaxMagic(tag.getFloat("maxMagic"));
}
}
Provider for that XiuXianStateProvider.java
package egod.mc.lingkiworld.capabilities;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
import net.minecraftforge.common.util.LazyOptional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class XiuXianStateProvider implements ICapabilitySerializable<CompoundNBT> {
@CapabilityInject(IXiuXianState.class)
public static final Capability<IXiuXianState> XiuXianStateCap=null;
private LazyOptional<IXiuXianState> instance = LazyOptional.of(XiuXianStateClass::new);
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
if(cap != XiuXianStateCap){
return LazyOptional.empty();
}
return this.instance.cast();
}
@Override
public CompoundNBT serializeNBT() {
return (CompoundNBT)XiuXianStateCap.getStorage()
.writeNBT(XiuXianStateCap,
instance
.orElseThrow(()->new IllegalArgumentException("LazyOptional must not be empty!")),
null);
}
@Override
public void deserializeNBT(CompoundNBT nbt) {
XiuXianStateCap.getStorage()
.readNBT(XiuXianStateCap,
instance
.orElseThrow(()->new IllegalArgumentException("LazyOptional must not be empty!")),
null, nbt);
}
}
And here is my package XiuXianStateSyncMessage.java , but it does not work.
package egod.mc.lingkiworld.network;
import egod.mc.lingkiworld.capabilities.CapabilityLoader;
import egod.mc.lingkiworld.capabilities.IXiuXianState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fml.network.NetworkEvent;
import java.util.function.Supplier;
public class XiuXianStateSyncMessage {
private CompoundNBT data;
XiuXianStateSyncMessage(PacketBuffer buf) {
this.data = buf.readCompoundTag();
}
public XiuXianStateSyncMessage(CompoundNBT nbt) {
this.data = nbt;
}
void encode(PacketBuffer buf) {
buf.writeCompoundTag(data);
}
void handle(Supplier<NetworkEvent.Context> context) {
NetworkEvent.Context ctx = context.get();
ctx.enqueueWork(() -> {
if (ctx.getDirection().getReceptionSide().isClient() && ctx.getDirection().getOriginationSide().isServer()) {
PlayerEntity player = Minecraft.getInstance().player;
player.getCapability(CapabilityLoader.XiuXianState, null)
.ifPresent(state -> {
Capability.IStorage<IXiuXianState> storage = CapabilityLoader.XiuXianState.getStorage();
storage.readNBT(CapabilityLoader.XiuXianState, state, null, data);
});
}
});
ctx.setPacketHandled(true);
}
}
This is really long, but thanks if you can help me!