-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
create system Block based on PocketMine-MP 5 thanks dylan
- Loading branch information
1 parent
d6aca04
commit 02e79af
Showing
25 changed files
with
2,609 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<Object> 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. | ||
* <p> | ||
* 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<String> 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<Block> generateStatePermutations() { | ||
List<Block> 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. | ||
* <p> | ||
* 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. | ||
* <p> | ||
* 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(); | ||
} | ||
} |
Oops, something went wrong.