paletted contraptions
- use minecraft's palette-map during serialization and deserialization to reduce compound size in most cases - also update the placement_indicator sprite sheet
This commit is contained in:
parent
bec13b8e7d
commit
159e298e8b
4 changed files with 110 additions and 56 deletions
|
@ -28,11 +28,7 @@ import com.simibubi.create.content.logistics.block.inventories.AdjustableCrateBl
|
||||||
import com.simibubi.create.content.logistics.block.redstone.RedstoneContactBlock;
|
import com.simibubi.create.content.logistics.block.redstone.RedstoneContactBlock;
|
||||||
import com.simibubi.create.foundation.config.AllConfigs;
|
import com.simibubi.create.foundation.config.AllConfigs;
|
||||||
import com.simibubi.create.foundation.fluid.CombinedTankWrapper;
|
import com.simibubi.create.foundation.fluid.CombinedTankWrapper;
|
||||||
import com.simibubi.create.foundation.utility.BlockFace;
|
import com.simibubi.create.foundation.utility.*;
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
|
||||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
|
||||||
import com.simibubi.create.foundation.utility.NBTProcessors;
|
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
|
||||||
import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld;
|
import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld;
|
||||||
import net.minecraft.block.*;
|
import net.minecraft.block.*;
|
||||||
import net.minecraft.block.material.PushReaction;
|
import net.minecraft.block.material.PushReaction;
|
||||||
|
@ -41,6 +37,7 @@ import net.minecraft.fluid.Fluids;
|
||||||
import net.minecraft.fluid.IFluidState;
|
import net.minecraft.fluid.IFluidState;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.nbt.INBT;
|
||||||
import net.minecraft.nbt.ListNBT;
|
import net.minecraft.nbt.ListNBT;
|
||||||
import net.minecraft.nbt.NBTUtil;
|
import net.minecraft.nbt.NBTUtil;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
|
@ -55,6 +52,7 @@ import net.minecraft.util.Rotation;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.util.palette.PaletteHashMap;
|
||||||
import net.minecraft.world.IWorld;
|
import net.minecraft.world.IWorld;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||||
|
@ -67,6 +65,7 @@ import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
|
||||||
import net.minecraftforge.fluids.capability.templates.FluidTank;
|
import net.minecraftforge.fluids.capability.templates.FluidTank;
|
||||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||||
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||||
|
import net.minecraftforge.registries.GameData;
|
||||||
import org.apache.commons.lang3.tuple.MutablePair;
|
import org.apache.commons.lang3.tuple.MutablePair;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
@ -595,51 +594,16 @@ public abstract class Contraption {
|
||||||
presentTileEntities.clear();
|
presentTileEntities.clear();
|
||||||
renderedTileEntities.clear();
|
renderedTileEntities.clear();
|
||||||
|
|
||||||
nbt.getList("Blocks", 10)
|
INBT blocks = nbt.get("Blocks");
|
||||||
.forEach(c -> {
|
//used to differentiate between the 'old' and the paletted serialization
|
||||||
CompoundNBT comp = (CompoundNBT) c;
|
boolean usePalettedDeserialization = blocks != null && blocks.getId() == 10 && ((CompoundNBT) blocks).contains("Palette");
|
||||||
BlockInfo info = new BlockInfo(NBTUtil.readBlockPos(comp.getCompound("Pos")),
|
readBlocksCompound(blocks, world, usePalettedDeserialization);
|
||||||
NBTUtil.readBlockState(comp.getCompound("Block")),
|
|
||||||
comp.contains("Data") ? comp.getCompound("Data") : null);
|
|
||||||
blocks.put(info.pos, info);
|
|
||||||
|
|
||||||
if (world.isRemote) {
|
|
||||||
Block block = info.state.getBlock();
|
|
||||||
CompoundNBT tag = info.nbt;
|
|
||||||
MovementBehaviour movementBehaviour = AllMovementBehaviours.of(block);
|
|
||||||
if (tag == null || (movementBehaviour != null && movementBehaviour.hasSpecialMovementRenderer()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
tag.putInt("x", info.pos.getX());
|
|
||||||
tag.putInt("y", info.pos.getY());
|
|
||||||
tag.putInt("z", info.pos.getZ());
|
|
||||||
|
|
||||||
TileEntity te = TileEntity.create(tag);
|
|
||||||
if (te == null)
|
|
||||||
return;
|
|
||||||
te.setLocation(new WrappedWorld(world) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getBlockState(BlockPos pos) {
|
|
||||||
if (!pos.equals(te.getPos()))
|
|
||||||
return Blocks.AIR.getDefaultState();
|
|
||||||
return info.state;
|
|
||||||
}
|
|
||||||
|
|
||||||
}, te.getPos());
|
|
||||||
if (te instanceof KineticTileEntity)
|
|
||||||
((KineticTileEntity) te).setSpeed(0);
|
|
||||||
te.getBlockState();
|
|
||||||
presentTileEntities.put(info.pos, te);
|
|
||||||
renderedTileEntities.add(te);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
actors.clear();
|
actors.clear();
|
||||||
nbt.getList("Actors", 10)
|
nbt.getList("Actors", 10)
|
||||||
.forEach(c -> {
|
.forEach(c -> {
|
||||||
CompoundNBT comp = (CompoundNBT) c;
|
CompoundNBT comp = (CompoundNBT) c;
|
||||||
BlockInfo info = blocks.get(NBTUtil.readBlockPos(comp.getCompound("Pos")));
|
BlockInfo info = this.blocks.get(NBTUtil.readBlockPos(comp.getCompound("Pos")));
|
||||||
MovementContext context = MovementContext.readNBT(world, info, comp, this);
|
MovementContext context = MovementContext.readNBT(world, info, comp, this);
|
||||||
getActors().add(MutablePair.of(info, context));
|
getActors().add(MutablePair.of(info, context));
|
||||||
});
|
});
|
||||||
|
@ -704,15 +668,8 @@ public abstract class Contraption {
|
||||||
public CompoundNBT writeNBT(boolean spawnPacket) {
|
public CompoundNBT writeNBT(boolean spawnPacket) {
|
||||||
CompoundNBT nbt = new CompoundNBT();
|
CompoundNBT nbt = new CompoundNBT();
|
||||||
nbt.putString("Type", getType().id);
|
nbt.putString("Type", getType().id);
|
||||||
ListNBT blocksNBT = new ListNBT();
|
|
||||||
for (BlockInfo block : this.blocks.values()) {
|
CompoundNBT blocksNBT = writeBlocksCompound();
|
||||||
CompoundNBT c = new CompoundNBT();
|
|
||||||
c.put("Block", NBTUtil.writeBlockState(block.state));
|
|
||||||
c.put("Pos", NBTUtil.writeBlockPos(block.pos));
|
|
||||||
if (block.nbt != null)
|
|
||||||
c.put("Data", block.nbt);
|
|
||||||
blocksNBT.add(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
ListNBT actorsNBT = new ListNBT();
|
ListNBT actorsNBT = new ListNBT();
|
||||||
for (MutablePair<BlockInfo, MovementContext> actor : getActors()) {
|
for (MutablePair<BlockInfo, MovementContext> actor : getActors()) {
|
||||||
|
@ -789,6 +746,100 @@ public abstract class Contraption {
|
||||||
return nbt;
|
return nbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CompoundNBT writeBlocksCompound() {
|
||||||
|
CompoundNBT compound = new CompoundNBT();
|
||||||
|
PaletteHashMap<BlockState> palette = new PaletteHashMap<>(GameData.getBlockStateIDMap(), 16, (i, s) -> {throw new IllegalStateException("Palette Map index exceeded maximum");}, NBTUtil::readBlockState, NBTUtil::writeBlockState);
|
||||||
|
ListNBT blockList = new ListNBT();
|
||||||
|
|
||||||
|
for (BlockInfo block : this.blocks.values()) {
|
||||||
|
int id = palette.idFor(block.state);
|
||||||
|
CompoundNBT c = new CompoundNBT();
|
||||||
|
c.putLong("Pos", block.pos.toLong());
|
||||||
|
c.putInt("State", id);
|
||||||
|
if (block.nbt != null)
|
||||||
|
c.put("Data", block.nbt);
|
||||||
|
blockList.add(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
ListNBT paletteNBT = new ListNBT();
|
||||||
|
palette.writePaletteToList(paletteNBT);
|
||||||
|
compound.put("Palette", paletteNBT);
|
||||||
|
compound.put("BlockList", blockList);
|
||||||
|
|
||||||
|
return compound;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readBlocksCompound(INBT compound, World world, boolean usePalettedDeserialization) {
|
||||||
|
PaletteHashMap<BlockState> palette = null;
|
||||||
|
ListNBT blockList;
|
||||||
|
if (usePalettedDeserialization) {
|
||||||
|
CompoundNBT c = ((CompoundNBT) compound);
|
||||||
|
palette = new PaletteHashMap<>(GameData.getBlockStateIDMap(), 16, (i, s) -> {throw new IllegalStateException("Palette Map index exceeded maximum");}, NBTUtil::readBlockState, NBTUtil::writeBlockState);
|
||||||
|
palette.read(c.getList("Palette", 10));
|
||||||
|
|
||||||
|
blockList = c.getList("BlockList", 10);
|
||||||
|
} else {
|
||||||
|
blockList = (ListNBT) compound;
|
||||||
|
}
|
||||||
|
|
||||||
|
PaletteHashMap<BlockState> finalPalette = palette;
|
||||||
|
blockList.forEach(e -> {
|
||||||
|
CompoundNBT c = (CompoundNBT) e;
|
||||||
|
|
||||||
|
BlockInfo info = usePalettedDeserialization ? readBlockInfo(c, finalPalette) : legacyReadBlockInfo(c);
|
||||||
|
|
||||||
|
this.blocks.put(info.pos, info);
|
||||||
|
|
||||||
|
if (world.isRemote) {
|
||||||
|
Block block = info.state.getBlock();
|
||||||
|
CompoundNBT tag = info.nbt;
|
||||||
|
MovementBehaviour movementBehaviour = AllMovementBehaviours.of(block);
|
||||||
|
if (tag == null || (movementBehaviour != null && movementBehaviour.hasSpecialMovementRenderer()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
tag.putInt("x", info.pos.getX());
|
||||||
|
tag.putInt("y", info.pos.getY());
|
||||||
|
tag.putInt("z", info.pos.getZ());
|
||||||
|
|
||||||
|
TileEntity te = TileEntity.create(tag);
|
||||||
|
if (te == null)
|
||||||
|
return;
|
||||||
|
te.setLocation(new WrappedWorld(world) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlockState(BlockPos pos) {
|
||||||
|
if (!pos.equals(te.getPos()))
|
||||||
|
return Blocks.AIR.getDefaultState();
|
||||||
|
return info.state;
|
||||||
|
}
|
||||||
|
|
||||||
|
}, te.getPos());
|
||||||
|
if (te instanceof KineticTileEntity)
|
||||||
|
((KineticTileEntity) te).setSpeed(0);
|
||||||
|
te.getBlockState();
|
||||||
|
presentTileEntities.put(info.pos, te);
|
||||||
|
renderedTileEntities.add(te);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BlockInfo readBlockInfo(CompoundNBT blockListEntry, PaletteHashMap<BlockState> palette) {
|
||||||
|
return new BlockInfo(
|
||||||
|
BlockPos.fromLong(blockListEntry.getLong("Pos")),
|
||||||
|
Objects.requireNonNull(palette.get(blockListEntry.getInt("State"))),
|
||||||
|
blockListEntry.contains("Data") ? blockListEntry.getCompound("Data") : null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BlockInfo legacyReadBlockInfo(CompoundNBT blockListEntry) {
|
||||||
|
return new BlockInfo(
|
||||||
|
NBTUtil.readBlockPos(blockListEntry.getCompound("Pos")),
|
||||||
|
NBTUtil.readBlockState(blockListEntry.getCompound("Block")),
|
||||||
|
blockListEntry.contains("Data") ? blockListEntry.getCompound("Data") : null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public void removeBlocksFromWorld(World world, BlockPos offset) {
|
public void removeBlocksFromWorld(World world, BlockPos offset) {
|
||||||
storage.values()
|
storage.values()
|
||||||
.forEach(MountedStorage::removeStorageFromWorld);
|
.forEach(MountedStorage::removeStorageFromWorld);
|
||||||
|
|
|
@ -79,7 +79,7 @@ public enum AllGuiTextures {
|
||||||
INDICATOR_RED("widgets.png", 72, 18, 18, 6),
|
INDICATOR_RED("widgets.png", 72, 18, 18, 6),
|
||||||
|
|
||||||
// PlacementIndicator
|
// PlacementIndicator
|
||||||
PLACEMENT_INDICATOR_SHEET("placement_indicator.png", 0, 0, 256, 256);
|
PLACEMENT_INDICATOR_SHEET("placement_indicator.png", 0, 0, 16, 256);
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -26,4 +26,7 @@ public net.minecraft.world.server.ServerTickList field_205374_d # pendingTickLis
|
||||||
public net.minecraft.world.server.ServerTickList field_205375_e # pendingTickListEntriesTreeSet
|
public net.minecraft.world.server.ServerTickList field_205375_e # pendingTickListEntriesTreeSet
|
||||||
|
|
||||||
# GameRenderer
|
# GameRenderer
|
||||||
public net.minecraft.client.renderer.GameRenderer func_215311_a(Lnet/minecraft/client/renderer/ActiveRenderInfo;FZ)D #getFOVModifier
|
public net.minecraft.client.renderer.GameRenderer func_215311_a(Lnet/minecraft/client/renderer/ActiveRenderInfo;FZ)D #getFOVModifier
|
||||||
|
|
||||||
|
# IResizeCallback
|
||||||
|
public net.minecraft.util.palette.IResizeCallback
|
Binary file not shown.
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.3 KiB |
Loading…
Reference in a new issue