1+ package  net .darkhax .bookshelf .api .util ;
2+ 
3+ import  java .math .BigDecimal ;
4+ import  java .math .RoundingMode ;
5+ import  java .text .DecimalFormat ;
6+ import  java .util .EnumMap ;
7+ import  java .util .Map ;
8+ import  java .util .Random ;
9+ 
10+ import  net .minecraft .world .level .block .Block ;
11+ import  net .minecraft .core .Direction ;
12+ import  net .minecraft .world .phys .AABB ;
13+ import  net .minecraft .world .phys .shapes .VoxelShape ;
14+ import  net .minecraft .world .phys .Vec3 ;
15+ 
16+ public  final  class  MathsUtils  {
17+ 
18+     /** 
19+      * A decimal format that only preserves two decimal places. 
20+      */ 
21+     public  static  final  DecimalFormat  DECIMAL_2  = new  DecimalFormat ("##.##" );
22+ 
23+     /** 
24+      * Checks if a double is within range of two other doubles. 
25+      * 
26+      * @param min: The smallest valid value. 
27+      * @param max: The largest valid value. 
28+      * @param value: The value to check. 
29+      * @return boolean: Whether or not the value is within the provided scope. 
30+      */ 
31+     public  static  boolean  isInRange  (double  min , double  max , double  value ) {
32+ 
33+         return  value  <= max  && value  >= min ;
34+     }
35+ 
36+     /** 
37+      * Calculates the distance between two Vec3 positions. 
38+      * 
39+      * @param firstPos: The first position to work with. 
40+      * @param secondPos: The second position to work with. 
41+      * @return double: The distance between the two provided locations. 
42+      */ 
43+     public  static  double  getDistanceBetweenPoints  (Vec3  firstPos , Vec3  secondPos ) {
44+ 
45+         final  double  distanceX  = firstPos .x  - secondPos .x ;
46+         final  double  distanceY  = firstPos .y  - secondPos .y ;
47+         final  double  distanceZ  = firstPos .z  - secondPos .z ;
48+ 
49+         return  Math .sqrt (distanceX  * distanceX  + distanceY  * distanceY  + distanceZ  * distanceZ );
50+     }
51+ 
52+     /** 
53+      * This method can be used to round a double to a certain amount of places. 
54+      * 
55+      * @param value: The double being round. 
56+      * @param places: The amount of places to round the double to. 
57+      * @return double: The double entered however being rounded to the amount of places 
58+      *         specified. 
59+      */ 
60+     public  static  double  round  (double  value , int  places ) {
61+ 
62+         return  value  >= 0  && places  > 0  ? BigDecimal .valueOf (value ).setScale (places , RoundingMode .HALF_UP ).doubleValue () : value ;
63+     }
64+ 
65+     /** 
66+      * Used to retrieve a random integer between the two provided integers. The integers 
67+      * provided are also possible outcomes. 
68+      * 
69+      * @param rand An instance of random. 
70+      * @param min The minimum value which can be returned by this method. 
71+      * @param max The maximum value which can be returned by this method. 
72+      * 
73+      * @return An integer between the min and max, including the min and max. 
74+      */ 
75+     public  static  int  nextIntInclusive  (Random  rand , int  min , int  max ) {
76+ 
77+         return  rand .nextInt (max  - min  + 1 ) + min ;
78+     }
79+ 
80+     /** 
81+      * A method which handles the calculating of percentages. While this isn't a particularly 
82+      * difficult piece of code, it has been added for the sake of simplicity. 
83+      * 
84+      * @param percent: The percent chance that this method should return true. 1.00 = 100% 
85+      * @return boolean: Returns are randomly true or false, based on the suplied percentage. 
86+      */ 
87+     public  static  boolean  tryPercentage  (double  percent ) {
88+ 
89+         return  Math .random () < percent ;
90+     }
91+ 
92+     /** 
93+      * Gets the middle integer between two other integers. The order is not important. 
94+      * 
95+      * @param first: The first integer. 
96+      * @param second: The second integer. 
97+      * @return int: The integer that is between the two provided integers. 
98+      */ 
99+     public  static  int  getAverage  (int  first , int  second ) {
100+ 
101+         return  Math .round ((first  + second ) / 2.0F );
102+     }
103+ 
104+     /** 
105+      * Converts time in ticks to a human readable string. 
106+      * 
107+      * @param ticks: The amount of ticks to convert. 
108+      * @return String: A human readable version of the time. 
109+      */ 
110+     public  static  String  ticksToTime  (int  ticks ) {
111+ 
112+         final  int  seconds  = ticks  / 20 ;
113+         final  int  minutes  = seconds  / 60 ;
114+         return  minutes  + ":"  + seconds ;
115+     }
116+ 
117+     /** 
118+      * Gets the percentage of an integer. Result is an integer and decimal is lost. 
119+      * 
120+      * @param value The value to get the percentage of. 
121+      * @param total The total/max value. 
122+      * @return The percentage as an integer. 
123+      */ 
124+     public  static  int  getPercentage  (int  value , int  total ) {
125+ 
126+         return  (int ) ((float ) value  / (float ) total  * 100f );
127+     }
128+ 
129+     /** 
130+      * Gets the distance in world for an amount of pixels. A basic block is a cubic meter, and 
131+      * each pixel is 1/16th of a block. 
132+      * 
133+      * @param pixels The amount of pixels 
134+      * @return The distance in game for those pixels. 
135+      */ 
136+     public  static  double  getPixelDistance  (int  pixels ) {
137+ 
138+         return  pixels  / 16d ;
139+     }
140+ 
141+     /** 
142+      * Creates a bounding box using pixel size. 
143+      * 
144+      * @param minX The min X pos. 
145+      * @param minY The min Y pos. 
146+      * @param minZ The min Z pos. 
147+      * @param maxX The max X pos. 
148+      * @param maxY The max Y pos. 
149+      * @param maxZ The max Z pos. 
150+      * @return A bounding box that is made to a pixel specific size. 
151+      */ 
152+     public  static  AABB  getBoundsForPixels  (int  minX , int  minY , int  minZ , int  maxX , int  maxY , int  maxZ ) {
153+ 
154+         return  new  AABB (getPixelDistance (minX ), getPixelDistance (minY ), getPixelDistance (minZ ), getPixelDistance (maxX ), getPixelDistance (maxY ), getPixelDistance (maxZ ));
155+     }
156+ 
157+     /** 
158+      * Takes an integer value and fits it within a range. If the initial value is less than the 
159+      * minimum it will be set to the minimum. If the initial value is greater than the maximum 
160+      * it will be lowered to the maximum. 
161+      * 
162+      * @param initial The initial value. 
163+      * @param min The minimum value. 
164+      * @param max The maximum value. 
165+      * @return The adjusted value. 
166+      */ 
167+     public  static  int  adjustToRange  (int  initial , int  min , int  max ) {
168+ 
169+         return  initial  < min  ? min  : initial  > max  ? max  : initial ;
170+     }
171+ 
172+     /** 
173+      * Multiplies an int packed color and returns a new int packed number. 
174+      * 
175+      * @param color The base color. 
176+      * @param factor The value to multiply the color by. Less than 1 will darken. Greater than 
177+      *        1 will lighten. 
178+      * @return The resulting color as a packed integer. 
179+      */ 
180+     public  static  int  multiplyColor  (int  color , float  factor ) {
181+ 
182+         final  int  a  = color  >> 24  & 0xFF ;
183+         final  int  r  = (int ) ((color  >> 16  & 0xFF ) * factor );
184+         final  int  g  = (int ) ((color  >> 8  & 0xFF ) * factor );
185+         final  int  b  = (int ) ((color  & 0xFF ) * factor );
186+ 
187+         return  a  << 24  | r  << 16  | g  << 8  | b ;
188+     }
189+ 
190+     /** 
191+      * Creates a rotated variant of a voxel shape for each horizontal direction. The 
192+      * default/base input is expected to be oriented north. 
193+      * 
194+      * @param x1 The min x coordinate. 
195+      * @param y1 The min y coordinate. 
196+      * @param z1 The min z coordinate. 
197+      * @param x2 The max x coordinate. 
198+      * @param y2 The max y coordinate. 
199+      * @param z2 The max z coordinate. 
200+      * @return A map containing rotated shape variants for each horizontal direction. 
201+      */ 
202+     public  static  Map <Direction , VoxelShape > createHorizontalShapes  (double  x1 , double  y1 , double  z1 , double  x2 , double  y2 , double  z2 ) {
203+ 
204+         final  Map <Direction , VoxelShape > shapes  = new  EnumMap <>(Direction .class );
205+         Direction .Plane .HORIZONTAL .forEach (dir  -> shapes .put (dir , rotateShape (dir , x1 , y1 , z1 , x2 , y2 , z2 )));
206+         return  shapes ;
207+     }
208+ 
209+     /** 
210+      * Creates a voxel shape that has been rotated a given direction. The default/base input is 
211+      * expected to be oriented north. Thanks to Gigaherz for writing the original version of 
212+      * this code. 
213+      * 
214+      * @param facing The direction to rotate the shape. 
215+      * @param x1 The min x coordinate. 
216+      * @param y1 The min y coordinate. 
217+      * @param z1 The min z coordinate. 
218+      * @param x2 The max x coordinate. 
219+      * @param y2 The max y coordinate. 
220+      * @param z2 The max z coordinate. 
221+      * @return A voxel shape that has been rotated in the specified direction. 
222+      */ 
223+     public  static  VoxelShape  rotateShape  (Direction  facing , double  x1 , double  y1 , double  z1 , double  x2 , double  y2 , double  z2 ) {
224+ 
225+         switch  (facing ) {
226+             case  NORTH :
227+                 return  Block .box (x1 , y1 , z1 , x2 , y2 , z2 );
228+             case  EAST :
229+                 return  Block .box (16  - z2 , y1 , x1 , 16  - z1 , y2 , x2 );
230+             case  SOUTH :
231+                 return  Block .box (16  - x2 , y1 , 16  - z2 , 16  - x1 , y2 , 16  - z1 );
232+             case  WEST :
233+                 return  Block .box (z1 , y1 , 16  - x2 , z2 , y2 , 16  - x1 );
234+             default :
235+                 throw  new  IllegalArgumentException ("Can not rotate face in direction "  + facing .name ());
236+         }
237+     }
238+ }
0 commit comments