Unicopia/src/main/java/com/minelittlepony/unicopia/container/SpellbookState.java

129 lines
3.9 KiB
Java

package com.minelittlepony.unicopia.container;
import java.util.*;
import java.util.function.Consumer;
import com.minelittlepony.unicopia.network.datasync.Synchronizable;
import com.minelittlepony.unicopia.util.NbtSerialisable;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper;
public class SpellbookState extends Synchronizable<SpellbookState> implements NbtSerialisable {
private Optional<Identifier> currentPageId = Optional.empty();
private boolean dirty;
private final Map<Identifier, PageState> states = new HashMap<>();
public boolean isDirty() {
boolean isDirty = dirty;
dirty = false;
return isDirty;
}
public Optional<Identifier> getCurrentPageId() {
return currentPageId;
}
public void setCurrentPageId(Identifier pageId) {
currentPageId = Optional.ofNullable(pageId);
synchronize();
}
public PageState getState(Identifier pageId) {
return states.computeIfAbsent(pageId, i -> new PageState(page -> synchronize()));
}
@Override
public void copyFrom(SpellbookState state) {
currentPageId = state.currentPageId;
state.states.forEach((id, page) -> getState(id).copyFrom(page));
dirty = true;
}
public void toPacket(PacketByteBuf buf) {
buf.writeOptional(currentPageId, PacketByteBuf::writeIdentifier);
buf.writeMap(states, PacketByteBuf::writeIdentifier, (b, v) -> v.toPacket(b));
}
public SpellbookState fromPacket(PacketByteBuf buf) {
currentPageId = buf.readOptional(PacketByteBuf::readIdentifier);
buf.readMap(PacketByteBuf::readIdentifier, b -> new PageState(page -> synchronize()).fromPacket(b)).forEach((id, state) -> {
getState(id).copyFrom(state);
});
return this;
}
@Override
public void toNBT(NbtCompound compound) {
currentPageId.ifPresent(id -> compound.putString("current_page", id.toString()));
NbtCompound states = new NbtCompound();
compound.put("states", states);
this.states.forEach((id, page) -> {
states.put(id.toString(), page.toNBT());
});
}
@Override
public void fromNBT(NbtCompound compound) {
currentPageId = compound.contains("current_page", NbtElement.STRING_TYPE) ? Optional.ofNullable(Identifier.tryParse(compound.getString("current_page"))) : Optional.empty();
NbtCompound states = compound.getCompound("states");
states.getKeys().stream().forEach(key -> {
Identifier id = Identifier.tryParse(key);
if (id != null) {
getState(id).fromNBT(states.getCompound(key));
}
});
}
public static class PageState extends Synchronizable<PageState> implements NbtSerialisable {
private int offset;
public PageState() {}
PageState(Consumer<PageState> synchronizer) {
setSynchronizer(synchronizer);
}
@Override
public void copyFrom(PageState other) {
offset = other.offset;
}
public void setOffset(int offset) {
this.offset = offset;
synchronize();
}
public int getOffset() {
return offset;
}
public void swap(int incr, int max) {
setOffset(MathHelper.clamp(getOffset() + incr, 0, max - 1));
}
public void toPacket(PacketByteBuf buf) {
buf.writeInt(offset);
}
public PageState fromPacket(PacketByteBuf buf) {
offset = buf.readInt();
return this;
}
@Override
public void toNBT(NbtCompound compound) {
compound.putInt("offset", offset);
}
@Override
public void fromNBT(NbtCompound compound) {
offset = compound.getInt("offset");
}
}
}