001/* 002 * Trident - A Multithreaded Server Alternative 003 * Copyright 2014 The TridentSDK Team 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package net.tridentsdk.server.world; 019 020import net.tridentsdk.meta.nbt.NBTField; 021import net.tridentsdk.meta.nbt.NBTSerializable; 022import net.tridentsdk.meta.nbt.TagType; 023import net.tridentsdk.util.NibbleArray; 024 025import java.util.Arrays; 026 027public final class ChunkSection implements NBTSerializable { 028 public static final int LENGTH = 4096; // 16^3 (width * height * depth) 029 030 @NBTField(name = "Blocks", type = TagType.BYTE_ARRAY) 031 public byte[] rawTypes = new byte[LENGTH]; 032 @NBTField(name = "Add", type = TagType.BYTE_ARRAY) 033 public byte[] add = new byte[LENGTH / 2]; 034 @NBTField(name = "Data", type = TagType.BYTE_ARRAY) 035 public byte[] data = new byte[LENGTH / 2]; 036 @NBTField(name = "BlockLight", type = TagType.BYTE_ARRAY) 037 public byte[] blockLight = new byte[LENGTH / 2]; 038 @NBTField(name = "SkyLight", type = TagType.BYTE_ARRAY) 039 public byte[] skyLight = new byte[LENGTH / 2]; 040 @NBTField(name = "Y", type = TagType.BYTE) 041 protected byte y; 042 public char[] types; 043 044 public ChunkSection(byte i) { 045 this.y = i; 046 } 047 048 // Serialization constructor 049 public ChunkSection() { 050 } 051 052 /** 053 * Gets the position in the section array 054 */ 055 public byte y() { 056 return y; 057 } 058 059 protected void loadBlocks() { 060 //NibbleArray add = new NibbleArray(this.add); 061 //NibbleArray data = new NibbleArray(this.data); 062 063 // DEBUG ===== makes the entire chunk completely lit, not ideal for production 064 Arrays.fill(skyLight, (byte) 255); 065 // ===== 066 067 types = new char[rawTypes.length]; 068 069 for (int i = 0; i < LENGTH; i += 1) { 070 byte b; 071 byte bData; 072 int bAdd; 073 074 /* Get block data; use extras accordingly */ 075 b = rawTypes[i]; 076 bAdd = NibbleArray.get(this.add, i) << 12; 077 bData = NibbleArray.get(this.data, i); 078 079 types[i] = (char) (bAdd | ((b & 0xff) << 4) | bData); 080 } 081 } 082 083 protected void updateRaw() { 084 updateRaw(types); 085 } 086 087 protected void updateRaw(char[] data) { 088 if(data.length != LENGTH) 089 throw new IllegalArgumentException("Data length must be 4096!"); 090 091 for (int i = 0; i < LENGTH; i++) { 092 rawTypes[i] = (byte) ((data[i] >> 4) & 0xFF); 093 NibbleArray.set(this.data, i, (byte) (data[i] & 0xf)); 094 NibbleArray.set(this.add, i, (byte) (data[i] >> 12)); 095 } 096 } 097 098 protected void setBlocks(char[] data) { 099 this.types = data; 100 } 101 102 protected void setData(byte[] data) { 103 this.data = data; 104 } 105 106 public char[] types() { 107 return types; 108 } 109}