[Feature] AirSelectionItem
allows Items to highlight/use air blocks
This commit is contained in:
parent
296696d23b
commit
75ccdf38d5
3 changed files with 89 additions and 41 deletions
|
@ -0,0 +1,60 @@
|
|||
package org.betterx.bclib.interfaces;
|
||||
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.InteractionResultHolder;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.context.UseOnContext;
|
||||
import net.minecraft.world.level.ClipBlockStateContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public interface AirSelectionItem {
|
||||
default boolean renderAirSelection() {
|
||||
return true;
|
||||
}
|
||||
|
||||
default int airSelectionColor() {
|
||||
return 0xBFF6FA70;
|
||||
}
|
||||
|
||||
default BlockHitResult getAirSelectionHit(Level level, Player player) {
|
||||
if (renderAirSelection()) {
|
||||
final var vec = new Vec3(0, 0, 1)
|
||||
.xRot(-player.getXRot() * Mth.DEG_TO_RAD)
|
||||
.yRot(-player.getYHeadRot() * Mth.DEG_TO_RAD);
|
||||
|
||||
return level.isBlockInLine(new ClipBlockStateContext(
|
||||
player.getEyePosition(),
|
||||
player.getEyePosition().add(vec.scale(4.9)),
|
||||
BlockBehaviour.BlockStateBase::isAir
|
||||
));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
default InteractionResultHolder<ItemStack> useOnAir(Level level, Player player, InteractionHand interactionHand) {
|
||||
final BlockHitResult hit = getAirSelectionHit(level, player);
|
||||
|
||||
if (hit != null) {
|
||||
var result = this.useOn(new UseOnContext(player, interactionHand, hit));
|
||||
|
||||
if (result == InteractionResult.SUCCESS)
|
||||
return InteractionResultHolder.success(player.getItemInHand(interactionHand));
|
||||
else if (result == InteractionResult.FAIL)
|
||||
return InteractionResultHolder.fail(player.getItemInHand(interactionHand));
|
||||
else if (result == InteractionResult.PASS)
|
||||
return InteractionResultHolder.pass(player.getItemInHand(interactionHand));
|
||||
else if (result == InteractionResult.CONSUME)
|
||||
return InteractionResultHolder.consume(player.getItemInHand(interactionHand));
|
||||
}
|
||||
|
||||
return InteractionResultHolder.pass(player.getItemInHand(interactionHand));
|
||||
}
|
||||
|
||||
InteractionResult useOn(UseOnContext useOnContext);
|
||||
}
|
|
@ -3,6 +3,7 @@ package org.betterx.bclib.items;
|
|||
import de.ambertation.wunderlib.math.Bounds;
|
||||
import org.betterx.bclib.client.models.ModelsHelper;
|
||||
import org.betterx.bclib.commands.PlaceCommand;
|
||||
import org.betterx.bclib.interfaces.AirSelectionItem;
|
||||
import org.betterx.bclib.interfaces.ItemModelProvider;
|
||||
import org.betterx.bclib.util.BlocksHelper;
|
||||
import org.betterx.ui.ColorUtil;
|
||||
|
@ -20,7 +21,6 @@ import net.minecraft.network.chat.Style;
|
|||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.InteractionResultHolder;
|
||||
|
@ -28,7 +28,6 @@ import net.minecraft.world.entity.player.Player;
|
|||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.context.UseOnContext;
|
||||
import net.minecraft.world.level.ClipBlockStateContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.JigsawBlock;
|
||||
|
@ -36,11 +35,8 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
|||
import net.minecraft.world.level.block.entity.JigsawBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.StructureBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
@ -48,7 +44,7 @@ import net.fabricmc.api.Environment;
|
|||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class DebugDataItem extends Item implements ItemModelProvider {
|
||||
public class DebugDataItem extends Item implements ItemModelProvider, AirSelectionItem {
|
||||
|
||||
public static final ResourceLocation DEFAULT_ICON = new ResourceLocation("stick");
|
||||
|
||||
|
@ -134,7 +130,7 @@ public class DebugDataItem extends Item implements ItemModelProvider {
|
|||
|
||||
if (predicate.test(level.getBlockState(pos))) {
|
||||
level.setBlock(pos, newState, BlocksHelper.SET_SILENT);
|
||||
|
||||
|
||||
floodFillStructureEntityBounds(level, bounds, pos.above(), entity, predicate, newState, visited);
|
||||
floodFillStructureEntityBounds(level, bounds, pos.below(), entity, predicate, newState, visited);
|
||||
floodFillStructureEntityBounds(level, bounds, pos.north(), entity, predicate, newState, visited);
|
||||
|
@ -177,6 +173,11 @@ public class DebugDataItem extends Item implements ItemModelProvider {
|
|||
this.placeInAir = placeInAir;
|
||||
}
|
||||
|
||||
|
||||
public boolean renderAirSelection() {
|
||||
return placeInAir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFoil(ItemStack itemStack) {
|
||||
return true;
|
||||
|
@ -218,32 +219,7 @@ public class DebugDataItem extends Item implements ItemModelProvider {
|
|||
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand interactionHand) {
|
||||
if (placeInAir) {
|
||||
final var vec = new Vec3(0, 0, 1)
|
||||
.xRot(-player.getXRot() * Mth.DEG_TO_RAD)
|
||||
.yRot(-player.getYHeadRot() * Mth.DEG_TO_RAD);
|
||||
|
||||
BlockHitResult hit = level.isBlockInLine(new ClipBlockStateContext(
|
||||
player.getEyePosition(),
|
||||
player.getEyePosition().add(vec.scale(4.9)),
|
||||
BlockBehaviour.BlockStateBase::isAir
|
||||
));
|
||||
|
||||
if (hit != null) {
|
||||
var result = this.useOn(new UseOnContext(player, interactionHand, hit));
|
||||
|
||||
if (result == InteractionResult.SUCCESS)
|
||||
return InteractionResultHolder.success(player.getItemInHand(interactionHand));
|
||||
else if (result == InteractionResult.FAIL)
|
||||
return InteractionResultHolder.fail(player.getItemInHand(interactionHand));
|
||||
else if (result == InteractionResult.PASS)
|
||||
return InteractionResultHolder.pass(player.getItemInHand(interactionHand));
|
||||
else if (result == InteractionResult.CONSUME)
|
||||
return InteractionResultHolder.consume(player.getItemInHand(interactionHand));
|
||||
}
|
||||
}
|
||||
|
||||
return InteractionResultHolder.pass(player.getItemInHand(interactionHand));
|
||||
return AirSelectionItem.super.useOnAir(level, player, interactionHand);
|
||||
}
|
||||
|
||||
public static DebugDataItem forLootTable(ResourceLocation table, Item icon) {
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
package org.betterx.bclib.mixin.client;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.items.DebugDataItem;
|
||||
import org.betterx.bclib.interfaces.AirSelectionItem;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.*;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.FastColor;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
@ -66,18 +70,26 @@ public abstract class LevelRendererMixin {
|
|||
if (BCLib.isDevEnvironment() && minecraft.hitResult instanceof BlockHitResult blockHitResult) {
|
||||
//will render a block outline when empty blocks are targeted
|
||||
ItemStack item = minecraft.player.getMainHandItem();
|
||||
if (item != null && (item.getItem() instanceof DebugDataItem ddi) && ddi.placeInAir) {
|
||||
final var pos = blockHitResult.getBlockPos();
|
||||
final var state = Blocks.DIRT.defaultBlockState();
|
||||
MultiBufferSource.BufferSource bufferSource = this.renderBuffers.bufferSource();
|
||||
VertexConsumer consumer = bufferSource.getBuffer(RenderType.lines());
|
||||
Vec3 camPos = camera.getPosition();
|
||||
if (item != null
|
||||
&& (item.getItem() instanceof AirSelectionItem airSelect)
|
||||
&& airSelect.renderAirSelection()
|
||||
&& blockHitResult.getType() == HitResult.Type.MISS
|
||||
) {
|
||||
final BlockPos pos = blockHitResult.getBlockPos();
|
||||
final BlockState state = Blocks.DIRT.defaultBlockState();
|
||||
final int color = airSelect.airSelectionColor();
|
||||
final MultiBufferSource.BufferSource bufferSource = this.renderBuffers.bufferSource();
|
||||
final VertexConsumer consumer = bufferSource.getBuffer(RenderType.lines());
|
||||
final Vec3 camPos = camera.getPosition();
|
||||
|
||||
this.renderShape(
|
||||
poseStack, consumer,
|
||||
state.getShape(minecraft.level, pos, CollisionContext.of(camera.getEntity())),
|
||||
pos.getX() - camPos.x(), pos.getY() - camPos.y(), pos.getZ() - camPos.z(),
|
||||
246.0f / 0xff, 250.0f / 0xff, 112.0f / 0xff, 0.75F
|
||||
FastColor.ARGB32.red(color) / (float) 0xff,
|
||||
FastColor.ARGB32.green(color) / (float) 0xff,
|
||||
FastColor.ARGB32.blue(color) / (float) 0xff,
|
||||
FastColor.ARGB32.alpha(color) / (float) 0xff
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue