diff --git a/ClassicalSharp/ClassicalSharp.csproj b/ClassicalSharp/ClassicalSharp.csproj
index ffb5aae35..30b93ed52 100644
--- a/ClassicalSharp/ClassicalSharp.csproj
+++ b/ClassicalSharp/ClassicalSharp.csproj
@@ -4,7 +4,7 @@
{BEB1C785-5CAD-48FF-A886-876BF0A318D4}
Debug
AnyCPU
- Exe
+ WinExe
ClassicalSharp
ClassicalSharp
v2.0
diff --git a/ClassicalSharp/Map/Lighting/BasicLighting.Updater.cs b/ClassicalSharp/Map/Lighting/BasicLighting.Updater.cs
index 1c521fa40..bd6df1bb1 100644
--- a/ClassicalSharp/Map/Lighting/BasicLighting.Updater.cs
+++ b/ClassicalSharp/Map/Lighting/BasicLighting.Updater.cs
@@ -1,6 +1,7 @@
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
using System;
using ClassicalSharp.Renderers;
+using BlockRaw = System.Byte;
using BlockID = System.UInt16;
namespace ClassicalSharp.Map {
@@ -20,8 +21,8 @@ namespace ClassicalSharp.Map {
RefreshAffected(x, y, z, newBlock, lightH + 1, newHeight);
}
- MapRenderer renderer;
- void UpdateLighting(int x, int y, int z, BlockID oldBlock,
+ MapRenderer renderer;
+ void UpdateLighting(int x, int y, int z, BlockID oldBlock,
BlockID newBlock, int index, int lightH) {
bool didBlock = BlockInfo.BlocksLight[oldBlock];
bool nowBlocks = BlockInfo.BlocksLight[newBlock];
@@ -93,29 +94,43 @@ namespace ClassicalSharp.Map {
int cx, int cy, int cz, int minCy, int maxCy) {
World world = game.World;
if (minCy == maxCy) {
- int index = x + world.Width * (z + y * world.Length);
- ResetNeighourChunk(cx, cy, cz, block, y, index, y);
+ int minY = cy << 4;
+ int i = x + world.Width * (z + y * world.Length);
+
+ if (NeedsNeighbour(block, i, minY, y, y)) {
+ renderer.RefreshChunk(cx, cy, cz);
+ }
} else {
for (cy = maxCy; cy >= minCy; cy--) {
- int maxY = Math.Min(world.MaxY, (cy << 4) + 15);
- int index = x + world.Width * (z + maxY * world.Length);
- ResetNeighourChunk(cx, cy, cz, block, maxY, index, y);
+ int minY = cy << 4, maxY = Math.Min(world.MaxY, (cy << 4) + 15);
+ int i = x + world.Width * (z + maxY * world.Length);
+
+ if (NeedsNeighbour(block, i, minY, maxY, y)) {
+ renderer.RefreshChunk(cx, cy, cz);
+ }
}
}
}
- void ResetNeighourChunk(int cx, int cy, int cz, BlockID block,
- int y, int index, int nY) {
+ bool NeedsNeighbour(BlockID block, int i, int minY, int y, int nY) {
World world = game.World;
- int minY = cy << 4;
+ BlockRaw[] blocks = world.blocks;
// Update if any blocks in the chunk are affected by light change
- for (; y >= minY; y--) {
- BlockID other = world.blocks[index];
- bool affected = y == nY ? Needs(block, other) : BlockInfo.Draw[other] != DrawType.Gas;
- if (affected) { renderer.RefreshChunk(cx, cy, cz); return; }
- index -= world.Width * world.Length;
+ if (BlockInfo.MaxDefined < 256) {
+ for (; y >= minY; y--, i -= world.OneY) {
+ BlockID other = blocks[i];
+ bool affected = y == nY ? Needs(block, other) : BlockInfo.Draw[other] != DrawType.Gas;
+ if (affected) return true;
+ }
+ } else {
+ for (; y >= minY; y--, i -= world.OneY) {
+ BlockID other = (BlockID)(blocks[i] | (world.blocks2[i] << 8));
+ bool affected = y == nY ? Needs(block, other) : BlockInfo.Draw[other] != DrawType.Gas;
+ if (affected) return true;
+ }
}
+ return false;
}
void ResetColumn(int cx, int cy, int cz, int minCy, int maxCy) {
diff --git a/ClassicalSharp/Map/World.cs b/ClassicalSharp/Map/World.cs
index 058a04afa..45f76ec9d 100644
--- a/ClassicalSharp/Map/World.cs
+++ b/ClassicalSharp/Map/World.cs
@@ -13,7 +13,7 @@ namespace ClassicalSharp.Map {
public sealed class World {
public BlockRaw[] blocks, blocks2;
- public int Width, Height, Length, MaxX, MaxY, MaxZ;
+ public int Width, Height, Length, MaxX, MaxY, MaxZ, OneY;
public bool HasBlocks;
/// Contains the environment metadata for this world.
@@ -34,6 +34,8 @@ namespace ClassicalSharp.Map {
Env.Reset();
Width = 0; Height = 0; Length = 0;
MaxX = 0; MaxY = 0; MaxZ = 0;
+ OneY = 0;
+
blocks = null;
blocks2 = null;
Uuid = Guid.NewGuid();
@@ -45,6 +47,7 @@ namespace ClassicalSharp.Map {
Width = width; MaxX = width - 1;
Height = height; MaxY = height - 1;
Length = length; MaxZ = length - 1;
+ OneY = width * length;
blocks = blocksRaw;
if (blocks.Length == 0) blocks = null;
diff --git a/ClassicalSharp/Network/Protocols/Classic.cs b/ClassicalSharp/Network/Protocols/Classic.cs
index 72a608b2f..19cefe725 100644
--- a/ClassicalSharp/Network/Protocols/Classic.cs
+++ b/ClassicalSharp/Network/Protocols/Classic.cs
@@ -47,6 +47,9 @@ namespace ClassicalSharp.Network.Protocols {
GZipHeaderReader gzipHeader;
int mapSizeIndex, mapIndex;
byte[] mapSize = new byte[4], map;
+ #if USE16_BIT
+ byte[] map2;
+ #endif
FixedBufferStream gzippedMap;
Screen prevScreen;
bool prevCursorVisible;
@@ -74,10 +77,10 @@ namespace ClassicalSharp.Network.Protocols {
int size = reader.ReadInt32();
gzipHeader.done = true;
mapSizeIndex = 4;
- #if USE16_BIT
- if (reader.ExtendedBlocks) size *= 2;
- #endif
map = new byte[size];
+ #if USE16_BIT
+ if (reader.ExtendedBlocks) map2 = new byte[size];
+ #endif
}
}
@@ -130,10 +133,10 @@ namespace ClassicalSharp.Network.Protocols {
if (mapSizeIndex == 4) {
if (map == null) {
int size = mapSize[0] << 24 | mapSize[1] << 16 | mapSize[2] << 8 | mapSize[3];
- #if USE16_BIT
- if (reader.ExtendedBlocks) size *= 2;
- #endif
map = new byte[size];
+ #if USE16_BIT
+ if (reader.ExtendedBlocks) map2 = new byte[size];
+ #endif
}
mapIndex += gzipStream.Read(map, mapIndex, map.Length - mapIndex);
}
@@ -144,17 +147,6 @@ namespace ClassicalSharp.Network.Protocols {
game.WorldEvents.RaiseMapLoading(progress);
}
- #if USE16_BIT
- static void DecomposeArray(byte[] src, out byte[] b1, out byte[] b2) {
- b1 = new byte[src.Length / 2];
- b2 = new byte[src.Length / 2];
-
- for (int i = 0, j = 0; i < src.Length; j++) {
- b1[j] = src[i++]; b2[j] = src[i++];
- }
- }
- #endif
-
void HandleLevelFinalise() {
game.Gui.SetNewScreen(null);
game.Gui.activeScreen = prevScreen;
@@ -170,17 +162,9 @@ namespace ClassicalSharp.Network.Protocols {
double loadingMs = (DateTime.UtcNow - mapReceiveStart).TotalMilliseconds;
Utils.LogDebug("map loading took: " + loadingMs);
- #if USE16_BIT
- if (reader.ExtendedBlocks) {
- byte[] b1, b2;
- DecomposeArray(map, out b1, out b2);
- game.World.SetNewMap(b1, mapWidth, mapHeight, mapLength);
- game.World.blocks2 = b2;
- } else{
- game.World.SetNewMap(map, mapWidth, mapHeight, mapLength);
- }
- #else
game.World.SetNewMap(map, mapWidth, mapHeight, mapLength);
+ #if USE16_BIT
+ if (reader.ExtendedBlocks) game.World.blocks2 = map2;
#endif
game.WorldEvents.RaiseOnNewMapLoaded();
diff --git a/ClassicalSharp/Singleplayer/FoliagePhysics.cs b/ClassicalSharp/Singleplayer/FoliagePhysics.cs
index dabf947f0..ee66647f6 100644
--- a/ClassicalSharp/Singleplayer/FoliagePhysics.cs
+++ b/ClassicalSharp/Singleplayer/FoliagePhysics.cs
@@ -87,7 +87,7 @@ namespace ClassicalSharp.Singleplayer {
}
BlockRaw below = Block.Stone;
- if (y > 0) below = map.blocks[index - map.Width * map.Length];
+ if (y > 0) below = map.blocks[index - map.OneY];
if (!(below == Block.Stone || below == Block.Cobblestone)) {
game.UpdateBlock(x, y, z, Block.Air);
physics.ActivateNeighbours(x, y, z, index);
diff --git a/ClassicalSharp/Singleplayer/OtherPhysics.cs b/ClassicalSharp/Singleplayer/OtherPhysics.cs
index 57c848703..a2be1b18b 100644
--- a/ClassicalSharp/Singleplayer/OtherPhysics.cs
+++ b/ClassicalSharp/Singleplayer/OtherPhysics.cs
@@ -17,8 +17,8 @@ namespace ClassicalSharp.Singleplayer {
}
void HandleSlab(int index, BlockRaw block) {
- if (index < map.Width * map.Length) return; // y < 1
- if (map.blocks[index - map.Width * map.Length] != Block.Slab) return;
+ if (index < map.OneY) return;
+ if (map.blocks[index - map.OneY] != Block.Slab) return;
int x = index % map.Width;
int z = (index / map.Width) % map.Length;
@@ -28,8 +28,8 @@ namespace ClassicalSharp.Singleplayer {
}
void HandleCobblestoneSlab(int index, BlockRaw block) {
- if (index < map.Width * map.Length) return; // y < 1
- if (map.blocks[index - map.Width * map.Length] != Block.CobblestoneSlab) return;
+ if (index < map.OneY) return;
+ if (map.blocks[index - map.OneY] != Block.CobblestoneSlab) return;
int x = index % map.Width;
int z = (index / map.Width) % map.Length;
diff --git a/ClassicalSharp/Singleplayer/Physics.cs b/ClassicalSharp/Singleplayer/Physics.cs
index 96bd4ae45..0542867ff 100644
--- a/ClassicalSharp/Singleplayer/Physics.cs
+++ b/ClassicalSharp/Singleplayer/Physics.cs
@@ -103,7 +103,7 @@ namespace ClassicalSharp.Singleplayer {
return false;
return y >= env.SidesHeight && y < env.EdgeHeight
- && (x == 0 || z == 0 || x == (map.Width - 1) || z == (map.Length - 1));
+ && (x == 0 || z == 0 || x == map.MaxX || z == map.MaxZ);
}
void ResetMap(object sender, EventArgs e) {
diff --git a/src/Client/Lighting.c b/src/Client/Lighting.c
index ff84bc729..ff3970950 100644
--- a/src/Client/Lighting.c
+++ b/src/Client/Lighting.c
@@ -132,27 +132,32 @@ bool Lighting_Needs(BlockID block, BlockID other) {
return Block_Draw[block] != DRAW_OPAQUE || Block_Draw[other] != DRAW_GAS;
}
-void Lighting_ResetNeighourChunk(Int32 cx, Int32 cy, Int32 cz, BlockID block, Int32 y, Int32 index, Int32 nY) {
- Int32 minY = cy << 4;
-
+bool Lighting_NeedsNeighour(BlockID block, Int32 index, Int32 minY, Int32 y, Int32 nY) {
/* Update if any blocks in the chunk are affected by light change. */
- for (; y >= minY; y--) {
+ for (; y >= minY; y--, index -= World_OneY) {
BlockID other = World_Blocks[index];
bool affected = y == nY ? Lighting_Needs(block, other) : Block_Draw[other] != DRAW_GAS;
- if (affected) { MapRenderer_RefreshChunk(cx, cy, cz); return; }
- index -= World_OneY;
+ if (affected) return true;
}
+ return false;
}
void Lighting_ResetNeighbour(Int32 x, Int32 y, Int32 z, BlockID block,
Int32 cx, Int32 cy, Int32 cz, Int32 minCy, Int32 maxCy) {
if (minCy == maxCy) {
- Lighting_ResetNeighourChunk(cx, cy, cz, block, y, World_Pack(x, y, z), y);
+ Int32 minY = cy << 4;
+
+ if (Lighting_NeedsNeighour(block, World_Pack(x, y, z), minY, y, y)) {
+ MapRenderer_RefreshChunk(cx, cy, cz);
+ }
} else {
for (cy = maxCy; cy >= minCy; cy--) {
- Int32 maxY = (cy << 4) + 15;
+ Int32 minY = cy << 4, maxY = (cy << 4) + 15;
if (maxY > World_MaxY) maxY = World_MaxY;
- Lighting_ResetNeighourChunk(cx, cy, cz, block, maxY, World_Pack(x, maxY, z), y);
+
+ if (Lighting_NeedsNeighour(block, World_Pack(x, maxY, z), minY, maxY, y)) {
+ MapRenderer_RefreshChunk(cx, cy, cz);
+ }
}
}
}