@@ -32,8 +32,8 @@ public class TickrateChangerClient implements ClientPacketHandler {
3232 public float ticksPerSecond ;
3333
3434 /**
35- * The tickrate before {@link #ticksPerSecond} was changed to 0, used to toggle
36- * pausing
35+ * <p> The tickrate before {@link #ticksPerSecond} was changed to 0
36+ * <p>Used to toggle pausing
3737 */
3838 public float tickrateSaved = 20F ;
3939
@@ -42,12 +42,33 @@ public class TickrateChangerClient implements ClientPacketHandler {
4242 */
4343 public boolean advanceTick = false ;
4444
45+ /**
46+ * How many milliseconds should pass in a tick.
47+ */
4548 public long millisecondsPerTick = 50L ;
4649
50+ /**
51+ * The tickrate steps that can be set via {@link #increaseTickrate()} and {@link #decreaseTickrate()}
52+ */
53+ private float [] rates = new float [] { .1f , .2f , .5f , 1f , 2f , 5f , 10f , 20f , 40f , 100f };
54+ /**
55+ * The current index of the {@link #rates}
56+ */
57+ private short rateIndex = 7 ; // Defaults to tickrate 20
58+
59+ /**
60+ * <p>Creates a new Tickratechanger that is intended to run solely on the client side
61+ * <p>The initial tickrate will be set to 20 ticks/s
62+ */
4763 public TickrateChangerClient () {
4864 this (20f );
4965 }
5066
67+ /**
68+ * <p>Creates a new Tickratechanger that is intended to run solely on the client side
69+ *
70+ * @param initialTickrate The initial tickrate of the client
71+ */
5172 public TickrateChangerClient (float initialTickrate ) {
5273 ticksPerSecond = initialTickrate ;
5374 }
@@ -62,16 +83,24 @@ public void changeTickrate(float tickrate) {
6283 changeServerTickrate (tickrate );
6384 }
6485
86+ /**
87+ * <p>Changes the tickrate of the client
88+ * <p>If tickrate is zero, it will pause the game and store the previous tickrate
89+ * in {@link #tickrateSaved}
90+ *
91+ * @param tickrate The new tickrate of the client
92+ */
6593 public void changeClientTickrate (float tickrate ) {
6694 changeClientTickrate (tickrate , true );
6795 }
6896
6997 /**
70- * Changes the tickrate of the client <br>
71- * If tickrate is zero, it will pause the game and store the previous tickrate
98+ * <p> Changes the tickrate of the client
99+ * <p> If tickrate is zero, it will pause the game and store the previous tickrate
72100 * in {@link #tickrateSaved}
73101 *
74102 * @param tickrate The new tickrate of the client
103+ * @param log Whether this interaction should be logged
75104 */
76105 public void changeClientTickrate (float tickrate , boolean log ) {
77106 if (tickrate < 0 ) {
@@ -95,8 +124,8 @@ public void changeClientTickrate(float tickrate, boolean log) {
95124 }
96125
97126 /**
98- * Attempts to change the tickrate on the server. Sends a
99- * {@link TASmodPackets#TICKRATE_CHANGE} packet to the server
127+ * <p> Attempts to change the tickrate on the server.
128+ * <p>Sends a {@link TASmodPackets#TICKRATE_CHANGE} packet to the server
100129 *
101130 * @param tickrate The new server tickrate
102131 */
@@ -114,7 +143,7 @@ public void changeServerTickrate(float tickrate) {
114143 }
115144
116145 /**
117- * Toggles between tickrate 0 and tickrate > 0
146+ * <p> Toggles between tickrate 0 and tickrate > 0
118147 */
119148 public void togglePause () {
120149 try {
@@ -126,7 +155,7 @@ public void togglePause() {
126155 }
127156
128157 /**
129- * Pauses and unpauses the client, used in main menus
158+ * <p> Pauses and unpauses the client, used in main menus
130159 */
131160 public void togglePauseClient () {
132161 if (ticksPerSecond > 0 ) {
@@ -138,7 +167,7 @@ public void togglePauseClient() {
138167 }
139168
140169 /**
141- * Enables tickrate 0
170+ * <p> Enables tickrate 0
142171 *
143172 * @param pause True if the game should be paused, false if unpause
144173 */
@@ -152,7 +181,7 @@ public void pauseGame(boolean pause) {
152181 }
153182
154183 /**
155- * Pauses the game without sending a command to the server
184+ * <p> Pauses the game without sending a command to the server
156185 *
157186 * @param pause The state of the client
158187 */
@@ -165,8 +194,9 @@ public void pauseClientGame(boolean pause) {
165194 }
166195
167196 /**
168- * Advances the game by 1 tick. Sends a {@link AdvanceTickratePacket} to the
169- * server or calls {@link #advanceClientTick()} if the world is null
197+ * <p>Advances the game by 1 tick.
198+ * <p>Sends a {@link TASmodPackets#TICKRATE_ADVANCE} to the server<p>
199+ * or calls {@link #advanceClientTick()} if the world is null.
170200 */
171201 public void advanceTick () {
172202 if (Minecraft .getMinecraft ().world != null ) {
@@ -177,7 +207,7 @@ public void advanceTick() {
177207 }
178208
179209 /**
180- * Sends a {@link AdvanceTickratePacket} to the server to advance the server
210+ * <p> Sends a {@link TASmodPackets#TICKRATE_ADVANCE} packet to the server
181211 */
182212 public void advanceServerTick () {
183213 try {
@@ -188,7 +218,7 @@ public void advanceServerTick() {
188218 }
189219
190220 /**
191- * Advances the game by 1 tick. Doesn't send a packet to the server
221+ * <p> Advances the game by 1 tick. Doesn't send a packet to the server
192222 */
193223 public void advanceClientTick () {
194224 if (ticksPerSecond == 0 ) {
@@ -197,6 +227,26 @@ public void advanceClientTick() {
197227 }
198228 }
199229
230+ /**
231+ * <p>Increases the tickrate to the next value of {@link #rateIndex} in {@link #rates}
232+ */
233+ public void increaseTickrate () {
234+ rateIndex = findClosestRateIndex (ticksPerSecond );
235+ rateIndex ++;
236+ rateIndex = (short ) clamp (rateIndex , 0 , rates .length - 1 );
237+ changeTickrate (rates [rateIndex ]);
238+ }
239+
240+ /**
241+ * <p>Decreases the tickrate to the previous value of {@link #rateIndex} in {@link #rates}
242+ */
243+ public void decreaseTickrate () {
244+ rateIndex = findClosestRateIndex (ticksPerSecond );
245+ rateIndex --;
246+ rateIndex = (short ) clamp (rateIndex , 0 , rates .length - 1 );
247+ changeTickrate (rates [rateIndex ]);
248+ }
249+
200250 public void joinServer () {
201251 changeServerTickrate (ticksPerSecond );
202252 }
@@ -244,4 +294,52 @@ public void onClientPacket(PacketID id, ByteBuffer buf, String username) throws
244294 }
245295 }
246296
297+ /**
298+ * <p>Finds the nearest rate index from the current tickrate
299+ * @param tickrate The current tickrate to find the rateIndex for
300+ * @return The rateIndex
301+ */
302+ private short findClosestRateIndex (float tickrate ) {
303+ for (int i = 0 ; i < rates .length ; i ++) {
304+ int iMinus1 = i - 1 ;
305+
306+ float min = 0f ;
307+ if (iMinus1 >= 0 ) {
308+ min = rates [iMinus1 ];
309+ }
310+ float max = rates [i ];
311+
312+ if (tickrate >= min && tickrate < max ) {
313+ if (min == 0f ) {
314+ return (short ) i ;
315+ }
316+
317+ float distanceToMin = tickrate - min ;
318+ float distanceToMax = max - tickrate ;
319+
320+ if (distanceToMin < distanceToMax ) {
321+ return (short ) iMinus1 ;
322+ } else if (distanceToMax < distanceToMin ) {
323+ return (short ) i ;
324+ } else {
325+ return (short ) iMinus1 ;
326+ }
327+ }
328+ }
329+ return (short ) (rates .length - 1 );
330+ }
331+
332+ /**
333+ * Basic clamping method
334+ * @param value The value to clamp
335+ * @param min The minimum value
336+ * @param max The maximum value
337+ * @return The clamped value
338+ */
339+ private static int clamp (long value , int min , int max ) {
340+ if (min > max ) {
341+ throw new IllegalArgumentException (min + " > " + max );
342+ }
343+ return (int ) Math .min (max , Math .max (value , min ));
344+ }
247345}
0 commit comments