22
33import com .mojang .blaze3d .vertex .PoseStack ;
44import com .mojang .math .Axis ;
5+ import net .blay09 .mods .cookingforblockheads .block .BaseKitchenBlock ;
56import net .blay09 .mods .cookingforblockheads .block .ChickenSinkBlock ;
67import net .blay09 .mods .cookingforblockheads .block .entity .ChickenSinkBlockEntity ;
78import net .minecraft .client .model .animal .chicken .AdultChickenModel ;
2021import net .minecraft .core .registries .Registries ;
2122import net .minecraft .resources .Identifier ;
2223import net .minecraft .util .Mth ;
24+ import net .minecraft .world .attribute .EnvironmentAttributes ;
2325import net .minecraft .world .entity .animal .chicken .ChickenVariant ;
2426import net .minecraft .world .entity .animal .chicken .ChickenVariants ;
2527import net .minecraft .world .level .Level ;
28+ import net .minecraft .world .level .MoonPhase ;
29+ import net .minecraft .world .level .block .state .BlockState ;
2630import net .minecraft .world .phys .Vec3 ;
2731import org .jspecify .annotations .Nullable ;
2832
@@ -48,6 +52,74 @@ public ChickenSinkRenderState createRenderState() {
4852 return new ChickenSinkRenderState ();
4953 }
5054
55+ private boolean shouldCreepyStare (@ Nullable Level level , net .minecraft .core .BlockPos pos ) {
56+ if (level == null ) {
57+ return false ;
58+ }
59+
60+ final var moonPhase = level .environmentAttributes ().getValue (EnvironmentAttributes .MOON_PHASE , pos );
61+ final var moonAngle = level .environmentAttributes ().getValue (EnvironmentAttributes .MOON_ANGLE , pos ) % 360 ;
62+ boolean moonVisible = (moonAngle >= 270 || moonAngle <= 87.5 );
63+ return moonPhase == MoonPhase .FULL_MOON && moonVisible ;
64+ }
65+
66+ private void headbang (@ Nullable Level level , ChickenSinkRenderState renderState , int bpm ) {
67+ long gameTime = level != null ? level .getGameTime () : 0 ;
68+ float headbangIntensity = 25f ;
69+ float headbangSpeed = bpm * (float ) Math .PI / 600f ;
70+ renderState .chicken .xRot = (float ) Math .sin (gameTime * headbangSpeed ) * headbangIntensity ;
71+ renderState .chicken .yRot = (float ) Math .cos (gameTime * headbangSpeed * 0.7f ) * 10f ;
72+ }
73+
74+ private void creepyStare (Level level , net .minecraft .core .BlockPos pos , BlockState state , float delta , ChickenSinkRenderState renderState ) {
75+ final var nearestPlayer = level .getNearestPlayer (pos .getX () + 0.5f , pos .getY () + 0.5f , pos .getZ () + 0.5f , 16f , false );
76+ if (nearestPlayer != null ) {
77+ final var chickenPos = new Vec3 (pos .getX () + 0.5f , pos .getY () + 0.5f , pos .getZ () + 0.5f );
78+ final var playerPos = nearestPlayer .getEyePosition (delta );
79+ final var direction = playerPos .subtract (chickenPos );
80+
81+ float blockYaw = state .getValue (BaseKitchenBlock .FACING ).toYRot ();
82+ double yaw = Math .atan2 (-direction .x , direction .z );
83+ float yawDegrees = (float ) Math .toDegrees (yaw );
84+ float relativeYaw = yawDegrees - blockYaw ;
85+ while (relativeYaw > 180f ) relativeYaw -= 360f ;
86+ while (relativeYaw < -180f ) relativeYaw += 360f ;
87+ renderState .chicken .yRot = Mth .clamp (relativeYaw , -90f , 90f );
88+
89+ double horizontalDistance = Math .sqrt (direction .x * direction .x + direction .z * direction .z );
90+ double pitch = Math .atan2 (-direction .y , horizontalDistance );
91+ float pitchDegrees = (float ) Math .toDegrees (pitch );
92+ renderState .chicken .xRot = Mth .clamp (pitchDegrees , -60f , 60f );
93+ } else {
94+ applyIdleAnimation (level , delta , renderState );
95+ }
96+ }
97+
98+ private void applyIdleAnimation (@ Nullable Level level , float delta , ChickenSinkRenderState renderState ) {
99+ long gameTime = level != null ? level .getGameTime () : 0L ;
100+ float animationTime = (gameTime + delta ) * 0.08f ;
101+ renderState .chicken .xRot = -8f + Mth .sin (animationTime * 0.7f ) * 4f ;
102+ renderState .chicken .yRot = Mth .cos (animationTime * 0.55f ) * 10f ;
103+ }
104+
105+ private void updateChickenPose (ChickenSinkBlockEntity blockEntity , float delta , ChickenSinkRenderState renderState ) {
106+ final var level = blockEntity .getLevel ();
107+ final var pos = blockEntity .getBlockPos ();
108+ final var state = blockEntity .getBlockState ();
109+
110+ if (blockEntity .isPartying ()) {
111+ headbang (level , renderState , 85 );
112+ return ;
113+ }
114+
115+ if (shouldCreepyStare (level , pos )) {
116+ creepyStare (level , pos , state , delta , renderState );
117+ return ;
118+ }
119+
120+ applyIdleAnimation (level , delta , renderState );
121+ }
122+
51123 @ Override
52124 public void extractRenderState (ChickenSinkBlockEntity blockEntity , ChickenSinkRenderState renderState , float delta , Vec3 vec , ModelFeatureRenderer .@ Nullable CrumblingOverlay crumblingOverlay ) {
53125 BlockEntityRenderer .super .extractRenderState (blockEntity , renderState , delta , vec , crumblingOverlay );
@@ -58,11 +130,7 @@ public void extractRenderState(ChickenSinkBlockEntity blockEntity, ChickenSinkRe
58130 .flatMap (it -> it .getOptional (ChickenVariants .DEFAULT ))
59131 .orElse (null )
60132 : null ;
61-
62- long gameTime = blockEntity .getLevel () != null ? blockEntity .getLevel ().getGameTime () : 0L ;
63- float animationTime = (gameTime + delta ) * 0.08f ;
64- renderState .chicken .xRot = -8f + Mth .sin (animationTime * 0.7f ) * 4f ;
65- renderState .chicken .yRot = Mth .cos (animationTime * 0.55f ) * 10f ;
133+ updateChickenPose (blockEntity , delta , renderState );
66134 }
67135
68136 @ Override
0 commit comments