From 02e79afe525ae63a3a95b9c260e6191c87149f82 Mon Sep 17 00:00:00 2001 From: SenseiTarzan Date: Fri, 23 Aug 2024 02:31:34 +0200 Subject: [PATCH] create system Block based on PocketMine-MP 5 thanks dylan --- pom.xml | 5 + src/main/java/org/sculk/block/AirBlock.java | 32 + src/main/java/org/sculk/block/Block.java | 306 ++++++++ .../java/org/sculk/block/BlockBreakInfo.java | 79 ++ .../java/org/sculk/block/BlockIdentifier.java | 44 ++ .../java/org/sculk/block/BlockToolType.java | 35 + .../java/org/sculk/block/BlockTypeIds.java | 725 ++++++++++++++++++ .../java/org/sculk/block/BlockTypeInfo.java | 36 + ...InvalidSerializedRuntimeDataException.java | 22 + .../block/RuntimeBlockStateRegistry.java | 103 +++ .../org/sculk/block/TransparentBlock.java | 27 + .../java/org/sculk/block/UnknownBlock.java | 36 + .../java/org/sculk/block/VanillaBlocks.java | 30 + src/main/java/org/sculk/block/tile/Tile.java | 18 + .../data/runtime/RuntimeDataDescriber.java | 65 ++ .../sculk/data/runtime/RuntimeDataReader.java | 221 ++++++ .../runtime/RuntimeDataSizeCalculator.java | 113 +++ .../sculk/data/runtime/RuntimeDataWriter.java | 172 +++++ src/main/java/org/sculk/math/Axis.java | 35 + src/main/java/org/sculk/math/Facing.java | 153 ++++ src/main/java/org/sculk/utils/Binary.java | 45 ++ src/main/java/org/sculk/utils/SculkMath.java | 37 + src/main/java/org/sculk/world/Position.java | 231 ++++++ src/main/java/org/sculk/world/World.java | 18 + .../org/sculk/world/light/LightUpdate.java | 21 + 25 files changed, 2609 insertions(+) create mode 100644 src/main/java/org/sculk/block/AirBlock.java create mode 100644 src/main/java/org/sculk/block/Block.java create mode 100644 src/main/java/org/sculk/block/BlockBreakInfo.java create mode 100644 src/main/java/org/sculk/block/BlockIdentifier.java create mode 100644 src/main/java/org/sculk/block/BlockToolType.java create mode 100644 src/main/java/org/sculk/block/BlockTypeIds.java create mode 100644 src/main/java/org/sculk/block/BlockTypeInfo.java create mode 100644 src/main/java/org/sculk/block/InvalidSerializedRuntimeDataException.java create mode 100644 src/main/java/org/sculk/block/RuntimeBlockStateRegistry.java create mode 100644 src/main/java/org/sculk/block/TransparentBlock.java create mode 100644 src/main/java/org/sculk/block/UnknownBlock.java create mode 100644 src/main/java/org/sculk/block/VanillaBlocks.java create mode 100644 src/main/java/org/sculk/block/tile/Tile.java create mode 100644 src/main/java/org/sculk/data/runtime/RuntimeDataDescriber.java create mode 100644 src/main/java/org/sculk/data/runtime/RuntimeDataReader.java create mode 100644 src/main/java/org/sculk/data/runtime/RuntimeDataSizeCalculator.java create mode 100644 src/main/java/org/sculk/data/runtime/RuntimeDataWriter.java create mode 100644 src/main/java/org/sculk/math/Axis.java create mode 100644 src/main/java/org/sculk/math/Facing.java create mode 100644 src/main/java/org/sculk/utils/Binary.java create mode 100644 src/main/java/org/sculk/utils/SculkMath.java create mode 100644 src/main/java/org/sculk/world/Position.java create mode 100644 src/main/java/org/sculk/world/World.java create mode 100644 src/main/java/org/sculk/world/light/LightUpdate.java diff --git a/pom.xml b/pom.xml index e8bf360..7a1e475 100644 --- a/pom.xml +++ b/pom.xml @@ -110,6 +110,11 @@ + + com.dynatrace.hash4j + hash4j + 0.18.0 + com.google.inject guice diff --git a/src/main/java/org/sculk/block/AirBlock.java b/src/main/java/org/sculk/block/AirBlock.java new file mode 100644 index 0000000..761b3dd --- /dev/null +++ b/src/main/java/org/sculk/block/AirBlock.java @@ -0,0 +1,32 @@ +package org.sculk.block; + +import org.sculk.data.runtime.RuntimeDataDescriber; + +import java.util.concurrent.atomic.AtomicBoolean; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public class AirBlock extends Block{ + + public AirBlock(BlockIdentifier identifier, String name, BlockTypeInfo blockTypeInfo) { + super(identifier, name, blockTypeInfo); + } + + @Override + public boolean isTransparent() { + return true; + } +} diff --git a/src/main/java/org/sculk/block/Block.java b/src/main/java/org/sculk/block/Block.java new file mode 100644 index 0000000..470a9d8 --- /dev/null +++ b/src/main/java/org/sculk/block/Block.java @@ -0,0 +1,306 @@ +package org.sculk.block; + +import com.dynatrace.hash4j.hashing.XXH3_64; +import jline.internal.Nullable; +import lombok.SneakyThrows; +import org.sculk.data.runtime.RuntimeDataDescriber; +import org.sculk.data.runtime.RuntimeDataReader; +import org.sculk.data.runtime.RuntimeDataSizeCalculator; +import org.sculk.data.runtime.RuntimeDataWriter; +import org.sculk.world.Position; +import lombok.Getter; +import org.sculk.utils.Binary; +import org.sculk.world.World; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public class Block implements Cloneable{ + static final long INTERNAL_STATE_DATA_BITS = 11; + static final long INTERNAL_STATE_DATA_MASK = ~(~0 << Block.INTERNAL_STATE_DATA_BITS); + static final long EMPTY_STATE_ID = computeStateIdXorMask(BlockTypeIds.AIR); + + private static long computeStateIdXorMask(long typeId){ + return typeId << Block.INTERNAL_STATE_DATA_BITS | (XXH3_64.create().hashBytesToLong(Binary.writeLLong(typeId)) & Block.INTERNAL_STATE_DATA_MASK); + } + + @Getter + private BlockIdentifier identifier; + @Getter + private String fallbackName; + @Getter + private BlockTypeInfo typeInfo; + @Getter + private Position position; + private final long requiredBlockItemStateDataBits; + private final long requiredBlockOnlyStateDataBits; + @Nullable + private List collisionBoxes; + + private final long stateIdXorMask; + + private Block defaultState; + + public Block(BlockIdentifier identifier, String name, BlockTypeInfo blockTypeInfo){ + this.identifier = identifier; + this.fallbackName = name; + this.typeInfo = blockTypeInfo; + this.position = new Position(0,0,0, null); + RuntimeDataSizeCalculator calculator = new RuntimeDataSizeCalculator(); + this.describeBlockItemState(calculator); + this.requiredBlockItemStateDataBits = calculator.getBitsUsed(); + calculator.reset(); + this.describeBlockOnlyState(calculator); + this.requiredBlockOnlyStateDataBits = calculator.getBitsUsed(); + this.stateIdXorMask = Block.computeStateIdXorMask(identifier.getBlockTypeId()); + Block defaultState = this.clone(); + this.defaultState = defaultState; + defaultState.defaultState = defaultState; + } + + public final void position(World world, long x, long y, long z) { + this.position = new Position((double)x, (double)y, (double)z, world); + this.collisionBoxes = null; + } + + public long getTypeId() { + return identifier.getBlockTypeId(); + } + + /** + * @internal + * + * Returns the full blockstate ID of this block. This is a compact way of representing a blockstate used to store + * blocks in chunks at runtime. + * + * This usually encodes all properties of the block, such as facing, open/closed, powered/unpowered, colour, etc. + * State ID may change depending on the properties of the block (e.g. a torch facing east will have a different + * state ID to one facing west). + * + * Some blocks (such as signs and chests) may store additional properties in an associated "tile" if they + * have too many possible values to be encoded into the state ID. These extra properties are **NOT** included in + * this function's result. + * + * This ID can be used to later obtain a copy of the block with the same state properties by using + * {@link RuntimeBlockStateRegistry::fromStateId()}. + */ + @SneakyThrows + public long getStateId() { + return encodeFullState() ^ stateIdXorMask; + } + /** + * Returns whether the given block has the same type and properties as this block. + *

+ * Note: Tile data (e.g. sign text, chest contents) are not compared here. + */ + public boolean isSameState(Block other){ + return this.getStateId() == other.getStateId(); + } + + public final boolean hasSameTypeId(Block other) { + return this.getTypeId() == other.getTypeId(); + } + + public final List getTypeTags() { + return typeInfo.getTypeTags(); + } + + public final boolean hasTypeTag(String tag) + { + return typeInfo.hasTypeTag(tag); + } + + /** + * Describes properties of this block which apply to both the block and item form of the block. + * Examples of suitable properties include colour, skull type, and any other information which **IS** kept when the + * block is mined or block-picked. + * + * The method implementation must NOT use conditional logic to determine which properties are written. It must + * always write the same properties in the same order, regardless of the current state of the block. + */ + @SneakyThrows + public void describeBlockItemState(RuntimeDataDescriber w) { + //NOOP + } + + /** + * Describes properties of this block which apply only to the block form of the block. + * Examples of suitable properties include facing, open/closed, powered/unpowered, on/off, and any other information + * which **IS NOT** kept when the block is mined or block-picked. + * + * The method implementation must NOT use conditional logic to determine which properties are written. It must + * always write the same properties in the same order, regardless of the current state of the block. + */ + @SneakyThrows + protected void describeBlockOnlyState(RuntimeDataDescriber w) { + //NOOP + } + + private void decodeBlockItemState(long data) throws InvalidSerializedRuntimeDataException { + RuntimeDataReader reader = new RuntimeDataReader(this.requiredBlockItemStateDataBits, data); + + this.describeBlockItemState(reader); + long readBits = reader.getOffset(); + if(this.requiredBlockItemStateDataBits != readBits){ + throw new InvalidSerializedRuntimeDataException(STR."\{this.getClass()}: Exactly $this->requiredBlockItemStateDataBits bits of block-item state data were provided, but \{readBits} were read"); + } + } + + private void decodeBlockOnlyState(long data) throws InvalidSerializedRuntimeDataException { + RuntimeDataReader reader = new RuntimeDataReader(this.requiredBlockOnlyStateDataBits, data); + + this.describeBlockOnlyState(reader); + long readBits = reader.getOffset(); + if(this.requiredBlockOnlyStateDataBits != readBits) + throw new InvalidSerializedRuntimeDataException(STR."\{this.getClass()}: Exactly this.requiredBlockOnlyStateDataBits bits of block-only state data were provided, but \{readBits} were read"); + } + + public long encodeBlockItemState() throws InvalidSerializedRuntimeDataException { + RuntimeDataWriter writer = new RuntimeDataWriter(this.requiredBlockItemStateDataBits); + + this.describeBlockItemState(writer); + long writtenBits = writer.getOffset(); + if(this.requiredBlockItemStateDataBits != writtenBits){ + throw new InvalidSerializedRuntimeDataException(STR."\{this.getClass()}: Exactly this.requiredBlockItemStateDataBits bits of block-item state data were expected, but \{writtenBits} were written"); + } + + return writer.getValue(); + } + + public long encodeBlockOnlyState() throws InvalidSerializedRuntimeDataException { + + RuntimeDataWriter writer = new RuntimeDataWriter(this.requiredBlockOnlyStateDataBits); + + this.describeBlockOnlyState(writer); + long writtenBits = writer.getOffset(); + if(this.requiredBlockOnlyStateDataBits != writtenBits){ + throw new InvalidSerializedRuntimeDataException(STR."\{this.getClass()}: Exactly this.requiredBlockOnlyStateDataBits bits of block-only state data were expected, but \{writtenBits} were written"); + } + + return writer.getValue(); + } + + private long encodeFullState() throws InvalidSerializedRuntimeDataException { + long blockItemBits = this.requiredBlockItemStateDataBits; + long blockOnlyBits = this.requiredBlockOnlyStateDataBits; + + if (blockOnlyBits == 0 && blockItemBits == 0) { + return 0; + } + + long result = 0; + if (blockItemBits > 0) { + result |= encodeBlockItemState(); + } + if (blockOnlyBits > 0) { + result |= encodeBlockOnlyState() << blockItemBits; + } + + return result; + } + + + public List generateStatePermutations() { + List permutations = new ArrayList<>(); + + long totalBits = this.requiredBlockItemStateDataBits + this.requiredBlockOnlyStateDataBits; + if (totalBits > INTERNAL_STATE_DATA_BITS) { + throw new IllegalStateException(STR."Block state data cannot use more than \{INTERNAL_STATE_DATA_BITS} bits"); + } + + for (long blockItemStateData = 0; blockItemStateData < (1L << this.requiredBlockItemStateDataBits); blockItemStateData++) { + Block withType = this.clone(); + try { + withType.decodeBlockItemState(blockItemStateData); + long encoded = withType.encodeBlockItemState(); + if (encoded != blockItemStateData) { + throw new IllegalStateException(STR."\{this.getClass().getSimpleName()}::decodeBlockItemState() accepts invalid inputs (returned \{encoded} for input \{blockItemStateData})"); + } + } catch (InvalidSerializedRuntimeDataException e) { + continue; + } + + for (long blockOnlyStateData = 0; blockOnlyStateData < (1L << this.requiredBlockOnlyStateDataBits); ++blockOnlyStateData) { + Block withState = withType.clone(); + try { + withState.decodeBlockOnlyState(blockOnlyStateData); + long encoded = withState.encodeBlockOnlyState(); + if (encoded != blockOnlyStateData) { + throw new IllegalStateException(STR."\{this.getClass().getSimpleName()}::decodeBlockOnlyState() accepts invalid inputs (returned \{encoded} for input \{blockOnlyStateData})"); + } + } catch (InvalidSerializedRuntimeDataException e) { + continue; + } + permutations.add(withState); + } + } + + return permutations; + } + + public Block clone() { + Block o = null; + try { + o = (Block) super.clone(); + o.position = o.getPosition().clone(); + + } catch(CloneNotSupportedException cnse) { + // Ne devrait jamais arriver, car nous implémentons + // l'interface Cloneable + cnse.printStackTrace(System.err); + } + // on renvoie le clone + return o; + } + + public int getLightLevel() { + return 0; + } + public int getLightFilter() { + return this.isTransparent() ? 0 : 15; + } + public boolean blocksDirectSkyLight() { + return getLightFilter() > 0; + } + + /** + * Returns whether this block allows any light to pass through it. + */ + public boolean isTransparent() { + return false; + } + + /** + * @deprecated Don't use this function. Its results are confusing and inconsistent. + *

+ * No one is sure what the meaning of this property actually is. It's borrowed from Minecraft Java Edition, and is + * used by various blocks for support checks. + *

+ * Things like signs and banners are considered "solid" despite having no collision box, and things like skulls and + * flower pots are considered non-solid despite obviously being "solid" in the conventional, real-world sense. + */ + public boolean isSolid() { + return true; + } + + public BlockBreakInfo getBreakInfo() { + return typeInfo.getBreakInfo(); + } +} diff --git a/src/main/java/org/sculk/block/BlockBreakInfo.java b/src/main/java/org/sculk/block/BlockBreakInfo.java new file mode 100644 index 0000000..e2ec34a --- /dev/null +++ b/src/main/java/org/sculk/block/BlockBreakInfo.java @@ -0,0 +1,79 @@ +package org.sculk.block; + +import jline.internal.Nullable; +import lombok.Getter; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public class BlockBreakInfo { + /** + * If the tool is the correct type and high enough harvest level (tool tier), base break time is hardness multiplied + * by this value. + */ + public final static float COMPATIBLE_TOOL_MULTIPLIER = 1.5F; + /** + * If the tool is an incorrect type or too low harvest level (tool tier), base break time is hardness multiplied by + * this value. + */ + public final static float INCOMPATIBLE_TOOL_MULTIPLIER = 5.0F; + @Getter + private float hardness; + @Getter + private BlockToolType toolType; + @Getter + private int toolHarvestLevel; + @Getter + private float blastResistance; + + BlockBreakInfo(float hardness, BlockToolType toolType, int toolHarvestLevel, float blastResistance) { + this.hardness = hardness; + this.toolType = toolType; + this.toolHarvestLevel = toolHarvestLevel; + this.blastResistance = blastResistance; + } + + BlockBreakInfo(float hardness, BlockToolType toolType, int toolHarvestLevel) { + this.hardness = hardness; + this.toolType = toolType; + this.toolHarvestLevel = toolHarvestLevel; + this.blastResistance = hardness * 5F; + } + BlockBreakInfo(float hardness, BlockToolType toolType) { + this.hardness = hardness; + this.toolType = toolType; + this.toolHarvestLevel = 0; + this.blastResistance = hardness * 5F; + } + + public static BlockBreakInfo instant() { + return instant(BlockToolType.NONE); + } + public static BlockBreakInfo instant(BlockToolType toolType) { + return instant(toolType, 0); + } + + public static BlockBreakInfo instant(BlockToolType toolType, int toolHarvestLevel) { + return new BlockBreakInfo(0, toolType, toolHarvestLevel); + } + + public static BlockBreakInfo indestructible(float blastResistance) { + return new BlockBreakInfo(-1.0F, BlockToolType.NONE, 0, blastResistance); + } + public static BlockBreakInfo indestructible() { + return new BlockBreakInfo(-1.0F, BlockToolType.NONE, 0, 18000000.0F); + } + +} diff --git a/src/main/java/org/sculk/block/BlockIdentifier.java b/src/main/java/org/sculk/block/BlockIdentifier.java new file mode 100644 index 0000000..e69988f --- /dev/null +++ b/src/main/java/org/sculk/block/BlockIdentifier.java @@ -0,0 +1,44 @@ +package org.sculk.block; + +import jline.internal.Nullable; +import org.sculk.block.tile.Tile; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public class BlockIdentifier { + private final long blockTypeId; + @Nullable + private Class tileClass; + + public BlockIdentifier(long blockTypeId) { + this.blockTypeId = blockTypeId; + this.tileClass = null; + } + + public BlockIdentifier(long blockTypeId, Class tileClass) { + this.blockTypeId = blockTypeId; + this.tileClass = tileClass; + } + + public long getBlockTypeId() { + return blockTypeId; + } + + @Nullable + public Class getTileClass() { + return tileClass; + } +} diff --git a/src/main/java/org/sculk/block/BlockToolType.java b/src/main/java/org/sculk/block/BlockToolType.java new file mode 100644 index 0000000..dd0d855 --- /dev/null +++ b/src/main/java/org/sculk/block/BlockToolType.java @@ -0,0 +1,35 @@ +package org.sculk.block; +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public enum BlockToolType { + NONE(0), + SWORD(1), + SHOVEL(1 << 1), + PICKAXE(1 << 2), + AXE(1 << 3), + SHEARS(1 << 4), + HOE(1 << 5); + + + private int value; + BlockToolType(int value){ + this.value = value; + } + + public int getValue() { + return value; + } +} diff --git a/src/main/java/org/sculk/block/BlockTypeIds.java b/src/main/java/org/sculk/block/BlockTypeIds.java new file mode 100644 index 0000000..4d49f5e --- /dev/null +++ b/src/main/java/org/sculk/block/BlockTypeIds.java @@ -0,0 +1,725 @@ +package org.sculk.block; +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public class BlockTypeIds { + + + + public static final int AIR = 10000; + + public static final int ACACIA_BUTTON = 10001; + public static final int ACACIA_DOOR = 10002; + public static final int ACACIA_FENCE = 10003; + public static final int ACACIA_FENCE_GATE = 10004; + public static final int ACACIA_LEAVES = 10005; + public static final int ACACIA_LOG = 10006; + public static final int ACACIA_PLANKS = 10007; + public static final int ACACIA_PRESSURE_PLATE = 10008; + public static final int ACACIA_SAPLING = 10009; + public static final int ACACIA_SIGN = 10010; + public static final int ACACIA_SLAB = 10011; + public static final int ACACIA_STAIRS = 10012; + public static final int ACACIA_TRAPDOOR = 10013; + public static final int ACACIA_WALL_SIGN = 10014; + public static final int ACACIA_WOOD = 10015; + public static final int ACTIVATOR_RAIL = 10016; + public static final int ALL_SIDED_MUSHROOM_STEM = 10017; + public static final int ALLIUM = 10018; + public static final int ANDESITE = 10019; + public static final int ANDESITE_SLAB = 10020; + public static final int ANDESITE_STAIRS = 10021; + public static final int ANDESITE_WALL = 10022; + public static final int ANVIL = 10023; + public static final int AZURE_BLUET = 10024; + public static final int BAMBOO = 10025; + public static final int BAMBOO_SAPLING = 10026; + public static final int BANNER = 10027; + public static final int BARREL = 10028; + public static final int BARRIER = 10029; + public static final int BEACON = 10030; + public static final int BED = 10031; + public static final int BEDROCK = 10032; + public static final int BEETROOTS = 10033; + public static final int BELL = 10034; + public static final int BIRCH_BUTTON = 10035; + public static final int BIRCH_DOOR = 10036; + public static final int BIRCH_FENCE = 10037; + public static final int BIRCH_FENCE_GATE = 10038; + public static final int BIRCH_LEAVES = 10039; + public static final int BIRCH_LOG = 10040; + public static final int BIRCH_PLANKS = 10041; + public static final int BIRCH_PRESSURE_PLATE = 10042; + public static final int BIRCH_SAPLING = 10043; + public static final int BIRCH_SIGN = 10044; + public static final int BIRCH_SLAB = 10045; + public static final int BIRCH_STAIRS = 10046; + public static final int BIRCH_TRAPDOOR = 10047; + public static final int BIRCH_WALL_SIGN = 10048; + public static final int BIRCH_WOOD = 10049; + public static final int BLAST_FURNACE = 10051; + public static final int BLUE_ICE = 10053; + public static final int BLUE_ORCHID = 10054; + public static final int BLUE_TORCH = 10055; + public static final int BONE_BLOCK = 10056; + public static final int BOOKSHELF = 10057; + public static final int BREWING_STAND = 10058; + public static final int BRICK_SLAB = 10059; + public static final int BRICK_STAIRS = 10060; + public static final int BRICK_WALL = 10061; + public static final int BRICKS = 10062; + public static final int BROWN_MUSHROOM = 10064; + public static final int BROWN_MUSHROOM_BLOCK = 10065; + public static final int CACTUS = 10066; + public static final int CAKE = 10067; + public static final int CARPET = 10068; + public static final int CARROTS = 10069; + public static final int CARVED_PUMPKIN = 10070; + public static final int CHEMICAL_HEAT = 10071; + public static final int CHEST = 10072; + public static final int CHISELED_QUARTZ = 10073; + public static final int CHISELED_RED_SANDSTONE = 10074; + public static final int CHISELED_SANDSTONE = 10075; + public static final int CHISELED_STONE_BRICKS = 10076; + public static final int CLAY = 10077; + public static final int COAL = 10078; + public static final int COAL_ORE = 10079; + public static final int COBBLESTONE = 10080; + public static final int COBBLESTONE_SLAB = 10081; + public static final int COBBLESTONE_STAIRS = 10082; + public static final int COBBLESTONE_WALL = 10083; + public static final int COBWEB = 10084; + public static final int COCOA_POD = 10085; + public static final int COMPOUND_CREATOR = 10086; + public static final int CONCRETE = 10087; + public static final int CONCRETE_POWDER = 10088; + public static final int CORAL = 10089; + public static final int CORAL_BLOCK = 10090; + public static final int CORAL_FAN = 10091; + public static final int CORNFLOWER = 10092; + public static final int CRACKED_STONE_BRICKS = 10093; + public static final int CRAFTING_TABLE = 10094; + public static final int CUT_RED_SANDSTONE = 10095; + public static final int CUT_RED_SANDSTONE_SLAB = 10096; + public static final int CUT_SANDSTONE = 10097; + public static final int CUT_SANDSTONE_SLAB = 10098; + public static final int DANDELION = 10100; + public static final int DARK_OAK_BUTTON = 10101; + public static final int DARK_OAK_DOOR = 10102; + public static final int DARK_OAK_FENCE = 10103; + public static final int DARK_OAK_FENCE_GATE = 10104; + public static final int DARK_OAK_LEAVES = 10105; + public static final int DARK_OAK_LOG = 10106; + public static final int DARK_OAK_PLANKS = 10107; + public static final int DARK_OAK_PRESSURE_PLATE = 10108; + public static final int DARK_OAK_SAPLING = 10109; + public static final int DARK_OAK_SIGN = 10110; + public static final int DARK_OAK_SLAB = 10111; + public static final int DARK_OAK_STAIRS = 10112; + public static final int DARK_OAK_TRAPDOOR = 10113; + public static final int DARK_OAK_WALL_SIGN = 10114; + public static final int DARK_OAK_WOOD = 10115; + public static final int DARK_PRISMARINE = 10116; + public static final int DARK_PRISMARINE_SLAB = 10117; + public static final int DARK_PRISMARINE_STAIRS = 10118; + public static final int DAYLIGHT_SENSOR = 10119; + public static final int DEAD_BUSH = 10120; + public static final int DETECTOR_RAIL = 10121; + public static final int DIAMOND = 10122; + public static final int DIAMOND_ORE = 10123; + public static final int DIORITE = 10124; + public static final int DIORITE_SLAB = 10125; + public static final int DIORITE_STAIRS = 10126; + public static final int DIORITE_WALL = 10127; + public static final int DIRT = 10128; + public static final int DOUBLE_TALLGRASS = 10129; + public static final int DRAGON_EGG = 10130; + public static final int DRIED_KELP = 10131; + public static final int DYED_SHULKER_BOX = 10132; + public static final int ELEMENT_ACTINIUM = 10133; + public static final int ELEMENT_ALUMINUM = 10134; + public static final int ELEMENT_AMERICIUM = 10135; + public static final int ELEMENT_ANTIMONY = 10136; + public static final int ELEMENT_ARGON = 10137; + public static final int ELEMENT_ARSENIC = 10138; + public static final int ELEMENT_ASTATINE = 10139; + public static final int ELEMENT_BARIUM = 10140; + public static final int ELEMENT_BERKELIUM = 10141; + public static final int ELEMENT_BERYLLIUM = 10142; + public static final int ELEMENT_BISMUTH = 10143; + public static final int ELEMENT_BOHRIUM = 10144; + public static final int ELEMENT_BORON = 10145; + public static final int ELEMENT_BROMINE = 10146; + public static final int ELEMENT_CADMIUM = 10147; + public static final int ELEMENT_CALCIUM = 10148; + public static final int ELEMENT_CALIFORNIUM = 10149; + public static final int ELEMENT_CARBON = 10150; + public static final int ELEMENT_CERIUM = 10151; + public static final int ELEMENT_CESIUM = 10152; + public static final int ELEMENT_CHLORINE = 10153; + public static final int ELEMENT_CHROMIUM = 10154; + public static final int ELEMENT_COBALT = 10155; + public static final int ELEMENT_CONSTRUCTOR = 10156; + public static final int ELEMENT_COPERNICIUM = 10157; + public static final int ELEMENT_COPPER = 10158; + public static final int ELEMENT_CURIUM = 10159; + public static final int ELEMENT_DARMSTADTIUM = 10160; + public static final int ELEMENT_DUBNIUM = 10161; + public static final int ELEMENT_DYSPROSIUM = 10162; + public static final int ELEMENT_EINSTEINIUM = 10163; + public static final int ELEMENT_ERBIUM = 10164; + public static final int ELEMENT_EUROPIUM = 10165; + public static final int ELEMENT_FERMIUM = 10166; + public static final int ELEMENT_FLEROVIUM = 10167; + public static final int ELEMENT_FLUORINE = 10168; + public static final int ELEMENT_FRANCIUM = 10169; + public static final int ELEMENT_GADOLINIUM = 10170; + public static final int ELEMENT_GALLIUM = 10171; + public static final int ELEMENT_GERMANIUM = 10172; + public static final int ELEMENT_GOLD = 10173; + public static final int ELEMENT_HAFNIUM = 10174; + public static final int ELEMENT_HASSIUM = 10175; + public static final int ELEMENT_HELIUM = 10176; + public static final int ELEMENT_HOLMIUM = 10177; + public static final int ELEMENT_HYDROGEN = 10178; + public static final int ELEMENT_INDIUM = 10179; + public static final int ELEMENT_IODINE = 10180; + public static final int ELEMENT_IRIDIUM = 10181; + public static final int ELEMENT_IRON = 10182; + public static final int ELEMENT_KRYPTON = 10183; + public static final int ELEMENT_LANTHANUM = 10184; + public static final int ELEMENT_LAWRENCIUM = 10185; + public static final int ELEMENT_LEAD = 10186; + public static final int ELEMENT_LITHIUM = 10187; + public static final int ELEMENT_LIVERMORIUM = 10188; + public static final int ELEMENT_LUTETIUM = 10189; + public static final int ELEMENT_MAGNESIUM = 10190; + public static final int ELEMENT_MANGANESE = 10191; + public static final int ELEMENT_MEITNERIUM = 10192; + public static final int ELEMENT_MENDELEVIUM = 10193; + public static final int ELEMENT_MERCURY = 10194; + public static final int ELEMENT_MOLYBDENUM = 10195; + public static final int ELEMENT_MOSCOVIUM = 10196; + public static final int ELEMENT_NEODYMIUM = 10197; + public static final int ELEMENT_NEON = 10198; + public static final int ELEMENT_NEPTUNIUM = 10199; + public static final int ELEMENT_NICKEL = 10200; + public static final int ELEMENT_NIHONIUM = 10201; + public static final int ELEMENT_NIOBIUM = 10202; + public static final int ELEMENT_NITROGEN = 10203; + public static final int ELEMENT_NOBELIUM = 10204; + public static final int ELEMENT_OGANESSON = 10205; + public static final int ELEMENT_OSMIUM = 10206; + public static final int ELEMENT_OXYGEN = 10207; + public static final int ELEMENT_PALLADIUM = 10208; + public static final int ELEMENT_PHOSPHORUS = 10209; + public static final int ELEMENT_PLATINUM = 10210; + public static final int ELEMENT_PLUTONIUM = 10211; + public static final int ELEMENT_POLONIUM = 10212; + public static final int ELEMENT_POTASSIUM = 10213; + public static final int ELEMENT_PRASEODYMIUM = 10214; + public static final int ELEMENT_PROMETHIUM = 10215; + public static final int ELEMENT_PROTACTINIUM = 10216; + public static final int ELEMENT_RADIUM = 10217; + public static final int ELEMENT_RADON = 10218; + public static final int ELEMENT_RHENIUM = 10219; + public static final int ELEMENT_RHODIUM = 10220; + public static final int ELEMENT_ROENTGENIUM = 10221; + public static final int ELEMENT_RUBIDIUM = 10222; + public static final int ELEMENT_RUTHENIUM = 10223; + public static final int ELEMENT_RUTHERFORDIUM = 10224; + public static final int ELEMENT_SAMARIUM = 10225; + public static final int ELEMENT_SCANDIUM = 10226; + public static final int ELEMENT_SEABORGIUM = 10227; + public static final int ELEMENT_SELENIUM = 10228; + public static final int ELEMENT_SILICON = 10229; + public static final int ELEMENT_SILVER = 10230; + public static final int ELEMENT_SODIUM = 10231; + public static final int ELEMENT_STRONTIUM = 10232; + public static final int ELEMENT_SULFUR = 10233; + public static final int ELEMENT_TANTALUM = 10234; + public static final int ELEMENT_TECHNETIUM = 10235; + public static final int ELEMENT_TELLURIUM = 10236; + public static final int ELEMENT_TENNESSINE = 10237; + public static final int ELEMENT_TERBIUM = 10238; + public static final int ELEMENT_THALLIUM = 10239; + public static final int ELEMENT_THORIUM = 10240; + public static final int ELEMENT_THULIUM = 10241; + public static final int ELEMENT_TIN = 10242; + public static final int ELEMENT_TITANIUM = 10243; + public static final int ELEMENT_TUNGSTEN = 10244; + public static final int ELEMENT_URANIUM = 10245; + public static final int ELEMENT_VANADIUM = 10246; + public static final int ELEMENT_XENON = 10247; + public static final int ELEMENT_YTTERBIUM = 10248; + public static final int ELEMENT_YTTRIUM = 10249; + public static final int ELEMENT_ZERO = 10250; + public static final int ELEMENT_ZINC = 10251; + public static final int ELEMENT_ZIRCONIUM = 10252; + public static final int EMERALD = 10253; + public static final int EMERALD_ORE = 10254; + public static final int ENCHANTING_TABLE = 10255; + public static final int END_PORTAL_FRAME = 10256; + public static final int END_ROD = 10257; + public static final int END_STONE = 10258; + public static final int END_STONE_BRICK_SLAB = 10259; + public static final int END_STONE_BRICK_STAIRS = 10260; + public static final int END_STONE_BRICK_WALL = 10261; + public static final int END_STONE_BRICKS = 10262; + public static final int ENDER_CHEST = 10263; + public static final int FAKE_WOODEN_SLAB = 10264; + public static final int FARMLAND = 10265; + public static final int FERN = 10266; + public static final int FIRE = 10267; + public static final int FLETCHING_TABLE = 10268; + public static final int FLOWER_POT = 10269; + public static final int FROSTED_ICE = 10270; + public static final int FURNACE = 10271; + public static final int GLASS = 10272; + public static final int GLASS_PANE = 10273; + public static final int GLOWING_OBSIDIAN = 10274; + public static final int GLOWSTONE = 10275; + public static final int GOLD = 10276; + public static final int GOLD_ORE = 10277; + public static final int GRANITE = 10278; + public static final int GRANITE_SLAB = 10279; + public static final int GRANITE_STAIRS = 10280; + public static final int GRANITE_WALL = 10281; + public static final int GRASS = 10282; + public static final int GRASS_PATH = 10283; + public static final int GRAVEL = 10284; + public static final int GREEN_TORCH = 10287; + public static final int HARDENED_CLAY = 10288; + public static final int HARDENED_GLASS = 10289; + public static final int HARDENED_GLASS_PANE = 10290; + public static final int HAY_BALE = 10291; + public static final int HOPPER = 10292; + public static final int ICE = 10293; + public static final int INFESTED_CHISELED_STONE_BRICK = 10294; + public static final int INFESTED_COBBLESTONE = 10295; + public static final int INFESTED_CRACKED_STONE_BRICK = 10296; + public static final int INFESTED_MOSSY_STONE_BRICK = 10297; + public static final int INFESTED_STONE = 10298; + public static final int INFESTED_STONE_BRICK = 10299; + public static final int INFO_UPDATE = 10300; + public static final int INFO_UPDATE2 = 10301; + public static final int INVISIBLE_BEDROCK = 10302; + public static final int IRON = 10303; + public static final int IRON_BARS = 10304; + public static final int IRON_DOOR = 10305; + public static final int IRON_ORE = 10306; + public static final int IRON_TRAPDOOR = 10307; + public static final int ITEM_FRAME = 10308; + public static final int JUKEBOX = 10309; + public static final int JUNGLE_BUTTON = 10310; + public static final int JUNGLE_DOOR = 10311; + public static final int JUNGLE_FENCE = 10312; + public static final int JUNGLE_FENCE_GATE = 10313; + public static final int JUNGLE_LEAVES = 10314; + public static final int JUNGLE_LOG = 10315; + public static final int JUNGLE_PLANKS = 10316; + public static final int JUNGLE_PRESSURE_PLATE = 10317; + public static final int JUNGLE_SAPLING = 10318; + public static final int JUNGLE_SIGN = 10319; + public static final int JUNGLE_SLAB = 10320; + public static final int JUNGLE_STAIRS = 10321; + public static final int JUNGLE_TRAPDOOR = 10322; + public static final int JUNGLE_WALL_SIGN = 10323; + public static final int JUNGLE_WOOD = 10324; + public static final int LAB_TABLE = 10325; + public static final int LADDER = 10326; + public static final int LANTERN = 10327; + public static final int LAPIS_LAZULI = 10328; + public static final int LAPIS_LAZULI_ORE = 10329; + public static final int LARGE_FERN = 10330; + public static final int LAVA = 10331; + public static final int LECTERN = 10332; + public static final int LEGACY_STONECUTTER = 10333; + public static final int LEVER = 10334; + public static final int LILAC = 10337; + public static final int LILY_OF_THE_VALLEY = 10338; + public static final int LILY_PAD = 10339; + public static final int LIT_PUMPKIN = 10341; + public static final int LOOM = 10342; + public static final int MAGMA = 10344; + public static final int MATERIAL_REDUCER = 10345; + public static final int MELON = 10346; + public static final int MELON_STEM = 10347; + public static final int MOB_HEAD = 10348; + public static final int MONSTER_SPAWNER = 10349; + public static final int MOSSY_COBBLESTONE = 10350; + public static final int MOSSY_COBBLESTONE_SLAB = 10351; + public static final int MOSSY_COBBLESTONE_STAIRS = 10352; + public static final int MOSSY_COBBLESTONE_WALL = 10353; + public static final int MOSSY_STONE_BRICK_SLAB = 10354; + public static final int MOSSY_STONE_BRICK_STAIRS = 10355; + public static final int MOSSY_STONE_BRICK_WALL = 10356; + public static final int MOSSY_STONE_BRICKS = 10357; + public static final int MUSHROOM_STEM = 10358; + public static final int MYCELIUM = 10359; + public static final int NETHER_BRICK_FENCE = 10360; + public static final int NETHER_BRICK_SLAB = 10361; + public static final int NETHER_BRICK_STAIRS = 10362; + public static final int NETHER_BRICK_WALL = 10363; + public static final int NETHER_BRICKS = 10364; + public static final int NETHER_PORTAL = 10365; + public static final int NETHER_QUARTZ_ORE = 10366; + public static final int NETHER_REACTOR_CORE = 10367; + public static final int NETHER_WART = 10368; + public static final int NETHER_WART_BLOCK = 10369; + public static final int NETHERRACK = 10370; + public static final int NOTE_BLOCK = 10371; + public static final int OAK_BUTTON = 10372; + public static final int OAK_DOOR = 10373; + public static final int OAK_FENCE = 10374; + public static final int OAK_FENCE_GATE = 10375; + public static final int OAK_LEAVES = 10376; + public static final int OAK_LOG = 10377; + public static final int OAK_PLANKS = 10378; + public static final int OAK_PRESSURE_PLATE = 10379; + public static final int OAK_SAPLING = 10380; + public static final int OAK_SIGN = 10381; + public static final int OAK_SLAB = 10382; + public static final int OAK_STAIRS = 10383; + public static final int OAK_TRAPDOOR = 10384; + public static final int OAK_WALL_SIGN = 10385; + public static final int OAK_WOOD = 10386; + public static final int OBSIDIAN = 10387; + public static final int ORANGE_TULIP = 10389; + public static final int OXEYE_DAISY = 10390; + public static final int PACKED_ICE = 10391; + public static final int PEONY = 10392; + public static final int PINK_TULIP = 10394; + public static final int PODZOL = 10395; + public static final int POLISHED_ANDESITE = 10396; + public static final int POLISHED_ANDESITE_SLAB = 10397; + public static final int POLISHED_ANDESITE_STAIRS = 10398; + public static final int POLISHED_DIORITE = 10399; + public static final int POLISHED_DIORITE_SLAB = 10400; + public static final int POLISHED_DIORITE_STAIRS = 10401; + public static final int POLISHED_GRANITE = 10402; + public static final int POLISHED_GRANITE_SLAB = 10403; + public static final int POLISHED_GRANITE_STAIRS = 10404; + public static final int POPPY = 10405; + public static final int POTATOES = 10406; + public static final int POWERED_RAIL = 10407; + public static final int PRISMARINE = 10408; + public static final int PRISMARINE_BRICKS = 10409; + public static final int PRISMARINE_BRICKS_SLAB = 10410; + public static final int PRISMARINE_BRICKS_STAIRS = 10411; + public static final int PRISMARINE_SLAB = 10412; + public static final int PRISMARINE_STAIRS = 10413; + public static final int PRISMARINE_WALL = 10414; + public static final int PUMPKIN = 10415; + public static final int PUMPKIN_STEM = 10416; + public static final int PURPLE_TORCH = 10418; + public static final int PURPUR = 10419; + public static final int PURPUR_PILLAR = 10420; + public static final int PURPUR_SLAB = 10421; + public static final int PURPUR_STAIRS = 10422; + public static final int QUARTZ = 10423; + public static final int QUARTZ_PILLAR = 10424; + public static final int QUARTZ_SLAB = 10425; + public static final int QUARTZ_STAIRS = 10426; + public static final int RAIL = 10427; + public static final int RED_MUSHROOM = 10429; + public static final int RED_MUSHROOM_BLOCK = 10430; + public static final int RED_NETHER_BRICK_SLAB = 10431; + public static final int RED_NETHER_BRICK_STAIRS = 10432; + public static final int RED_NETHER_BRICK_WALL = 10433; + public static final int RED_NETHER_BRICKS = 10434; + public static final int RED_SAND = 10435; + public static final int RED_SANDSTONE = 10436; + public static final int RED_SANDSTONE_SLAB = 10437; + public static final int RED_SANDSTONE_STAIRS = 10438; + public static final int RED_SANDSTONE_WALL = 10439; + public static final int RED_TORCH = 10440; + public static final int RED_TULIP = 10441; + public static final int REDSTONE = 10442; + public static final int REDSTONE_COMPARATOR = 10443; + public static final int REDSTONE_LAMP = 10444; + public static final int REDSTONE_ORE = 10445; + public static final int REDSTONE_REPEATER = 10446; + public static final int REDSTONE_TORCH = 10447; + public static final int REDSTONE_WIRE = 10448; + public static final int RESERVED6 = 10449; + public static final int ROSE_BUSH = 10450; + public static final int SAND = 10451; + public static final int SANDSTONE = 10452; + public static final int SANDSTONE_SLAB = 10453; + public static final int SANDSTONE_STAIRS = 10454; + public static final int SANDSTONE_WALL = 10455; + public static final int SEA_LANTERN = 10456; + public static final int SEA_PICKLE = 10457; + public static final int SHULKER_BOX = 10458; + public static final int SLIME = 10459; + public static final int SMOKER = 10460; + public static final int SMOOTH_QUARTZ = 10461; + public static final int SMOOTH_QUARTZ_SLAB = 10462; + public static final int SMOOTH_QUARTZ_STAIRS = 10463; + public static final int SMOOTH_RED_SANDSTONE = 10464; + public static final int SMOOTH_RED_SANDSTONE_SLAB = 10465; + public static final int SMOOTH_RED_SANDSTONE_STAIRS = 10466; + public static final int SMOOTH_SANDSTONE = 10467; + public static final int SMOOTH_SANDSTONE_SLAB = 10468; + public static final int SMOOTH_SANDSTONE_STAIRS = 10469; + public static final int SMOOTH_STONE = 10470; + public static final int SMOOTH_STONE_SLAB = 10471; + public static final int SNOW = 10472; + public static final int SNOW_LAYER = 10473; + public static final int SOUL_SAND = 10474; + public static final int SPONGE = 10475; + public static final int SPRUCE_BUTTON = 10476; + public static final int SPRUCE_DOOR = 10477; + public static final int SPRUCE_FENCE = 10478; + public static final int SPRUCE_FENCE_GATE = 10479; + public static final int SPRUCE_LEAVES = 10480; + public static final int SPRUCE_LOG = 10481; + public static final int SPRUCE_PLANKS = 10482; + public static final int SPRUCE_PRESSURE_PLATE = 10483; + public static final int SPRUCE_SAPLING = 10484; + public static final int SPRUCE_SIGN = 10485; + public static final int SPRUCE_SLAB = 10486; + public static final int SPRUCE_STAIRS = 10487; + public static final int SPRUCE_TRAPDOOR = 10488; + public static final int SPRUCE_WALL_SIGN = 10489; + public static final int SPRUCE_WOOD = 10490; + public static final int STAINED_CLAY = 10491; + public static final int STAINED_GLASS = 10492; + public static final int STAINED_GLASS_PANE = 10493; + public static final int STAINED_HARDENED_GLASS = 10494; + public static final int STAINED_HARDENED_GLASS_PANE = 10495; + public static final int STONE = 10496; + public static final int STONE_BRICK_SLAB = 10497; + public static final int STONE_BRICK_STAIRS = 10498; + public static final int STONE_BRICK_WALL = 10499; + public static final int STONE_BRICKS = 10500; + public static final int STONE_BUTTON = 10501; + public static final int STONE_PRESSURE_PLATE = 10502; + public static final int STONE_SLAB = 10503; + public static final int STONE_STAIRS = 10504; + public static final int STONECUTTER = 10505; + public static final int SUGARCANE = 10518; + public static final int SUNFLOWER = 10519; + public static final int SWEET_BERRY_BUSH = 10520; + public static final int TALL_GRASS = 10521; + public static final int TNT = 10522; + public static final int TORCH = 10523; + public static final int TRAPPED_CHEST = 10524; + public static final int TRIPWIRE = 10525; + public static final int TRIPWIRE_HOOK = 10526; + public static final int UNDERWATER_TORCH = 10527; + public static final int VINES = 10528; + public static final int WALL_BANNER = 10529; + public static final int WALL_CORAL_FAN = 10530; + public static final int WATER = 10531; + public static final int WEIGHTED_PRESSURE_PLATE_HEAVY = 10532; + public static final int WEIGHTED_PRESSURE_PLATE_LIGHT = 10533; + public static final int WHEAT = 10534; + public static final int BUDDING_AMETHYST = 10535; + public static final int WHITE_TULIP = 10536; + public static final int WOOL = 10537; + public static final int AMETHYST_CLUSTER = 10538; + public static final int GLAZED_TERRACOTTA = 10539; + public static final int AMETHYST = 10540; + public static final int ANCIENT_DEBRIS = 10541; + public static final int BASALT = 10542; + public static final int POLISHED_BASALT = 10543; + public static final int SMOOTH_BASALT = 10544; + public static final int BLACKSTONE = 10545; + public static final int BLACKSTONE_SLAB = 10546; + public static final int BLACKSTONE_STAIRS = 10547; + public static final int BLACKSTONE_WALL = 10548; + public static final int POLISHED_BLACKSTONE = 10549; + public static final int POLISHED_BLACKSTONE_BUTTON = 10550; + public static final int POLISHED_BLACKSTONE_PRESSURE_PLATE = 10551; + public static final int POLISHED_BLACKSTONE_SLAB = 10552; + public static final int POLISHED_BLACKSTONE_STAIRS = 10553; + public static final int POLISHED_BLACKSTONE_WALL = 10554; + public static final int CHISELED_POLISHED_BLACKSTONE = 10555; + public static final int POLISHED_BLACKSTONE_BRICKS = 10556; + public static final int POLISHED_BLACKSTONE_BRICK_SLAB = 10557; + public static final int POLISHED_BLACKSTONE_BRICK_STAIRS = 10558; + public static final int POLISHED_BLACKSTONE_BRICK_WALL = 10559; + public static final int CRACKED_POLISHED_BLACKSTONE_BRICKS = 10560; + public static final int LIGHT = 10561; + public static final int RAW_COPPER = 10562; + public static final int RAW_GOLD = 10563; + public static final int RAW_IRON = 10564; + public static final int CALCITE = 10565; + public static final int DEEPSLATE = 10566; + public static final int DEEPSLATE_BRICKS = 10567; + public static final int DEEPSLATE_BRICK_SLAB = 10568; + public static final int DEEPSLATE_BRICK_STAIRS = 10569; + public static final int DEEPSLATE_BRICK_WALL = 10570; + public static final int CRACKED_DEEPSLATE_BRICKS = 10571; + public static final int DEEPSLATE_TILES = 10572; + public static final int DEEPSLATE_TILE_SLAB = 10573; + public static final int DEEPSLATE_TILE_STAIRS = 10574; + public static final int DEEPSLATE_TILE_WALL = 10575; + public static final int CRACKED_DEEPSLATE_TILES = 10576; + public static final int COBBLED_DEEPSLATE = 10577; + public static final int COBBLED_DEEPSLATE_SLAB = 10578; + public static final int COBBLED_DEEPSLATE_STAIRS = 10579; + public static final int COBBLED_DEEPSLATE_WALL = 10580; + public static final int POLISHED_DEEPSLATE = 10581; + public static final int POLISHED_DEEPSLATE_SLAB = 10582; + public static final int POLISHED_DEEPSLATE_STAIRS = 10583; + public static final int POLISHED_DEEPSLATE_WALL = 10584; + public static final int QUARTZ_BRICKS = 10585; + public static final int CHISELED_DEEPSLATE = 10586; + public static final int CHISELED_NETHER_BRICKS = 10587; + public static final int CRACKED_NETHER_BRICKS = 10588; + public static final int TUFF = 10589; + public static final int SOUL_TORCH = 10590; + public static final int SOUL_LANTERN = 10591; + public static final int SOUL_SOIL = 10592; + public static final int SOUL_FIRE = 10593; + public static final int SHROOMLIGHT = 10594; + public static final int MANGROVE_PLANKS = 10595; + public static final int CRIMSON_PLANKS = 10596; + public static final int WARPED_PLANKS = 10597; + public static final int MANGROVE_FENCE = 10598; + public static final int CRIMSON_FENCE = 10599; + public static final int WARPED_FENCE = 10600; + public static final int MANGROVE_SLAB = 10601; + public static final int CRIMSON_SLAB = 10602; + public static final int WARPED_SLAB = 10603; + public static final int MANGROVE_LOG = 10604; + public static final int CRIMSON_STEM = 10605; + public static final int WARPED_STEM = 10606; + public static final int MANGROVE_WOOD = 10607; + public static final int CRIMSON_HYPHAE = 10608; + public static final int WARPED_HYPHAE = 10609; + public static final int MANGROVE_TRAPDOOR = 10610; + public static final int CRIMSON_TRAPDOOR = 10611; + public static final int WARPED_TRAPDOOR = 10612; + public static final int MANGROVE_BUTTON = 10613; + public static final int CRIMSON_BUTTON = 10614; + public static final int WARPED_BUTTON = 10615; + public static final int MANGROVE_PRESSURE_PLATE = 10616; + public static final int CRIMSON_PRESSURE_PLATE = 10617; + public static final int WARPED_PRESSURE_PLATE = 10618; + public static final int MANGROVE_DOOR = 10619; + public static final int CRIMSON_DOOR = 10620; + public static final int WARPED_DOOR = 10621; + public static final int MANGROVE_FENCE_GATE = 10622; + public static final int CRIMSON_FENCE_GATE = 10623; + public static final int WARPED_FENCE_GATE = 10624; + public static final int MANGROVE_STAIRS = 10625; + public static final int CRIMSON_STAIRS = 10626; + public static final int WARPED_STAIRS = 10627; + public static final int MANGROVE_SIGN = 10628; + public static final int CRIMSON_SIGN = 10629; + public static final int WARPED_SIGN = 10630; + public static final int MANGROVE_WALL_SIGN = 10631; + public static final int CRIMSON_WALL_SIGN = 10632; + public static final int WARPED_WALL_SIGN = 10633; + public static final int TINTED_GLASS = 10634; + public static final int HONEYCOMB = 10635; + public static final int DEEPSLATE_COAL_ORE = 10636; + public static final int DEEPSLATE_DIAMOND_ORE = 10637; + public static final int DEEPSLATE_EMERALD_ORE = 10638; + public static final int DEEPSLATE_LAPIS_LAZULI_ORE = 10639; + public static final int DEEPSLATE_REDSTONE_ORE = 10640; + public static final int DEEPSLATE_IRON_ORE = 10641; + public static final int DEEPSLATE_GOLD_ORE = 10642; + public static final int DEEPSLATE_COPPER_ORE = 10643; + public static final int COPPER_ORE = 10644; + public static final int NETHER_GOLD_ORE = 10645; + public static final int MUD = 10646; + public static final int MUD_BRICKS = 10647; + public static final int MUD_BRICK_SLAB = 10648; + public static final int MUD_BRICK_STAIRS = 10649; + public static final int MUD_BRICK_WALL = 10650; + public static final int PACKED_MUD = 10651; + public static final int WARPED_WART_BLOCK = 10652; + public static final int CRYING_OBSIDIAN = 10653; + public static final int GILDED_BLACKSTONE = 10654; + public static final int LIGHTNING_ROD = 10655; + public static final int COPPER = 10656; + public static final int CUT_COPPER = 10657; + public static final int CUT_COPPER_SLAB = 10658; + public static final int CUT_COPPER_STAIRS = 10659; + public static final int CANDLE = 10660; + public static final int DYED_CANDLE = 10661; + public static final int CAKE_WITH_CANDLE = 10662; + public static final int CAKE_WITH_DYED_CANDLE = 10663; + public static final int WITHER_ROSE = 10664; + public static final int HANGING_ROOTS = 10665; + public static final int CARTOGRAPHY_TABLE = 10666; + public static final int SMITHING_TABLE = 10667; + public static final int NETHERITE = 10668; + public static final int SPORE_BLOSSOM = 10669; + public static final int CAULDRON = 10670; + public static final int WATER_CAULDRON = 10671; + public static final int LAVA_CAULDRON = 10672; + public static final int POTION_CAULDRON = 10673; + public static final int POWDER_SNOW_CAULDRON = 10674; + public static final int CHORUS_FLOWER = 10675; + public static final int CHORUS_PLANT = 10676; + public static final int MANGROVE_ROOTS = 10677; + public static final int MUDDY_MANGROVE_ROOTS = 10678; + public static final int FROGLIGHT = 10679; + public static final int TWISTING_VINES = 10680; + public static final int WEEPING_VINES = 10681; + public static final int CHAIN = 10682; + public static final int SCULK = 10683; + public static final int GLOWING_ITEM_FRAME = 10684; + public static final int MANGROVE_LEAVES = 10685; + public static final int AZALEA_LEAVES = 10686; + public static final int FLOWERING_AZALEA_LEAVES = 10687; + public static final int REINFORCED_DEEPSLATE = 10688; + public static final int CAVE_VINES = 10689; + public static final int GLOW_LICHEN = 10690; + public static final int CHERRY_BUTTON = 10691; + public static final int CHERRY_DOOR = 10692; + public static final int CHERRY_FENCE = 10693; + public static final int CHERRY_FENCE_GATE = 10694; + public static final int CHERRY_LEAVES = 10695; + public static final int CHERRY_LOG = 10696; + public static final int CHERRY_PLANKS = 10697; + public static final int CHERRY_PRESSURE_PLATE = 10698; + public static final int CHERRY_SAPLING = 10699; + public static final int CHERRY_SIGN = 10700; + public static final int CHERRY_SLAB = 10701; + public static final int CHERRY_STAIRS = 10702; + public static final int CHERRY_TRAPDOOR = 10703; + public static final int CHERRY_WALL_SIGN = 10704; + public static final int CHERRY_WOOD = 10705; + public static final int SMALL_DRIPLEAF = 10706; + public static final int BIG_DRIPLEAF_HEAD = 10707; + public static final int BIG_DRIPLEAF_STEM = 10708; + public static final int PINK_PETALS = 10709; + public static final int CRIMSON_ROOTS = 10710; + public static final int WARPED_ROOTS = 10711; + public static final int CHISELED_BOOKSHELF = 10712; + public static final int TORCHFLOWER = 10713; + public static final int TORCHFLOWER_CROP = 10714; + public static final int PITCHER_PLANT = 10715; + public static final int PITCHER_CROP = 10716; + public static final int DOUBLE_PITCHER_CROP = 10717; + + public static final int FIRST_UNUSED_BLOCK_ID = 10718; + + private static int nextDynamicId = FIRST_UNUSED_BLOCK_ID; + + /** + * Returns a new runtime block type ID, e.g., for use by a custom block. + */ + public static int newId() { + return nextDynamicId++; + } +} diff --git a/src/main/java/org/sculk/block/BlockTypeInfo.java b/src/main/java/org/sculk/block/BlockTypeInfo.java new file mode 100644 index 0000000..7565570 --- /dev/null +++ b/src/main/java/org/sculk/block/BlockTypeInfo.java @@ -0,0 +1,36 @@ +package org.sculk.block; + +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public final class BlockTypeInfo { + @Getter + private BlockBreakInfo breakInfo; + @Getter + private List typeTags; + public BlockTypeInfo(final BlockBreakInfo breakInfo) { + this.breakInfo = breakInfo; + this.typeTags = new ArrayList<>(); + } + + public boolean hasTypeTag(String tag) { + return typeTags.contains(tag); + } +} diff --git a/src/main/java/org/sculk/block/InvalidSerializedRuntimeDataException.java b/src/main/java/org/sculk/block/InvalidSerializedRuntimeDataException.java new file mode 100644 index 0000000..29baa12 --- /dev/null +++ b/src/main/java/org/sculk/block/InvalidSerializedRuntimeDataException.java @@ -0,0 +1,22 @@ +package org.sculk.block; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public class InvalidSerializedRuntimeDataException extends Exception { + public InvalidSerializedRuntimeDataException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/org/sculk/block/RuntimeBlockStateRegistry.java b/src/main/java/org/sculk/block/RuntimeBlockStateRegistry.java new file mode 100644 index 0000000..ed7ef9d --- /dev/null +++ b/src/main/java/org/sculk/block/RuntimeBlockStateRegistry.java @@ -0,0 +1,103 @@ +package org.sculk.block; + +import lombok.Getter; +import lombok.SneakyThrows; +import org.sculk.world.light.LightUpdate; + +import java.util.*; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public class RuntimeBlockStateRegistry { + private static final RuntimeBlockStateRegistry instance; + + static { + instance = new RuntimeBlockStateRegistry(); + } + + private final Map typeIndex = new HashMap<>(); + private final Map fullList = new HashMap<>(); + public final Map light = new HashMap<>(); + public final Map lightFilter = new HashMap<>(); + public final Map blocksDirectSkyLight = new HashMap<>(); + public final Map blastResistance = new HashMap<>(); + RuntimeBlockStateRegistry() { + for (VanillaBlocks block: VanillaBlocks.values()){ + register(block.getBlock()); + } + } + + + /** + * Maps a block type's state permutations to its corresponding state IDs. This is necessary for the block to be + * recognized when fetching it by its state ID from chunks at runtime. + * + */ + @SneakyThrows + public void register(Block block) { + long typeId = block.getTypeId(); + + if (typeIndex.containsKey(typeId)) { + throw new IllegalArgumentException(STR."Block ID \{typeId} is already used by another block"); + } + + typeIndex.put(typeId, block.clone()); + + block.generateStatePermutations().forEach(block1 -> { + if (block1 == null) + return; + this.fillStaticArrays(block1.getStateId(), block1); + }); + } + + private void fillStaticArrays(long index, Block block) { + long fullId = block.getStateId(); + if (index != fullId) { + throw new IllegalStateException("Cannot fill static arrays for an invalid block state"); + } else { + fullList.put(index, block); + blastResistance.put(index, block.getBreakInfo().getBlastResistance()); + light.put(index, block.getLightLevel()); + lightFilter.put(index, Math.min(15, block.getLightFilter() + LightUpdate.BASE_LIGHT_FILTER)); + if (block.blocksDirectSkyLight()) { + blocksDirectSkyLight.put(index, true); + } + } + } + public Block fromStateId(long stateId){ + if(stateId < 0){ + throw new IllegalArgumentException("Block state ID cannot be negative"); + } + Block block; + if(this.fullList.containsKey(stateId)) { //hot + block = this.fullList.get(stateId); + }else{ + long typeId = stateId >> Block.INTERNAL_STATE_DATA_BITS; + long stateData = (stateId ^ typeId) & Block.INTERNAL_STATE_DATA_MASK; + block = new UnknownBlock(new BlockIdentifier(typeId), new BlockTypeInfo(BlockBreakInfo.instant()), stateData); + } + + return block; + } + + public Map getAllKnownStates() { + return fullList; + } + + public static RuntimeBlockStateRegistry getInstance() { + return instance; + } +} diff --git a/src/main/java/org/sculk/block/TransparentBlock.java b/src/main/java/org/sculk/block/TransparentBlock.java new file mode 100644 index 0000000..1a4b6d6 --- /dev/null +++ b/src/main/java/org/sculk/block/TransparentBlock.java @@ -0,0 +1,27 @@ +package org.sculk.block; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public class TransparentBlock extends Block{ + public TransparentBlock(BlockIdentifier identifier, String name, BlockTypeInfo blockTypeInfo) { + super(identifier, name, blockTypeInfo); + } + + @Override + public boolean isTransparent() { + return true; + } +} diff --git a/src/main/java/org/sculk/block/UnknownBlock.java b/src/main/java/org/sculk/block/UnknownBlock.java new file mode 100644 index 0000000..067c9c9 --- /dev/null +++ b/src/main/java/org/sculk/block/UnknownBlock.java @@ -0,0 +1,36 @@ +package org.sculk.block; + +import lombok.Getter; +import org.sculk.data.runtime.RuntimeDataDescriber; + +import java.util.concurrent.atomic.AtomicLong; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public class UnknownBlock extends Block{ + @Getter + private long stateData; + public UnknownBlock(BlockIdentifier identifier, BlockTypeInfo blockTypeInfo, long stateData) { + super(identifier, "Unknown", blockTypeInfo); + this.stateData = stateData; + } + + public void describeBlockItemState(RuntimeDataDescriber w){ + AtomicLong data = new AtomicLong(stateData); + w._int(Block.INTERNAL_STATE_DATA_BITS, data); + this.stateData = data.get(); + } +} diff --git a/src/main/java/org/sculk/block/VanillaBlocks.java b/src/main/java/org/sculk/block/VanillaBlocks.java new file mode 100644 index 0000000..dc8d8eb --- /dev/null +++ b/src/main/java/org/sculk/block/VanillaBlocks.java @@ -0,0 +1,30 @@ +package org.sculk.block; + +import lombok.Getter; +import lombok.NonNull; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public enum VanillaBlocks { + AIR(new AirBlock(new BlockIdentifier(BlockTypeIds.AIR), "air", new BlockTypeInfo(BlockBreakInfo.indestructible()))), + BEDROCK(new Block(new BlockIdentifier(BlockTypeIds.BEDROCK), "bedrock", new BlockTypeInfo(BlockBreakInfo.indestructible()))); + @Getter + private @NonNull Block block; + VanillaBlocks(Block block){ + this.block = block; + } + +} diff --git a/src/main/java/org/sculk/block/tile/Tile.java b/src/main/java/org/sculk/block/tile/Tile.java new file mode 100644 index 0000000..406ccb2 --- /dev/null +++ b/src/main/java/org/sculk/block/tile/Tile.java @@ -0,0 +1,18 @@ +package org.sculk.block.tile; +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public class Tile { +} diff --git a/src/main/java/org/sculk/data/runtime/RuntimeDataDescriber.java b/src/main/java/org/sculk/data/runtime/RuntimeDataDescriber.java new file mode 100644 index 0000000..af0eebc --- /dev/null +++ b/src/main/java/org/sculk/data/runtime/RuntimeDataDescriber.java @@ -0,0 +1,65 @@ +package org.sculk.data.runtime; + +import lombok.SneakyThrows; +import org.sculk.block.InvalidSerializedRuntimeDataException; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public interface RuntimeDataDescriber { + void _int(long bits, AtomicLong value); + + /** + * @deprecated Use {@link RuntimeDataDescriber::boundedIntAuto()} instead. + */ + @SneakyThrows(InvalidSerializedRuntimeDataException.class) + void boundedInt(long bits, long min, long max, @Nullable AtomicLong value); + + /** + * Same as boundedInt() but automatically calculates the required number of bits from the range. + * The range bounds must be constant. + */ + @SneakyThrows(InvalidSerializedRuntimeDataException.class) + void boundedIntAuto(long min, long max, @Nullable AtomicLong value); + + void bool(AtomicBoolean value); + + void horizontalFacing(@Nullable AtomicInteger facing); + + void facingFlags(@Nullable List faces); + + void horizontalFacingFlags(@Nullable List faces); + + @SneakyThrows(InvalidSerializedRuntimeDataException.class) + void facing(@Nullable AtomicInteger facing); + + @SneakyThrows(InvalidSerializedRuntimeDataException.class) + void facingExcept(@Nullable AtomicInteger facing, int except); + + @SneakyThrows(InvalidSerializedRuntimeDataException.class) + void axis(@Nullable AtomicInteger axis); + + void horizontalAxis(@Nullable AtomicInteger axis); + + void railShape(@Nullable AtomicInteger railShape); + + void straightOnlyRailShape(@Nullable AtomicInteger railShape); +} diff --git a/src/main/java/org/sculk/data/runtime/RuntimeDataReader.java b/src/main/java/org/sculk/data/runtime/RuntimeDataReader.java new file mode 100644 index 0000000..15398eb --- /dev/null +++ b/src/main/java/org/sculk/data/runtime/RuntimeDataReader.java @@ -0,0 +1,221 @@ +package org.sculk.data.runtime; + +import lombok.Getter; +import lombok.SneakyThrows; +import org.sculk.block.InvalidSerializedRuntimeDataException; +import org.sculk.math.Axis; +import org.sculk.math.Facing; +import org.sculk.utils.SculkMath; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public class RuntimeDataReader implements RuntimeDataDescriber{ + private final long maxBits; + @Getter + private long value = 0; + @Getter + private long offset = 0; + public RuntimeDataReader(long maxBits, + long value){ + this.maxBits = maxBits; + this.value = value; + } + + + /** + * Lit un entier sur un nombre spécifié de bits. + * + * @param bits Nombre de bits à lire. + * @return L'entier lu. + * @throws IllegalArgumentException Si les bits demandés dépassent le buffer. + */ + public long readInt(long bits) { + long bitsLeft = maxBits - offset; + if (bits > bitsLeft) { + throw new IllegalArgumentException(STR."No bits left in buffer (need \{bits}, have \{bitsLeft})"); + } + + int mask = (~0 >>> (32 - bits)); + long result = (value >> offset) & mask; + offset += bits; + return result; + } + /** + * Lit un entier sur un nombre spécifié de bits. + * + * @param bits Nombre de bits à lire. + * @return L'entier lu. + * @throws IllegalArgumentException Si les bits demandés dépassent le buffer. + */ + public int readInt(int bits) { + long bitsLeft = maxBits - offset; + if (bits > bitsLeft) { + throw new IllegalArgumentException(STR."No bits left in buffer (need \{bits}, have \{bitsLeft})"); + } + + int mask = (~0 >>> (32 - bits)); + int result = (int) ((value >> offset) & mask); + offset += bits; + return result; + } + + public void _int(long bits, AtomicLong value) { + value.set(readInt(bits)); + } + + @Override + public void boundedInt(long bits, long min, long max, AtomicLong valueRef) { + long startOffset = this.offset; + this.boundedIntAuto(min, max, valueRef); + long actualBits = this.offset - startOffset; + if (this.offset != startOffset + bits) { + throw new IllegalArgumentException("Bits should be " + actualBits + " for the given bounds, but received " + bits + ". Use boundedIntAuto() for automatic bits calculation."); + } + } + + @SneakyThrows + private long readBoundedIntAuto(long min, long max) { + long bits = SculkMath.log2(max - min) + 1; + long result = this.readInt(bits) + min; + if (result < min || result > max) { + throw new InvalidSerializedRuntimeDataException(STR."Value is outside the range \{min} - \{max}"); + } + return result; + } + public void boundedIntAuto(long min, long max, AtomicLong valueRef) { + valueRef.set(this.readBoundedIntAuto(min, max)); + } + public boolean readBool() { + return this.readInt(1) == 1; + } + @Override + public void bool(AtomicBoolean value) { + value.set(this.readBool()); + } + + @Override + public void horizontalFacing(@Nullable AtomicInteger facingRef) { + int facing = switch (this.readInt(2)) { + case 0 -> Facing.NORTH; + case 1 -> Facing.EAST; + case 2 -> Facing.SOUTH; + case 3 -> Facing.WEST; + default -> throw new AssertionError("Unreachable"); + }; + facingRef.set(facing); + } + + @Override + public void facingFlags(@Nullable List facesRef) { + assert facesRef != null; + List tmp = new ArrayList<>(); + for (int facing : Facing.ALL) { + if (this.readBool()) { + tmp.add(facing); + } + } + facesRef.addAll(tmp); + } + + @Override + public void horizontalFacingFlags(@Nullable List facesRef) { + assert facesRef != null; + List tmp = new ArrayList<>(); + for (int facing: Facing.HORIZONTAL) + { + if (this.readBool()) { + tmp.add(facing); + } + } + facesRef.addAll(tmp); + + } + + @Override + @SneakyThrows + public void facing(@Nullable AtomicInteger facingRef) { + assert facingRef != null; + int facing = switch (this.readInt(3)) { + case 0 -> Facing.DOWN; + case 1 -> Facing.UP; + case 2 -> Facing.NORTH; + case 3 -> Facing.SOUTH; + case 4 -> Facing.WEST; + case 5 -> Facing.EAST; + default -> throw new InvalidSerializedRuntimeDataException("Invalid facing value"); + }; + facingRef.set(facing); + } + + @Override + @SneakyThrows + public void facingExcept(@Nullable AtomicInteger facingRef, int except) { + assert facingRef != null; + this.facing(facingRef); + if (facingRef.get() == except) { + throw new InvalidSerializedRuntimeDataException("Illegal facing value"); + } + } + + @Override + @SneakyThrows + public void axis(AtomicInteger axisRef) { + int axis = switch (this.readInt(2)) { + case 0 -> Axis.X; + case 1 -> Axis.Z; + case 2 -> Axis.Y; + default -> throw new InvalidSerializedRuntimeDataException("Invalid axis value"); + }; + axisRef.set(axis); + } + + @Override + public void horizontalAxis(AtomicInteger axisRef) { + int axis = switch (this.readInt(1)) { + case 0 -> Axis.X; + case 1 -> Axis.Z; + default -> throw new AssertionError("Unreachable"); + }; + axisRef.set(axis); + } + + @Override + public void railShape(AtomicInteger railShapeRef) { + assert railShapeRef != null; + int result = this.readInt(4); + /*if (!RailConnectionInfo.CONNECTIONS.containsKey(result) && !RailConnectionInfo.CURVE_CONNECTIONS.containsKey(result)) { + throw new InvalidSerializedRuntimeDataException("Invalid rail shape " + result); + }*/ + railShapeRef.set(result); + } + + @Override + public void straightOnlyRailShape(AtomicInteger railShapeRef) { + assert railShapeRef != null; + int result = this.readInt(3); + /*if (!RailConnectionInfo.CONNECTIONS.containsKey(result)) { + throw new InvalidSerializedRuntimeDataException("No rail shape matches meta " + result); + }*/ + railShapeRef.set(result); + } +} diff --git a/src/main/java/org/sculk/data/runtime/RuntimeDataSizeCalculator.java b/src/main/java/org/sculk/data/runtime/RuntimeDataSizeCalculator.java new file mode 100644 index 0000000..d3de482 --- /dev/null +++ b/src/main/java/org/sculk/data/runtime/RuntimeDataSizeCalculator.java @@ -0,0 +1,113 @@ +package org.sculk.data.runtime; + +import lombok.SneakyThrows; +import org.sculk.math.Facing; +import org.sculk.utils.SculkMath; + +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public class RuntimeDataSizeCalculator implements RuntimeDataDescriber{ + + private long bits = 0; + + protected void addBits(long bits) { + this.bits += bits; + } + public void reset() { + bits = 0; + } + + public long getBitsUsed() { + return bits; + } + + @Override + public void _int(long bits, AtomicLong value) { + this.addBits(bits); + } + + @Override + @SneakyThrows + public void boundedInt(long bits, long min, long max, AtomicLong value) { + long currentBits = this.bits; + this.boundedIntAuto(min, max, value); + long actualBits = this.bits - currentBits; + if(actualBits != bits){ + throw new IllegalArgumentException(STR."Bits should be \{actualBits} for the given bounds, but received $bits. Use boundedIntAuto() for automatic bits calculation."); + } + } + + @Override + public void boundedIntAuto(long min, long max, AtomicLong value) { + this.addBits(SculkMath.log2(max - min) + 1); + } + + @Override + public void bool(AtomicBoolean value) { + this.addBits(1); + } + + @Override + public void horizontalFacing(AtomicInteger facing) { + this.addBits(2); + } + + @Override + public void facingFlags(List faces) { + this.addBits(Facing.ALL.size()); + } + + @Override + public void horizontalFacingFlags(List faces) { + this.addBits(Facing.HORIZONTAL.size()); + + } + + @Override + public void facing(AtomicInteger facing) { + this.addBits(3); + } + + @Override + public void facingExcept(AtomicInteger facing, int except) { + this.facing(facing); + } + + @Override + public void axis(AtomicInteger axis) { + this.addBits(2); + } + + @Override + public void horizontalAxis(AtomicInteger axis) { + this.addBits(1); + } + + @Override + public void railShape(AtomicInteger railShape) { + this.addBits(4); + } + + @Override + public void straightOnlyRailShape(AtomicInteger railShape) { + this.addBits(3); + } +} diff --git a/src/main/java/org/sculk/data/runtime/RuntimeDataWriter.java b/src/main/java/org/sculk/data/runtime/RuntimeDataWriter.java new file mode 100644 index 0000000..57ddd3b --- /dev/null +++ b/src/main/java/org/sculk/data/runtime/RuntimeDataWriter.java @@ -0,0 +1,172 @@ +package org.sculk.data.runtime; + +import lombok.Getter; +import org.sculk.math.Axis; +import org.sculk.math.Facing; +import org.sculk.utils.SculkMath; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public class RuntimeDataWriter implements RuntimeDataDescriber{ + private final long maxBits; + @Getter + private long value = 0; + @Getter + private long offset = 0; + public RuntimeDataWriter(long maxBits){ + this.maxBits = maxBits; + } + + public void writeInt(long bits, AtomicLong value) { + if (this.offset + bits > this.maxBits) + throw new IllegalArgumentException("Bit buffer cannot be larger than this.maxBits bits (already have this.offset bits)"); + if ((value.get() & (~0L << bits)) != 0) + throw new IllegalArgumentException(STR."Value \{value} does not fit into \{bits} bits"); + + this.value |= (value.get() << this.offset); + this.offset += bits; + } + + public void _int(long bits, AtomicLong value) { + this.writeInt(bits, value); + } + + @Override + public void boundedInt(long bits, long min, long max, @Nullable AtomicLong value) { + assert value != null; + long offset = this.offset; + this.writeBoundedIntAuto(min, max, value); + long actualBits = this.offset - offset; + if(actualBits != bits){ + throw new IllegalArgumentException("Bits should be $actualBits for the given bounds, but received $bits. Use boundedIntAuto() for automatic bits calculation."); + } + } + + private void writeBoundedIntAuto(long min, long max, AtomicLong value) { + long _value = value.get(); + if(_value < min || _value > max){ + throw new IllegalArgumentException(STR."Value $value is outside the range \{min} - \{max}"); + } + long bits = SculkMath.log2(max - min) + 1; + this.writeInt(bits, new AtomicLong(_value - min)); + } + + + @Override + public void boundedIntAuto(long min, long max, @Nullable AtomicLong value) { + assert value != null; + this.writeBoundedIntAuto(min, max, value); + } + + public void writeBool(AtomicBoolean value) { + this.writeInt(1, new AtomicLong(value.get() ? 1L : 0L)); + } + @Override + public void bool(AtomicBoolean value) { + this.writeBool(value); + } + + @Override + public void horizontalFacing(@Nullable AtomicInteger facing) { + assert facing != null; + this.writeInt(2, new AtomicLong(switch (facing.get()) { + case Facing.NORTH -> 0; + case Facing.EAST -> 1; + case Facing.SOUTH -> 2; + case Facing.WEST -> 3; + default -> throw new IllegalArgumentException("Invalid horizontal facing " + facing.get()); + })); + } + + @Override + public void facingFlags(@Nullable List faces) { + assert faces != null; + for (int facings: Facing.ALL) + { + this.writeBool(new AtomicBoolean(faces.contains(facings))); + } + } + + @Override + public void horizontalFacingFlags(@Nullable List faces) { + assert faces != null; + for (int facings: Facing.HORIZONTAL) + { + this.writeBool(new AtomicBoolean(faces.contains(facings))); + } + + } + + @Override + public void facing(@Nullable AtomicInteger facing) { + assert facing != null; + this.writeInt(3, new AtomicLong(switch (facing.get()) { + case 0 -> Facing.DOWN; + case 1 -> Facing.UP; + case 2 -> Facing.NORTH; + case 3 -> Facing.SOUTH; + case 4 -> Facing.WEST; + case 5 -> Facing.EAST; + default -> throw new IllegalArgumentException(STR."Invalid horizontal facing \{facing.get()}"); + })); + } + + @Override + public void facingExcept(@Nullable AtomicInteger facing, int except) { + this.facing(facing); + } + + @Override + public void axis(@Nullable AtomicInteger axis) { + assert axis != null; + this.writeInt(2, new AtomicLong(switch (axis.get()) { + case Axis.X -> 0; + case Axis.Y -> 1; + case Axis.Z -> 2; + default -> throw new IllegalArgumentException(STR."Invalid horizontal facing \{axis.get()}"); + })); + } + + @Override + public void horizontalAxis(@Nullable AtomicInteger axis) { + assert axis != null; + this.writeInt(1, new AtomicLong(switch (axis.get()) { + case Axis.X -> 0; + case Axis.Z -> 1; + default -> throw new IllegalArgumentException(STR."Invalid horizontal facing \{axis.get()}"); + })); + + } + + @Override + public void railShape(@Nullable AtomicInteger railShape) { + assert railShape != null; + this._int(4, new AtomicLong(railShape.get())); + } + + @Override + public void straightOnlyRailShape(@Nullable AtomicInteger railShape) { + assert railShape != null; + this._int(3, new AtomicLong(railShape.get())); + + } +} diff --git a/src/main/java/org/sculk/math/Axis.java b/src/main/java/org/sculk/math/Axis.java new file mode 100644 index 0000000..a78b967 --- /dev/null +++ b/src/main/java/org/sculk/math/Axis.java @@ -0,0 +1,35 @@ +package org.sculk.math; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public final class Axis { + public static final int Y = 0; + public static final int Z = 1; + public static final int X = 2; + /** + * Returns a human-readable string representation of the given axis. + * + * @throws IllegalArgumentException if the axis is invalid + */ + public static String toString(int axis) { + return switch (axis) { + case Y -> "y"; + case Z -> "z"; + case X -> "x"; + default -> throw new IllegalArgumentException("Invalid axis " + axis); + }; + } +} diff --git a/src/main/java/org/sculk/math/Facing.java b/src/main/java/org/sculk/math/Facing.java new file mode 100644 index 0000000..e836066 --- /dev/null +++ b/src/main/java/org/sculk/math/Facing.java @@ -0,0 +1,153 @@ +package org.sculk.math; + +import java.util.List; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public final class Facing { + public static final int FLAG_AXIS_POSITIVE = 1; + + /* most significant 2 bits = axis, least significant bit = is positive direction */ + public static final int DOWN = Axis.Y << 1; + public static final int UP = (Axis.Y << 1) | FLAG_AXIS_POSITIVE; + public static final int NORTH = Axis.Z << 1; + public static final int SOUTH = (Axis.Z << 1) | FLAG_AXIS_POSITIVE; + public static final int WEST = Axis.X << 1; + public static final int EAST = (Axis.X << 1) | FLAG_AXIS_POSITIVE; + + public static final List ALL = List.of( + DOWN, + UP, + NORTH, + SOUTH, + WEST, + EAST + ); + + public static final List HORIZONTAL = List.of( + NORTH, + SOUTH, + WEST, + EAST + ); + + public static final int[][] OFFSET = { + {0, -1, 0}, // DOWN + {0, 1, 0}, // UP + {0, 0, -1}, // NORTH + {0, 0, 1}, // SOUTH + {-1, 0, 0}, // WEST + {1, 0, 0} // EAST + }; + + private static final int[][][] CLOCKWISE = { + { // Y axis + {EAST, SOUTH, WEST, NORTH}, // Rotations for NORTH + }, + { // Z axis + {EAST, DOWN, WEST, UP}, // Rotations for UP + }, + { // X axis + {NORTH, DOWN, SOUTH, UP}, // Rotations for UP + } + }; + + /** + * Returns the axis of the given direction. + */ + public static int axis(int direction) { + return direction >> 1; //shift off positive/negative bit + } + + /** + * Returns whether the direction is facing the positive of its axis. + */ + public static boolean isPositive(int direction) { + return (direction & FLAG_AXIS_POSITIVE) == FLAG_AXIS_POSITIVE; + } + + /** + * Returns the opposite Facing of the specified one. + * + * @param direction 0-5 one of the Facing::* constants + */ + public static int opposite(int direction) { + return direction ^ FLAG_AXIS_POSITIVE; + } + + /** + * Rotates the given direction around the axis. + * + * @throws IllegalArgumentException if not possible to rotate direction around axis + */ + public static int rotate(int direction, int axis, boolean clockwise) { + if (axis >= CLOCKWISE.length || axis < 0) { + throw new IllegalArgumentException("Invalid axis " + axis); + } + if (direction >= CLOCKWISE[axis].length || direction < 0) { + throw new IllegalArgumentException("Cannot rotate facing \"" + toString(direction) + "\" around axis \"" + Axis.toString(axis) + "\""); + } + + int rotated = CLOCKWISE[axis][direction][clockwise ? 0 : 2]; + return clockwise ? rotated : opposite(rotated); + } + + /** + * @throws IllegalArgumentException + */ + public static int rotateY(int direction, boolean clockwise) { + return rotate(direction, Axis.Y, clockwise); + } + + /** + * @throws IllegalArgumentException + */ + public static int rotateZ(int direction, boolean clockwise) { + return rotate(direction, Axis.Z, clockwise); + } + + /** + */ + public static int rotateX(int direction, boolean clockwise) { + return rotate(direction, Axis.X, clockwise); + } + + /** + * Validates the given integer as a Facing direction. + * + * @throws IllegalArgumentException if the argument is not a valid Facing constant + */ + public static void validate(int facing) { + if (!ALL.contains(facing)) { + throw new IllegalArgumentException("Invalid direction " + facing); + } + } + + /** + * Returns a human-readable string representation of the given Facing direction. + */ + public static String toString(int facing) { + return switch (facing) { + case DOWN -> "down"; + case UP -> "up"; + case NORTH -> "north"; + case SOUTH -> "south"; + case WEST -> "west"; + case EAST -> "east"; + default -> throw new IllegalArgumentException("Invalid facing " + facing); + }; + } +} diff --git a/src/main/java/org/sculk/utils/Binary.java b/src/main/java/org/sculk/utils/Binary.java new file mode 100644 index 0000000..c6d6423 --- /dev/null +++ b/src/main/java/org/sculk/utils/Binary.java @@ -0,0 +1,45 @@ +package org.sculk.utils; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public class Binary { + + public static byte[] writeLong(long l) { + return new byte[]{ + (byte) (l >>> 56), + (byte) (l >>> 48), + (byte) (l >>> 40), + (byte) (l >>> 32), + (byte) (l >>> 24), + (byte) (l >>> 16), + (byte) (l >>> 8), + (byte) (l) + }; + } + + public static byte[] writeLLong(long l) { + return new byte[]{ + (byte) (l), + (byte) (l >>> 8), + (byte) (l >>> 16), + (byte) (l >>> 24), + (byte) (l >>> 32), + (byte) (l >>> 40), + (byte) (l >>> 48), + (byte) (l >>> 56), + }; + } +} diff --git a/src/main/java/org/sculk/utils/SculkMath.java b/src/main/java/org/sculk/utils/SculkMath.java new file mode 100644 index 0000000..dd76e33 --- /dev/null +++ b/src/main/java/org/sculk/utils/SculkMath.java @@ -0,0 +1,37 @@ +package org.sculk.utils; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public class SculkMath { + + public static long log2(long N) + { + + // calculate log2 N indirectly + // using log() method + + return (long)(Math.log(N) / Math.log(2)); + } + + public static int log2(int N) + { + + // calculate log2 N indirectly + // using log() method + + return (int)(Math.log(N) / Math.log(2)); + } +} diff --git a/src/main/java/org/sculk/world/Position.java b/src/main/java/org/sculk/world/Position.java new file mode 100644 index 0000000..1ca12d2 --- /dev/null +++ b/src/main/java/org/sculk/world/Position.java @@ -0,0 +1,231 @@ +package org.sculk.world; + +import lombok.Getter; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.math.GenericMath; +import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.math.vector.Vector3i; + +import javax.annotation.Nonnull; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public class Position extends Vector3f{ + public float x; + public float y; + public float z; + @Getter + public @Nullable World world; + public Position(float x, float y, float z, World world) { + this.x = x; + this.y = y; + this.z = z; + this.world = world; + } + public Position(double x, double y, double z, World world) { + this.x = (float) x; + this.y = (float) y; + this.z = (float) z; + this.world = world; + } + public Position(Vector3f vector3, World world) { + this.x = vector3.getX(); + this.y = vector3.getY(); + this.z = vector3.getZ(); + this.world = world; + } + public Position(Vector3i vector3, World world) { + this.x = vector3.getX(); + this.y = vector3.getY(); + this.z = vector3.getZ(); + this.world = world; + } + + public static Position from(World world) { + return from(ZERO, world); + } + + public static Position from(Vector3i position, World world) { + return from(position.getX(), position.getY(), position.getZ(), world); + } + + public static Position from(Vector3f position, World world) { + return from(position.getX(), position.getY(), position.getZ(), world); + } + + public static Position from(float x, float y, float z, World world) { + return new Position(from(x, y, z), world); + } + public static Position from(double x, double y, double z, World world) { + return new Position(from(x, y, z), world); + } + + public float getX() { + return this.x; + } + + public float getY() { + return this.y; + } + + public float getZ() { + return this.z; + } + + @Nonnull + @Override + public Position add(float x, float y, float z) { + return from(this.getX() + x, this.getY() + y, this.getZ() + z, this.world); + } + + @Nonnull + @Override + public Position sub(float x, float y, float z) { + return from(this.getX() - x, this.getY() - y, this.getZ() - z, this.world); + } + + @Nonnull + @Override + public Position mul(float x, float y, float z) { + return from(this.getX() * x, this.getY() * y, this.getZ() * z, this.world); + } + + @Nonnull + @Override + public Position div(float x, float y, float z) { + return from(this.getX() / x, this.getY() / y, this.getZ() / z, this.world); + } + + @Nonnull + @Override + public Position project(float x, float y, float z) { + float lengthSquared = x * x + y * y + z * z; + if (Math.abs(lengthSquared) < GenericMath.FLT_EPSILON) { + throw new ArithmeticException("Cannot project onto the zero vector"); + } else { + float a = this.dot(x, y, z) / lengthSquared; + return from(a * x, a * y, a * z, this.world); + } + } + + @Nonnull + @Override + public Position cross(float x, float y, float z) { + return from(this.getY() * z - this.getZ() * y, this.getZ() * x - this.getX() * z, this.getX() * y - this.getY() * x, this.world); + } + + @Nonnull + @Override + public Position pow(float power) { + return from(Math.pow((double)this.x, (double)power), Math.pow((double)this.y, (double)power), Math.pow((double)this.z, (double)power), this.world); + } + + @Nonnull + @Override + public Position ceil() { + return from(Math.ceil((double)this.getX()), Math.ceil((double)this.getY()), Math.ceil((double)this.getZ()), this.world); + } + + @Nonnull + @Override + public Position floor() { + return from((float)GenericMath.floor(this.getX()), (float)GenericMath.floor(this.getY()), (float)GenericMath.floor(this.getZ()), this.world); + } + + @Nonnull + @Override + public Position round() { + return from((float)Math.round(this.getX()), (float)Math.round(this.getY()), (float)Math.round(this.getZ()), this.world); + } + + @Nonnull + @Override + public Position abs() { + return from(Math.abs(this.getX()), Math.abs(this.getY()), Math.abs(this.getZ()), this.world); + } + + @Nonnull + @Override + public Position negate() { + return from(-this.getX(), -this.getY(), -this.getZ(), this.world); + } + + @Nonnull + @Override + public Position min(float x, float y, float z) { + return from(Math.min(this.getX(), x), Math.min(this.getY(), y), Math.min(this.getZ(), z), this.world); + } + + @Nonnull + @Override + public Position max(float x, float y, float z) { + return from(Math.max(this.getX(), x), Math.max(this.getY(), y), Math.max(this.getZ(), z), this.world); + } + + @Nonnull + @Override + public Position up(float v) { + return from(this.getX(), this.getY() + v, this.getZ(), this.world); + } + + @Nonnull + @Override + public Position down(float v) { + return from(this.getX(), this.getY() - v, this.getZ(), this.world); + } + + @Nonnull + @Override + public Position north(float v) { + return from(this.getX(), this.getY(), this.getZ() - v, this.world); + } + + @Nonnull + @Override + public Position south(float v) { + return from(this.getX(), this.getY(), this.getZ() + v, this.world); + } + + @Nonnull + @Override + public Position east(float v) { + return from(this.getX() + v, this.getY(), this.getZ(), this.world); + } + + @Nonnull + @Override + public Position west(float v) { + return from(this.getX() - v, this.getY(), this.getZ(), this.world); + } + + @Nonnull + @Override + public Position normalize() { + float length = this.length(); + if (Math.abs(length) < GenericMath.FLT_EPSILON) { + throw new ArithmeticException("Cannot normalize the zero vector"); + } else { + return from(this.getX() / length, this.getY() / length, this.getZ() / length, this.world); + } + } + + @Nonnull + @Override + public Position clone() { + return new Position(super.clone(), this.world); + } +} diff --git a/src/main/java/org/sculk/world/World.java b/src/main/java/org/sculk/world/World.java new file mode 100644 index 0000000..6328b59 --- /dev/null +++ b/src/main/java/org/sculk/world/World.java @@ -0,0 +1,18 @@ +package org.sculk.world; +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public class World { +} diff --git a/src/main/java/org/sculk/world/light/LightUpdate.java b/src/main/java/org/sculk/world/light/LightUpdate.java new file mode 100644 index 0000000..4adfc03 --- /dev/null +++ b/src/main/java/org/sculk/world/light/LightUpdate.java @@ -0,0 +1,21 @@ +package org.sculk.world.light; + +/* + * ____ _ _ __ __ ____ + * / ___| ___ _ _| | | __ | \/ | _ \ + * \___ \ / __| | | | | |/ / _____ | |\/| | |_) | + * ___) | (__| |_| | | < |_____| | | | | __/ + * |____/ \___|\__,_|_|_|\_\ |_| |_|_| + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @author: SculkTeams + * @link: http://www.sculkmp.org/ + */ +public class LightUpdate { + + public static final int BASE_LIGHT_FILTER = 1; +}