minecraft-src/net/minecraft/client/renderer/entity/layers/StuckInBodyLayer.java
2025-07-04 03:45:38 +03:00

87 lines
3.2 KiB
Java

package net.minecraft.client.renderer.entity.layers;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.model.Model;
import net.minecraft.client.model.PlayerModel;
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.LivingEntityRenderer;
import net.minecraft.client.renderer.entity.state.PlayerRenderState;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
@Environment(EnvType.CLIENT)
public abstract class StuckInBodyLayer<M extends PlayerModel> extends RenderLayer<PlayerRenderState, M> {
private final Model model;
private final ResourceLocation texture;
private final StuckInBodyLayer.PlacementStyle placementStyle;
public StuckInBodyLayer(
LivingEntityRenderer<?, PlayerRenderState, M> renderer, Model model, ResourceLocation texture, StuckInBodyLayer.PlacementStyle placementStyle
) {
super(renderer);
this.model = model;
this.texture = texture;
this.placementStyle = placementStyle;
}
protected abstract int numStuck(PlayerRenderState renderState);
private void renderStuckItem(PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, float x, float y, float z) {
float f = Mth.sqrt(x * x + z * z);
float g = (float)(Math.atan2(x, z) * 180.0F / (float)Math.PI);
float h = (float)(Math.atan2(y, f) * 180.0F / (float)Math.PI);
poseStack.mulPose(Axis.YP.rotationDegrees(g - 90.0F));
poseStack.mulPose(Axis.ZP.rotationDegrees(h));
this.model.renderToBuffer(poseStack, bufferSource.getBuffer(this.model.renderType(this.texture)), packedLight, OverlayTexture.NO_OVERLAY);
}
public void render(PoseStack poseStack, MultiBufferSource multiBufferSource, int i, PlayerRenderState playerRenderState, float f, float g) {
int j = this.numStuck(playerRenderState);
if (j > 0) {
RandomSource randomSource = RandomSource.create(playerRenderState.id);
for (int k = 0; k < j; k++) {
poseStack.pushPose();
ModelPart modelPart = this.getParentModel().getRandomBodyPart(randomSource);
ModelPart.Cube cube = modelPart.getRandomCube(randomSource);
modelPart.translateAndRotate(poseStack);
float h = randomSource.nextFloat();
float l = randomSource.nextFloat();
float m = randomSource.nextFloat();
if (this.placementStyle == StuckInBodyLayer.PlacementStyle.ON_SURFACE) {
int n = randomSource.nextInt(3);
switch (n) {
case 0:
h = snapToFace(h);
break;
case 1:
l = snapToFace(l);
break;
default:
m = snapToFace(m);
}
}
poseStack.translate(Mth.lerp(h, cube.minX, cube.maxX) / 16.0F, Mth.lerp(l, cube.minY, cube.maxY) / 16.0F, Mth.lerp(m, cube.minZ, cube.maxZ) / 16.0F);
this.renderStuckItem(poseStack, multiBufferSource, i, -(h * 2.0F - 1.0F), -(l * 2.0F - 1.0F), -(m * 2.0F - 1.0F));
poseStack.popPose();
}
}
}
private static float snapToFace(float value) {
return value > 0.5F ? 1.0F : 0.5F;
}
@Environment(EnvType.CLIENT)
public static enum PlacementStyle {
IN_CUBE,
ON_SURFACE;
}
}