minecraft-src/net/minecraft/client/renderer/entity/layers/StuckInBodyLayer.java
2025-07-04 02:49:36 +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 bufferSource, int packedLight, PlayerRenderState renderState, float yRot, float xRot) {
int i = this.numStuck(renderState);
if (i > 0) {
RandomSource randomSource = RandomSource.create(renderState.id);
for (int j = 0; j < i; j++) {
poseStack.pushPose();
ModelPart modelPart = this.getParentModel().getRandomBodyPart(randomSource);
ModelPart.Cube cube = modelPart.getRandomCube(randomSource);
modelPart.translateAndRotate(poseStack);
float f = randomSource.nextFloat();
float g = randomSource.nextFloat();
float h = randomSource.nextFloat();
if (this.placementStyle == StuckInBodyLayer.PlacementStyle.ON_SURFACE) {
int k = randomSource.nextInt(3);
switch (k) {
case 0:
f = snapToFace(f);
break;
case 1:
g = snapToFace(g);
break;
default:
h = snapToFace(h);
}
}
poseStack.translate(Mth.lerp(f, cube.minX, cube.maxX) / 16.0F, Mth.lerp(g, cube.minY, cube.maxY) / 16.0F, Mth.lerp(h, cube.minZ, cube.maxZ) / 16.0F);
this.renderStuckItem(poseStack, bufferSource, packedLight, -(f * 2.0F - 1.0F), -(g * 2.0F - 1.0F), -(h * 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;
}
}