mirror of
https://github.com/Ellpeck/ActuallyAdditions.git
synced 2024-12-22 19:39:24 +01:00
Add drill highlighting
This commit is contained in:
parent
5a1eabeac4
commit
f390ffd47f
3 changed files with 169 additions and 0 deletions
|
@ -12,34 +12,46 @@ package de.ellpeck.actuallyadditions.mod.event;
|
|||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import de.ellpeck.actuallyadditions.mod.ActuallyAdditions;
|
||||
import de.ellpeck.actuallyadditions.mod.blocks.IHudDisplay;
|
||||
import de.ellpeck.actuallyadditions.mod.config.CommonConfig;
|
||||
import de.ellpeck.actuallyadditions.mod.data.WorldData;
|
||||
import de.ellpeck.actuallyadditions.mod.inventory.gui.EnergyDisplay;
|
||||
import de.ellpeck.actuallyadditions.mod.items.DrillItem;
|
||||
import de.ellpeck.actuallyadditions.mod.items.ItemDrillUpgrade;
|
||||
import de.ellpeck.actuallyadditions.mod.tile.IEnergyDisplay;
|
||||
import de.ellpeck.actuallyadditions.mod.tile.TileEntityBase;
|
||||
import de.ellpeck.actuallyadditions.mod.util.AssetUtil;
|
||||
import de.ellpeck.actuallyadditions.mod.util.StackUtil;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
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.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.neoforge.client.event.RenderGuiOverlayEvent;
|
||||
import net.neoforged.neoforge.client.event.RenderHighlightEvent;
|
||||
import net.neoforged.neoforge.client.gui.overlay.GuiOverlayManager;
|
||||
import net.neoforged.neoforge.event.TickEvent;
|
||||
import net.neoforged.neoforge.event.entity.player.ItemTooltipEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ClientEvents {
|
||||
|
||||
|
@ -227,6 +239,46 @@ public class ClientEvents {
|
|||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void renderBlockHighlight(RenderHighlightEvent.Block event) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
Player player = mc.player;
|
||||
if (mc.player == null)
|
||||
return;
|
||||
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
if (stack.getItem() instanceof DrillItem drillItem) {
|
||||
if (!player.isShiftKeyDown() && drillItem.getHasUpgrade(stack, ItemDrillUpgrade.UpgradeType.THREE_BY_THREE)) {
|
||||
Level level = player.level();
|
||||
Vec3 vec3 = event.getCamera().getPosition();
|
||||
double d0 = vec3.x();
|
||||
double d1 = vec3.y();
|
||||
double d2 = vec3.z();
|
||||
BlockHitResult blockHitResult = event.getTarget();
|
||||
BlockPos targetPos = blockHitResult.getBlockPos();
|
||||
BlockState blockState = level.getBlockState(targetPos);
|
||||
VertexConsumer lineConsumer = event.getMultiBufferSource().getBuffer(RenderType.lines());
|
||||
if (stack.isCorrectToolForDrops(blockState)) {
|
||||
int radius = 0;
|
||||
if (drillItem.getHasUpgrade(stack, ItemDrillUpgrade.UpgradeType.FIVE_BY_FIVE)) {
|
||||
radius = 2;
|
||||
} else if (drillItem.getHasUpgrade(stack, ItemDrillUpgrade.UpgradeType.THREE_BY_THREE)) {
|
||||
radius = 1;
|
||||
}
|
||||
if (radius == 0) return; //No radius, no need to render extra hitboxes
|
||||
|
||||
List<BlockPos> coords = drillItem.gatherBreakingPositions(stack, radius, level, targetPos, blockHitResult.getDirection(), player);
|
||||
for (BlockPos blockPos : coords) {
|
||||
if (blockPos.equals(targetPos)) continue; //Let the original event draw this one!
|
||||
AssetUtil.renderHitOutline(event.getPoseStack(), lineConsumer, player, d0, d1, d2, level, blockPos, level.getBlockState(blockPos));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* @SubscribeEvent //TODO someday move the laser rendering to a new system
|
||||
public void onRenderStage(final RenderLevelStageEvent event) {
|
||||
if(event.getStage() == RenderLevelStageEvent.Stage.AFTER_SOLID_BLOCKS) {
|
||||
|
|
|
@ -54,6 +54,7 @@ import net.neoforged.neoforge.items.IItemHandler;
|
|||
import net.neoforged.neoforge.items.IItemHandlerModifiable;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DrillItem extends ItemEnergy {
|
||||
|
@ -457,6 +458,77 @@ public class DrillItem extends ItemEnergy {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a list of block positions that can be broken taking radius, poker and side into account
|
||||
* @param stack The Drill
|
||||
* @param radius The Radius to break Blocks in (0 means only 1 Block will be broken!)
|
||||
* @param world The World
|
||||
* @param aPos The position of the block being broken
|
||||
* @param side The side of the block being broken
|
||||
* @param player The Player who breaks the Blocks
|
||||
* @return A list of block positions that can be broken
|
||||
*/
|
||||
public List<BlockPos> gatherBreakingPositions(ItemStack stack, int radius, Level world, BlockPos aPos, Direction side, Player player) {
|
||||
int energyStored = this.getEnergyStored(stack);
|
||||
List<BlockPos> positions = new ArrayList<>();
|
||||
|
||||
int xRange = radius;
|
||||
int yRange = radius;
|
||||
int zRange = 0;
|
||||
|
||||
//Corrects Blocks to hit depending on Side of original Block hit
|
||||
if (side.getAxis() == Direction.Axis.Y) {
|
||||
zRange = radius;
|
||||
yRange = 0;
|
||||
}
|
||||
if (side.getAxis() == Direction.Axis.X) {
|
||||
xRange = 0;
|
||||
zRange = radius;
|
||||
}
|
||||
|
||||
//Not defined later because main Block is getting broken below
|
||||
BlockState state = world.getBlockState(aPos);
|
||||
float mainHardness = state.getDestroySpeed(world, aPos);
|
||||
|
||||
//Break Middle Block first
|
||||
int use = this.getEnergyUsePerBlock(stack);
|
||||
if (energyStored < use) {
|
||||
return positions;
|
||||
}
|
||||
|
||||
if (radius == 2 && side.getAxis() != Direction.Axis.Y) {
|
||||
aPos = aPos.above();
|
||||
BlockState theState = world.getBlockState(aPos);
|
||||
if (theState.getDestroySpeed(world, aPos) <= mainHardness + 5.0F) {
|
||||
positions.add(aPos.immutable());
|
||||
}
|
||||
}
|
||||
|
||||
//Break Blocks around
|
||||
if (radius > 0 && mainHardness >= 0.2F) {
|
||||
for (int xPos = aPos.getX() - xRange; xPos <= aPos.getX() + xRange; xPos++) {
|
||||
for (int yPos = aPos.getY() - yRange; yPos <= aPos.getY() + yRange; yPos++) {
|
||||
for (int zPos = aPos.getZ() - zRange; zPos <= aPos.getZ() + zRange; zPos++) {
|
||||
if (!(aPos.getX() == xPos && aPos.getY() == yPos && aPos.getZ() == zPos)) {
|
||||
if (energyStored >= use) {
|
||||
//Only break Blocks around that are (about) as hard or softer
|
||||
BlockPos thePos = new BlockPos(xPos, yPos, zPos);
|
||||
BlockState theState = world.getBlockState(thePos);
|
||||
if (theState.getDestroySpeed(world, thePos) <= mainHardness + 5.0F) {
|
||||
energyStored -= use;
|
||||
positions.add(thePos.immutable());
|
||||
}
|
||||
} else {
|
||||
return positions;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return positions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to harvest a certain Block
|
||||
* Breaks the Block, drops Particles etc.
|
||||
|
|
|
@ -36,13 +36,19 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
|||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.client.resources.language.I18n;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.item.ItemDisplayContext;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import net.neoforged.neoforge.client.ClientHooks;
|
||||
|
@ -423,4 +429,43 @@ public final class AssetUtil {
|
|||
}
|
||||
return new float[]{0.0f, (pos -= 170.0f) * 3.0f, 255.0f - pos * 3.0f};
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static void renderHitOutline(PoseStack poseStack, VertexConsumer consumer, Entity entity,
|
||||
double camX, double camY, double camZ, Level level, BlockPos pos, BlockState state) {
|
||||
renderShape(poseStack, consumer, state.getShape(level, pos, CollisionContext.of(entity)),
|
||||
(double) pos.getX() - camX,
|
||||
(double) pos.getY() - camY,
|
||||
(double) pos.getZ() - camZ,
|
||||
0.0F,
|
||||
0.0F,
|
||||
0.0F,
|
||||
0.4F
|
||||
);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private static void renderShape(PoseStack poseStack, VertexConsumer consumer, VoxelShape shape,
|
||||
double x, double y, double z, float red, float green, float blue, float alpha) {
|
||||
PoseStack.Pose posestack$pose = poseStack.last();
|
||||
shape.forAllEdges(
|
||||
(minX, minY, minZ, maxX, maxY, maxZ) -> {
|
||||
float f = (float) (maxX - minX);
|
||||
float f1 = (float) (maxY - minY);
|
||||
float f2 = (float) (maxZ - minZ);
|
||||
float f3 = Mth.sqrt(f * f + f1 * f1 + f2 * f2);
|
||||
f /= f3;
|
||||
f1 /= f3;
|
||||
f2 /= f3;
|
||||
consumer.vertex(posestack$pose.pose(), (float) (minX + x), (float) (minY + y), (float) (minZ + z))
|
||||
.color(red, green, blue, alpha)
|
||||
.normal(posestack$pose.normal(), f, f1, f2)
|
||||
.endVertex();
|
||||
consumer.vertex(posestack$pose.pose(), (float) (maxX + x), (float) (maxY + y), (float) (maxZ + z))
|
||||
.color(red, green, blue, alpha)
|
||||
.normal(posestack$pose.normal(), f, f1, f2)
|
||||
.endVertex();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue