use of org.spongepowered.api.data.property.block.SolidCubeProperty in project LanternServer by LanternPowered.
the class DoorBehavior method tryPlace.
@Override
public BehaviorResult tryPlace(BehaviorPipeline<Behavior> pipeline, BehaviorContext context) {
final Location<World> location = context.requireContext(ContextKeys.BLOCK_LOCATION);
final Direction face = context.requireContext(ContextKeys.INTERACTION_FACE);
// Door can only be placed by clicking in the floor
if (face != Direction.DOWN) {
return BehaviorResult.PASS;
}
final Location<World> down = location.getBlockRelative(Direction.DOWN);
final SolidCubeProperty solidProp = down.getProperty(SolidCubeProperty.class).get();
// The door must be placed on a solid block
if (!solidProp.getValue()) {
return BehaviorResult.PASS;
}
final Location<World> up = location.getBlockRelative(Direction.UP);
final ReplaceableProperty replaceableProp = up.getProperty(ReplaceableProperty.class).get();
if (!replaceableProp.getValue()) {
return BehaviorResult.PASS;
}
final BlockSnapshot snapshot = context.getContext(ContextKeys.BLOCK_SNAPSHOT).orElseThrow(() -> new IllegalStateException("The BlockSnapshotRetrieveBehavior BlockSnapshot isn't present."));
final BlockSnapshotBuilder builder = BlockSnapshotBuilder.create().from(snapshot);
context.populateBlockSnapshot(builder, BehaviorContext.PopulationFlags.CREATOR_AND_NOTIFIER);
Direction facing = Direction.NORTH;
Vector3i left = Vector3i.UNIT_X;
final Optional<Entity> optSource = context.first(Entity.class);
if (optSource.isPresent()) {
final Entity source = optSource.get();
final Vector3d rotVector;
if (source instanceof Living) {
rotVector = ((Living) source).getHeadRotation();
} else {
rotVector = optSource.get().getRotation();
}
// Calculate the direction the entity is looking
final Vector3d dir = Quaternions.fromAxesAnglesDeg(rotVector.mul(-1)).rotate(Vector3d.FORWARD);
facing = Direction.getClosestHorizontal(dir, Direction.Division.CARDINAL);
left = LEFT_ANGLE.rotate(facing.asOffset()).toInt();
facing = facing.getOpposite();
}
builder.add(Keys.DIRECTION, facing);
// TODO: Hinges
context.addBlockChange(builder.location(location).build());
context.addBlockChange(builder.add(LanternKeys.DOOR_HALF, LanternDoorHalf.UPPER).location(up).build());
return BehaviorResult.SUCCESS;
}
use of org.spongepowered.api.data.property.block.SolidCubeProperty 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