use of org.lanternpowered.server.block.provider.CachedSimpleObjectProvider in project LanternServer by LanternPowered.
the class LanternChunk method getBlockSelectionBox.
@Override
public Optional<AABB> getBlockSelectionBox(int x, int y, int z) {
final BlockState block = getBlock(x, y, z);
if (block.getType() == BlockTypes.AIR) {
return Optional.empty();
}
final ObjectProvider<AABB> aabbObjectProvider = ((LanternBlockType) block.getType()).getBoundingBoxProvider();
if (aabbObjectProvider == null) {
return Optional.empty();
}
final AABB aabb;
if (aabbObjectProvider instanceof ConstantObjectProvider || aabbObjectProvider instanceof CachedSimpleObjectProvider || aabbObjectProvider instanceof SimpleObjectProvider) {
aabb = aabbObjectProvider.get(block, null, null);
} else {
aabb = aabbObjectProvider.get(block, new Location<>(this.world, x, y, z), null);
}
return aabb == null ? Optional.empty() : Optional.of(aabb.offset(x, y, z));
}
use of org.lanternpowered.server.block.provider.CachedSimpleObjectProvider 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;
}
Aggregations