use of org.lanternpowered.server.block.state.LanternBlockState in project LanternServer by LanternPowered.
the class BlockRegistryModule method register.
@Override
public void register(int internalId, BlockType blockType) {
LanternBlockType blockType0 = (LanternBlockType) checkNotNull(blockType, "blockType");
checkState(blockType0.getBlockStateBase().getBlockStates().stream().filter(s -> !((LanternBlockState) s).isExtended()).count() <= 1, "You cannot register a blockType with more then one state with this method.");
register0(internalId, blockType0, blockState -> (byte) 0);
}
use of org.lanternpowered.server.block.state.LanternBlockState in project LanternServer by LanternPowered.
the class BlockTypeBuilderImpl method build.
@Override
public LanternBlockType build(String pluginId, String id) {
MutableBehaviorPipeline<Behavior> behaviorPipeline = this.behaviorPipeline;
if (behaviorPipeline == null) {
behaviorPipeline = new MutableBehaviorPipelineImpl<>(Behavior.class, new ArrayList<>());
} else {
behaviorPipeline = new MutableBehaviorPipelineImpl<>(Behavior.class, new ArrayList<>(behaviorPipeline.getBehaviors()));
}
TranslationProvider translationProvider = this.translationProvider;
if (translationProvider == null) {
String path = "tile." + id + ".name";
if (!pluginId.equals("minecraft")) {
path = pluginId + '.' + path;
}
translationProvider = TranslationProvider.of(tr(path));
}
PropertyProviderCollection.Builder properties;
if (this.propertiesBuilder != null) {
properties = this.propertiesBuilder;
} else {
properties = PropertyProviderCollections.DEFAULT.toBuilder();
}
ExtendedBlockStateProvider extendedBlockStateProvider = this.extendedBlockStateProvider;
if (extendedBlockStateProvider == null) {
extendedBlockStateProvider = new ExtendedBlockStateProvider() {
@Override
public BlockState get(BlockState blockState, @Nullable Location<World> location, @Nullable Direction face) {
return blockState;
}
@Override
public BlockState remove(BlockState blockState) {
return blockState;
}
};
}
final LanternBlockType blockType = new LanternBlockType(pluginId, id, this.traits, translationProvider, behaviorPipeline, this.tileEntityProvider, extendedBlockStateProvider);
// Override the default solid cube property provider if necessary
final PropertyProvider<SolidCubeProperty> provider = properties.build().get(SolidCubeProperty.class).orElse(null);
ObjectProvider<AABB> boundingBoxProvider = this.boundingBoxProvider;
if (boundingBoxProvider instanceof SimpleObjectProvider) {
// noinspection unchecked
boundingBoxProvider = new CachedSimpleObjectProvider(blockType, ((SimpleObjectProvider) boundingBoxProvider).getProvider());
}
// noinspection ConstantConditions
if (provider instanceof ConstantObjectProvider && provider.get(null, null, null).getValue()) {
if (boundingBoxProvider instanceof ConstantObjectProvider) {
// noinspection ConstantConditions
final AABB aabb = boundingBoxProvider.get(null, null, null);
final boolean isSolid = isSolid(aabb);
if (isSolid) {
properties.add(solidCube(true));
properties.add(solidSide(true));
} else {
properties.add(solidCube(false));
final BitSet solidSides = compileSidePropertyBitSet(aabb);
// Check if all the direction bits are set
final byte[] bytes = solidSides.toByteArray();
if (bytes.length == 0 || bytes[0] != (1 << DIRECTION_INDEXES) - 1) {
properties.add(solidSide((blockState, location, face) -> {
final int index = getDirectionIndex(face);
return index != -1 && solidSides.get(index);
}));
} else {
properties.add(solidSide(false));
}
}
} else if (boundingBoxProvider instanceof CachedSimpleObjectProvider) {
final List<AABB> values = ((CachedSimpleObjectProvider<AABB>) boundingBoxProvider).getValues();
final BitSet bitSet = new BitSet();
int count = 0;
for (int i = 0; i < values.size(); i++) {
if (isSolid(values.get(i))) {
bitSet.set(i);
count++;
}
}
final boolean flag1 = count == values.size();
final boolean flag2 = count == 0;
// Use the best possible solid cube property
if (flag1) {
properties.add(solidCube(true));
properties.add(solidSide(false));
} else if (flag2) {
properties.add(solidCube(false));
} else {
properties.add(solidCube(((blockState, location, face) -> bitSet.get(((LanternBlockState) blockState).getInternalId()))));
}
if (!flag1) {
final BitSet[] solidSides = new BitSet[values.size()];
int solidCount = 0;
for (int i = 0; i < values.size(); i++) {
solidSides[i] = compileSidePropertyBitSet(values.get(i));
// Check if all the direction bits are set
final byte[] bytes = solidSides[i].toByteArray();
if (bytes.length != 0 && bytes[0] == (1 << DIRECTION_INDEXES) - 1) {
solidCount++;
}
}
if (solidCount == 0) {
properties.add(solidSide(false));
} else {
properties.add(solidSide((blockState, location, face) -> {
final int index = getDirectionIndex(face);
if (index == -1) {
return false;
}
final int state = ((LanternBlockState) blockState).getInternalId();
return solidSides[state].get(index);
}));
}
}
} else {
final ObjectProvider<AABB> boundingBoxProvider1 = boundingBoxProvider;
properties.add(solidCube(((blockState, location, face) -> isSolid(boundingBoxProvider1.get(blockState, location, face)))));
properties.add(solidSide(((blockState, location, face) -> isSideSolid(boundingBoxProvider1.get(blockState, location, face), face))));
}
}
blockType.setBoundingBoxProvider(boundingBoxProvider);
blockType.setPropertyProviderCollection(properties.build());
if (this.defaultStateProvider != null) {
blockType.setDefaultBlockState(this.defaultStateProvider.apply(blockType.getDefaultState()));
}
if (this.itemTypeBuilder != null) {
final ItemType itemType = this.itemTypeBuilder.blockType(blockType).behaviors(pipeline -> {
// Only add the default behavior if there isn't any interaction behavior present
if (pipeline.pipeline(InteractWithItemBehavior.class).getBehaviors().isEmpty()) {
pipeline.add(new InteractWithBlockItemBehavior());
}
}).build(blockType.getPluginId(), blockType.getName());
blockType.setItemType(itemType);
}
return blockType;
}
use of org.lanternpowered.server.block.state.LanternBlockState in project LanternServer by LanternPowered.
the class BlockRegistryModule method register0.
private void register0(int internalId, LanternBlockType blockType, BlockState2DataFunction stateToDataConverter) {
checkNotNull(stateToDataConverter, "stateToDataConverter");
checkState(internalId >= 0, "The internal id cannot be negative: %s", internalId);
checkState(internalId <= 0xfff, "The internal id exceeded the internal id limit: %s > %s", internalId, 0xfff);
final short internalId0 = (short) internalId;
checkState(!this.blockTypeByInternalId.containsKey(internalId0), "The internal id is already used: %s", internalId);
super.register(blockType);
this.blockTypeByInternalId.put(internalId0, blockType);
this.internalIdByBlockType.put(blockType, internalId0);
Byte2ObjectMap<BlockState> usedValues = new Byte2ObjectOpenHashMap<>();
int internalStateIdBase = (internalId & 0xfff) << 4;
for (BlockState blockState : blockType.getBlockStateBase().getBlockStates()) {
if (((LanternBlockState) blockState).isExtended()) {
continue;
}
byte value = checkNotNull(stateToDataConverter.apply(blockState));
if (usedValues.containsKey(value)) {
throw new IllegalStateException("The data value " + value + " for state '" + blockState.getId() + "' is already used by '" + usedValues.get(value).getId() + "'");
}
usedValues.put(value, blockState);
final short internalStateId = (short) (internalStateIdBase | value & 0xf);
this.blockStateByPackedType.put(internalStateId, blockState);
this.packedTypeByBlockState.put(blockState, internalStateId);
}
final BlockState defaultBlockState = blockType.getDefaultState();
for (byte b = 0; b <= 0xf; b++) {
if (!usedValues.containsKey(b)) {
final short internalStateId = (short) (internalStateIdBase | b & 0xf);
this.blockStateByPackedType.put(internalStateId, defaultBlockState);
}
}
for (BlockState blockState : blockType.getBlockStateBase().getBlockStates()) {
if (!((LanternBlockState) blockState).isExtended()) {
continue;
}
blockState = blockType.getExtendedBlockStateProvider().remove(blockState);
this.packedTypeByBlockState.put(blockState, checkNotNull(this.packedTypeByBlockState.get(blockState)));
}
final BlockStateRegistryModule blockStateRegistryModule = Lantern.getRegistry().getRegistryModule(BlockStateRegistryModule.class).get();
blockType.getAllBlockStates().forEach(blockStateRegistryModule::registerState);
blockType.getItem().ifPresent(itemType -> ItemRegistryModule.get().register(internalId, itemType));
Lantern.getGame().getPropertyRegistry().registerBlockPropertyStores(blockType.getPropertyProviderCollection());
}
Aggregations