use of com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity in project Create_Aeronautics by Eriksonnaren.
the class ServerWorldEventMixin method addFreshEntity.
/**
* @author RyanHCode
*/
@Overwrite(remap = false)
public boolean addFreshEntity(Entity entity) {
if (((Object) this) instanceof ServerWorld && ((ServerWorld) (Object) this).dimension() == AirshipDimensionManager.WORLD_ID && !(entity instanceof AbstractContraptionEntity || entity instanceof SuperGlueEntity)) {
// get position of entity
Vector3d pos = entity.position();
BlockPos bPos = entity.blockPosition();
// get airship plot id
int id = AirshipManager.getIdFromPlotPos(bPos);
BlockPos plotPos = AirshipManager.getPlotPosFromId(id);
// get airship
AirshipContraptionEntity airship = AirshipManager.INSTANCE.AllAirships.get(id);
if (airship != null) {
Vector3d position = pos;
position = position.subtract(plotPos.getX(), plotPos.getY(), plotPos.getZ());
position = airship.toGlobalVector(position, 1.0f);
// rotate entity motion
entity.setDeltaMovement(airship.applyRotation(entity.getDeltaMovement(), 1.0f));
entity.setPosRaw(position.x, position.y, position.z);
entity.setLevel(airship.level);
return airship.level.addFreshEntity(entity);
}
}
return this.addEntity(entity);
}
use of com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity in project Create by Creators-of-Create.
the class Contraption method moveBlock.
/**
* move the first block in frontier queue
*/
protected boolean moveBlock(Level world, @Nullable Direction forcedDirection, Queue<BlockPos> frontier, Set<BlockPos> visited) throws AssemblyException {
BlockPos pos = frontier.poll();
if (pos == null)
return false;
visited.add(pos);
if (world.isOutsideBuildHeight(pos))
return true;
if (!world.isLoaded(pos))
throw AssemblyException.unloadedChunk(pos);
if (isAnchoringBlockAt(pos))
return true;
BlockState state = world.getBlockState(pos);
if (!BlockMovementChecks.isMovementNecessary(state, world, pos))
return true;
if (!movementAllowed(state, world, pos))
throw AssemblyException.unmovableBlock(pos, state);
if (state.getBlock() instanceof AbstractChassisBlock && !moveChassis(world, pos, forcedDirection, frontier, visited))
return false;
if (AllBlocks.BELT.has(state))
moveBelt(pos, frontier, visited, state);
if (AllBlocks.GANTRY_CARRIAGE.has(state))
moveGantryPinion(world, pos, frontier, visited, state);
if (AllBlocks.GANTRY_SHAFT.has(state))
moveGantryShaft(world, pos, frontier, visited, state);
if (AllBlocks.STICKER.has(state) && state.getValue(StickerBlock.EXTENDED)) {
Direction offset = state.getValue(StickerBlock.FACING);
BlockPos attached = pos.relative(offset);
if (!visited.contains(attached) && !BlockMovementChecks.isNotSupportive(world.getBlockState(attached), offset.getOpposite()))
frontier.add(attached);
}
// Double Chest halves stick together
if (state.hasProperty(ChestBlock.TYPE) && state.hasProperty(ChestBlock.FACING) && state.getValue(ChestBlock.TYPE) != ChestType.SINGLE) {
Direction offset = ChestBlock.getConnectedDirection(state);
BlockPos attached = pos.relative(offset);
if (!visited.contains(attached))
frontier.add(attached);
}
// Bearings potentially create stabilized sub-contraptions
if (AllBlocks.MECHANICAL_BEARING.has(state))
moveBearing(pos, frontier, visited, state);
// WM Bearings attach their structure when moved
if (AllBlocks.WINDMILL_BEARING.has(state))
moveWindmillBearing(pos, frontier, visited, state);
// Seats transfer their passenger to the contraption
if (state.getBlock() instanceof SeatBlock)
moveSeat(world, pos);
// Pulleys drag their rope and their attached structure
if (state.getBlock() instanceof PulleyBlock)
movePulley(world, pos, frontier, visited);
// Pistons drag their attaches poles and extension
if (state.getBlock() instanceof MechanicalPistonBlock)
if (!moveMechanicalPiston(world, pos, frontier, visited, state))
return false;
if (isExtensionPole(state))
movePistonPole(world, pos, frontier, visited, state);
if (isPistonHead(state))
movePistonHead(world, pos, frontier, visited, state);
// Cart assemblers attach themselves
BlockPos posDown = pos.below();
BlockState stateBelow = world.getBlockState(posDown);
if (!visited.contains(posDown) && AllBlocks.CART_ASSEMBLER.has(stateBelow))
frontier.add(posDown);
Map<Direction, SuperGlueEntity> superglue = SuperGlueHandler.gatherGlue(world, pos);
// Slime blocks and super glue drag adjacent blocks if possible
for (Direction offset : Iterate.directions) {
BlockPos offsetPos = pos.relative(offset);
BlockState blockState = world.getBlockState(offsetPos);
if (isAnchoringBlockAt(offsetPos))
continue;
if (!movementAllowed(blockState, world, offsetPos)) {
if (offset == forcedDirection)
throw AssemblyException.unmovableBlock(pos, state);
continue;
}
boolean wasVisited = visited.contains(offsetPos);
boolean faceHasGlue = superglue.containsKey(offset);
boolean blockAttachedTowardsFace = BlockMovementChecks.isBlockAttachedTowards(blockState, world, offsetPos, offset.getOpposite());
boolean brittle = BlockMovementChecks.isBrittle(blockState);
boolean canStick = !brittle && state.canStickTo(blockState) && blockState.canStickTo(state);
if (canStick) {
if (state.getPistonPushReaction() == PushReaction.PUSH_ONLY || blockState.getPistonPushReaction() == PushReaction.PUSH_ONLY) {
canStick = false;
}
if (BlockMovementChecks.isNotSupportive(state, offset)) {
canStick = false;
}
if (BlockMovementChecks.isNotSupportive(blockState, offset.getOpposite())) {
canStick = false;
}
}
if (!wasVisited && (canStick || blockAttachedTowardsFace || faceHasGlue || (offset == forcedDirection && !BlockMovementChecks.isNotSupportive(state, forcedDirection))))
frontier.add(offsetPos);
if (faceHasGlue)
addGlue(superglue.get(offset));
}
addBlock(pos, capture(world, pos));
if (blocks.size() <= AllConfigs.SERVER.kinetics.maxBlocksMoved.get())
return true;
else
throw AssemblyException.structureTooLarge();
}
use of com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity in project Create by Creators-of-Create.
the class CloneCommand method cloneGlue.
private static int cloneGlue(BoundingBox sourceArea, ServerLevel world, BlockPos diffToTarget) {
int gluePastes = 0;
List<SuperGlueEntity> glue = world.getEntitiesOfClass(SuperGlueEntity.class, AABB.of(sourceArea));
List<Pair<BlockPos, Direction>> newGlue = Lists.newArrayList();
for (SuperGlueEntity g : glue) {
BlockPos pos = g.getHangingPosition();
Direction direction = g.getFacingDirection();
newGlue.add(Pair.of(pos.offset(diffToTarget), direction));
}
for (Pair<BlockPos, Direction> p : newGlue) {
SuperGlueEntity g = new SuperGlueEntity(world, p.getFirst(), p.getSecond());
if (g.onValidSurface()) {
world.addFreshEntity(g);
gluePastes++;
}
}
return gluePastes;
}
use of com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity in project Create by Creators-of-Create.
the class Contraption method removeBlocksFromWorld.
public void removeBlocksFromWorld(Level world, BlockPos offset) {
storage.values().forEach(MountedStorage::removeStorageFromWorld);
fluidStorage.values().forEach(MountedFluidStorage::removeStorageFromWorld);
glueToRemove.forEach(SuperGlueEntity::discard);
for (boolean brittles : Iterate.trueAndFalse) {
for (Iterator<StructureBlockInfo> iterator = blocks.values().iterator(); iterator.hasNext(); ) {
StructureBlockInfo block = iterator.next();
if (brittles != BlockMovementChecks.isBrittle(block.state))
continue;
BlockPos add = block.pos.offset(anchor).offset(offset);
if (customBlockRemoval(world, add, block.state))
continue;
BlockState oldState = world.getBlockState(add);
Block blockIn = oldState.getBlock();
if (block.state.getBlock() != blockIn)
iterator.remove();
world.removeBlockEntity(add);
int flags = Block.UPDATE_MOVE_BY_PISTON | Block.UPDATE_SUPPRESS_DROPS | Block.UPDATE_KNOWN_SHAPE | Block.UPDATE_CLIENTS | Block.UPDATE_IMMEDIATE;
if (blockIn instanceof SimpleWaterloggedBlock && oldState.hasProperty(BlockStateProperties.WATERLOGGED) && oldState.getValue(BlockStateProperties.WATERLOGGED)) {
world.setBlock(add, Blocks.WATER.defaultBlockState(), flags);
continue;
}
world.setBlock(add, Blocks.AIR.defaultBlockState(), flags);
}
}
for (StructureBlockInfo block : blocks.values()) {
BlockPos add = block.pos.offset(anchor).offset(offset);
// if (!shouldUpdateAfterMovement(block))
// continue;
int flags = Block.UPDATE_MOVE_BY_PISTON | Block.UPDATE_ALL;
world.sendBlockUpdated(add, block.state, Blocks.AIR.defaultBlockState(), flags);
// when the blockstate is set to air, the block's POI data is removed, but
// markAndNotifyBlock tries to
// remove it again, so to prevent an error from being logged by double-removal
// we add the POI data back now
// (code copied from ServerWorld.onBlockStateChange)
ServerLevel serverWorld = (ServerLevel) world;
PoiType.forState(block.state).ifPresent(poiType -> {
world.getServer().execute(() -> {
serverWorld.getPoiManager().add(add, poiType);
DebugPackets.sendPoiAddedPacket(serverWorld, add);
});
});
world.markAndNotifyBlock(add, world.getChunkAt(add), block.state, Blocks.AIR.defaultBlockState(), flags, 512);
block.state.updateIndirectNeighbourShapes(world, add, flags & -2);
}
}
use of com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity in project Create by Creators-of-Create.
the class Contraption method addBlocksToWorld.
public void addBlocksToWorld(Level world, StructureTransform transform) {
for (boolean nonBrittles : Iterate.trueAndFalse) {
for (StructureBlockInfo block : blocks.values()) {
if (nonBrittles == BlockMovementChecks.isBrittle(block.state))
continue;
BlockPos targetPos = transform.apply(block.pos);
BlockState state = transform.apply(block.state);
if (customBlockPlacement(world, targetPos, state))
continue;
if (nonBrittles)
for (Direction face : Iterate.directions) state = state.updateShape(face, world.getBlockState(targetPos.relative(face)), world, targetPos, targetPos.relative(face));
BlockState blockState = world.getBlockState(targetPos);
if (blockState.getDestroySpeed(world, targetPos) == -1 || (state.getCollisionShape(world, targetPos).isEmpty() && !blockState.getCollisionShape(world, targetPos).isEmpty())) {
if (targetPos.getY() == 0)
targetPos = targetPos.above();
world.levelEvent(2001, targetPos, Block.getId(state));
Block.dropResources(state, world, targetPos, null);
continue;
}
if (state.getBlock() instanceof SimpleWaterloggedBlock && state.hasProperty(BlockStateProperties.WATERLOGGED)) {
FluidState FluidState = world.getFluidState(targetPos);
state = state.setValue(BlockStateProperties.WATERLOGGED, FluidState.getType() == Fluids.WATER);
}
world.destroyBlock(targetPos, true);
world.setBlock(targetPos, state, Block.UPDATE_MOVE_BY_PISTON | Block.UPDATE_ALL);
boolean verticalRotation = transform.rotationAxis == null || transform.rotationAxis.isHorizontal();
verticalRotation = verticalRotation && transform.rotation != Rotation.NONE;
if (verticalRotation) {
if (state.getBlock() instanceof RopeBlock || state.getBlock() instanceof MagnetBlock)
world.destroyBlock(targetPos, true);
}
BlockEntity tileEntity = world.getBlockEntity(targetPos);
CompoundTag tag = block.nbt;
if (tileEntity != null)
tag = NBTProcessors.process(tileEntity, tag, false);
if (tileEntity != null && tag != null) {
tag.putInt("x", targetPos.getX());
tag.putInt("y", targetPos.getY());
tag.putInt("z", targetPos.getZ());
if (verticalRotation && tileEntity instanceof PulleyTileEntity) {
tag.remove("Offset");
tag.remove("InitialOffset");
}
if (tileEntity instanceof IMultiTileContainer && tag.contains("LastKnownPos"))
tag.put("LastKnownPos", NbtUtils.writeBlockPos(BlockPos.ZERO.below(Integer.MAX_VALUE - 1)));
tileEntity.load(tag);
if (storage.containsKey(block.pos)) {
MountedStorage mountedStorage = storage.get(block.pos);
if (mountedStorage.isValid())
mountedStorage.addStorageToWorld(tileEntity);
}
if (fluidStorage.containsKey(block.pos)) {
MountedFluidStorage mountedStorage = fluidStorage.get(block.pos);
if (mountedStorage.isValid())
mountedStorage.addStorageToWorld(tileEntity);
}
}
transform.apply(tileEntity);
}
}
for (StructureBlockInfo block : blocks.values()) {
if (!shouldUpdateAfterMovement(block))
continue;
BlockPos targetPos = transform.apply(block.pos);
world.markAndNotifyBlock(targetPos, world.getChunkAt(targetPos), block.state, block.state, Block.UPDATE_MOVE_BY_PISTON | Block.UPDATE_ALL, 512);
}
for (int i = 0; i < inventory.getSlots(); i++) {
if (!inventory.isSlotExternal(i))
inventory.setStackInSlot(i, ItemStack.EMPTY);
}
for (int i = 0; i < fluidInventory.getTanks(); i++) fluidInventory.drain(fluidInventory.getFluidInTank(i), FluidAction.EXECUTE);
for (Pair<BlockPos, Direction> pair : superglue) {
BlockPos targetPos = transform.apply(pair.getKey());
Direction targetFacing = transform.transformFacing(pair.getValue());
SuperGlueEntity entity = new SuperGlueEntity(world, targetPos, targetFacing);
if (entity.onValidSurface()) {
if (!world.isClientSide)
world.addFreshEntity(entity);
}
}
}
Aggregations