Search in sources :

Example 1 with MechanicalPistonBlock

use of com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock in project Create by Creators-of-Create.

the class GoggleOverlayRenderer method renderOverlay.

public static void renderOverlay(ForgeIngameGui gui, PoseStack poseStack, float partialTicks, int width, int height) {
    HitResult objectMouseOver = Minecraft.getInstance().hitResult;
    if (!(objectMouseOver instanceof BlockHitResult)) {
        lastHovered = null;
        hoverTicks = 0;
        return;
    }
    for (OutlineEntry entry : outlines.values()) {
        if (!entry.isAlive())
            continue;
        Outline outline = entry.getOutline();
        if (outline instanceof ValueBox && !((ValueBox) outline).isPassive)
            return;
    }
    BlockHitResult result = (BlockHitResult) objectMouseOver;
    Minecraft mc = Minecraft.getInstance();
    ClientLevel world = mc.level;
    BlockPos pos = result.getBlockPos();
    ItemStack headSlot = mc.player.getItemBySlot(EquipmentSlot.HEAD);
    BlockEntity te = world.getBlockEntity(pos);
    if (lastHovered == null || lastHovered.equals(pos))
        hoverTicks++;
    else
        hoverTicks = 0;
    lastHovered = pos;
    boolean wearingGoggles = AllItems.GOGGLES.isIn(headSlot);
    for (Supplier<Boolean> supplier : customGogglePredicates) wearingGoggles |= supplier.get();
    boolean hasGoggleInformation = te instanceof IHaveGoggleInformation;
    boolean hasHoveringInformation = te instanceof IHaveHoveringInformation;
    boolean goggleAddedInformation = false;
    boolean hoverAddedInformation = false;
    List<Component> tooltip = new ArrayList<>();
    if (hasGoggleInformation && wearingGoggles) {
        IHaveGoggleInformation gte = (IHaveGoggleInformation) te;
        goggleAddedInformation = gte.addToGoggleTooltip(tooltip, mc.player.isShiftKeyDown());
    }
    if (hasHoveringInformation) {
        if (!tooltip.isEmpty())
            tooltip.add(TextComponent.EMPTY);
        IHaveHoveringInformation hte = (IHaveHoveringInformation) te;
        hoverAddedInformation = hte.addToTooltip(tooltip, mc.player.isShiftKeyDown());
        if (goggleAddedInformation && !hoverAddedInformation)
            tooltip.remove(tooltip.size() - 1);
    }
    if (te instanceof IDisplayAssemblyExceptions) {
        boolean exceptionAdded = ((IDisplayAssemblyExceptions) te).addExceptionToTooltip(tooltip);
        if (exceptionAdded) {
            hasHoveringInformation = true;
            hoverAddedInformation = true;
        }
    }
    // break early if goggle or hover returned false when present
    if ((hasGoggleInformation && !goggleAddedInformation) && (hasHoveringInformation && !hoverAddedInformation))
        return;
    // check for piston poles if goggles are worn
    BlockState state = world.getBlockState(pos);
    if (wearingGoggles && AllBlocks.PISTON_EXTENSION_POLE.has(state)) {
        Direction[] directions = Iterate.directionsInAxis(state.getValue(PistonExtensionPoleBlock.FACING).getAxis());
        int poles = 1;
        boolean pistonFound = false;
        for (Direction dir : directions) {
            int attachedPoles = PistonExtensionPoleBlock.PlacementHelper.get().attachedPoles(world, pos, dir);
            poles += attachedPoles;
            pistonFound |= world.getBlockState(pos.relative(dir, attachedPoles + 1)).getBlock() instanceof MechanicalPistonBlock;
        }
        if (!pistonFound)
            return;
        if (!tooltip.isEmpty())
            tooltip.add(TextComponent.EMPTY);
        tooltip.add(IHaveGoggleInformation.componentSpacing.plainCopy().append(Lang.translate("gui.goggles.pole_length")).append(new TextComponent(" " + poles)));
    }
    if (tooltip.isEmpty())
        return;
    poseStack.pushPose();
    int tooltipTextWidth = 0;
    for (FormattedText textLine : tooltip) {
        int textLineWidth = mc.font.width(textLine);
        if (textLineWidth > tooltipTextWidth)
            tooltipTextWidth = textLineWidth;
    }
    int tooltipHeight = 8;
    if (tooltip.size() > 1) {
        // gap between title lines and next lines
        tooltipHeight += 2;
        tooltipHeight += (tooltip.size() - 1) * 10;
    }
    CClient cfg = AllConfigs.CLIENT;
    int posX = width / 2 + cfg.overlayOffsetX.get();
    int posY = height / 2 + cfg.overlayOffsetY.get();
    posX = Math.min(posX, width - tooltipTextWidth - 20);
    posY = Math.min(posY, height - tooltipHeight - 20);
    float fade = Mth.clamp((hoverTicks + partialTicks) / 12f, 0, 1);
    Boolean useCustom = cfg.overlayCustomColor.get();
    Color colorBackground = useCustom ? new Color(cfg.overlayBackgroundColor.get()) : Theme.c(Theme.Key.VANILLA_TOOLTIP_BACKGROUND).scaleAlpha(.75f);
    Color colorBorderTop = useCustom ? new Color(cfg.overlayBorderColorTop.get()) : Theme.c(Theme.Key.VANILLA_TOOLTIP_BORDER, true).copy();
    Color colorBorderBot = useCustom ? new Color(cfg.overlayBorderColorBot.get()) : Theme.c(Theme.Key.VANILLA_TOOLTIP_BORDER, false).copy();
    if (fade < 1) {
        poseStack.translate((1 - fade) * Math.signum(cfg.overlayOffsetX.get() + .5f) * 4, 0, 0);
        colorBackground.scaleAlpha(fade);
        colorBorderTop.scaleAlpha(fade);
        colorBorderBot.scaleAlpha(fade);
    }
    RemovedGuiUtils.drawHoveringText(poseStack, tooltip, posX, posY, width, height, -1, colorBackground.getRGB(), colorBorderTop.getRGB(), colorBorderBot.getRGB(), mc.font);
    ItemStack item = AllItems.GOGGLES.asStack();
    GuiGameElement.of(item).at(posX + 10, posY - 16, 450).render(poseStack);
    poseStack.popPose();
}
Also used : ArrayList(java.util.ArrayList) IDisplayAssemblyExceptions(com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions) Direction(net.minecraft.core.Direction) BlockHitResult(net.minecraft.world.phys.BlockHitResult) HitResult(net.minecraft.world.phys.HitResult) OutlineEntry(com.simibubi.create.foundation.utility.outliner.Outliner.OutlineEntry) CClient(com.simibubi.create.foundation.config.CClient) BlockPos(net.minecraft.core.BlockPos) BlockHitResult(net.minecraft.world.phys.BlockHitResult) Component(net.minecraft.network.chat.Component) TextComponent(net.minecraft.network.chat.TextComponent) BlockEntity(net.minecraft.world.level.block.entity.BlockEntity) TextComponent(net.minecraft.network.chat.TextComponent) ClientLevel(net.minecraft.client.multiplayer.ClientLevel) MechanicalPistonBlock(com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock) Color(com.simibubi.create.foundation.utility.Color) Outline(com.simibubi.create.foundation.utility.outliner.Outline) FormattedText(net.minecraft.network.chat.FormattedText) Minecraft(net.minecraft.client.Minecraft) BlockState(net.minecraft.world.level.block.state.BlockState) ValueBox(com.simibubi.create.foundation.tileEntity.behaviour.ValueBox) ItemStack(net.minecraft.world.item.ItemStack)

Example 2 with MechanicalPistonBlock

use of com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock 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();
}
Also used : SeatBlock(com.simibubi.create.content.contraptions.components.actors.SeatBlock) BlockState(net.minecraft.world.level.block.state.BlockState) SuperGlueEntity(com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity) MechanicalPistonBlock(com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock) AbstractChassisBlock(com.simibubi.create.content.contraptions.components.structureMovement.chassis.AbstractChassisBlock) BlockPos(net.minecraft.core.BlockPos) Direction(net.minecraft.core.Direction) PulleyBlock(com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock)

Example 3 with MechanicalPistonBlock

use of com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock in project Create by Creators-of-Create.

the class Contraption method movePistonHead.

protected void movePistonHead(Level world, BlockPos pos, Queue<BlockPos> frontier, Set<BlockPos> visited, BlockState state) {
    Direction direction = state.getValue(MechanicalPistonHeadBlock.FACING);
    BlockPos offset = pos.relative(direction.getOpposite());
    if (!visited.contains(offset)) {
        BlockState blockState = world.getBlockState(offset);
        if (isExtensionPole(blockState) && blockState.getValue(PistonExtensionPoleBlock.FACING).getAxis() == direction.getAxis())
            frontier.add(offset);
        if (blockState.getBlock() instanceof MechanicalPistonBlock) {
            Direction pistonFacing = blockState.getValue(MechanicalPistonBlock.FACING);
            if (pistonFacing == direction && blockState.getValue(MechanicalPistonBlock.STATE) == PistonState.EXTENDED)
                frontier.add(offset);
        }
    }
    if (state.getValue(MechanicalPistonHeadBlock.TYPE) == PistonType.STICKY) {
        BlockPos attached = pos.relative(direction);
        if (!visited.contains(attached))
            frontier.add(attached);
    }
}
Also used : BlockState(net.minecraft.world.level.block.state.BlockState) MechanicalPistonBlock(com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock) BlockPos(net.minecraft.core.BlockPos) Direction(net.minecraft.core.Direction)

Aggregations

MechanicalPistonBlock (com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock)3 BlockPos (net.minecraft.core.BlockPos)3 Direction (net.minecraft.core.Direction)3 BlockState (net.minecraft.world.level.block.state.BlockState)3 SeatBlock (com.simibubi.create.content.contraptions.components.actors.SeatBlock)1 IDisplayAssemblyExceptions (com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions)1 AbstractChassisBlock (com.simibubi.create.content.contraptions.components.structureMovement.chassis.AbstractChassisBlock)1 SuperGlueEntity (com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity)1 PulleyBlock (com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock)1 CClient (com.simibubi.create.foundation.config.CClient)1 ValueBox (com.simibubi.create.foundation.tileEntity.behaviour.ValueBox)1 Color (com.simibubi.create.foundation.utility.Color)1 Outline (com.simibubi.create.foundation.utility.outliner.Outline)1 OutlineEntry (com.simibubi.create.foundation.utility.outliner.Outliner.OutlineEntry)1 ArrayList (java.util.ArrayList)1 Minecraft (net.minecraft.client.Minecraft)1 ClientLevel (net.minecraft.client.multiplayer.ClientLevel)1 Component (net.minecraft.network.chat.Component)1 FormattedText (net.minecraft.network.chat.FormattedText)1 TextComponent (net.minecraft.network.chat.TextComponent)1