start chunk save and load
parent
c66c09b8ac
commit
916fb380ea
|
@ -2,7 +2,7 @@ package com.github.halotroop.litecraft.logic;
|
|||
|
||||
import tk.valoeghese.sod.BinaryData;
|
||||
|
||||
public interface StoredData {
|
||||
public interface DataStorage {
|
||||
void read(BinaryData data);
|
||||
void write(BinaryData data);
|
||||
}
|
|
@ -1,18 +1,24 @@
|
|||
package com.github.halotroop.litecraft.types.block;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import com.github.hydos.ginger.engine.obj.ModelLoader;
|
||||
import com.github.hydos.ginger.engine.render.models.TexturedModel;
|
||||
|
||||
public class Block
|
||||
{
|
||||
public static final Block AIR = new Block(new Properties().visible(false));
|
||||
public static final Block DIRT = new Block("block/cubes/soil/dirt.png", new Properties());
|
||||
public static final Block STONE = new Block("block/cubes/stone/basic/gneiss.png", new Properties());
|
||||
|
||||
public static final Block AIR = new Block(new Properties("air").visible(false));
|
||||
public static final Block DIRT = new Block("block/cubes/soil/dirt.png", new Properties("dirt"));
|
||||
public static final Block STONE = new Block("block/cubes/stone/basic/gneiss.png", new Properties("stone"));
|
||||
|
||||
public static class Properties
|
||||
{ // add properties to this builder!
|
||||
private boolean visible = true;
|
||||
private boolean fullCube = true;
|
||||
private final String identifier;
|
||||
|
||||
public Properties(String identifier)
|
||||
{ this.identifier = identifier; }
|
||||
|
||||
public Properties fullCube(boolean fullCube)
|
||||
{
|
||||
|
@ -20,21 +26,22 @@ public class Block
|
|||
return this;
|
||||
}
|
||||
|
||||
public boolean isFullCube()
|
||||
{ return fullCube; }
|
||||
|
||||
public boolean isVisible()
|
||||
{ return visible; }
|
||||
|
||||
public Properties visible(boolean visible)
|
||||
{
|
||||
this.visible = visible;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public final TexturedModel model;
|
||||
public final boolean visible;
|
||||
private final boolean visible, fullCube;
|
||||
public final String identifier;
|
||||
|
||||
public boolean isFullCube()
|
||||
{ return this.fullCube; }
|
||||
|
||||
public boolean isVisible()
|
||||
{ return this.visible; }
|
||||
|
||||
protected Block(Properties properties)
|
||||
{ this((TexturedModel) null, properties); }
|
||||
|
@ -46,5 +53,15 @@ public class Block
|
|||
{
|
||||
this.model = model;
|
||||
this.visible = properties.visible;
|
||||
this.fullCube = properties.fullCube;
|
||||
this.identifier = properties.identifier;
|
||||
IDENTIFIER_TO_BLOCK.put(this.identifier, this);
|
||||
}
|
||||
|
||||
public static final Block getBlock(String identifier)
|
||||
{
|
||||
return IDENTIFIER_TO_BLOCK.get(identifier);
|
||||
}
|
||||
|
||||
private static final Map<String, Block> IDENTIFIER_TO_BLOCK = new HashMap<>();
|
||||
}
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
package com.github.halotroop.litecraft.world;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.ToIntFunction;
|
||||
|
||||
import com.github.halotroop.litecraft.logic.DataStorage;
|
||||
import com.github.halotroop.litecraft.types.block.*;
|
||||
import com.github.halotroop.litecraft.world.block.*;
|
||||
import com.github.halotroop.litecraft.world.block.BlockRenderer;
|
||||
import com.github.halotroop.litecraft.world.gen.WorldGenConstants;
|
||||
import com.github.hydos.ginger.engine.math.vectors.Vector3f;
|
||||
import com.github.hydos.ginger.engine.render.renderers.ObjectRenderer;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
import it.unimi.dsi.fastutil.longs.*;
|
||||
import it.unimi.dsi.fastutil.objects.*;
|
||||
import tk.valoeghese.sod.*;
|
||||
|
||||
public class Chunk implements BlockAccess, WorldGenConstants
|
||||
public class Chunk implements BlockAccess, WorldGenConstants, DataStorage
|
||||
{
|
||||
/** @param x in-chunk x coordinate.
|
||||
* @param y in-chunk y coordinate.
|
||||
|
@ -18,7 +22,7 @@ public class Chunk implements BlockAccess, WorldGenConstants
|
|||
* @return creates a long that represents a coordinate, for use as a key in maps. */
|
||||
private static long posHash(int x, int y, int z)
|
||||
{ return ((long) x & MAX_POS) | (((long) y & MAX_POS) << POS_SHIFT) | (((long) z & MAX_POS) << DOUBLE_SHIFT); }
|
||||
|
||||
|
||||
List<BlockEntity> renderList;
|
||||
private final Long2ObjectMap<Block> blocks = new Long2ObjectArrayMap<>();
|
||||
private final Long2ObjectMap<BlockEntity> blockEntities = new Long2ObjectArrayMap<>();
|
||||
|
@ -70,7 +74,7 @@ public class Chunk implements BlockAccess, WorldGenConstants
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
blockRenderer.render(renderList);
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +95,6 @@ public class Chunk implements BlockAccess, WorldGenConstants
|
|||
this.blocks.put(hash, block);
|
||||
if (this.render)
|
||||
{
|
||||
// TODO remove current block entity from game data when this class is integrated with the game
|
||||
this.blockEntities.put(hash, new BlockEntity(block, new Vector3f(this.chunkStartX + x, this.chunkStartY + y, this.chunkStartZ + z)));
|
||||
}
|
||||
}
|
||||
|
@ -109,10 +112,10 @@ public class Chunk implements BlockAccess, WorldGenConstants
|
|||
long hash = posHash(x, y, z);
|
||||
Block block = this.blocks.get(hash);
|
||||
if (block.visible) this.blockEntities.put(hash, new BlockEntity(block,
|
||||
new Vector3f(
|
||||
this.chunkStartX + x,
|
||||
this.chunkStartY + y,
|
||||
this.chunkStartZ + z)));
|
||||
new Vector3f(
|
||||
this.chunkStartX + x,
|
||||
this.chunkStartY + y,
|
||||
this.chunkStartZ + z)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -128,4 +131,80 @@ public class Chunk implements BlockAccess, WorldGenConstants
|
|||
|
||||
public boolean isFullyGenerated()
|
||||
{ return this.fullyGenerated; }
|
||||
|
||||
@Override
|
||||
public void read(BinaryData data)
|
||||
{
|
||||
Int2ObjectMap<Block> palette = new Int2ObjectArrayMap<>();
|
||||
|
||||
DataSection paletteData = data.get("palette");
|
||||
|
||||
boolean readInt = true; // whether the thing from the palette to be read is int
|
||||
int intIdCache = 0;
|
||||
for (Object o : paletteData)
|
||||
{
|
||||
if (readInt)
|
||||
{
|
||||
intIdCache = (int) o;
|
||||
readInt = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
palette.put(intIdCache, Block.getBlock((String) o));
|
||||
readInt = true;
|
||||
}
|
||||
}
|
||||
|
||||
DataSection blockData = data.get("block");
|
||||
|
||||
long posHash = 0L; // also the index
|
||||
for (int z = 0; z < CHUNK_SIZE; ++z) // z, y, x order for data saving and loading so we can use incremental pos hashes
|
||||
{
|
||||
for (int y = 0; y < CHUNK_SIZE; ++y)
|
||||
{
|
||||
for (int x = 0; x < CHUNK_SIZE; ++x)
|
||||
{
|
||||
this.blocks.put(posHash, palette.get(blockData.readInt((int) posHash)));
|
||||
++posHash;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int nextId; // for saving
|
||||
|
||||
@Override
|
||||
public void write(BinaryData data)
|
||||
{
|
||||
Object2IntMap<Block> palette = new Object2IntArrayMap<>(); // block to int id
|
||||
|
||||
DataSection paletteData = new DataSection();
|
||||
DataSection blockData = new DataSection();
|
||||
|
||||
long posHash = 0L;
|
||||
nextId = 0;
|
||||
|
||||
ToIntFunction<Block> nextIdProvider = b -> nextId++;
|
||||
|
||||
for (int z = 0; z < CHUNK_SIZE; ++z) // z, y, x order for data saving and loading so we can use incremental pos hashes
|
||||
{
|
||||
for (int y = 0; y < CHUNK_SIZE; ++y)
|
||||
{
|
||||
for (int x = 0; x < CHUNK_SIZE; ++x)
|
||||
{
|
||||
Block b = this.blocks.get(posHash);
|
||||
blockData.writeInt(palette.computeIntIfAbsent(b, nextIdProvider));
|
||||
++posHash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
palette.forEach((b, id) -> {
|
||||
paletteData.writeInt(id);
|
||||
paletteData.writeString(b.identifier);
|
||||
});
|
||||
|
||||
data.put("palette", paletteData);
|
||||
data.put("block", blockData);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue