improve client performance and fix chunk light concurrency
This commit is contained in:
parent
46c95630f3
commit
ca97bf2e18
10 changed files with 44 additions and 208 deletions
|
@ -336,15 +336,11 @@ public class Client implements IThreadListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onEntityAdded(Entity entityIn) {
|
protected void onEntityAdded(Entity entityIn) {
|
||||||
if(Client.this.spawnQueue.contains(entityIn))
|
|
||||||
Client.this.spawnQueue.remove(entityIn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onEntityRemoved(Entity entityIn) {
|
protected void onEntityRemoved(Entity entityIn) {
|
||||||
if(Client.this.entityList.contains(entityIn)) {
|
if(Client.this.entityList.contains(entityIn)) {
|
||||||
if(entityIn.isEntityAlive())
|
if(!entityIn.isEntityAlive())
|
||||||
Client.this.spawnQueue.add(entityIn);
|
|
||||||
else
|
|
||||||
Client.this.entityList.remove(entityIn);
|
Client.this.entityList.remove(entityIn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -446,10 +442,7 @@ public class Client implements IThreadListener {
|
||||||
public final Map<String, Integer> playerList = Maps.<String, Integer>newTreeMap();
|
public final Map<String, Integer> playerList = Maps.<String, Integer>newTreeMap();
|
||||||
public final List<PlayerCharacter> characterList = Lists.<PlayerCharacter>newArrayList();
|
public final List<PlayerCharacter> characterList = Lists.<PlayerCharacter>newArrayList();
|
||||||
private final Set<Entity> entityList = Sets.<Entity>newHashSet();
|
private final Set<Entity> entityList = Sets.<Entity>newHashSet();
|
||||||
private final Set<Entity> spawnQueue = Sets.<Entity>newHashSet();
|
|
||||||
private final Set<ChunkPos> previousActive = Sets.<ChunkPos>newHashSet();
|
|
||||||
private final LongHashMap<ChunkClient> chunkMapping = new LongHashMap();
|
private final LongHashMap<ChunkClient> chunkMapping = new LongHashMap();
|
||||||
private final List<ChunkClient> chunkListing = Lists.<ChunkClient>newArrayList();
|
|
||||||
private final Set<Long> emptyChunkListing = Sets.<Long>newHashSet();
|
private final Set<Long> emptyChunkListing = Sets.<Long>newHashSet();
|
||||||
private final Set<Long> nextEmptyChunkListing = Sets.<Long>newHashSet();
|
private final Set<Long> nextEmptyChunkListing = Sets.<Long>newHashSet();
|
||||||
public final int[] lastSelection = new int[ItemCategory.values().length];
|
public final int[] lastSelection = new int[ItemCategory.values().length];
|
||||||
|
@ -489,6 +482,7 @@ public class Client implements IThreadListener {
|
||||||
public boolean freecam;
|
public boolean freecam;
|
||||||
public boolean servercam;
|
public boolean servercam;
|
||||||
public boolean shaders;
|
public boolean shaders;
|
||||||
|
public volatile boolean worldLight;
|
||||||
|
|
||||||
private int leftClickCounter;
|
private int leftClickCounter;
|
||||||
private int rightClickTimer;
|
private int rightClickTimer;
|
||||||
|
@ -587,12 +581,10 @@ public class Client implements IThreadListener {
|
||||||
public int renderDistance = 8;
|
public int renderDistance = 8;
|
||||||
@Variable(name = "chunk_build_time", category = CVarCategory.RENDER, min = 1, max = 100, display = "Zeit für Chunk-Bau", unit = "ms")
|
@Variable(name = "chunk_build_time", category = CVarCategory.RENDER, min = 1, max = 100, display = "Zeit für Chunk-Bau", unit = "ms")
|
||||||
public int maxBuildTime = 8;
|
public int maxBuildTime = 8;
|
||||||
@Variable(name = "chunk_light_updates", category = CVarCategory.RENDER, min = 100, max = 10000, display = "Licht-Updates / Tick")
|
@Variable(name = "chunk_light_updates", category = CVarCategory.RENDER, min = 0, max = 10000, display = "Licht-Updates / Frame")
|
||||||
private int lightUpdates = 2048;
|
private int lightUpdates = 150;
|
||||||
@Variable(name = "chunk_light_range", category = CVarCategory.RENDER, min = 5, max = 1024, display = "Radius Licht-Updates")
|
@Variable(name = "chunk_light_range", category = CVarCategory.RENDER, min = 5, max = 1024, display = "Radius Licht-Updates")
|
||||||
private int lightRange = 32;
|
private int lightRange = 32;
|
||||||
@Variable(name = "chunk_light_onload", category = CVarCategory.RENDER, min = 0, max = 32, display = "Licht-Init. / Tick")
|
|
||||||
private int lightInit = 0;
|
|
||||||
@Variable(name = "draw_fov", category = CVarCategory.RENDER, min = 20.0f, max = 160.0f, display = "Sichtfeld (FOV)", unit = "°", precision = 1)
|
@Variable(name = "draw_fov", category = CVarCategory.RENDER, min = 20.0f, max = 160.0f, display = "Sichtfeld (FOV)", unit = "°", precision = 1)
|
||||||
public float fov = 70.0f;
|
public float fov = 70.0f;
|
||||||
@Variable(name = "draw_wireframe", category = CVarCategory.RENDER, display = "Gitter-Render-Modus")
|
@Variable(name = "draw_wireframe", category = CVarCategory.RENDER, display = "Gitter-Render-Modus")
|
||||||
|
@ -823,6 +815,7 @@ public class Client implements IThreadListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unloadWorld() {
|
public void unloadWorld() {
|
||||||
|
this.worldLight = false;
|
||||||
ClientPlayer netHandler = this.getNetHandler();
|
ClientPlayer netHandler = this.getNetHandler();
|
||||||
if(netHandler != null)
|
if(netHandler != null)
|
||||||
netHandler.cleanup();
|
netHandler.cleanup();
|
||||||
|
@ -1110,11 +1103,19 @@ public class Client implements IThreadListener {
|
||||||
GuiPlayer.INSTANCE.updatePlayer();
|
GuiPlayer.INSTANCE.updatePlayer();
|
||||||
if (this.world != null)
|
if (this.world != null)
|
||||||
{
|
{
|
||||||
this.tickWorld();
|
this.world.updatePhysics();
|
||||||
if (this.world != null)
|
this.markReload();
|
||||||
|
|
||||||
|
if (Vars.timeFlow > 0)
|
||||||
{
|
{
|
||||||
this.displayTick(ExtMath.floord(this.player.posX), ExtMath.floord(this.player.posY), ExtMath.floord(this.player.posZ));
|
if(this.world.dimension.hasOrbit())
|
||||||
|
this.world.setOrbit((this.world.getOrbit() + (long)Vars.timeFlow) % this.world.dimension.getOrbitalPeriod());
|
||||||
|
if(this.world.dimension.hasRotation())
|
||||||
|
this.world.setRotation((this.world.getRotation() + (long)Vars.timeFlow) % this.world.dimension.getRotationalPeriod());
|
||||||
|
this.world.dimension.setEpoch(this.world.dimension.getEpoch() + (long)Vars.timeFlow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.displayTick(ExtMath.floord(this.player.posX), ExtMath.floord(this.player.posY), ExtMath.floord(this.player.posZ));
|
||||||
this.effectRenderer.update();
|
this.effectRenderer.update();
|
||||||
if(this.player != null && (this.player.getHeldItem() == null || this.player.getHeldItem().getItem().getCategory() != this.itemSelection))
|
if(this.player != null && (this.player.getHeldItem() == null || this.player.getHeldItem().getItem().getCategory() != this.itemSelection))
|
||||||
this.select(1);
|
this.select(1);
|
||||||
|
@ -1843,6 +1844,7 @@ public class Client implements IThreadListener {
|
||||||
|
|
||||||
public World loadWorld(Dimension dim, int type)
|
public World loadWorld(Dimension dim, int type)
|
||||||
{
|
{
|
||||||
|
this.worldLight = false;
|
||||||
this.resetWorld();
|
this.resetWorld();
|
||||||
this.viewEntity = null;
|
this.viewEntity = null;
|
||||||
this.freecam = this.servercam = false;
|
this.freecam = this.servercam = false;
|
||||||
|
@ -1854,6 +1856,7 @@ public class Client implements IThreadListener {
|
||||||
this.tiles = this.world.tiles;
|
this.tiles = this.world.tiles;
|
||||||
this.entityIds = this.world.entityIds;
|
this.entityIds = this.world.entityIds;
|
||||||
this.initWorld();
|
this.initWorld();
|
||||||
|
this.worldLight = true;
|
||||||
|
|
||||||
this.renderer.setWorldAndLoadRenderers(this.world);
|
this.renderer.setWorldAndLoadRenderers(this.world);
|
||||||
|
|
||||||
|
@ -2094,8 +2097,8 @@ public class Client implements IThreadListener {
|
||||||
// this.connected != null ? this.connected : "[???]"))),
|
// this.connected != null ? this.connected : "[???]"))),
|
||||||
this.renderer.getDebugInfoRenders() + "\n" +
|
this.renderer.getDebugInfoRenders() + "\n" +
|
||||||
this.renderer.getDebugInfoEntities() + "\n" +
|
this.renderer.getDebugInfoEntities() + "\n" +
|
||||||
"Partikel: " + this.effectRenderer.getParticleCount() + ". O: " + this.entities.size() + "\n" +
|
"Partikel: " + this.effectRenderer.getParticleCount() + ", O: " + this.entities.size() + "\n" +
|
||||||
"Chunk-Cache: M " + this.chunkMapping.getNumHashElements() + ", L " + this.chunkListing.size() + "\n" +
|
"Chunk-Cache: " + this.chunkMapping.getNumHashElements() + "\n" +
|
||||||
String.format("XYZ: %.3f / %.3f / %.3f", this.viewEntity.posX,
|
String.format("XYZ: %.3f / %.3f / %.3f", this.viewEntity.posX,
|
||||||
this.viewEntity.getEntityBoundingBox().minY, this.viewEntity.posZ) + "\n" +
|
this.viewEntity.getEntityBoundingBox().minY, this.viewEntity.posZ) + "\n" +
|
||||||
String.format("Block: %d %d %d, R: '%s/%s'", pos.getX(), pos.getY(), pos.getZ(),
|
String.format("Block: %d %d %d, R: '%s/%s'", pos.getX(), pos.getY(), pos.getZ(),
|
||||||
|
@ -2697,6 +2700,16 @@ public class Client implements IThreadListener {
|
||||||
this.tickFraction = ((double)this.tick_torun) / 1000000.0;
|
this.tickFraction = ((double)this.tick_torun) / 1000000.0;
|
||||||
this.tick_ttime += this.tick_ftime;
|
this.tick_ttime += this.tick_ftime;
|
||||||
this.tick_time = this.tickFrame != 0 ? (this.tick_ftime / (long)this.tickFrame) : 0L;
|
this.tick_time = this.tickFrame != 0 ? (this.tick_ftime / (long)this.tickFrame) : 0L;
|
||||||
|
|
||||||
|
if(this.player != null) {
|
||||||
|
int radius = Math.min(this.renderDistance * 16, this.lightRange);
|
||||||
|
for(int n = 0; n < this.lightUpdates; n++) {
|
||||||
|
int x = ExtMath.floord(this.player.posX) + this.world.rand.range(-radius, radius);
|
||||||
|
int y = ExtMath.floord(this.player.posY) + this.world.rand.range(-radius, radius);
|
||||||
|
int z = ExtMath.floord(this.player.posZ) + this.world.rand.range(-radius, radius);
|
||||||
|
this.world.checkBlockLight(new LocalPos(x, y, z));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void tick_target(float tps) {
|
public void tick_target(float tps) {
|
||||||
|
@ -3640,10 +3653,7 @@ public class Client implements IThreadListener {
|
||||||
|
|
||||||
private void resetWorld() {
|
private void resetWorld() {
|
||||||
this.entityList.clear();
|
this.entityList.clear();
|
||||||
this.spawnQueue.clear();
|
|
||||||
this.previousActive.clear();
|
|
||||||
this.chunkMapping.clear();
|
this.chunkMapping.clear();
|
||||||
this.chunkListing.clear();
|
|
||||||
this.emptyChunkListing.clear();
|
this.emptyChunkListing.clear();
|
||||||
this.nextEmptyChunkListing.clear();
|
this.nextEmptyChunkListing.clear();
|
||||||
this.emptyChunk = null;
|
this.emptyChunk = null;
|
||||||
|
@ -3714,88 +3724,6 @@ public class Client implements IThreadListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tickWorld()
|
|
||||||
{
|
|
||||||
this.world.updatePhysics();
|
|
||||||
this.markReload();
|
|
||||||
|
|
||||||
if (Vars.timeFlow > 0)
|
|
||||||
{
|
|
||||||
if(this.world.dimension.hasOrbit())
|
|
||||||
this.world.setOrbit((this.world.getOrbit() + (long)Vars.timeFlow) % this.world.dimension.getOrbitalPeriod());
|
|
||||||
if(this.world.dimension.hasRotation())
|
|
||||||
this.world.setRotation((this.world.getRotation() + (long)Vars.timeFlow) % this.world.dimension.getRotationalPeriod());
|
|
||||||
this.world.dimension.setEpoch(this.world.dimension.getEpoch() + (long)Vars.timeFlow);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 10 && !this.spawnQueue.isEmpty(); ++i)
|
|
||||||
{
|
|
||||||
Entity entity = (Entity)this.spawnQueue.iterator().next();
|
|
||||||
this.spawnQueue.remove(entity);
|
|
||||||
|
|
||||||
if (!this.entities.contains(entity))
|
|
||||||
{
|
|
||||||
this.world.spawnEntityInWorld(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
long time = System.currentTimeMillis();
|
|
||||||
for (ChunkClient chunk : this.chunkListing)
|
|
||||||
{
|
|
||||||
chunk.spawnTiles();
|
|
||||||
}
|
|
||||||
if (System.currentTimeMillis() - time > 100L)
|
|
||||||
{
|
|
||||||
Log.TICK.warn("Render-Chunk-Tick dauerte " + (System.currentTimeMillis() - time) + " ms");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.player != null) {
|
|
||||||
int radius = Math.min(this.renderDistance * 16, this.lightRange);
|
|
||||||
for(int n = 0; n < this.lightUpdates; n++) {
|
|
||||||
int x = ExtMath.floord(this.player.posX) + this.world.rand.range(-radius, radius);
|
|
||||||
int y = ExtMath.floord(this.player.posY) + this.world.rand.range(-radius, radius);
|
|
||||||
int z = ExtMath.floord(this.player.posZ) + this.world.rand.range(-radius, radius);
|
|
||||||
this.world.checkBlockLight(new LocalPos(x, y, z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<ChunkPos> active = this.world.getActiveChunks();
|
|
||||||
active.clear();
|
|
||||||
if(this.player != null) {
|
|
||||||
int x = ExtMath.floord(this.player.posX / 16.0D);
|
|
||||||
int z = ExtMath.floord(this.player.posZ / 16.0D);
|
|
||||||
for(int cx = -this.renderDistance; cx <= this.renderDistance; cx++) {
|
|
||||||
for(int cz = -this.renderDistance; cz <= this.renderDistance; cz++) {
|
|
||||||
active.add(new ChunkPos(cx + x, cz + z));
|
|
||||||
if(this.lightInit > 0)
|
|
||||||
this.getChunk(cx + x, cz + z).updateLight(this.lightInit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.previousActive.retainAll(active);
|
|
||||||
if (this.previousActive.size() == active.size())
|
|
||||||
{
|
|
||||||
this.previousActive.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
for (ChunkPos chunkcoordintpair : active)
|
|
||||||
{
|
|
||||||
if (!this.previousActive.contains(chunkcoordintpair))
|
|
||||||
{
|
|
||||||
ChunkClient chunk = this.getChunk(chunkcoordintpair.x, chunkcoordintpair.z);
|
|
||||||
this.previousActive.add(chunkcoordintpair);
|
|
||||||
++i;
|
|
||||||
|
|
||||||
if (i >= 10)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doPreChunk(int x, int z, boolean load)
|
public void doPreChunk(int x, int z, boolean load)
|
||||||
{
|
{
|
||||||
long id = LongHashMap.packInt(x, z);
|
long id = LongHashMap.packInt(x, z);
|
||||||
|
@ -3805,7 +3733,6 @@ public class Client implements IThreadListener {
|
||||||
this.doPreChunk(x, z, false);
|
this.doPreChunk(x, z, false);
|
||||||
ChunkClient chunk = new ChunkClient(this.world, x, z);
|
ChunkClient chunk = new ChunkClient(this.world, x, z);
|
||||||
this.chunkMapping.add(id, chunk);
|
this.chunkMapping.add(id, chunk);
|
||||||
this.chunkListing.add(chunk);
|
|
||||||
chunk.setLoaded();
|
chunk.setLoaded();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3813,7 +3740,6 @@ public class Client implements IThreadListener {
|
||||||
ChunkClient chunk = this.getChunk(x, z);
|
ChunkClient chunk = this.getChunk(x, z);
|
||||||
chunk.onChunkUnload();
|
chunk.onChunkUnload();
|
||||||
this.chunkMapping.remove(id);
|
this.chunkMapping.remove(id);
|
||||||
this.chunkListing.remove(chunk);
|
|
||||||
this.emptyChunkListing.remove(id);
|
this.emptyChunkListing.remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3875,9 +3801,7 @@ public class Client implements IThreadListener {
|
||||||
{
|
{
|
||||||
Entity entity2 = this.unloaded.get(l);
|
Entity entity2 = this.unloaded.get(l);
|
||||||
if(this.entityList.contains(entity2)) {
|
if(this.entityList.contains(entity2)) {
|
||||||
if(entity2.isEntityAlive())
|
if(!entity2.isEntityAlive())
|
||||||
this.spawnQueue.add(entity2);
|
|
||||||
else
|
|
||||||
this.entityList.remove(entity2);
|
this.entityList.remove(entity2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3919,10 +3843,8 @@ public class Client implements IThreadListener {
|
||||||
private void spawnEntity(Entity entityIn) {
|
private void spawnEntity(Entity entityIn) {
|
||||||
boolean flag = this.world.spawnEntityInWorld(entityIn);
|
boolean flag = this.world.spawnEntityInWorld(entityIn);
|
||||||
this.entityList.add(entityIn);
|
this.entityList.add(entityIn);
|
||||||
if(!flag)
|
if(flag && entityIn instanceof EntityCart cart)
|
||||||
this.spawnQueue.add(entityIn);
|
this.soundManager.playSound(new MovingSoundMinecart(cart));
|
||||||
else if(entityIn instanceof EntityCart)
|
|
||||||
this.soundManager.playSound(new MovingSoundMinecart((EntityCart)entityIn));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ensureAreaLoaded(Entity entity) {
|
private void ensureAreaLoaded(Entity entity) {
|
||||||
|
|
|
@ -91,8 +91,7 @@ public class GuiGraphics extends GuiOptions {
|
||||||
this.addSelector("chunk_light_range", 0, y += BASE_SHIFT, 0, 0);
|
this.addSelector("chunk_light_range", 0, y += BASE_SHIFT, 0, 0);
|
||||||
this.addSelector("chunk_light_updates", H_SHIFT, y, 0, 0);
|
this.addSelector("chunk_light_updates", H_SHIFT, y, 0, 0);
|
||||||
|
|
||||||
this.addSelector("chunk_light_onload", 0, y += BASE_SHIFT, 0, 0);
|
this.addSelector("chunk_build_time", 0, y += BASE_SHIFT, 0, 0);
|
||||||
this.addSelector("chunk_build_time", H_SHIFT, y, 0, 0);
|
|
||||||
|
|
||||||
this.addSelector("draw_player_firstperson", 0, y += BASE_SHIFT, 0, 0);
|
this.addSelector("draw_player_firstperson", 0, y += BASE_SHIFT, 0, 0);
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class RegionRenderCache implements IWorldAccess
|
||||||
{
|
{
|
||||||
int i = (pos.getX() >> 4) - this.xPos;
|
int i = (pos.getX() >> 4) - this.xPos;
|
||||||
int j = (pos.getZ() >> 4) - this.zPos;
|
int j = (pos.getZ() >> 4) - this.zPos;
|
||||||
return this.chunks[i][j].getTileEntity(pos, TileEntity.CreateMode.QUEUED);
|
return this.chunks[i][j].getTileEntity(pos, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCombinedLight(LocalPos pos)
|
public int getCombinedLight(LocalPos pos)
|
||||||
|
|
|
@ -4071,7 +4071,7 @@ public class Renderer {
|
||||||
pos = new LocalPos(pos.getX(), -World.MAX_SIZE_Y, pos.getZ());
|
pos = new LocalPos(pos.getX(), -World.MAX_SIZE_Y, pos.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!World.isValid(pos) || this.gm.world == null) {
|
if(!World.isValid(pos) || !this.gm.worldLight) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if(this.gm.world.getState(pos).getBlock().getSumBrightness()) {
|
else if(this.gm.world.getState(pos).getBlock().getSumBrightness()) {
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
package client.world;
|
package client.world;
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
||||||
|
|
||||||
import common.block.Block;
|
import common.block.Block;
|
||||||
import common.block.ITileEntityProvider;
|
|
||||||
import common.init.Blocks;
|
import common.init.Blocks;
|
||||||
import common.tileentity.TileEntity;
|
import common.tileentity.TileEntity;
|
||||||
import common.util.Facing;
|
import common.util.Facing;
|
||||||
|
@ -13,12 +10,9 @@ import common.world.Chunk;
|
||||||
import common.world.World;
|
import common.world.World;
|
||||||
|
|
||||||
public class ChunkClient extends Chunk {
|
public class ChunkClient extends Chunk {
|
||||||
private final ConcurrentLinkedQueue<LocalPos> tileQueue = new ConcurrentLinkedQueue<LocalPos>();
|
|
||||||
private final float[] temperatures = new float[256];
|
private final float[] temperatures = new float[256];
|
||||||
private final float[] offsets = new float[256];
|
private final float[] offsets = new float[256];
|
||||||
|
|
||||||
private int lightUpdates = Integer.MAX_VALUE;
|
|
||||||
|
|
||||||
public ChunkClient(World world, int x, int z) {
|
public ChunkClient(World world, int x, int z) {
|
||||||
super(world, x, z);
|
super(world, x, z);
|
||||||
}
|
}
|
||||||
|
@ -116,8 +110,6 @@ public class ChunkClient extends Chunk {
|
||||||
for(TileEntity tile : this.tiles.values()) {
|
for(TileEntity tile : this.tiles.values()) {
|
||||||
tile.resetBlock();
|
tile.resetBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.lightUpdates = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLoaded() {
|
public void setLoaded() {
|
||||||
|
@ -140,37 +132,6 @@ public class ChunkClient extends Chunk {
|
||||||
return this.offsets[z << 4 | x];
|
return this.offsets[z << 4 | x];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void spawnTiles() {
|
|
||||||
while(!this.tileQueue.isEmpty()) {
|
|
||||||
LocalPos pos = this.tileQueue.poll();
|
|
||||||
if(this.getTileEntity(pos, TileEntity.CreateMode.CHECK) == null && this.getBlock(pos) instanceof ITileEntityProvider) {
|
|
||||||
TileEntity tile = this.createNewTileEntity(pos);
|
|
||||||
this.world.setTileEntity(pos, tile);
|
|
||||||
this.world.markBlockRangeForRenderUpdate(pos, pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public TileEntity getTileEntity(LocalPos pos, TileEntity.CreateMode type) {
|
|
||||||
TileEntity tile = this.tiles.get(pos);
|
|
||||||
|
|
||||||
if(tile == null) {
|
|
||||||
if(type == TileEntity.CreateMode.IMMEDIATE) {
|
|
||||||
tile = this.createNewTileEntity(pos);
|
|
||||||
this.world.setTileEntity(pos, tile);
|
|
||||||
}
|
|
||||||
else if(type == TileEntity.CreateMode.QUEUED) {
|
|
||||||
this.tileQueue.add(pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(tile.isInvalid()) {
|
|
||||||
this.tiles.remove(pos);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLight(LocalPos pos) {
|
public int getLight(LocalPos pos) {
|
||||||
int x = pos.getX() & 15;
|
int x = pos.getX() & 15;
|
||||||
int y = pos.getY();
|
int y = pos.getY();
|
||||||
|
@ -193,38 +154,4 @@ public class ChunkClient extends Chunk {
|
||||||
|
|
||||||
stor.setLight(x, y & 15, z, value);
|
stor.setLight(x, y & 15, z, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateLight(int iters) {
|
|
||||||
if(this.lightUpdates == Integer.MAX_VALUE)
|
|
||||||
return;
|
|
||||||
LocalPos pos = new LocalPos(this.xPos << 4, 0, this.zPos << 4);
|
|
||||||
for(int n = 0; n < iters; ++n) {
|
|
||||||
if(this.top == Integer.MIN_VALUE) {
|
|
||||||
this.lightUpdates = Integer.MAX_VALUE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int h = 1 + (this.top >> 4) - (this.bottom >> 4);
|
|
||||||
if(this.lightUpdates >= 256 * h) {
|
|
||||||
this.lightUpdates = Integer.MAX_VALUE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int s = (this.lightUpdates % h) + (this.bottom >> 4);
|
|
||||||
int x = this.lightUpdates / h % 16;
|
|
||||||
int z = this.lightUpdates / 512;
|
|
||||||
++this.lightUpdates;
|
|
||||||
for(int y = 0; y < 16; ++y) {
|
|
||||||
LocalPos block = pos.add(x, (s << 4) + y, z);
|
|
||||||
boolean edge = y == 0 || y == 15 || x == 0 || x == 15 || z == 0 || z == 15;
|
|
||||||
BlockArray arr = this.getArray(s);
|
|
||||||
if(arr == null && edge || arr != null && arr.getBlock(x, y, z) == Blocks.air) {
|
|
||||||
for(Facing face : Facing.values()) {
|
|
||||||
LocalPos side = block.offset(face);
|
|
||||||
if(this.world.getState(side).getBlock().getLight() != 0)
|
|
||||||
this.world.checkBlockLight(side);
|
|
||||||
}
|
|
||||||
this.world.checkBlockLight(block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ public class ChunkEmpty extends ChunkClient {
|
||||||
public void removeEntity(Entity entity) {
|
public void removeEntity(Entity entity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public TileEntity getTileEntity(LocalPos pos, TileEntity.CreateMode type) {
|
public TileEntity getTileEntity(LocalPos pos, boolean create) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ public class ChunkEmpty extends ChunkClient {
|
||||||
return pos.getY() < this.liquidY ? this.dummy : (pos.getY() == this.liquidY ? this.liquid : Blocks.air.getState());
|
return pos.getY() < this.liquidY ? this.dummy : (pos.getY() == this.liquidY ? this.liquid : Blocks.air.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
public State setState(LocalPos pos, State state, boolean updateLight) {
|
public State setState(LocalPos pos, State state) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,9 +125,6 @@ public class ChunkEmpty extends ChunkClient {
|
||||||
return new LocalPos(pos.getX(), this.liquidY + 1, pos.getZ());
|
return new LocalPos(pos.getX(), this.liquidY + 1, pos.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void spawnTiles() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onChunkUnload() {
|
public void onChunkUnload() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +149,4 @@ public class ChunkEmpty extends ChunkClient {
|
||||||
public int getLowest() {
|
public int getLowest() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateLight(int iters) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,7 +250,7 @@ public class BlockChest extends Block implements ITileEntityProvider, Rotatable
|
||||||
TileEntity te = world.getTileEntity(pos);
|
TileEntity te = world.getTileEntity(pos);
|
||||||
if(te instanceof TileEntityChest chest)
|
if(te instanceof TileEntityChest chest)
|
||||||
return state.withProperty(OPEN, chest.numPlayersUsing > 0);
|
return state.withProperty(OPEN, chest.numPlayersUsing > 0);
|
||||||
return state;
|
return state.withProperty(OPEN, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isXrayVisible()
|
public boolean isXrayVisible()
|
||||||
|
|
|
@ -13,12 +13,6 @@ import common.world.State;
|
||||||
import common.world.World;
|
import common.world.World;
|
||||||
|
|
||||||
public abstract class TileEntity {
|
public abstract class TileEntity {
|
||||||
public static enum CreateMode {
|
|
||||||
IMMEDIATE,
|
|
||||||
QUEUED,
|
|
||||||
CHECK;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected World world;
|
protected World world;
|
||||||
protected LocalPos pos = LocalPos.ORIGIN;
|
protected LocalPos pos = LocalPos.ORIGIN;
|
||||||
private boolean invalid;
|
private boolean invalid;
|
||||||
|
|
|
@ -220,7 +220,7 @@ public abstract class Chunk {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(oldb instanceof ITileEntityProvider) {
|
if(oldb instanceof ITileEntityProvider) {
|
||||||
TileEntity tile = this.getTileEntity(pos, TileEntity.CreateMode.CHECK);
|
TileEntity tile = this.getTileEntity(pos, false);
|
||||||
|
|
||||||
if(tile != null) {
|
if(tile != null) {
|
||||||
tile.resetBlock();
|
tile.resetBlock();
|
||||||
|
@ -232,7 +232,7 @@ public abstract class Chunk {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(block instanceof ITileEntityProvider) {
|
if(block instanceof ITileEntityProvider) {
|
||||||
TileEntity tile = this.getTileEntity(pos, TileEntity.CreateMode.CHECK);
|
TileEntity tile = this.getTileEntity(pos, false);
|
||||||
|
|
||||||
if(tile == null) {
|
if(tile == null) {
|
||||||
tile = ((ITileEntityProvider)block).createNewTileEntity();
|
tile = ((ITileEntityProvider)block).createNewTileEntity();
|
||||||
|
@ -297,11 +297,11 @@ public abstract class Chunk {
|
||||||
return !(block instanceof ITileEntityProvider provider) ? null : provider.createNewTileEntity();
|
return !(block instanceof ITileEntityProvider provider) ? null : provider.createNewTileEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TileEntity getTileEntity(LocalPos pos, TileEntity.CreateMode type) {
|
public TileEntity getTileEntity(LocalPos pos, boolean create) {
|
||||||
TileEntity tile = this.tiles.get(pos);
|
TileEntity tile = this.tiles.get(pos);
|
||||||
|
|
||||||
if(tile == null) {
|
if(tile == null) {
|
||||||
if(type == TileEntity.CreateMode.IMMEDIATE) {
|
if(create) {
|
||||||
tile = this.createNewTileEntity(pos);
|
tile = this.createNewTileEntity(pos);
|
||||||
this.world.setTileEntity(pos, tile);
|
this.world.setTileEntity(pos, tile);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1087,7 +1087,7 @@ public abstract class World implements IWorldAccess {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tileentity == null) {
|
if(tileentity == null) {
|
||||||
tileentity = this.getChunk(pos).getTileEntity(pos, TileEntity.CreateMode.IMMEDIATE);
|
tileentity = this.getChunk(pos).getTileEntity(pos, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tileentity == null) {
|
if(tileentity == null) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue