use of org.lanternpowered.server.block.LanternBlockType 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.LanternBlockType in project LanternServer by LanternPowered.
the class PlayerInteractionHandler method handleBrokenBlock.
private void handleBrokenBlock() {
final Location<World> location = new Location<>(this.player.getWorld(), this.diggingBlock);
final CauseStack causeStack = CauseStack.current();
try (CauseStack.Frame frame = causeStack.pushCauseFrame()) {
frame.pushCause(this.player);
// Add context
frame.addContext(EventContextKeys.PLAYER, this.player);
frame.addContext(ContextKeys.INTERACTION_LOCATION, location);
frame.addContext(ContextKeys.BLOCK_LOCATION, location);
final BehaviorContextImpl context = new BehaviorContextImpl(causeStack);
final BlockState blockState = location.getBlock();
final LanternBlockType blockType = (LanternBlockType) blockState.getType();
if (context.process(blockType.getPipeline().pipeline(BreakBlockBehavior.class), (ctx, behavior) -> behavior.tryBreak(blockType.getPipeline(), ctx)).isSuccess()) {
context.accept();
this.diggingBlock = null;
this.diggingBlockType = null;
} else {
context.revert();
// TODO: Resend tile entity data, action data, ... ???
this.player.sendBlockChange(this.diggingBlock, blockState);
}
if (this.lastBreakState != -1) {
sendBreakUpdate(-1);
}
}
}
use of org.lanternpowered.server.block.LanternBlockType in project LanternServer by LanternPowered.
the class LanternChunk method createSnapshot.
@Override
public BlockSnapshot createSnapshot(int x, int y, int z) {
final BlockState state = getBlock(x, y, z);
final Location<World> loc = new Location<>(this.world, x, y, z);
// TODO: Tile entity data
return new LanternBlockSnapshot(loc, state, ((LanternBlockType) state.getType()).getExtendedBlockStateProvider().get(state, loc, null), getCreator(x, y, z), getNotifier(x, y, z), ImmutableMap.of());
}
use of org.lanternpowered.server.block.LanternBlockType 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.LanternBlockType in project LanternServer by LanternPowered.
the class LanternChunk method setBlock.
@Override
public boolean setBlock(int x, int y, int z, BlockState block, BlockChangeFlag flag) {
checkNotNull(block, "block");
checkNotNull(flag, "flag");
checkVolumeBounds(x, y, z);
if (!this.loaded) {
return false;
}
final short type = BlockRegistryModule.get().getStateInternalIdAndData(block);
final short type1;
// Air doesn't have metadata values
if (type >> 4 == 0 && type != 0) {
type1 = 0;
} else {
type1 = type;
}
final BlockState[] changeData = new BlockState[1];
final int rx = x & 0xf;
final int rz = z & 0xf;
this.chunkSections.work(y >> 4, section -> {
if (section == null) {
// so we can fail fast
if (type1 == 0) {
return section;
}
// Create a new section
section = new ChunkSection();
}
final int index = ChunkSection.index(rx, y & 0xf, rz);
final short oldType = section.types[index];
if (oldType == type1) {
return section;
}
if (oldType != 0) {
short count = section.typesCountMap.get(oldType);
if (count > 0) {
if (--count <= 0) {
section.typesCountMap.remove(oldType);
} else {
section.typesCountMap.put(oldType, count);
}
}
}
if (type1 != 0) {
section.typesCountMap.put(type1, (short) (section.typesCountMap.get(type1) + 1));
if (oldType == 0) {
section.nonAirCount++;
}
} else {
section.nonAirCount--;
}
final BlockState oldState = BlockRegistryModule.get().getStateByInternalIdAndData(oldType).get();
changeData[0] = oldState;
// The section is empty, destroy it
if (section.nonAirCount <= 0) {
return null;
}
final LanternTileEntity tileEntity = section.tileEntities.get((short) index);
boolean remove = false;
boolean refresh = false;
final Optional<TileEntityProvider> tileEntityProvider = ((LanternBlockType) block.getType()).getTileEntityProvider();
if (tileEntity != null) {
if (oldType == 0 || type1 == 0) {
remove = true;
} else if (tileEntity instanceof ITileEntityRefreshBehavior) {
if (((ITileEntityRefreshBehavior) tileEntity).shouldRefresh(oldState, block)) {
remove = true;
refresh = true;
}
} else if (oldType >> 4 != type1 >> 4) {
// The default behavior will only refresh if the
// block type is changed and not the block state
remove = true;
refresh = true;
}
if (refresh && !tileEntityProvider.isPresent()) {
refresh = false;
}
} else if (tileEntityProvider.isPresent()) {
refresh = true;
}
if (remove) {
tileEntity.setValid(false);
}
if (refresh) {
final Location<World> location = tileEntity != null ? tileEntity.getLocation() : new Location<>(this.world, x, y, z);
final LanternTileEntity newTileEntity = (LanternTileEntity) tileEntityProvider.get().get(block, location, null);
section.tileEntities.put((short) index, newTileEntity);
newTileEntity.setLocation(location);
newTileEntity.setValid(true);
} else if (remove) {
section.tileEntities.remove((short) index);
}
section.types[index] = type1;
return section;
});
final int index = rz << 4 | rx;
long stamp = this.heightMapLock.writeLock();
try {
// TODO: Check first and then use the write lock?
if (type != 0 && (this.heightMap[index] & 0xff) < y) {
this.heightMap[index] = (byte) y;
this.heightMapUpdateFlags.clear(index);
} else if (type == 0 && (this.heightMap[index] & 0xff) == y) {
this.heightMapUpdateFlags.set(index);
}
} finally {
this.heightMapLock.unlock(stamp);
}
if (changeData[0] != null) {
this.world.getEventListener().onBlockChange(x, y, z, changeData[0], block);
}
return true;
}
Aggregations