forked from BLOCKFANTASY/LOOHP-Limbo
0.3.7-ALPHA Exterimental Light Engine (Reset mapping.json to use)
This commit is contained in:
parent
052d8bb021
commit
82e575e897
7
pom.xml
7
pom.xml
|
|
@ -4,7 +4,7 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.loohp</groupId>
|
<groupId>com.loohp</groupId>
|
||||||
<artifactId>Limbo</artifactId>
|
<artifactId>Limbo</artifactId>
|
||||||
<version>0.3.6-ALPHA</version>
|
<version>0.3.7-ALPHA</version>
|
||||||
<build>
|
<build>
|
||||||
<sourceDirectory>src</sourceDirectory>
|
<sourceDirectory>src</sourceDirectory>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
@ -64,6 +64,11 @@
|
||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>3.11</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.Querz</groupId>
|
<groupId>com.github.Querz</groupId>
|
||||||
<artifactId>NBT</artifactId>
|
<artifactId>NBT</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ import com.loohp.limbo.Server.Packets.PacketPlayInRotation;
|
||||||
import com.loohp.limbo.Server.Packets.PacketPlayInTabComplete;
|
import com.loohp.limbo.Server.Packets.PacketPlayInTabComplete;
|
||||||
import com.loohp.limbo.Server.Packets.PacketPlayOutDeclareCommands;
|
import com.loohp.limbo.Server.Packets.PacketPlayOutDeclareCommands;
|
||||||
import com.loohp.limbo.Server.Packets.PacketPlayOutDisconnect;
|
import com.loohp.limbo.Server.Packets.PacketPlayOutDisconnect;
|
||||||
|
import com.loohp.limbo.Server.Packets.PacketPlayOutLightUpdate;
|
||||||
import com.loohp.limbo.Server.Packets.PacketPlayOutLogin;
|
import com.loohp.limbo.Server.Packets.PacketPlayOutLogin;
|
||||||
import com.loohp.limbo.Server.Packets.PacketPlayOutMapChunk;
|
import com.loohp.limbo.Server.Packets.PacketPlayOutMapChunk;
|
||||||
import com.loohp.limbo.Server.Packets.PacketPlayOutPlayerAbilities;
|
import com.loohp.limbo.Server.Packets.PacketPlayOutPlayerAbilities;
|
||||||
|
|
@ -300,11 +301,28 @@ public class ClientConnection extends Thread {
|
||||||
if (chunk != null) {
|
if (chunk != null) {
|
||||||
PacketPlayOutMapChunk chunkdata = new PacketPlayOutMapChunk(x, z, chunk, world.getEnvironment());
|
PacketPlayOutMapChunk chunkdata = new PacketPlayOutMapChunk(x, z, chunk, world.getEnvironment());
|
||||||
sendPacket(chunkdata);
|
sendPacket(chunkdata);
|
||||||
//Limbo.getInstance().getConsole().sendMessage(x + ", " + z);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int x = 0; x < world.getChunks().length; x++) {
|
||||||
|
for (int z = 0; z < world.getChunks()[x].length; z++) {
|
||||||
|
List<Byte[]> blockChunk = world.getLightEngineBlock().getBlockLightBitMask(x, z);
|
||||||
|
if (blockChunk == null) {
|
||||||
|
blockChunk = new ArrayList<>();
|
||||||
|
}
|
||||||
|
List<Byte[]> skyChunk = null;
|
||||||
|
if (world.hasSkyLight()) {
|
||||||
|
skyChunk = world.getLightEngineSky().getSkyLightBitMask(x, z);
|
||||||
|
}
|
||||||
|
if (skyChunk == null) {
|
||||||
|
skyChunk = new ArrayList<>();
|
||||||
|
}
|
||||||
|
PacketPlayOutLightUpdate chunkdata = new PacketPlayOutLightUpdate(x, z, true, skyChunk, blockChunk);
|
||||||
|
sendPacket(chunkdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SkinResponse skinresponce = isBungeecord ? bungeeSkin : MojangAPIUtils.getSkinFromMojangServer(player.getName());
|
SkinResponse skinresponce = isBungeecord ? bungeeSkin : MojangAPIUtils.getSkinFromMojangServer(player.getName());
|
||||||
PlayerSkinProperty skin = skinresponce != null ? new PlayerSkinProperty(skinresponce.getSkin(), skinresponce.getSignature()) : null;
|
PlayerSkinProperty skin = skinresponce != null ? new PlayerSkinProperty(skinresponce.getSkin(), skinresponce.getSignature()) : null;
|
||||||
PacketPlayOutPlayerInfo info = new PacketPlayOutPlayerInfo(PlayerInfoAction.ADD_PLAYER, player.getUUID(), new PlayerInfoData.PlayerInfoDataAddPlayer(player.getName(), Optional.ofNullable(skin), p.getDefaultGamemode(), 0, false, Optional.empty()));
|
PacketPlayOutPlayerInfo info = new PacketPlayOutPlayerInfo(PlayerInfoAction.ADD_PLAYER, player.getUUID(), new PlayerInfoData.PlayerInfoDataAddPlayer(player.getName(), Optional.ofNullable(skin), p.getDefaultGamemode(), 0, false, Optional.empty()));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,111 @@
|
||||||
|
package com.loohp.limbo.Server.Packets;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.loohp.limbo.Utils.DataTypeIO;
|
||||||
|
|
||||||
|
public class PacketPlayOutLightUpdate extends PacketOut {
|
||||||
|
|
||||||
|
private int chunkX;
|
||||||
|
private int chunkZ;
|
||||||
|
private boolean trustEdges;
|
||||||
|
private int skyLightBitMask;
|
||||||
|
private int blockLightBitMask;
|
||||||
|
private List<Byte[]> skylightArrays;
|
||||||
|
private List<Byte[]> blocklightArrays;
|
||||||
|
|
||||||
|
public PacketPlayOutLightUpdate(int chunkX, int chunkZ, boolean trustEdges, List<Byte[]> skylightArrays, List<Byte[]> blocklightArrays) {
|
||||||
|
this.chunkX = chunkX;
|
||||||
|
this.chunkZ = chunkZ;
|
||||||
|
this.trustEdges = trustEdges;
|
||||||
|
this.skylightArrays = skylightArrays;
|
||||||
|
this.blocklightArrays = blocklightArrays;
|
||||||
|
|
||||||
|
skyLightBitMask = 0;
|
||||||
|
for (int i = Math.min(17, skylightArrays.size() - 1); i >= 0; i--) {
|
||||||
|
skyLightBitMask = skyLightBitMask >> 1;
|
||||||
|
if (skylightArrays.get(i) != null) {
|
||||||
|
skyLightBitMask |= 131072;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blockLightBitMask = 0;
|
||||||
|
for (int i = Math.min(17, blocklightArrays.size() - 1); i >= 0; i--) {
|
||||||
|
blockLightBitMask = blockLightBitMask >> 1;
|
||||||
|
if (blocklightArrays.get(i) != null) {
|
||||||
|
blockLightBitMask |= 131072;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getChunkX() {
|
||||||
|
return chunkX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getChunkZ() {
|
||||||
|
return chunkZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTrustEdges() {
|
||||||
|
return trustEdges;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSkyLightBitMask() {
|
||||||
|
return skyLightBitMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBlockLightBitMask() {
|
||||||
|
return blockLightBitMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Byte[]> getSkylightArrays() {
|
||||||
|
return skylightArrays;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Byte[]> getBlocklightArrays() {
|
||||||
|
return blocklightArrays;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] serializePacket() throws IOException {
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
DataOutputStream output = new DataOutputStream(buffer);
|
||||||
|
output.writeByte(Packet.getPlayOut().get(getClass()));
|
||||||
|
DataTypeIO.writeVarInt(output, chunkX);
|
||||||
|
DataTypeIO.writeVarInt(output, chunkZ);
|
||||||
|
output.writeBoolean(trustEdges);
|
||||||
|
DataTypeIO.writeVarInt(output, skyLightBitMask);
|
||||||
|
DataTypeIO.writeVarInt(output, blockLightBitMask);
|
||||||
|
DataTypeIO.writeVarInt(output, ~skyLightBitMask & 262143);
|
||||||
|
DataTypeIO.writeVarInt(output, ~blockLightBitMask & 262143);
|
||||||
|
|
||||||
|
for (int i = skylightArrays.size() - 1; i >= 0; i--) {
|
||||||
|
Byte[] array = skylightArrays.get(i);
|
||||||
|
if (array != null) {
|
||||||
|
DataTypeIO.writeVarInt(output, 2048);
|
||||||
|
//System.out.println(Arrays.toString(ArrayUtils.toPrimitive(array)));
|
||||||
|
for (int u = 0; u < array.length; u++) {
|
||||||
|
output.writeByte(array[u]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = blocklightArrays.size() - 1; i >= 0; i--) {
|
||||||
|
Byte[] array = blocklightArrays.get(i);
|
||||||
|
if (array != null) {
|
||||||
|
DataTypeIO.writeVarInt(output, 2048);
|
||||||
|
//System.out.println(Arrays.toString(ArrayUtils.toPrimitive(array)));
|
||||||
|
for (int u = 0; u < array.length; u++) {
|
||||||
|
output.writeByte(array[u]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -60,4 +60,34 @@ public class BlockState {
|
||||||
properties.putString(key, ((T) value).toString());
|
properties.putString(key, ((T) value).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((tag == null) ? 0 : tag.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
BlockState other = (BlockState) obj;
|
||||||
|
if (tag == null) {
|
||||||
|
if (other.tag != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!tag.equals(other.tag)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,17 @@
|
||||||
package com.loohp.limbo.World;
|
package com.loohp.limbo.World;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import com.loohp.limbo.Utils.NamespacedKey;
|
import com.loohp.limbo.Utils.NamespacedKey;
|
||||||
|
|
||||||
public class Environment {
|
public class Environment {
|
||||||
|
|
||||||
public static final Environment NORMAL = new Environment(new NamespacedKey("minecraft:overworld"));
|
public static final Environment NORMAL = new Environment(new NamespacedKey("minecraft:overworld"), true);
|
||||||
public static final Environment NETHER = new Environment(new NamespacedKey("minecraft:the_nether"));
|
public static final Environment NETHER = new Environment(new NamespacedKey("minecraft:the_nether"), false);
|
||||||
public static final Environment END = new Environment(new NamespacedKey("minecraft:the_end"));
|
public static final Environment END = new Environment(new NamespacedKey("minecraft:the_end"), false);
|
||||||
|
|
||||||
|
public static final Set<Environment> REGISTERED_ENVIRONMENTS = new HashSet<>();
|
||||||
|
|
||||||
public static Environment fromNamespacedKey(NamespacedKey key) {
|
public static Environment fromNamespacedKey(NamespacedKey key) {
|
||||||
if (key.equals(NORMAL.getNamespacedKey())) {
|
if (key.equals(NORMAL.getNamespacedKey())) {
|
||||||
|
|
@ -19,19 +24,71 @@ public class Environment {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static Environment createCustom(NamespacedKey key) {
|
public static Environment createCustom(NamespacedKey key) {
|
||||||
return new Environment(key);
|
return createCustom(key, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Environment createCustom(NamespacedKey key, boolean hasSkyLight) {
|
||||||
|
if (REGISTERED_ENVIRONMENTS.stream().anyMatch(each -> each.getNamespacedKey().equals(key))) {
|
||||||
|
throw new IllegalArgumentException("An Environment is already created with this NamespacedKey");
|
||||||
|
}
|
||||||
|
return new Environment(key, hasSkyLight);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Environment getCustom(NamespacedKey key) {
|
||||||
|
return REGISTERED_ENVIRONMENTS.stream().filter(each -> each.getNamespacedKey().equals(key)).findFirst().orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
//=========================
|
//=========================
|
||||||
|
|
||||||
private NamespacedKey key;
|
private NamespacedKey key;
|
||||||
|
private boolean hasSkyLight;
|
||||||
|
|
||||||
private Environment(NamespacedKey key) {
|
private Environment(NamespacedKey key, boolean hasSkyLight) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
|
this.hasSkyLight = hasSkyLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NamespacedKey getNamespacedKey() {
|
public NamespacedKey getNamespacedKey() {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasSkyLight() {
|
||||||
|
return hasSkyLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + (hasSkyLight ? 1231 : 1237);
|
||||||
|
result = prime * result + ((key == null) ? 0 : key.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Environment other = (Environment) obj;
|
||||||
|
if (hasSkyLight != other.hasSkyLight) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (key == null) {
|
||||||
|
if (other.key != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!key.equals(other.key)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.loohp.limbo.World;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public abstract class LightEngine {
|
||||||
|
|
||||||
|
private static Map<String, Byte> blockLightLevelMapping = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:torch", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
blockLightLevelMapping.put("minecraft:beacon", (byte) 15);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getBlockLight(BlockState block) {
|
||||||
|
return blockLightLevelMapping.getOrDefault(block.getType().toString(), (byte) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
package com.loohp.limbo.World;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class LightEngineBlock extends LightEngine {
|
||||||
|
|
||||||
|
private World world;
|
||||||
|
private byte[][][] blockLightArray;
|
||||||
|
|
||||||
|
public LightEngineBlock(World world) {
|
||||||
|
blockLightArray = new byte[world.getChunkWidth() * 16][16 * 18][world.getChunkLength() * 16];
|
||||||
|
this.world = world;
|
||||||
|
updateWorld();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateWorld() {
|
||||||
|
blockLightArray = new byte[world.getChunkWidth() * 16][16 * 18][world.getChunkLength() * 16];
|
||||||
|
for (int x = 0; x < world.getWidth(); x++) {
|
||||||
|
for (int y = 0; y < 256; y++) {
|
||||||
|
for (int z = 0; z < world.getLength(); z++) {
|
||||||
|
updateBlock(x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateBlock(int x, int y, int z) {
|
||||||
|
BlockState block = world.getBlock(x, y, z);
|
||||||
|
int lightLevel = getBlockLight(block);
|
||||||
|
if (lightLevel > 0) {
|
||||||
|
propergate(lightLevel, x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void propergate(int level, int x, int y, int z) {
|
||||||
|
if (blockLightArray[x][y + 16][z] < level) {
|
||||||
|
blockLightArray[x][y + 16][z] = (byte) level;
|
||||||
|
if (level > 1) {
|
||||||
|
propergate(level - 1, x + 1, y, z);
|
||||||
|
propergate(level - 1, x - 1, y, z);
|
||||||
|
propergate(level - 1, x, y + 1, z);
|
||||||
|
propergate(level - 1, x, y - 1, z);
|
||||||
|
propergate(level - 1, x, y, z + 1);
|
||||||
|
propergate(level - 1, x, y, z - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Byte[]> getBlockLightBitMask(int chunkX, int chunkZ) {
|
||||||
|
List<Byte[]> subchunks = new ArrayList<>(18);
|
||||||
|
int startX = chunkX * 16;
|
||||||
|
int endingX = startX + 16;
|
||||||
|
int startZ = chunkZ * 16;
|
||||||
|
int endingZ = startZ + 16;
|
||||||
|
|
||||||
|
for (int sub = 17; sub >= 0; sub--) {
|
||||||
|
List<Byte> array = new ArrayList<>();
|
||||||
|
for (int y = sub * 16; y < (sub * 16) + 16; y++) {
|
||||||
|
for (int z = startZ; z < endingZ; z++) {
|
||||||
|
for (int x = startX; x < endingX; x += 2) {
|
||||||
|
int bit = blockLightArray[x][y][z];
|
||||||
|
bit = bit << 4;
|
||||||
|
bit |= blockLightArray[x + 1][y][z];
|
||||||
|
array.add((byte) bit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
subchunks.add(array.toArray(new Byte[2048]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return subchunks;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
package com.loohp.limbo.World;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class LightEngineSky extends LightEngine {
|
||||||
|
|
||||||
|
private World world;
|
||||||
|
private byte[][][] skyLightArray;
|
||||||
|
|
||||||
|
public LightEngineSky(World world) {
|
||||||
|
skyLightArray = new byte[world.getChunkWidth() * 16][16 * 18][world.getChunkLength() * 16];
|
||||||
|
/*
|
||||||
|
for (byte[][] arrayarray : skyLightArray) {
|
||||||
|
for (byte[] array : arrayarray) {
|
||||||
|
Arrays.fill(array, (byte) 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
this.world = world;
|
||||||
|
updateWorld();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateWorld() {
|
||||||
|
skyLightArray = new byte[world.getChunkWidth() * 16][16 * 18][world.getChunkLength() * 16];
|
||||||
|
for (int x = 0; x < world.getWidth(); x++) {
|
||||||
|
for (int z = 0; z < world.getLength(); z++) {
|
||||||
|
updateColumn(x, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateColumn(int x, int z) {
|
||||||
|
for (int y = 272; y >= 256; y--) {
|
||||||
|
propergate(15, x, y, z);
|
||||||
|
}
|
||||||
|
for (int y = 255; y >= 0; y--) {
|
||||||
|
BlockState block = world.getBlock(x, y, z);
|
||||||
|
//System.out.println("X:" + x + " Y: " + y + " Z: " + z + " Block: " + block.getType().toString());
|
||||||
|
if (!block.getType().toString().equals("minecraft:air")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
propergate(15, x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void propergate(int level, int x, int y, int z) {
|
||||||
|
try {
|
||||||
|
if (skyLightArray[x][y + 16][z] < level) {
|
||||||
|
skyLightArray[x][y + 16][z] = (byte) level;
|
||||||
|
if (level > 1) {
|
||||||
|
propergate(level - 1, x + 1, y, z);
|
||||||
|
propergate(level - 1, x - 1, y, z);
|
||||||
|
propergate(level - 1, x, y + 1, z);
|
||||||
|
propergate(level - 1, x, y, z + 1);
|
||||||
|
propergate(level - 1, x, y, z - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ArrayIndexOutOfBoundsException e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Byte[]> getSkyLightBitMask(int chunkX, int chunkZ) {
|
||||||
|
List<Byte[]> subchunks = new ArrayList<>(18);
|
||||||
|
int startX = chunkX * 16;
|
||||||
|
int endingX = startX + 16;
|
||||||
|
int startZ = chunkZ * 16;
|
||||||
|
int endingZ = startZ + 16;
|
||||||
|
|
||||||
|
for (int sub = 17; sub >= 0; sub--) {
|
||||||
|
List<Byte> array = new ArrayList<>();
|
||||||
|
for (int y = sub * 16; y < (sub * 16) + 16; y++) {
|
||||||
|
for (int z = startZ; z < endingZ; z++) {
|
||||||
|
for (int x = startX; x < endingX; x += 2) {
|
||||||
|
int bit = skyLightArray[x][y][z];
|
||||||
|
bit = bit << 4;
|
||||||
|
bit |= skyLightArray[x + 1][y][z];
|
||||||
|
array.add((byte) bit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
subchunks.add(array.toArray(new Byte[2048]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return subchunks;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -78,11 +78,16 @@ public class Schematic {
|
||||||
heightMap.putLongArray("MOTION_BLOCKING", new long[] {1371773531765642314L,1389823183635651148L,1371738278539598925L,1389823183635388492L,1353688558756731469L,1389823114781694027L,1317765589597723213L,1371773531899860042L,1389823183635651149L,1371773462911685197L,1389823183635650636L,1353688626805119565L,1371773531900123211L,1335639250618849869L,1371738278674077258L,1389823114781694028L,1353723811310638154L,1371738278674077259L,1335674228429068364L,1335674228429067338L,1335674228698027594L,1317624576693539402L,1335709481520370249L,1299610178184057417L,1335638906349064264L,1299574993811968586L,1299574924958011464L,1299610178184056904L,1299574924958011464L,1299610109330100296L,1299574924958011464L,1299574924823793736L,1299574924958011465L,1281525273222484040L,1299574924958011464L,1281525273222484040L,9548107335L});
|
heightMap.putLongArray("MOTION_BLOCKING", new long[] {1371773531765642314L,1389823183635651148L,1371738278539598925L,1389823183635388492L,1353688558756731469L,1389823114781694027L,1317765589597723213L,1371773531899860042L,1389823183635651149L,1371773462911685197L,1389823183635650636L,1353688626805119565L,1371773531900123211L,1335639250618849869L,1371738278674077258L,1389823114781694028L,1353723811310638154L,1371738278674077259L,1335674228429068364L,1335674228429067338L,1335674228698027594L,1317624576693539402L,1335709481520370249L,1299610178184057417L,1335638906349064264L,1299574993811968586L,1299574924958011464L,1299610178184056904L,1299574924958011464L,1299610109330100296L,1299574924958011464L,1299574924823793736L,1299574924958011465L,1281525273222484040L,1299574924958011464L,1281525273222484040L,9548107335L});
|
||||||
chunk.setHeightMaps(heightMap);
|
chunk.setHeightMaps(heightMap);
|
||||||
chunk.setBiomes(new int[256]);
|
chunk.setBiomes(new int[256]);
|
||||||
//chunk.cleanupPalettesAndBlockStates();
|
chunk.cleanupPalettesAndBlockStates();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
world.getLightEngineBlock().updateWorld();
|
||||||
|
if (world.hasSkyLight()) {
|
||||||
|
world.getLightEngineSky().updateWorld();
|
||||||
|
}
|
||||||
|
|
||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -13,11 +13,17 @@ public class World {
|
||||||
private String name;
|
private String name;
|
||||||
private Environment environment;
|
private Environment environment;
|
||||||
private Chunk[][] chunks;
|
private Chunk[][] chunks;
|
||||||
|
private int width;
|
||||||
|
private int length;
|
||||||
|
private LightEngineBlock lightEngineBlock;
|
||||||
|
private LightEngineSky lightEngineSky;
|
||||||
|
|
||||||
public World(String name, int width, int length, Environment environment) {
|
public World(String name, int width, int length, Environment environment) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.environment = environment;
|
this.environment = environment;
|
||||||
this.chunks = new Chunk[(width >> 4) + 1][(length >> 4) + 1];
|
this.chunks = new Chunk[(width >> 4) + 1][(length >> 4) + 1];
|
||||||
|
this.width = width;
|
||||||
|
this.length = length;
|
||||||
|
|
||||||
for (int x = 0; x < chunks.length; x++) {
|
for (int x = 0; x < chunks.length; x++) {
|
||||||
for (int z = 0; z < chunks[x].length; z++) {
|
for (int z = 0; z < chunks[x].length; z++) {
|
||||||
|
|
@ -41,6 +47,23 @@ public class World {
|
||||||
chunk.setTileEntities(new ListTag<CompoundTag>(CompoundTag.class));
|
chunk.setTileEntities(new ListTag<CompoundTag>(CompoundTag.class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.lightEngineBlock = new LightEngineBlock(this);
|
||||||
|
if (environment.hasSkyLight()) {
|
||||||
|
this.lightEngineSky = new LightEngineSky(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public LightEngineBlock getLightEngineBlock() {
|
||||||
|
return lightEngineBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LightEngineSky getLightEngineSky() {
|
||||||
|
return lightEngineSky;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasSkyLight() {
|
||||||
|
return lightEngineSky != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setBlock(int x, int y, int z, String blockdata) {
|
protected void setBlock(int x, int y, int z, String blockdata) {
|
||||||
|
|
@ -59,7 +82,13 @@ public class World {
|
||||||
chunk = Chunk.newChunk();
|
chunk = Chunk.newChunk();
|
||||||
this.chunks[(x >> 4)][(z >> 4)] = chunk;
|
this.chunks[(x >> 4)][(z >> 4)] = chunk;
|
||||||
}
|
}
|
||||||
return new BlockState(chunk.getBlockStateAt(x % 16, y % 16, z % 16));
|
|
||||||
|
CompoundTag tag = chunk.getBlockStateAt(x, y, z);
|
||||||
|
if (tag == null) {
|
||||||
|
tag = new CompoundTag();
|
||||||
|
tag.putString("Name", "minecraft:air");
|
||||||
|
}
|
||||||
|
return new BlockState(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBlock(int x, int y, int z, BlockState state) {
|
public void setBlock(int x, int y, int z, BlockState state) {
|
||||||
|
|
@ -87,6 +116,22 @@ public class World {
|
||||||
return environment;
|
return environment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLength() {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getChunkWidth() {
|
||||||
|
return (width >> 4) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getChunkLength() {
|
||||||
|
return (length >> 4) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
"PacketPlayOutChat": "0x0E",
|
"PacketPlayOutChat": "0x0E",
|
||||||
"PacketPlayOutPlayerAbilities": "0x30",
|
"PacketPlayOutPlayerAbilities": "0x30",
|
||||||
"PacketPlayOutMapChunk": "0x20",
|
"PacketPlayOutMapChunk": "0x20",
|
||||||
|
"PacketPlayOutLightUpdate": "0x23",
|
||||||
"PacketPlayOutKeepAlive": "0x1F",
|
"PacketPlayOutKeepAlive": "0x1F",
|
||||||
"PacketPlayOutPlayerInfo": "0x32",
|
"PacketPlayOutPlayerInfo": "0x32",
|
||||||
"PacketPlayOutUpdateViewPosition": "0x40",
|
"PacketPlayOutUpdateViewPosition": "0x40",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue