17
17
18
18
package baritone .api .utils ;
19
19
20
+ import net .minecraft .block .BlockFire ;
21
+ import net .minecraft .block .state .IBlockState ;
22
+ import net .minecraft .client .Minecraft ;
23
+ import net .minecraft .entity .Entity ;
24
+ import net .minecraft .util .math .*;
25
+
26
+ import java .util .Optional ;
27
+
20
28
/**
21
29
* @author Brady
22
30
* @since 9/25/2018
@@ -25,6 +33,33 @@ public final class RotationUtils {
25
33
26
34
private RotationUtils () {}
27
35
36
+ /**
37
+ * The {@link Minecraft} instance
38
+ */
39
+ private static final Minecraft mc = Minecraft .getMinecraft ();
40
+
41
+ /**
42
+ * Constant that a degree value is multiplied by to get the equivalent radian value
43
+ */
44
+ public static final double DEG_TO_RAD = Math .PI / 180.0 ;
45
+
46
+ /**
47
+ * Constant that a radian value is multiplied by to get the equivalent degree value
48
+ */
49
+ public static final double RAD_TO_DEG = 180.0 / Math .PI ;
50
+
51
+ /**
52
+ * Offsets from the root block position to the center of each side.
53
+ */
54
+ private static final Vec3d [] BLOCK_SIDE_MULTIPLIERS = new Vec3d []{
55
+ new Vec3d (0.5 , 0 , 0.5 ), // Down
56
+ new Vec3d (0.5 , 1 , 0.5 ), // Up
57
+ new Vec3d (0.5 , 0.5 , 0 ), // North
58
+ new Vec3d (0.5 , 0.5 , 1 ), // South
59
+ new Vec3d (0 , 0.5 , 0.5 ), // West
60
+ new Vec3d (1 , 0.5 , 0.5 ) // East
61
+ };
62
+
28
63
/**
29
64
* Clamps the specified pitch value between -90 and 90.
30
65
*
@@ -51,4 +86,157 @@ public static float normalizeYaw(float yaw) {
51
86
}
52
87
return newYaw ;
53
88
}
89
+
90
+ /**
91
+ * Calculates the rotation from BlockPos<sub>dest</sub> to BlockPos<sub>orig</sub>
92
+ *
93
+ * @param orig The origin position
94
+ * @param dest The destination position
95
+ * @return The rotation from the origin to the destination
96
+ */
97
+ public static Rotation calcRotationFromCoords (BlockPos orig , BlockPos dest ) {
98
+ return calcRotationFromVec3d (new Vec3d (orig ), new Vec3d (dest ));
99
+ }
100
+
101
+ /**
102
+ * Wraps the target angles to a relative value from the current angles. This is done by
103
+ * subtracting the current from the target, normalizing it, and then adding the current
104
+ * angles back to it.
105
+ *
106
+ * @param current The current angles
107
+ * @param target The target angles
108
+ * @return The wrapped angles
109
+ */
110
+ public static Rotation wrapAnglesToRelative (Rotation current , Rotation target ) {
111
+ return target .subtract (current ).normalize ().add (current );
112
+ }
113
+
114
+ /**
115
+ * Calculates the rotation from Vec<sub>dest</sub> to Vec<sub>orig</sub> and makes the
116
+ * return value relative to the specified current rotations.
117
+ *
118
+ * @see #wrapAnglesToRelative(Rotation, Rotation)
119
+ *
120
+ * @param orig The origin position
121
+ * @param dest The destination position
122
+ * @param current The current rotations
123
+ * @return The rotation from the origin to the destination
124
+ */
125
+ public static Rotation calcRotationFromVec3d (Vec3d orig , Vec3d dest , Rotation current ) {
126
+ return wrapAnglesToRelative (current , calcRotationFromVec3d (orig , dest ));
127
+ }
128
+
129
+ /**
130
+ * Calculates the rotation from Vec<sub>dest</sub> to Vec<sub>orig</sub>
131
+ *
132
+ * @param orig The origin position
133
+ * @param dest The destination position
134
+ * @return The rotation from the origin to the destination
135
+ */
136
+ public static Rotation calcRotationFromVec3d (Vec3d orig , Vec3d dest ) {
137
+ double [] delta = { orig .x - dest .x , orig .y - dest .y , orig .z - dest .z };
138
+ double yaw = MathHelper .atan2 (delta [0 ], -delta [2 ]);
139
+ double dist = Math .sqrt (delta [0 ] * delta [0 ] + delta [2 ] * delta [2 ]);
140
+ double pitch = MathHelper .atan2 (delta [1 ], dist );
141
+ return new Rotation (
142
+ (float ) (yaw * RAD_TO_DEG ),
143
+ (float ) (pitch * RAD_TO_DEG )
144
+ );
145
+ }
146
+
147
+ /**
148
+ * Calculates the look vector for the specified yaw/pitch rotations.
149
+ *
150
+ * @param rotation The input rotation
151
+ * @return Look vector for the rotation
152
+ */
153
+ public static Vec3d calcVec3dFromRotation (Rotation rotation ) {
154
+ float f = MathHelper .cos (-rotation .getYaw () * (float ) DEG_TO_RAD - (float ) Math .PI );
155
+ float f1 = MathHelper .sin (-rotation .getYaw () * (float ) DEG_TO_RAD - (float ) Math .PI );
156
+ float f2 = -MathHelper .cos (-rotation .getPitch () * (float ) DEG_TO_RAD );
157
+ float f3 = MathHelper .sin (-rotation .getPitch () * (float ) DEG_TO_RAD );
158
+ return new Vec3d ((double ) (f1 * f2 ), (double ) f3 , (double ) (f * f2 ));
159
+ }
160
+
161
+ /**
162
+ * Determines if the specified entity is able to reach the center of any of the sides
163
+ * of the specified block. It first checks if the block center is reachable, and if so,
164
+ * that rotation will be returned. If not, it will return the first center of a given
165
+ * side that is reachable. The return type will be {@link Optional#empty()} if the entity is
166
+ * unable to reach any of the sides of the block.
167
+ *
168
+ * @param entity The viewing entity
169
+ * @param pos The target block position
170
+ * @return The optional rotation
171
+ */
172
+ public static Optional <Rotation > reachable (Entity entity , BlockPos pos ) {
173
+ if (pos .equals (RayTraceUtils .getSelectedBlock ().orElse (null ))) {
174
+ /*
175
+ * why add 0.0001?
176
+ * to indicate that we actually have a desired pitch
177
+ * the way we indicate that the pitch can be whatever and we only care about the yaw
178
+ * is by setting the desired pitch to the current pitch
179
+ * setting the desired pitch to the current pitch + 0.0001 means that we do have a desired pitch, it's
180
+ * just what it currently is
181
+ */
182
+ return Optional .of (new Rotation (entity .rotationYaw , entity .rotationPitch + 0.0001F ));
183
+ }
184
+ Optional <Rotation > possibleRotation = reachableCenter (entity , pos );
185
+ //System.out.println("center: " + possibleRotation);
186
+ if (possibleRotation .isPresent ()) {
187
+ return possibleRotation ;
188
+ }
189
+
190
+ IBlockState state = mc .world .getBlockState (pos );
191
+ AxisAlignedBB aabb = state .getBoundingBox (entity .world , pos );
192
+ for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS ) {
193
+ double xDiff = aabb .minX * sideOffset .x + aabb .maxX * (1 - sideOffset .x );
194
+ double yDiff = aabb .minY * sideOffset .y + aabb .maxY * (1 - sideOffset .y );
195
+ double zDiff = aabb .minZ * sideOffset .z + aabb .maxZ * (1 - sideOffset .z );
196
+ possibleRotation = reachableOffset (entity , pos , new Vec3d (pos ).add (xDiff , yDiff , zDiff ));
197
+ if (possibleRotation .isPresent ()) {
198
+ return possibleRotation ;
199
+ }
200
+ }
201
+ return Optional .empty ();
202
+ }
203
+
204
+ /**
205
+ * Determines if the specified entity is able to reach the specified block with
206
+ * the given offsetted position. The return type will be {@link Optional#empty()} if
207
+ * the entity is unable to reach the block with the offset applied.
208
+ *
209
+ * @param entity The viewing entity
210
+ * @param pos The target block position
211
+ * @param offsetPos The position of the block with the offset applied.
212
+ * @return The optional rotation
213
+ */
214
+ public static Optional <Rotation > reachableOffset (Entity entity , BlockPos pos , Vec3d offsetPos ) {
215
+ Rotation rotation = calcRotationFromVec3d (entity .getPositionEyes (1.0F ), offsetPos );
216
+ RayTraceResult result = RayTraceUtils .rayTraceTowards (rotation );
217
+ System .out .println (result );
218
+ if (result != null && result .typeOfHit == RayTraceResult .Type .BLOCK ) {
219
+ if (result .getBlockPos ().equals (pos )) {
220
+ return Optional .of (rotation );
221
+ }
222
+ if (entity .world .getBlockState (pos ).getBlock () instanceof BlockFire ) {
223
+ if (result .getBlockPos ().equals (pos .down ())) {
224
+ return Optional .of (rotation );
225
+ }
226
+ }
227
+ }
228
+ return Optional .empty ();
229
+ }
230
+
231
+ /**
232
+ * Determines if the specified entity is able to reach the specified block where it is
233
+ * looking at the direct center of it's hitbox.
234
+ *
235
+ * @param entity The viewing entity
236
+ * @param pos The target block position
237
+ * @return The optional rotation
238
+ */
239
+ public static Optional <Rotation > reachableCenter (Entity entity , BlockPos pos ) {
240
+ return reachableOffset (entity , pos , VecUtils .calculateBlockCenter (pos ));
241
+ }
54
242
}
0 commit comments